Replace SkImage_Base::view() and ::refView() with new asView().

Make SkImage_Gpu and SkImage_GpuYUVA have their own implementations
rather than sharing one in SkImage_GpuBase.

New function takes a GrImageTexGenPolicy to enable caller to
force a new texture to be made and choose it's budgeting status rather
than receive a cached view or a view owned by the image.

It also communicates any color type changes when converting a non-
texture image to a texture.

Bug: skia:11208
Change-Id: I6b389442bf9752276a83b21021070e3190610cd7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/361356
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2021-02-03 10:15:31 -05:00 committed by Skia Commit-Bot
parent d80f966d25
commit d0924f3ba9
26 changed files with 355 additions and 296 deletions

View File

@ -66,9 +66,7 @@ static void run(GrRecordingContext* rContext, GrSurfaceDrawContext* rtc, bool su
surf->getCanvas()->drawLine({7.f*w/8.f, 0.f}, {7.f*h/8.f, h}, paint); surf->getCanvas()->drawLine({7.f*w/8.f, 0.f}, {7.f*h/8.f, h}, paint);
auto img = surf->makeImageSnapshot(); auto img = surf->makeImageSnapshot();
if (auto v = as_IB(img)->view(rContext)) { std::tie(src, std::ignore) = as_IB(img)->asView(rContext, GrMipmapped::kNo);
src = *v;
}
} }
if (!src) { if (!src) {
return; return;

View File

@ -174,10 +174,7 @@ public:
surface->getCanvas()->translate(-100, -100); surface->getCanvas()->translate(-100, -100);
surface->getCanvas()->drawPicture(pic); surface->getCanvas()->drawPicture(pic);
sk_sp<SkImage> image(surface->makeImageSnapshot()); sk_sp<SkImage> image(surface->makeImageSnapshot());
const GrSurfaceProxyView* view = as_IB(image)->view(rContext); std::tie(fView, std::ignore) = as_IB(image)->asView(rContext, GrMipmapped::kNo);
if (view) {
fView = *view;
}
} }
} }
protected: protected:
@ -305,19 +302,20 @@ protected:
static void draw_as_tex(SkCanvas* canvas, SkImage* image, SkScalar x, SkScalar y) { static void draw_as_tex(SkCanvas* canvas, SkImage* image, SkScalar x, SkScalar y) {
// The gpu-backed images are drawn in this manner bc the generator backed images // The gpu-backed images are drawn in this manner bc the generator backed images
// aren't considered texture-backed // aren't considered texture-backed
GrSurfaceProxyView view = as_IB(image)->refView(canvas->recordingContext(), auto [view, ct] = as_IB(image)->asView(canvas->recordingContext(), GrMipmapped::kNo);
GrMipmapped::kNo);
if (!view) { if (!view) {
// show placeholder if we have no texture // show placeholder if we have no texture
draw_placeholder(canvas, x, y, image->width(), image->height()); draw_placeholder(canvas, x, y, image->width(), image->height());
return; return;
} }
SkColorInfo colorInfo(GrColorTypeToSkColorType(ct),
image->alphaType(),
image->refColorSpace());
// No API to draw a GrTexture directly, so we cheat and create a private image subclass // No API to draw a GrTexture directly, so we cheat and create a private image subclass
sk_sp<SkImage> texImage(new SkImage_Gpu(sk_ref_sp(canvas->recordingContext()), sk_sp<SkImage> texImage(new SkImage_Gpu(sk_ref_sp(canvas->recordingContext()),
image->uniqueID(), std::move(view), image->uniqueID(),
image->colorType(), image->alphaType(), std::move(view),
image->refColorSpace())); std::move(colorInfo)));
canvas->drawImage(texImage.get(), x, y); canvas->drawImage(texImage.get(), x, y);
} }

View File

@ -97,7 +97,7 @@ bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels,
GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext* ctx, GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext* ctx,
const SkImageInfo& info, const SkImageInfo& info,
const SkIPoint& origin, const SkIPoint& origin,
GrMipmapped mipMapped, GrMipmapped mipmapped,
GrImageTexGenPolicy texGenPolicy) { GrImageTexGenPolicy texGenPolicy) {
SkASSERT(ctx); SkASSERT(ctx);
@ -106,9 +106,8 @@ GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext
SkBudgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted SkBudgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
? SkBudgeted::kNo ? SkBudgeted::kNo
: SkBudgeted::kYes; : SkBudgeted::kYes;
auto surface = SkSurface::MakeRenderTarget(ctx, budgeted, info, 0, auto surface = SkSurface::MakeRenderTarget(ctx, budgeted, info, 0, kTopLeft_GrSurfaceOrigin,
kTopLeft_GrSurfaceOrigin, &props, &props, mipmapped == GrMipmapped::kYes);
mipMapped == GrMipmapped::kYes);
if (!surface) { if (!surface) {
return {}; return {};
} }
@ -121,10 +120,10 @@ GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext
if (!image) { if (!image) {
return {}; return {};
} }
const GrSurfaceProxyView* view = as_IB(image)->view(ctx); auto [view, ct] = as_IB(image)->asView(ctx, mipmapped);
SkASSERT(view); SkASSERT(view);
SkASSERT(mipMapped == GrMipmapped::kNo || SkASSERT(mipmapped == GrMipmapped::kNo ||
view->asTextureProxy()->mipmapped() == GrMipmapped::kYes); view.asTextureProxy()->mipmapped() == GrMipmapped::kYes);
return *view; return view;
} }
#endif #endif

View File

@ -160,10 +160,14 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromImage(GrRecordingContext* rContext
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
if (rContext) { if (rContext) {
GrSurfaceProxyView view = as_IB(image)->refView(rContext, GrMipmapped::kNo); auto [view, ct] = as_IB(image)->asView(rContext, GrMipmapped::kNo);
return MakeDeferredFromGpu(rContext, subset, image->uniqueID(), view, return MakeDeferredFromGpu(rContext,
SkColorTypeToGrColorType(image->colorType()), subset,
image->refColorSpace(), props); image->uniqueID(),
std::move(view),
ct,
image->refColorSpace(),
props);
} }
#endif #endif

View File

@ -46,16 +46,10 @@ GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrRecordingContext* context, co
SkASSERT(as_IB(client)->isYUVA()); SkASSERT(as_IB(client)->isYUVA());
} }
GrSurfaceProxyView GrYUVAImageTextureMaker::refOriginalTextureProxyView(GrMipmapped mipMapped) { GrSurfaceProxyView GrYUVAImageTextureMaker::refOriginalTextureProxyView(GrMipmapped mipmapped) {
if (mipMapped == GrMipmapped::kYes) { auto [view, ct] = fImage->asView(this->context(), mipmapped);
return fImage->refMippedView(this->context()); SkASSERT(ct == this->colorType());
} else { return view;
if (const GrSurfaceProxyView* view = fImage->view(this->context())) {
return *view;
} else {
return {};
}
}
} }
std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProcessor( std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProcessor(

View File

@ -104,6 +104,20 @@ public:
return {std::move(copy), src.origin(), src.swizzle()}; return {std::move(copy), src.origin(), src.swizzle()};
} }
static GrSurfaceProxyView Copy(GrRecordingContext* context,
GrSurfaceProxyView src,
GrMipmapped mipMapped,
SkBackingFit fit,
SkBudgeted budgeted) {
auto copy = GrSurfaceProxy::Copy(context,
src.refProxy(),
src.origin(),
mipMapped,
fit,
budgeted);
return {std::move(copy), src.origin(), src.swizzle()};
}
// This does not reset the origin or swizzle, so the View can still be used to access those // This does not reset the origin or swizzle, so the View can still be used to access those
// properties associated with the detached proxy. // properties associated with the detached proxy.
sk_sp<GrSurfaceProxy> detachProxy() { sk_sp<GrSurfaceProxy> detachProxy() {

View File

@ -653,14 +653,14 @@ sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) {
sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkImage* image) { sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkImage* image) {
SkPixmap pm; SkPixmap pm;
if (image->isTextureBacked()) { if (image->isTextureBacked()) {
const GrSurfaceProxyView* view = as_IB(image)->view(this->recordingContext()); auto [view, ct] = as_IB(image)->asView(this->recordingContext(), GrMipmapped::kNo);
SkASSERT(view); SkASSERT(view);
return SkSpecialImage::MakeDeferredFromGpu(fContext.get(), return SkSpecialImage::MakeDeferredFromGpu(fContext.get(),
SkIRect::MakeWH(image->width(), image->height()), SkIRect::MakeWH(image->width(), image->height()),
image->uniqueID(), image->uniqueID(),
*view, std::move(view),
SkColorTypeToGrColorType(image->colorType()), ct,
image->refColorSpace(), image->refColorSpace(),
&this->surfaceProps()); &this->surfaceProps());
} else if (image->peekPixels(&pm)) { } else if (image->peekPixels(&pm)) {
@ -771,10 +771,10 @@ void SkGpuDevice::drawImageLattice(const SkImage* image,
SkFilterMode filter, const SkPaint& paint) { SkFilterMode filter, const SkPaint& paint) {
ASSERT_SINGLE_OWNER ASSERT_SINGLE_OWNER
auto iter = std::make_unique<SkLatticeIter>(lattice, dst); auto iter = std::make_unique<SkLatticeIter>(lattice, dst);
if (GrSurfaceProxyView view = as_IB(image)->refView(this->recordingContext(), if (auto [view, ct] = as_IB(image)->asView(this->recordingContext(), GrMipmapped::kNo); view) {
GrMipmapped::kNo)) { GrColorInfo colorInfo(ct, image->alphaType(), image->refColorSpace());
this->drawViewLattice(std::move(view), this->drawViewLattice(std::move(view),
image->imageInfo().colorInfo(), std::move(colorInfo),
std::move(iter), std::move(iter),
dst, dst,
filter, filter,

View File

@ -760,13 +760,14 @@ void SkGpuDevice::drawImageQuad(const SkImage* image, const SkRect* srcRect, con
} }
} }
if (GrSurfaceProxyView view = as_IB(image)->refView(this->recordingContext(), if (auto [view, ct] = as_IB(image)->asView(this->recordingContext(),
GrMipmapped(mm != SkMipmapMode::kNone))) { GrMipmapped(mm != SkMipmapMode::kNone)); view) {
// This adjuster shouldn't do anything since we already asked for mip maps if necessary. // This adjuster shouldn't do anything since we already asked for mip maps if necessary.
// TODO: Pull YUVA out of draw_texture_producer and make it work directly from a view. // TODO: Pull YUVA out of draw_texture_producer and make it work directly from a view.
GrColorInfo colorInfo(ct, image->alphaType(), image->refColorSpace());
GrTextureAdjuster adjuster(fContext.get(), GrTextureAdjuster adjuster(fContext.get(),
std::move(view), std::move(view),
image->imageInfo().colorInfo(), std::move(colorInfo),
image->uniqueID()); image->uniqueID());
draw_texture_producer(fContext.get(), fSurfaceDrawContext.get(), clip, matrixProvider, draw_texture_producer(fContext.get(), fSurfaceDrawContext.get(), clip, matrixProvider,
paint, &adjuster, src, dst, dstClip, srcToDst, aa, aaFlags, paint, &adjuster, src, dst, dstClip, srcToDst, aa, aaFlags,
@ -857,7 +858,7 @@ void SkGpuDevice::drawEdgeAAImageSet(const SkCanvas::ImageSetEntry set[], int co
// Extract view from image, but skip YUV images so they get processed through // Extract view from image, but skip YUV images so they get processed through
// drawImageQuad and the proper effect to dynamically sample their planes. // drawImageQuad and the proper effect to dynamically sample their planes.
if (!image->isYUVA()) { if (!image->isYUVA()) {
view = image->refView(this->recordingContext(), GrMipmapped::kNo); std::tie(view, std::ignore) = image->asView(this->recordingContext(), GrMipmapped::kNo);
if (image->isAlphaOnly()) { if (image->isAlphaOnly()) {
GrSwizzle swizzle = GrSwizzle::Concat(view.swizzle(), GrSwizzle("aaaa")); GrSwizzle swizzle = GrSwizzle::Concat(view.swizzle(), GrSwizzle("aaaa"));
view = {view.detachProxy(), view.origin(), swizzle}; view = {view.detachProxy(), view.origin(), swizzle};

View File

@ -33,6 +33,7 @@
#include "include/gpu/GrDirectContext.h" #include "include/gpu/GrDirectContext.h"
#include "src/gpu/GrDirectContextPriv.h" #include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrImageContextPriv.h" #include "src/gpu/GrImageContextPriv.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/image/SkImage_Gpu.h" #include "src/image/SkImage_Gpu.h"
#endif #endif
#include "include/gpu/GrBackendSurface.h" #include "include/gpu/GrBackendSurface.h"
@ -308,6 +309,20 @@ void SkImage_Base::onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace,
callback(context, nullptr); callback(context, nullptr);
} }
#if SK_SUPPORT_GPU
std::tuple<GrSurfaceProxyView, GrColorType> SkImage_Base::asView(GrRecordingContext* context,
GrMipmapped mipmapped,
GrImageTexGenPolicy policy) const {
if (!context) {
return {};
}
if (!context->priv().caps()->mipmapSupport() || this->dimensions().area() <= 1) {
mipmapped = GrMipmapped::kNo;
}
return this->onAsView(context, mipmapped, policy);
}
#endif
GrBackendTexture SkImage_Base::onGetBackendTexture(bool flushPendingGrContextIO, GrBackendTexture SkImage_Base::onGetBackendTexture(bool flushPendingGrContextIO,
GrSurfaceOrigin* origin) const { GrSurfaceOrigin* origin) const {
return GrBackendTexture(); // invalid return GrBackendTexture(); // invalid

View File

@ -17,6 +17,7 @@
#include "include/private/SkTDArray.h" #include "include/private/SkTDArray.h"
#include "src/gpu/GrSurfaceProxyView.h" #include "src/gpu/GrSurfaceProxyView.h"
#include "src/gpu/GrTextureProxy.h" #include "src/gpu/GrTextureProxy.h"
#include "src/gpu/SkGr.h"
class GrTexture; class GrTexture;
#endif #endif
@ -92,13 +93,15 @@ public:
// that single backing proxy will be returned. // that single backing proxy will be returned.
virtual GrTextureProxy* peekProxy() const { return nullptr; } virtual GrTextureProxy* peekProxy() const { return nullptr; }
// If it exists, this returns a pointer to the GrSurfaceProxyView of image. The caller does not // Returns a GrSurfaceProxyView representation of the image, if possible. This also returns
// own the returned view and must copy it if they want to gain a ref to the internal proxy. // a color type. This may be different than the image's color type when the image is not
// If the returned view is not null, then it is guaranteed to have a valid proxy. Additionally // texture-backed and the capabilities of the GPU require a data type conversion to put
// this call will flatten a SkImage_GpuYUV to a single texture. // the data in a texture.
virtual const GrSurfaceProxyView* view(GrRecordingContext*) const { return nullptr; } std::tuple<GrSurfaceProxyView, GrColorType> asView(
GrRecordingContext* context,
GrMipmapped mipmapped,
GrImageTexGenPolicy policy = GrImageTexGenPolicy::kDraw) const;
virtual GrSurfaceProxyView refView(GrRecordingContext*, GrMipmapped) const = 0;
virtual bool isYUVA() const { return false; } virtual bool isYUVA() const { return false; }
#endif #endif
@ -148,7 +151,21 @@ public:
protected: protected:
SkImage_Base(const SkImageInfo& info, uint32_t uniqueID); SkImage_Base(const SkImageInfo& info, uint32_t uniqueID);
#if SK_SUPPORT_GPU
// Utility for making a copy of an existing view when the GrImageTexGenPolicy is not kDraw.
static GrSurfaceProxyView CopyView(GrRecordingContext*,
GrSurfaceProxyView src,
GrMipmapped,
GrImageTexGenPolicy);
#endif
private: private:
#if SK_SUPPORT_GPU
virtual std::tuple<GrSurfaceProxyView, GrColorType> onAsView(
GrRecordingContext*,
GrMipmapped,
GrImageTexGenPolicy policy) const = 0;
#endif
// Set true by caches when they cache content that's derived from the current pixels. // Set true by caches when they cache content that's derived from the current pixels.
mutable std::atomic<bool> fAddedToRasterCache; mutable std::atomic<bool> fAddedToRasterCache;
@ -167,4 +184,20 @@ static inline const SkImage_Base* as_IB(const SkImage* image) {
return static_cast<const SkImage_Base*>(image); return static_cast<const SkImage_Base*>(image);
} }
#if SK_SUPPORT_GPU
inline GrSurfaceProxyView SkImage_Base::CopyView(GrRecordingContext* context,
GrSurfaceProxyView src,
GrMipmapped mipmapped,
GrImageTexGenPolicy policy) {
SkBudgeted budgeted = policy == GrImageTexGenPolicy::kNew_Uncached_Budgeted
? SkBudgeted::kYes
: SkBudgeted::kNo;
return GrSurfaceProxyView::Copy(context,
std::move(src),
mipmapped,
SkBackingFit::kExact,
budgeted);
}
#endif
#endif #endif

View File

@ -40,7 +40,6 @@
#include "src/gpu/GrTextureProxy.h" #include "src/gpu/GrTextureProxy.h"
#include "src/gpu/GrTextureProxyPriv.h" #include "src/gpu/GrTextureProxyPriv.h"
#include "src/gpu/GrYUVATextureProxies.h" #include "src/gpu/GrYUVATextureProxies.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/gl/GrGLTexture.h" #include "src/gpu/gl/GrGLTexture.h"
#include <cstddef> #include <cstddef>
@ -54,12 +53,8 @@ SkImage_Gpu::SkImage_Gpu(sk_sp<GrImageContext> context, uint32_t uniqueID, GrSur
, fView(std::move(view)) { , fView(std::move(view)) {
#ifdef SK_DEBUG #ifdef SK_DEBUG
const GrBackendFormat& format = fView.proxy()->backendFormat(); const GrBackendFormat& format = fView.proxy()->backendFormat();
GrColorType grCT = SkColorTypeToGrColorType(ct);
const GrCaps* caps = this->context()->priv().caps(); const GrCaps* caps = this->context()->priv().caps();
if (caps->isFormatSRGB(format)) { GrColorType grCT = SkColorTypeAndFormatToGrColorType(caps, ct, format);
SkASSERT(grCT == GrColorType::kRGBA_8888);
grCT = GrColorType::kRGBA_8888_SRGB;
}
SkASSERT(caps->isFormatCompressed(format) || SkASSERT(caps->isFormatCompressed(format) ||
caps->areColorTypeAndFormatCompatible(grCT, format)); caps->areColorTypeAndFormatCompatible(grCT, format));
#endif #endif
@ -127,8 +122,8 @@ sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(SkColorType targetCT,
if (!surfaceFillContext) { if (!surfaceFillContext) {
return nullptr; return nullptr;
} }
auto [view, ct] = this->asView(direct, GrMipmapped(this->hasMipmaps()));
auto texFP = GrTextureEffect::Make(*this->view(direct), this->alphaType()); auto texFP = GrTextureEffect::Make(std::move(view), this->alphaType());
auto colorFP = GrColorSpaceXformEffect::Make(std::move(texFP), auto colorFP = GrColorSpaceXformEffect::Make(std::move(texFP),
this->colorSpace(), this->alphaType(), this->colorSpace(), this->alphaType(),
targetCS.get(), this->alphaType()); targetCS.get(), this->alphaType());
@ -339,58 +334,38 @@ sk_sp<SkImage> SkImage::MakeTextureFromCompressed(GrDirectContext* direct, sk_sp
colorType, kOpaque_SkAlphaType, nullptr); colorType, kOpaque_SkAlphaType, nullptr);
} }
static sk_sp<SkImage> create_image_from_producer(GrRecordingContext* context,
GrTextureProducer* producer,
uint32_t id, GrMipmapped mipMapped) {
auto view = producer->view(mipMapped);
if (!view) {
return nullptr;
}
return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), id, std::move(view),
GrColorTypeToSkColorType(producer->colorType()),
producer->alphaType(), sk_ref_sp(producer->colorSpace()));
}
sk_sp<SkImage> SkImage::makeTextureImage(GrDirectContext* dContext, sk_sp<SkImage> SkImage::makeTextureImage(GrDirectContext* dContext,
GrMipmapped mipMapped, GrMipmapped mipmapped,
SkBudgeted budgeted) const { SkBudgeted budgeted) const {
if (!dContext) { if (!dContext) {
return nullptr; return nullptr;
} }
if (!dContext->priv().caps()->mipmapSupport()) {
mipmapped = GrMipmapped::kNo;
}
if (this->isTextureBacked()) { if (this->isTextureBacked()) {
if (!as_IB(this)->context()->priv().matches(dContext)) { if (!as_IB(this)->context()->priv().matches(dContext)) {
return nullptr; return nullptr;
} }
// TODO: Don't flatten YUVA images here. if (this->isTextureBacked() && (mipmapped == GrMipmapped::kNo || this->hasMipmaps())) {
const GrSurfaceProxyView* view = as_IB(this)->view(dContext);
SkASSERT(view && view->asTextureProxy());
if (mipMapped == GrMipmapped::kNo || view->asTextureProxy()->mipmapped() == mipMapped ||
!dContext->priv().caps()->mipmapSupport()) {
return sk_ref_sp(const_cast<SkImage*>(this)); return sk_ref_sp(const_cast<SkImage*>(this));
} }
auto copy = GrCopyBaseMipMapToView(dContext, *view, budgeted);
if (!copy) {
return nullptr;
} }
return sk_make_sp<SkImage_Gpu>(sk_ref_sp(dContext), this->uniqueID(), copy, GrImageTexGenPolicy policy = budgeted == SkBudgeted::kYes
this->colorType(), this->alphaType(), this->refColorSpace()); ? GrImageTexGenPolicy::kNew_Uncached_Budgeted
}
auto policy = budgeted == SkBudgeted::kYes ? GrImageTexGenPolicy::kNew_Uncached_Budgeted
: GrImageTexGenPolicy::kNew_Uncached_Unbudgeted; : GrImageTexGenPolicy::kNew_Uncached_Unbudgeted;
if (this->isLazyGenerated()) { // TODO: Don't flatten YUVA images here. Add mips to the planes instead.
GrImageTextureMaker maker(dContext, this, policy); auto [view, ct] = as_IB(this)->asView(dContext, mipmapped, policy);
return create_image_from_producer(dContext, &maker, this->uniqueID(), mipMapped); SkASSERT(view && view.asTextureProxy());
} SkASSERT(mipmapped == GrMipmapped::kNo ||
view.asTextureProxy()->mipmapped() == GrMipmapped::kYes);
if (const SkBitmap* bmp = as_IB(this)->onPeekBitmap()) { SkColorInfo colorInfo(GrColorTypeToSkColorType(ct), this->alphaType(), this->refColorSpace());
GrBitmapTextureMaker maker(dContext, *bmp, policy); return sk_make_sp<SkImage_Gpu>(sk_ref_sp(dContext),
return create_image_from_producer(dContext, &maker, this->uniqueID(), mipMapped); this->uniqueID(),
} std::move(view),
return nullptr; std::move(colorInfo));
} }
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
@ -605,7 +580,7 @@ bool SkImage::MakeBackendTextureFromSkImage(GrDirectContext* direct,
return false; return false;
} }
GrSurfaceProxyView view = as_IB(image)->refView(direct, GrMipmapped::kNo); auto [view, ct] = as_IB(image)->asView(direct, GrMipmapped::kNo);
if (!view) { if (!view) {
return false; return false;
@ -643,3 +618,22 @@ bool SkImage::MakeBackendTextureFromSkImage(GrDirectContext* direct,
// Steal the backend texture from the GrTexture, releasing the GrTexture in the process. // Steal the backend texture from the GrTexture, releasing the GrTexture in the process.
return GrTexture::StealBackendTexture(std::move(textureRef), backendTexture, releaseProc); return GrTexture::StealBackendTexture(std::move(textureRef), backendTexture, releaseProc);
} }
std::tuple<GrSurfaceProxyView, GrColorType> SkImage_Gpu::onAsView(
GrRecordingContext* context,
GrMipmapped mipmapped,
GrImageTexGenPolicy policy) const {
if (!fContext->priv().matches(context)) {
return {};
}
if (policy != GrImageTexGenPolicy::kDraw) {
return {CopyView(context, fView, mipmapped, policy),
SkColorTypeToGrColorType(this->colorType())};
}
GrColorType ct = SkColorTypeAndFormatToGrColorType(context->priv().caps(),
this->colorType(),
fView.proxy()->backendFormat());
GrColorInfo colorInfo(ct, this->alphaType(), this->refColorSpace());
GrTextureAdjuster adjuster(context, fView, colorInfo, this->uniqueID());
return {adjuster.view(mipmapped), adjuster.colorType()};
}

View File

@ -12,7 +12,6 @@
#include "src/gpu/GrGpuResourcePriv.h" #include "src/gpu/GrGpuResourcePriv.h"
#include "src/gpu/GrSurfaceProxyPriv.h" #include "src/gpu/GrSurfaceProxyPriv.h"
#include "src/gpu/GrSurfaceProxyView.h" #include "src/gpu/GrSurfaceProxyView.h"
#include "src/gpu/SkGr.h"
#include "src/image/SkImage_GpuBase.h" #include "src/image/SkImage_GpuBase.h"
class GrDirectContext; class GrDirectContext;
@ -21,7 +20,7 @@ class GrTexture;
class SkBitmap; class SkBitmap;
class SkImage_Gpu : public SkImage_GpuBase { class SkImage_Gpu final : public SkImage_GpuBase {
public: public:
SkImage_Gpu(sk_sp<GrImageContext>, uint32_t uniqueID, GrSurfaceProxyView, SkColorType, SkImage_Gpu(sk_sp<GrImageContext>, uint32_t uniqueID, GrSurfaceProxyView, SkColorType,
SkAlphaType, sk_sp<SkColorSpace>); SkAlphaType, sk_sp<SkColorSpace>);
@ -44,16 +43,7 @@ public:
GrSemaphoresSubmitted onFlush(GrDirectContext*, const GrFlushInfo&) override; GrSemaphoresSubmitted onFlush(GrDirectContext*, const GrFlushInfo&) override;
GrTextureProxy* peekProxy() const override { GrTextureProxy* peekProxy() const override { return fView.asTextureProxy(); }
return fView.asTextureProxy();
}
const GrSurfaceProxyView* view(GrRecordingContext* context) const override {
if (!fView.proxy()) {
return nullptr;
}
return &fView;
}
GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO, GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
GrSurfaceOrigin* origin) const final; GrSurfaceOrigin* origin) const final;
@ -100,6 +90,10 @@ public:
PromiseImageTextureContext textureContext); PromiseImageTextureContext textureContext);
private: private:
std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*,
GrMipmapped,
GrImageTexGenPolicy) const override;
GrSurfaceProxyView fView; GrSurfaceProxyView fView;
using INHERITED = SkImage_GpuBase; using INHERITED = SkImage_GpuBase;

View File

@ -116,14 +116,13 @@ bool SkImage_GpuBase::getROPixels(GrDirectContext* dContext,
} }
} }
const GrSurfaceProxyView* view = this->view(dContext); auto [view, ct] = this->asView(dContext, GrMipmapped::kNo);
SkASSERT(view); if (!view) {
GrColorType grColorType = SkColorTypeAndFormatToGrColorType( return false;
fContext->priv().caps(), this->colorType(), view->proxy()->backendFormat()); }
auto sContext = GrSurfaceContext::Make(dContext, GrColorInfo colorInfo(ct, this->alphaType(), this->refColorSpace());
*view, auto sContext = GrSurfaceContext::Make(dContext, std::move(view), std::move(colorInfo));
{grColorType, this->alphaType(), this->refColorSpace()});
if (!sContext) { if (!sContext) {
return false; return false;
} }
@ -145,19 +144,26 @@ sk_sp<SkImage> SkImage_GpuBase::onMakeSubset(const SkIRect& subset,
return nullptr; return nullptr;
} }
const GrSurfaceProxyView* view = this->view(direct); auto [view, ct] = this->asView(direct, GrMipmapped::kNo);
SkASSERT(view && view->proxy()); SkASSERT(view);
SkASSERT(ct == SkColorTypeToGrColorType(this->colorType()));
auto copyView = GrSurfaceProxyView::Copy(direct, *view, GrMipmapped::kNo, subset, SkBudgeted isBudgeted = view.proxy()->isBudgeted();
SkBackingFit::kExact, view->proxy()->isBudgeted()); auto copyView = GrSurfaceProxyView::Copy(direct,
std::move(view),
GrMipmapped::kNo,
subset,
SkBackingFit::kExact,
isBudgeted);
if (!copyView) { if (!copyView) {
return nullptr; return nullptr;
} }
// MDB: this call is okay bc we know 'sContext' was kExact return sk_make_sp<SkImage_Gpu>(sk_ref_sp(direct),
return sk_make_sp<SkImage_Gpu>(sk_ref_sp(direct), kNeedNewImageUniqueID, std::move(copyView), kNeedNewImageUniqueID,
this->colorType(), this->alphaType(), this->refColorSpace()); std::move(copyView),
this->imageInfo().colorInfo());
} }
bool SkImage_GpuBase::onReadPixels(GrDirectContext* dContext, bool SkImage_GpuBase::onReadPixels(GrDirectContext* dContext,
@ -172,13 +178,11 @@ bool SkImage_GpuBase::onReadPixels(GrDirectContext* dContext,
return false; return false;
} }
const GrSurfaceProxyView* view = this->view(dContext); auto [view, ct] = this->asView(dContext, GrMipmapped::kNo);
SkASSERT(view); SkASSERT(view);
GrColorType grColorType = SkColorTypeAndFormatToGrColorType(
dContext->priv().caps(), this->colorType(), view->proxy()->backendFormat());
GrColorInfo colorInfo(grColorType, this->alphaType(), this->refColorSpace()); GrColorInfo colorInfo(ct, this->alphaType(), this->refColorSpace());
auto sContext = GrSurfaceContext::Make(dContext, *view, colorInfo); auto sContext = GrSurfaceContext::Make(dContext, std::move(view), colorInfo);
if (!sContext) { if (!sContext) {
return false; return false;
} }
@ -186,23 +190,6 @@ bool SkImage_GpuBase::onReadPixels(GrDirectContext* dContext,
return sContext->readPixels(dContext, {dstInfo, dstPixels, dstRB}, {srcX, srcY}); return sContext->readPixels(dContext, {dstInfo, dstPixels, dstRB}, {srcX, srcY});
} }
GrSurfaceProxyView SkImage_GpuBase::refView(GrRecordingContext* context,
GrMipmapped mipMapped) const {
if (!context || !fContext->priv().matches(context)) {
return {};
}
const GrSurfaceProxyView* view = this->view(context);
if (!view) {
return {};
}
GrColorType ct = SkColorTypeAndFormatToGrColorType(context->priv().caps(),
this->colorType(),
view->proxy()->backendFormat());
GrColorInfo colorInfo(ct, this->alphaType(), this->refColorSpace());
GrTextureAdjuster adjuster(context, *view, colorInfo, this->uniqueID());
return adjuster.view(mipMapped);
}
bool SkImage_GpuBase::onIsValid(GrRecordingContext* context) const { bool SkImage_GpuBase::onIsValid(GrRecordingContext* context) const {
// The base class has already checked that 'context' isn't abandoned (if it's not nullptr) // The base class has already checked that 'context' isn't abandoned (if it's not nullptr)
if (fContext->priv().abandoned()) { if (fContext->priv().abandoned()) {

View File

@ -35,8 +35,6 @@ public:
int srcY, int srcY,
CachingHint) const override; CachingHint) const override;
GrSurfaceProxyView refView(GrRecordingContext*, GrMipmapped) const final;
bool onIsValid(GrRecordingContext*) const final; bool onIsValid(GrRecordingContext*) const final;
#if GR_TEST_UTILS #if GR_TEST_UTILS

View File

@ -143,75 +143,9 @@ bool SkImage_GpuYUVA::onHasMipmaps() const {
GrTextureProxy* SkImage_GpuYUVA::peekProxy() const { return fRGBView.asTextureProxy(); } GrTextureProxy* SkImage_GpuYUVA::peekProxy() const { return fRGBView.asTextureProxy(); }
void SkImage_GpuYUVA::flattenToRGB(GrRecordingContext* context) const { sk_sp<SkImage> SkImage_GpuYUVA::onMakeColorTypeAndColorSpace(SkColorType,
if (fRGBView.proxy()) { sk_sp<SkColorSpace> targetCS,
return; GrDirectContext* direct) const {
}
if (!context || !fContext->priv().matches(context)) {
return;
}
// Needs to create a render target in order to draw to it for the yuv->rgb conversion.
GrImageInfo info(GrColorType::kRGBA_8888,
kPremul_SkAlphaType,
this->refColorSpace(),
this->dimensions());
auto surfaceFillContext = GrSurfaceFillContext::Make(context,
info,
SkBackingFit::kExact,
/*sample count*/ 1,
GrMipmapped::kNo,
GrProtected::kNo);
if (!surfaceFillContext) {
return;
}
const GrCaps& caps = *context->priv().caps();
auto fp = GrYUVtoRGBEffect::Make(fYUVAProxies, GrSamplerState::Filter::kNearest, caps);
if (fFromColorSpace) {
fp = GrColorSpaceXformEffect::Make(std::move(fp),
fFromColorSpace.get(), this->alphaType(),
this->colorSpace(), this->alphaType());
}
surfaceFillContext->fillWithFP(std::move(fp));
fRGBView = surfaceFillContext->readSurfaceView();
SkASSERT(fRGBView.swizzle() == GrSwizzle());
fYUVAProxies = {};
}
GrSurfaceProxyView SkImage_GpuYUVA::refMippedView(GrRecordingContext* context) const {
// if invalid or already has miplevels
this->flattenToRGB(context);
if (!fRGBView || fRGBView.asTextureProxy()->mipmapped() == GrMipmapped::kYes) {
return fRGBView;
}
// need to generate mips for the proxy
auto mippedView = GrCopyBaseMipMapToView(context, fRGBView);
if (!mippedView) {
return {};
}
fRGBView = std::move(mippedView);
return fRGBView;
}
const GrSurfaceProxyView* SkImage_GpuYUVA::view(GrRecordingContext* context) const {
this->flattenToRGB(context);
if (!fRGBView.proxy()) {
return nullptr;
}
return &fRGBView;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<SkImage> SkImage_GpuYUVA::onMakeColorTypeAndColorSpace(
SkColorType, sk_sp<SkColorSpace> targetCS, GrDirectContext* direct) const {
// We explicitly ignore color type changes, for now. // We explicitly ignore color type changes, for now.
// we may need a mutex here but for now we expect usage to be in a single thread // we may need a mutex here but for now we expect usage to be in a single thread
@ -231,6 +165,99 @@ sk_sp<SkImage> SkImage_GpuYUVA::onReinterpretColorSpace(sk_sp<SkColorSpace> newC
return sk_sp<SkImage>(new SkImage_GpuYUVA(fContext, this, std::move(newCS))); return sk_sp<SkImage>(new SkImage_GpuYUVA(fContext, this, std::move(newCS)));
} }
static GrSurfaceProxyView render_to_rgb(GrRecordingContext* context,
const SkColorInfo& colorInfo,
const GrYUVATextureProxies& proxies,
SkColorSpace* fromColorSpace,
GrMipmapped mipmapped,
SkBudgeted budgeted) {
GrImageInfo ii(colorInfo, proxies.yuvaInfo().dimensions());
auto surfaceFillContext = GrSurfaceFillContext::Make(context,
std::move(ii),
SkBackingFit::kExact,
/*sample count*/ 1,
mipmapped,
GrProtected::kNo,
kTopLeft_GrSurfaceOrigin,
budgeted);
if (!surfaceFillContext) {
return {};
}
const GrCaps& caps = *context->priv().caps();
auto fp = GrYUVtoRGBEffect::Make(proxies, GrSamplerState::Filter::kNearest, caps);
if (fromColorSpace) {
fp = GrColorSpaceXformEffect::Make(std::move(fp),
fromColorSpace, colorInfo.alphaType(),
colorInfo.colorSpace(), colorInfo.alphaType());
}
surfaceFillContext->fillWithFP(std::move(fp));
return surfaceFillContext->readSurfaceView();
}
bool SkImage_GpuYUVA::flattenToRGB(GrRecordingContext* context, GrMipmapped mipmapped) const {
if (fRGBView.proxy()) {
if (mipmapped == GrMipmapped::kYes &&
fRGBView.proxy()->asTextureProxy()->mipmapped() == GrMipmapped::kNo) {
GrSurfaceProxyView mippedView = GrCopyBaseMipMapToView(context, fRGBView);
if (!mippedView) {
return false;
}
fRGBView = std::move(mippedView);
return true;
}
return true;
}
if (!context || !fContext->priv().matches(context)) {
return false;
}
GrSurfaceProxyView rgbView = render_to_rgb(context,
this->imageInfo().colorInfo(),
fYUVAProxies,
fFromColorSpace.get(),
mipmapped,
SkBudgeted::kYes);
if (!rgbView) {
return false;
}
fRGBView = std::move(rgbView);
fYUVAProxies = {};
return true;
}
std::tuple<GrSurfaceProxyView, GrColorType> SkImage_GpuYUVA::onAsView(
GrRecordingContext* context,
GrMipmapped mipmapped,
GrImageTexGenPolicy policy) const {
if (!fContext->priv().matches(context)) {
return {};
}
if (policy != GrImageTexGenPolicy::kDraw) {
SkBudgeted budgeted = policy == GrImageTexGenPolicy::kNew_Uncached_Budgeted
? SkBudgeted::kYes
: SkBudgeted::kNo;
if (fRGBView) {
return {CopyView(context, fRGBView, mipmapped, policy), GrColorType::kRGBA_8888};
}
auto view = render_to_rgb(context,
this->imageInfo().colorInfo(),
fYUVAProxies,
fFromColorSpace.get(),
mipmapped,
budgeted);
return {std::move(view), GrColorType::kRGBA_8888};
}
if (!this->flattenToRGB(context, mipmapped)) {
return {};
}
return {fRGBView, GrColorType::kRGBA_8888};
}
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<SkImage> SkImage::MakeFromYUVATextures(GrRecordingContext* context, sk_sp<SkImage> SkImage::MakeFromYUVATextures(GrRecordingContext* context,

View File

@ -21,7 +21,7 @@ class GrTexture;
// Initially any direct rendering will be done by passing the individual planes to a shader. // Initially any direct rendering will be done by passing the individual planes to a shader.
// Once any method requests a flattened image (e.g., onReadPixels), the flattened RGB // Once any method requests a flattened image (e.g., onReadPixels), the flattened RGB
// proxy will be stored and used for any future rendering. // proxy will be stored and used for any future rendering.
class SkImage_GpuYUVA : public SkImage_GpuBase { class SkImage_GpuYUVA final : public SkImage_GpuBase {
public: public:
friend class GrYUVAImageTextureMaker; friend class GrYUVAImageTextureMaker;
@ -38,8 +38,6 @@ public:
// nullptr if they have not. // nullptr if they have not.
GrTextureProxy* peekProxy() const override; GrTextureProxy* peekProxy() const override;
const GrSurfaceProxyView* view(GrRecordingContext* context) const override;
bool onIsTextureBacked() const override { bool onIsTextureBacked() const override {
// We should have YUVA proxies or a RGBA proxy,but not both. // We should have YUVA proxies or a RGBA proxy,but not both.
SkASSERT(fYUVAProxies.isValid() != SkToBool(fRGBView)); SkASSERT(fYUVAProxies.isValid() != SkToBool(fRGBView));
@ -55,9 +53,6 @@ public:
bool setupMipmapsForPlanes(GrRecordingContext*) const; bool setupMipmapsForPlanes(GrRecordingContext*) const;
// Returns a ref-ed texture proxy view with miplevels
GrSurfaceProxyView refMippedView(GrRecordingContext*) const;
#if GR_TEST_UTILS #if GR_TEST_UTILS
bool testingOnly_IsFlattened() const { bool testingOnly_IsFlattened() const {
// We should only have the flattened proxy or the planar proxies at one point in time. // We should only have the flattened proxy or the planar proxies at one point in time.
@ -79,7 +74,11 @@ public:
private: private:
SkImage_GpuYUVA(sk_sp<GrImageContext>, const SkImage_GpuYUVA* image, sk_sp<SkColorSpace>); SkImage_GpuYUVA(sk_sp<GrImageContext>, const SkImage_GpuYUVA* image, sk_sp<SkColorSpace>);
void flattenToRGB(GrRecordingContext*) const; std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*,
GrMipmapped,
GrImageTexGenPolicy) const override;
bool flattenToRGB(GrRecordingContext*, GrMipmapped) const;
mutable GrYUVATextureProxies fYUVAProxies; mutable GrYUVATextureProxies fYUVAProxies;

View File

@ -32,7 +32,6 @@
#include "src/gpu/GrSamplerState.h" #include "src/gpu/GrSamplerState.h"
#include "src/gpu/GrSurfaceFillContext.h" #include "src/gpu/GrSurfaceFillContext.h"
#include "src/gpu/GrYUVATextureProxies.h" #include "src/gpu/GrYUVATextureProxies.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/effects/GrYUVtoRGBEffect.h" #include "src/gpu/effects/GrYUVtoRGBEffect.h"
#endif #endif
@ -195,17 +194,6 @@ bool SkImage_Lazy::onIsValid(GrRecordingContext* context) const {
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
GrSurfaceProxyView SkImage_Lazy::refView(GrRecordingContext* context, GrMipmapped mipMapped) const {
if (!context) {
return {};
}
GrImageTextureMaker textureMaker(context, this, GrImageTexGenPolicy::kDraw);
return textureMaker.view(mipMapped);
}
#endif
sk_sp<SkImage> SkImage_Lazy::onMakeSubset(const SkIRect& subset, GrDirectContext* direct) const { sk_sp<SkImage> SkImage_Lazy::onMakeSubset(const SkIRect& subset, GrDirectContext* direct) const {
// TODO: can we do this more efficiently, by telling the generator we want to // TODO: can we do this more efficiently, by telling the generator we want to
// "realize" a subset? // "realize" a subset?
@ -259,6 +247,14 @@ sk_sp<SkImage> SkImage::MakeFromGenerator(std::unique_ptr<SkImageGenerator> gene
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
std::tuple<GrSurfaceProxyView, GrColorType> SkImage_Lazy::onAsView(
GrRecordingContext* context,
GrMipmapped mipmapped,
GrImageTexGenPolicy policy) const {
GrImageTextureMaker textureMaker(context, this, policy);
return {textureMaker.view(mipmapped), textureMaker.colorType()};
}
GrSurfaceProxyView SkImage_Lazy::textureProxyViewFromPlanes(GrRecordingContext* ctx, GrSurfaceProxyView SkImage_Lazy::textureProxyViewFromPlanes(GrRecordingContext* ctx,
SkBudgeted budgeted) const { SkBudgeted budgeted) const {
SkYUVAPixmapInfo::SupportedDataTypes supportedDataTypes(*ctx); SkYUVAPixmapInfo::SupportedDataTypes supportedDataTypes(*ctx);

View File

@ -10,7 +10,6 @@
#include "include/private/SkIDChangeListener.h" #include "include/private/SkIDChangeListener.h"
#include "include/private/SkMutex.h" #include "include/private/SkMutex.h"
#include "src/gpu/SkGr.h"
#include "src/image/SkImage_Base.h" #include "src/image/SkImage_Base.h"
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
@ -43,9 +42,6 @@ public:
bool onReadPixels(GrDirectContext*, const SkImageInfo&, void*, size_t, int srcX, int srcY, bool onReadPixels(GrDirectContext*, const SkImageInfo&, void*, size_t, int srcX, int srcY,
CachingHint) const override; CachingHint) const override;
#if SK_SUPPORT_GPU
GrSurfaceProxyView refView(GrRecordingContext*, GrMipmapped) const override;
#endif
sk_sp<SkData> onRefEncoded() const override; sk_sp<SkData> onRefEncoded() const override;
sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const override; sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const override;
bool getROPixels(GrDirectContext*, SkBitmap*, CachingHint) const override; bool getROPixels(GrDirectContext*, SkBitmap*, CachingHint) const override;
@ -73,9 +69,12 @@ public:
private: private:
void addUniqueIDListener(sk_sp<SkIDChangeListener>) const; void addUniqueIDListener(sk_sp<SkIDChangeListener>) const;
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*,
GrMipmapped,
GrImageTexGenPolicy) const override;
GrSurfaceProxyView textureProxyViewFromPlanes(GrRecordingContext*, SkBudgeted) const;
sk_sp<SkCachedData> getPlanes(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes, sk_sp<SkCachedData> getPlanes(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
SkYUVAPixmaps* pixmaps) const; SkYUVAPixmaps* pixmaps) const;
GrSurfaceProxyView textureProxyViewFromPlanes(GrRecordingContext*, SkBudgeted) const;
#endif #endif
class ScopedGenerator; class ScopedGenerator;

View File

@ -20,6 +20,7 @@
#include "src/shaders/SkBitmapProcShader.h" #include "src/shaders/SkBitmapProcShader.h"
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
#include "src/gpu/GrBitmapTextureMaker.h"
#include "src/gpu/GrTextureAdjuster.h" #include "src/gpu/GrTextureAdjuster.h"
#include "src/gpu/SkGr.h" #include "src/gpu/SkGr.h"
#endif #endif
@ -83,10 +84,6 @@ public:
bool onPeekPixels(SkPixmap*) const override; bool onPeekPixels(SkPixmap*) const override;
const SkBitmap* onPeekBitmap() const override { return &fBitmap; } const SkBitmap* onPeekBitmap() const override { return &fBitmap; }
#if SK_SUPPORT_GPU
GrSurfaceProxyView refView(GrRecordingContext*, GrMipmapped) const override;
#endif
bool getROPixels(GrDirectContext*, SkBitmap*, CachingHint) const override; bool getROPixels(GrDirectContext*, SkBitmap*, CachingHint) const override;
sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const override; sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const override;
@ -136,6 +133,12 @@ public:
} }
private: private:
#if SK_SUPPORT_GPU
std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*,
GrMipmapped,
GrImageTexGenPolicy) const override;
#endif
SkBitmap fBitmap; SkBitmap fBitmap;
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
@ -143,6 +146,7 @@ private:
mutable int32_t fPinnedCount = 0; mutable int32_t fPinnedCount = 0;
mutable uint32_t fPinnedUniqueID = SK_InvalidUniqueID; mutable uint32_t fPinnedUniqueID = SK_InvalidUniqueID;
mutable uint32_t fPinnedContextID = SK_InvalidUniqueID; mutable uint32_t fPinnedContextID = SK_InvalidUniqueID;
mutable GrColorType fPinnedColorType = GrColorType::kUnknown;
#endif #endif
using INHERITED = SkImage_Base; using INHERITED = SkImage_Base;
@ -191,24 +195,6 @@ bool SkImage_Raster::getROPixels(GrDirectContext*, SkBitmap* dst, CachingHint) c
} }
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
GrSurfaceProxyView SkImage_Raster::refView(GrRecordingContext* context,
GrMipmapped mipmapped) const {
if (!context) {
return {};
}
if (fPinnedView) {
GrColorType ct = SkColorTypeAndFormatToGrColorType(context->priv().caps(),
this->colorType(),
fPinnedView.proxy()->backendFormat());
GrColorInfo colorInfo(ct, this->alphaType(), this->refColorSpace());
GrTextureAdjuster adjuster(context, fPinnedView, colorInfo, fPinnedUniqueID);
return adjuster.view(mipmapped);
}
return GrRefCachedBitmapView(context, fBitmap, mipmapped);
}
bool SkImage_Raster::onPinAsTexture(GrRecordingContext* rContext) const { bool SkImage_Raster::onPinAsTexture(GrRecordingContext* rContext) const {
if (fPinnedView) { if (fPinnedView) {
SkASSERT(fPinnedCount > 0); SkASSERT(fPinnedCount > 0);
@ -219,13 +205,15 @@ bool SkImage_Raster::onPinAsTexture(GrRecordingContext* rContext) const {
} else { } else {
SkASSERT(fPinnedCount == 0); SkASSERT(fPinnedCount == 0);
SkASSERT(fPinnedUniqueID == 0); SkASSERT(fPinnedUniqueID == 0);
fPinnedView = GrRefCachedBitmapView(rContext, fBitmap, GrMipmapped::kNo); GrBitmapTextureMaker maker(rContext, fBitmap, GrImageTexGenPolicy::kDraw);
fPinnedView = maker.view(GrMipmapped::kNo);
if (!fPinnedView) { if (!fPinnedView) {
return false; return false;
} }
SkASSERT(fPinnedView.asTextureProxy()); SkASSERT(fPinnedView.asTextureProxy());
fPinnedUniqueID = fBitmap.getGenerationID(); fPinnedUniqueID = fBitmap.getGenerationID();
fPinnedContextID = rContext->priv().contextID(); fPinnedContextID = rContext->priv().contextID();
fPinnedColorType = maker.colorType();
} }
// Note: we only increment if the texture was successfully pinned // Note: we only increment if the texture was successfully pinned
++fPinnedCount; ++fPinnedCount;
@ -246,13 +234,13 @@ void SkImage_Raster::onUnpinAsTexture(GrRecordingContext* rContext) const {
fPinnedView = GrSurfaceProxyView(); fPinnedView = GrSurfaceProxyView();
fPinnedUniqueID = SK_InvalidUniqueID; fPinnedUniqueID = SK_InvalidUniqueID;
fPinnedContextID = SK_InvalidUniqueID; fPinnedContextID = SK_InvalidUniqueID;
fPinnedColorType = GrColorType::kUnknown;
} }
} }
bool SkImage_Raster::isPinnedOnContext(GrRecordingContext* rContext) const { bool SkImage_Raster::isPinnedOnContext(GrRecordingContext* rContext) const {
return fPinnedContextID == rContext->priv().contextID(); return fPinnedContextID == rContext->priv().contextID();
} }
#endif #endif
sk_sp<SkImage> SkImage_Raster::onMakeSubset(const SkIRect& subset, GrDirectContext*) const { sk_sp<SkImage> SkImage_Raster::onMakeSubset(const SkIRect& subset, GrDirectContext*) const {
@ -416,3 +404,22 @@ sk_sp<SkImage> SkImage_Raster::onReinterpretColorSpace(sk_sp<SkColorSpace> newCS
pixmap.setColorSpace(std::move(newCS)); pixmap.setColorSpace(std::move(newCS));
return SkImage::MakeRasterCopy(pixmap); return SkImage::MakeRasterCopy(pixmap);
} }
#if SK_SUPPORT_GPU
std::tuple<GrSurfaceProxyView, GrColorType> SkImage_Raster::onAsView(
GrRecordingContext* context,
GrMipmapped mipmapped,
GrImageTexGenPolicy policy) const {
if (fPinnedView) {
if (policy != GrImageTexGenPolicy::kDraw) {
return {CopyView(context, fPinnedView, mipmapped, policy), fPinnedColorType};
}
GrColorInfo colorInfo(fPinnedColorType, this->alphaType(), this->refColorSpace());
GrTextureAdjuster adjuster(context, fPinnedView, colorInfo, fPinnedUniqueID);
return {adjuster.view(mipmapped), adjuster.colorType()};
}
GrBitmapTextureMaker maker(context, fBitmap, policy);
return {maker.view(mipmapped), maker.colorType()};
}
#endif

View File

@ -407,7 +407,7 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
auto mipmapped = !GrValidCubicResampler(kernel) && mm != SkMipmapMode::kNone auto mipmapped = !GrValidCubicResampler(kernel) && mm != SkMipmapMode::kNone
? GrMipmapped::kYes ? GrMipmapped::kYes
: GrMipmapped::kNo; : GrMipmapped::kNo;
GrSurfaceProxyView view = as_IB(fImage)->refView(args.fContext, mipmapped); auto [view, ct] = as_IB(fImage)->asView(args.fContext, mipmapped);
if (!view) { if (!view) {
return nullptr; return nullptr;
} }

View File

@ -61,10 +61,10 @@ DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendSurfaceMutableStateTest, reporter, ctxIn
kRGBA_8888_SkColorType, kRGBA_8888_SkColorType,
kPremul_SkAlphaType, nullptr); kPremul_SkAlphaType, nullptr);
const GrSurfaceProxyView* view = as_IB(wrappedImage)->view(dContext); GrSurfaceProxy* proxy = as_IB(wrappedImage)->peekProxy();
REPORTER_ASSERT(reporter, view); REPORTER_ASSERT(reporter, proxy);
REPORTER_ASSERT(reporter, view->proxy()->isInstantiated()); REPORTER_ASSERT(reporter, proxy->isInstantiated());
GrTexture* texture = view->proxy()->peekTexture(); GrTexture* texture = proxy->peekTexture();
REPORTER_ASSERT(reporter, texture); REPORTER_ASSERT(reporter, texture);
// Verify that modifying the layout via the GrVkTexture is reflected in the GrBackendTexture // Verify that modifying the layout via the GrVkTexture is reflected in the GrBackendTexture

View File

@ -69,10 +69,10 @@ DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLTextureParameters, reporter, ctxInfo) {
kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr); kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
REPORTER_ASSERT(reporter, wrappedImage); REPORTER_ASSERT(reporter, wrappedImage);
const GrSurfaceProxyView* view = as_IB(wrappedImage)->view(dContext); GrSurfaceProxy* proxy = as_IB(wrappedImage)->peekProxy();
REPORTER_ASSERT(reporter, view); REPORTER_ASSERT(reporter, proxy);
REPORTER_ASSERT(reporter, view->proxy()->isInstantiated()); REPORTER_ASSERT(reporter, proxy->isInstantiated());
auto texture = static_cast<GrGLTexture*>(view->proxy()->peekTexture()); auto texture = static_cast<GrGLTexture*>(proxy->peekTexture());
REPORTER_ASSERT(reporter, texture); REPORTER_ASSERT(reporter, texture);
auto parameters = texture->parameters(); auto parameters = texture->parameters();
REPORTER_ASSERT(reporter, parameters); REPORTER_ASSERT(reporter, parameters);

View File

@ -86,12 +86,12 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest, reporter, ctxInfo) {
sk_gpu_test::ManagedBackendTexture::ReleaseProc, sk_gpu_test::ManagedBackendTexture::ReleaseProc,
mbet->releaseContext()); mbet->releaseContext());
REPORTER_ASSERT(reporter, (mipmapped == GrMipmapped::kYes) == image->hasMipmaps()); REPORTER_ASSERT(reporter, (mipmapped == GrMipmapped::kYes) == image->hasMipmaps());
const GrSurfaceProxyView* view = as_IB(image)->view(dContext); GrSurfaceProxy* surfaceProxy = as_IB(image)->peekProxy();
REPORTER_ASSERT(reporter, view); REPORTER_ASSERT(reporter, surfaceProxy);
if (!view) { if (!proxy) {
continue; continue;
} }
proxy = view->asTextureProxyRef(); proxy = sk_ref_sp(surfaceProxy->asTextureProxy());
} }
REPORTER_ASSERT(reporter, proxy); REPORTER_ASSERT(reporter, proxy);
if (!proxy) { if (!proxy) {

View File

@ -380,7 +380,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkImage_makeTextureImage, reporter, contextIn
GrContextFactory otherFactory; GrContextFactory otherFactory;
ContextInfo otherContextInfo = otherFactory.getContextInfo(contextInfo.type()); ContextInfo otherContextInfo = otherFactory.getContextInfo(contextInfo.type());
testContext->makeCurrent(); testContext->makeCurrent();
std::function<sk_sp<SkImage>()> imageFactories[] = { std::function<sk_sp<SkImage>()> imageFactories[] = {
create_image, create_codec_image, create_data_image, create_image, create_codec_image, create_data_image,
// Create an image from a picture. // Create an image from a picture.
@ -996,19 +995,21 @@ static void test_cross_context_image(skiatest::Reporter* reporter, const GrConte
testContext->makeCurrent(); testContext->makeCurrent();
sk_sp<SkImage> refImg(imageMaker(dContext)); sk_sp<SkImage> refImg(imageMaker(dContext));
GrSurfaceProxyView view, otherView, viewSecondRef;
// Any context should be able to borrow the texture at this point // Any context should be able to borrow the texture at this point
GrSurfaceProxyView view = as_IB(refImg)->refView(dContext, GrMipmapped::kNo); std::tie(view, std::ignore) = as_IB(refImg)->asView(dContext, GrMipmapped::kNo);
REPORTER_ASSERT(reporter, view); REPORTER_ASSERT(reporter, view);
// But once it's borrowed, no other context should be able to borrow // But once it's borrowed, no other context should be able to borrow
otherTestContext->makeCurrent(); otherTestContext->makeCurrent();
GrSurfaceProxyView otherView = as_IB(refImg)->refView(otherCtx, GrMipmapped::kNo); std::tie(otherView, std::ignore) = as_IB(refImg)->asView(otherCtx, GrMipmapped::kNo);
REPORTER_ASSERT(reporter, !otherView); REPORTER_ASSERT(reporter, !otherView);
// Original context (that's already borrowing) should be okay // Original context (that's already borrowing) should be okay
testContext->makeCurrent(); testContext->makeCurrent();
GrSurfaceProxyView viewSecondRef = as_IB(refImg)->refView(dContext, GrMipmapped::kNo); std::tie(viewSecondRef, std::ignore) = as_IB(refImg)->asView(dContext,
GrMipmapped::kNo);
REPORTER_ASSERT(reporter, viewSecondRef); REPORTER_ASSERT(reporter, viewSecondRef);
// Release first ref from the original context // Release first ref from the original context
@ -1017,7 +1018,7 @@ static void test_cross_context_image(skiatest::Reporter* reporter, const GrConte
// We released one proxy but not the other from the current borrowing context. Make sure // We released one proxy but not the other from the current borrowing context. Make sure
// a new context is still not able to borrow the texture. // a new context is still not able to borrow the texture.
otherTestContext->makeCurrent(); otherTestContext->makeCurrent();
otherView = as_IB(refImg)->refView(otherCtx, GrMipmapped::kNo); std::tie(otherView, std::ignore) = as_IB(refImg)->asView(otherCtx, GrMipmapped::kNo);
REPORTER_ASSERT(reporter, !otherView); REPORTER_ASSERT(reporter, !otherView);
// Release second ref from the original context // Release second ref from the original context
@ -1026,7 +1027,7 @@ static void test_cross_context_image(skiatest::Reporter* reporter, const GrConte
// Now we should be able to borrow the texture from the other context // Now we should be able to borrow the texture from the other context
otherTestContext->makeCurrent(); otherTestContext->makeCurrent();
otherView = as_IB(refImg)->refView(otherCtx, GrMipmapped::kNo); std::tie(otherView, std::ignore) = as_IB(refImg)->asView(otherCtx, GrMipmapped::kNo);
REPORTER_ASSERT(reporter, otherView); REPORTER_ASSERT(reporter, otherView);
// Release everything // Release everything
@ -1067,8 +1068,9 @@ DEF_GPUTEST(SkImage_CrossContextGrayAlphaConfigs, reporter, options) {
sk_sp<SkImage> image = SkImage::MakeCrossContextFromPixmap(dContext, pixmap, false); sk_sp<SkImage> image = SkImage::MakeCrossContextFromPixmap(dContext, pixmap, false);
REPORTER_ASSERT(reporter, image); REPORTER_ASSERT(reporter, image);
GrSurfaceProxyView view = as_IB(image)->refView(dContext, GrMipmapped::kNo); auto [view, viewCT] = as_IB(image)->asView(dContext, GrMipmapped::kNo);
REPORTER_ASSERT(reporter, view); REPORTER_ASSERT(reporter, view);
REPORTER_ASSERT(reporter, GrColorTypeToSkColorType(viewCT) == ct);
bool expectAlpha = kAlpha_8_SkColorType == ct; bool expectAlpha = kAlpha_8_SkColorType == ct;
GrColorType grCT = SkColorTypeToGrColorType(image->colorType()); GrColorType grCT = SkColorTypeToGrColorType(image->colorType());
@ -1461,7 +1463,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ImageFlush, reporter, ctxInfo) {
REPORTER_ASSERT(reporter, static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->isTextureBacked()); REPORTER_ASSERT(reporter, static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->isTextureBacked());
// Flatten it and repeat. // Flatten it and repeat.
as_IB(i2.get())->view(dContext); as_IB(i2.get())->asView(dContext, GrMipmapped::kNo);
REPORTER_ASSERT(reporter, REPORTER_ASSERT(reporter,
static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->testingOnly_IsFlattened()); static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->testingOnly_IsFlattened());
REPORTER_ASSERT(reporter, static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->isTextureBacked()); REPORTER_ASSERT(reporter, static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->isTextureBacked());
@ -1483,7 +1485,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ImageFlush, reporter, ctxInfo) {
// make the YUVA planes from backend textures rather than pixmaps that the context must upload. // make the YUVA planes from backend textures rather than pixmaps that the context must upload.
// Calling numSubmits rebases the flush count from here. // Calling numSubmits rebases the flush count from here.
numSubmits(); numSubmits();
as_IB(i2.get())->view(dContext); as_IB(i2.get())->asView(dContext, GrMipmapped::kNo);
REPORTER_ASSERT(reporter, REPORTER_ASSERT(reporter,
static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->testingOnly_IsFlattened()); static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->testingOnly_IsFlattened());
REPORTER_ASSERT(reporter, static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->isTextureBacked()); REPORTER_ASSERT(reporter, static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->isTextureBacked());

View File

@ -754,10 +754,10 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceClear_Gpu, reporter, ctxInfo) {
// Snaps an image from a surface and then makes a GrSurfaceContext from the image's texture. // Snaps an image from a surface and then makes a GrSurfaceContext from the image's texture.
auto makeImageSurfaceContext = [dContext](SkSurface* surface) { auto makeImageSurfaceContext = [dContext](SkSurface* surface) {
sk_sp<SkImage> i(surface->makeImageSnapshot()); sk_sp<SkImage> i(surface->makeImageSnapshot());
SkImage_Gpu* gpuImage = (SkImage_Gpu*)as_IB(i); auto gpuImage = static_cast<SkImage_Gpu*>(as_IB(i));
return GrSurfaceContext::Make(dContext, auto [view, ct] = gpuImage->asView(dContext, GrMipmapped::kNo);
*gpuImage->view(dContext), GrColorInfo colorInfo(ct, i->alphaType(), i->refColorSpace());
i->imageInfo().colorInfo()); return GrSurfaceContext::Make(dContext, view, std::move(colorInfo));
}; };
// Test that non-wrapped RTs are created clear. // Test that non-wrapped RTs are created clear.

View File

@ -72,10 +72,10 @@ DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkImageLayoutTest, reporter, ctxInfo) {
mbet->releaseContext()); mbet->releaseContext());
REPORTER_ASSERT(reporter, wrappedImage.get()); REPORTER_ASSERT(reporter, wrappedImage.get());
const GrSurfaceProxyView* view = as_IB(wrappedImage)->view(dContext); GrSurfaceProxy* proxy = as_IB(wrappedImage)->peekProxy();
REPORTER_ASSERT(reporter, view); REPORTER_ASSERT(reporter, proxy);
REPORTER_ASSERT(reporter, view->proxy()->isInstantiated()); REPORTER_ASSERT(reporter, proxy->isInstantiated());
GrTexture* texture = view->proxy()->peekTexture(); GrTexture* texture = proxy->peekTexture();
REPORTER_ASSERT(reporter, texture); REPORTER_ASSERT(reporter, texture);
// Verify that modifying the layout via the GrVkTexture is reflected in the GrBackendTexture // Verify that modifying the layout via the GrVkTexture is reflected in the GrBackendTexture