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:
parent
d80f966d25
commit
d0924f3ba9
@ -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);
|
||||
|
||||
auto img = surf->makeImageSnapshot();
|
||||
if (auto v = as_IB(img)->view(rContext)) {
|
||||
src = *v;
|
||||
}
|
||||
std::tie(src, std::ignore) = as_IB(img)->asView(rContext, GrMipmapped::kNo);
|
||||
}
|
||||
if (!src) {
|
||||
return;
|
||||
|
@ -174,10 +174,7 @@ public:
|
||||
surface->getCanvas()->translate(-100, -100);
|
||||
surface->getCanvas()->drawPicture(pic);
|
||||
sk_sp<SkImage> image(surface->makeImageSnapshot());
|
||||
const GrSurfaceProxyView* view = as_IB(image)->view(rContext);
|
||||
if (view) {
|
||||
fView = *view;
|
||||
}
|
||||
std::tie(fView, std::ignore) = as_IB(image)->asView(rContext, GrMipmapped::kNo);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
@ -305,19 +302,20 @@ protected:
|
||||
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
|
||||
// aren't considered texture-backed
|
||||
GrSurfaceProxyView view = as_IB(image)->refView(canvas->recordingContext(),
|
||||
GrMipmapped::kNo);
|
||||
auto [view, ct] = as_IB(image)->asView(canvas->recordingContext(), GrMipmapped::kNo);
|
||||
if (!view) {
|
||||
// show placeholder if we have no texture
|
||||
draw_placeholder(canvas, x, y, image->width(), image->height());
|
||||
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
|
||||
sk_sp<SkImage> texImage(new SkImage_Gpu(sk_ref_sp(canvas->recordingContext()),
|
||||
image->uniqueID(), std::move(view),
|
||||
image->colorType(), image->alphaType(),
|
||||
image->refColorSpace()));
|
||||
image->uniqueID(),
|
||||
std::move(view),
|
||||
std::move(colorInfo)));
|
||||
canvas->drawImage(texImage.get(), x, y);
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ bool SkPictureImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels,
|
||||
GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext* ctx,
|
||||
const SkImageInfo& info,
|
||||
const SkIPoint& origin,
|
||||
GrMipmapped mipMapped,
|
||||
GrMipmapped mipmapped,
|
||||
GrImageTexGenPolicy texGenPolicy) {
|
||||
SkASSERT(ctx);
|
||||
|
||||
@ -106,9 +106,8 @@ GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext
|
||||
SkBudgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
|
||||
? SkBudgeted::kNo
|
||||
: SkBudgeted::kYes;
|
||||
auto surface = SkSurface::MakeRenderTarget(ctx, budgeted, info, 0,
|
||||
kTopLeft_GrSurfaceOrigin, &props,
|
||||
mipMapped == GrMipmapped::kYes);
|
||||
auto surface = SkSurface::MakeRenderTarget(ctx, budgeted, info, 0, kTopLeft_GrSurfaceOrigin,
|
||||
&props, mipmapped == GrMipmapped::kYes);
|
||||
if (!surface) {
|
||||
return {};
|
||||
}
|
||||
@ -121,10 +120,10 @@ GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext
|
||||
if (!image) {
|
||||
return {};
|
||||
}
|
||||
const GrSurfaceProxyView* view = as_IB(image)->view(ctx);
|
||||
auto [view, ct] = as_IB(image)->asView(ctx, mipmapped);
|
||||
SkASSERT(view);
|
||||
SkASSERT(mipMapped == GrMipmapped::kNo ||
|
||||
view->asTextureProxy()->mipmapped() == GrMipmapped::kYes);
|
||||
return *view;
|
||||
SkASSERT(mipmapped == GrMipmapped::kNo ||
|
||||
view.asTextureProxy()->mipmapped() == GrMipmapped::kYes);
|
||||
return view;
|
||||
}
|
||||
#endif
|
||||
|
@ -160,10 +160,14 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromImage(GrRecordingContext* rContext
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
if (rContext) {
|
||||
GrSurfaceProxyView view = as_IB(image)->refView(rContext, GrMipmapped::kNo);
|
||||
return MakeDeferredFromGpu(rContext, subset, image->uniqueID(), view,
|
||||
SkColorTypeToGrColorType(image->colorType()),
|
||||
image->refColorSpace(), props);
|
||||
auto [view, ct] = as_IB(image)->asView(rContext, GrMipmapped::kNo);
|
||||
return MakeDeferredFromGpu(rContext,
|
||||
subset,
|
||||
image->uniqueID(),
|
||||
std::move(view),
|
||||
ct,
|
||||
image->refColorSpace(),
|
||||
props);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -46,16 +46,10 @@ GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrRecordingContext* context, co
|
||||
SkASSERT(as_IB(client)->isYUVA());
|
||||
}
|
||||
|
||||
GrSurfaceProxyView GrYUVAImageTextureMaker::refOriginalTextureProxyView(GrMipmapped mipMapped) {
|
||||
if (mipMapped == GrMipmapped::kYes) {
|
||||
return fImage->refMippedView(this->context());
|
||||
} else {
|
||||
if (const GrSurfaceProxyView* view = fImage->view(this->context())) {
|
||||
return *view;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
GrSurfaceProxyView GrYUVAImageTextureMaker::refOriginalTextureProxyView(GrMipmapped mipmapped) {
|
||||
auto [view, ct] = fImage->asView(this->context(), mipmapped);
|
||||
SkASSERT(ct == this->colorType());
|
||||
return view;
|
||||
}
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProcessor(
|
||||
|
@ -104,6 +104,20 @@ public:
|
||||
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
|
||||
// properties associated with the detached proxy.
|
||||
sk_sp<GrSurfaceProxy> detachProxy() {
|
||||
|
@ -653,14 +653,14 @@ sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) {
|
||||
sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkImage* image) {
|
||||
SkPixmap pm;
|
||||
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);
|
||||
|
||||
return SkSpecialImage::MakeDeferredFromGpu(fContext.get(),
|
||||
SkIRect::MakeWH(image->width(), image->height()),
|
||||
image->uniqueID(),
|
||||
*view,
|
||||
SkColorTypeToGrColorType(image->colorType()),
|
||||
std::move(view),
|
||||
ct,
|
||||
image->refColorSpace(),
|
||||
&this->surfaceProps());
|
||||
} else if (image->peekPixels(&pm)) {
|
||||
@ -771,10 +771,10 @@ void SkGpuDevice::drawImageLattice(const SkImage* image,
|
||||
SkFilterMode filter, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
auto iter = std::make_unique<SkLatticeIter>(lattice, dst);
|
||||
if (GrSurfaceProxyView view = as_IB(image)->refView(this->recordingContext(),
|
||||
GrMipmapped::kNo)) {
|
||||
if (auto [view, ct] = as_IB(image)->asView(this->recordingContext(), GrMipmapped::kNo); view) {
|
||||
GrColorInfo colorInfo(ct, image->alphaType(), image->refColorSpace());
|
||||
this->drawViewLattice(std::move(view),
|
||||
image->imageInfo().colorInfo(),
|
||||
std::move(colorInfo),
|
||||
std::move(iter),
|
||||
dst,
|
||||
filter,
|
||||
|
@ -760,13 +760,14 @@ void SkGpuDevice::drawImageQuad(const SkImage* image, const SkRect* srcRect, con
|
||||
}
|
||||
}
|
||||
|
||||
if (GrSurfaceProxyView view = as_IB(image)->refView(this->recordingContext(),
|
||||
GrMipmapped(mm != SkMipmapMode::kNone))) {
|
||||
if (auto [view, ct] = as_IB(image)->asView(this->recordingContext(),
|
||||
GrMipmapped(mm != SkMipmapMode::kNone)); view) {
|
||||
// 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.
|
||||
GrColorInfo colorInfo(ct, image->alphaType(), image->refColorSpace());
|
||||
GrTextureAdjuster adjuster(fContext.get(),
|
||||
std::move(view),
|
||||
image->imageInfo().colorInfo(),
|
||||
std::move(colorInfo),
|
||||
image->uniqueID());
|
||||
draw_texture_producer(fContext.get(), fSurfaceDrawContext.get(), clip, matrixProvider,
|
||||
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
|
||||
// drawImageQuad and the proper effect to dynamically sample their planes.
|
||||
if (!image->isYUVA()) {
|
||||
view = image->refView(this->recordingContext(), GrMipmapped::kNo);
|
||||
std::tie(view, std::ignore) = image->asView(this->recordingContext(), GrMipmapped::kNo);
|
||||
if (image->isAlphaOnly()) {
|
||||
GrSwizzle swizzle = GrSwizzle::Concat(view.swizzle(), GrSwizzle("aaaa"));
|
||||
view = {view.detachProxy(), view.origin(), swizzle};
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "include/gpu/GrDirectContext.h"
|
||||
#include "src/gpu/GrDirectContextPriv.h"
|
||||
#include "src/gpu/GrImageContextPriv.h"
|
||||
#include "src/gpu/GrRecordingContextPriv.h"
|
||||
#include "src/image/SkImage_Gpu.h"
|
||||
#endif
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
@ -308,6 +309,20 @@ void SkImage_Base::onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace,
|
||||
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,
|
||||
GrSurfaceOrigin* origin) const {
|
||||
return GrBackendTexture(); // invalid
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "include/private/SkTDArray.h"
|
||||
#include "src/gpu/GrSurfaceProxyView.h"
|
||||
#include "src/gpu/GrTextureProxy.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
|
||||
class GrTexture;
|
||||
#endif
|
||||
@ -92,13 +93,15 @@ public:
|
||||
// that single backing proxy will be returned.
|
||||
virtual GrTextureProxy* peekProxy() const { return nullptr; }
|
||||
|
||||
// If it exists, this returns a pointer to the GrSurfaceProxyView of image. The caller does not
|
||||
// own the returned view and must copy it if they want to gain a ref to the internal proxy.
|
||||
// If the returned view is not null, then it is guaranteed to have a valid proxy. Additionally
|
||||
// this call will flatten a SkImage_GpuYUV to a single texture.
|
||||
virtual const GrSurfaceProxyView* view(GrRecordingContext*) const { return nullptr; }
|
||||
// Returns a GrSurfaceProxyView representation of the image, if possible. This also returns
|
||||
// a color type. This may be different than the image's color type when the image is not
|
||||
// texture-backed and the capabilities of the GPU require a data type conversion to put
|
||||
// the data in a texture.
|
||||
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; }
|
||||
|
||||
#endif
|
||||
@ -148,7 +151,21 @@ public:
|
||||
protected:
|
||||
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:
|
||||
#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.
|
||||
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);
|
||||
}
|
||||
|
||||
#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
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "src/gpu/GrTextureProxy.h"
|
||||
#include "src/gpu/GrTextureProxyPriv.h"
|
||||
#include "src/gpu/GrYUVATextureProxies.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
#include "src/gpu/gl/GrGLTexture.h"
|
||||
|
||||
#include <cstddef>
|
||||
@ -54,12 +53,8 @@ SkImage_Gpu::SkImage_Gpu(sk_sp<GrImageContext> context, uint32_t uniqueID, GrSur
|
||||
, fView(std::move(view)) {
|
||||
#ifdef SK_DEBUG
|
||||
const GrBackendFormat& format = fView.proxy()->backendFormat();
|
||||
GrColorType grCT = SkColorTypeToGrColorType(ct);
|
||||
const GrCaps* caps = this->context()->priv().caps();
|
||||
if (caps->isFormatSRGB(format)) {
|
||||
SkASSERT(grCT == GrColorType::kRGBA_8888);
|
||||
grCT = GrColorType::kRGBA_8888_SRGB;
|
||||
}
|
||||
GrColorType grCT = SkColorTypeAndFormatToGrColorType(caps, ct, format);
|
||||
SkASSERT(caps->isFormatCompressed(format) ||
|
||||
caps->areColorTypeAndFormatCompatible(grCT, format));
|
||||
#endif
|
||||
@ -127,11 +122,11 @@ sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(SkColorType targetCT,
|
||||
if (!surfaceFillContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto texFP = GrTextureEffect::Make(*this->view(direct), this->alphaType());
|
||||
auto [view, ct] = this->asView(direct, GrMipmapped(this->hasMipmaps()));
|
||||
auto texFP = GrTextureEffect::Make(std::move(view), this->alphaType());
|
||||
auto colorFP = GrColorSpaceXformEffect::Make(std::move(texFP),
|
||||
this->colorSpace(), this->alphaType(),
|
||||
targetCS.get(), this->alphaType());
|
||||
targetCS.get(), this->alphaType());
|
||||
SkASSERT(colorFP);
|
||||
|
||||
surfaceFillContext->fillWithFP(std::move(colorFP));
|
||||
@ -339,58 +334,38 @@ sk_sp<SkImage> SkImage::MakeTextureFromCompressed(GrDirectContext* direct, sk_sp
|
||||
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,
|
||||
GrMipmapped mipMapped,
|
||||
GrMipmapped mipmapped,
|
||||
SkBudgeted budgeted) const {
|
||||
if (!dContext) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!dContext->priv().caps()->mipmapSupport()) {
|
||||
mipmapped = GrMipmapped::kNo;
|
||||
}
|
||||
|
||||
if (this->isTextureBacked()) {
|
||||
if (!as_IB(this)->context()->priv().matches(dContext)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO: Don't flatten YUVA images here.
|
||||
const GrSurfaceProxyView* view = as_IB(this)->view(dContext);
|
||||
SkASSERT(view && view->asTextureProxy());
|
||||
|
||||
if (mipMapped == GrMipmapped::kNo || view->asTextureProxy()->mipmapped() == mipMapped ||
|
||||
!dContext->priv().caps()->mipmapSupport()) {
|
||||
if (this->isTextureBacked() && (mipmapped == GrMipmapped::kNo || this->hasMipmaps())) {
|
||||
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,
|
||||
this->colorType(), this->alphaType(), this->refColorSpace());
|
||||
}
|
||||
|
||||
auto policy = budgeted == SkBudgeted::kYes ? GrImageTexGenPolicy::kNew_Uncached_Budgeted
|
||||
: GrImageTexGenPolicy::kNew_Uncached_Unbudgeted;
|
||||
if (this->isLazyGenerated()) {
|
||||
GrImageTextureMaker maker(dContext, this, policy);
|
||||
return create_image_from_producer(dContext, &maker, this->uniqueID(), mipMapped);
|
||||
}
|
||||
|
||||
if (const SkBitmap* bmp = as_IB(this)->onPeekBitmap()) {
|
||||
GrBitmapTextureMaker maker(dContext, *bmp, policy);
|
||||
return create_image_from_producer(dContext, &maker, this->uniqueID(), mipMapped);
|
||||
}
|
||||
return nullptr;
|
||||
GrImageTexGenPolicy policy = budgeted == SkBudgeted::kYes
|
||||
? GrImageTexGenPolicy::kNew_Uncached_Budgeted
|
||||
: GrImageTexGenPolicy::kNew_Uncached_Unbudgeted;
|
||||
// TODO: Don't flatten YUVA images here. Add mips to the planes instead.
|
||||
auto [view, ct] = as_IB(this)->asView(dContext, mipmapped, policy);
|
||||
SkASSERT(view && view.asTextureProxy());
|
||||
SkASSERT(mipmapped == GrMipmapped::kNo ||
|
||||
view.asTextureProxy()->mipmapped() == GrMipmapped::kYes);
|
||||
SkColorInfo colorInfo(GrColorTypeToSkColorType(ct), this->alphaType(), this->refColorSpace());
|
||||
return sk_make_sp<SkImage_Gpu>(sk_ref_sp(dContext),
|
||||
this->uniqueID(),
|
||||
std::move(view),
|
||||
std::move(colorInfo));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -605,7 +580,7 @@ bool SkImage::MakeBackendTextureFromSkImage(GrDirectContext* direct,
|
||||
return false;
|
||||
}
|
||||
|
||||
GrSurfaceProxyView view = as_IB(image)->refView(direct, GrMipmapped::kNo);
|
||||
auto [view, ct] = as_IB(image)->asView(direct, GrMipmapped::kNo);
|
||||
|
||||
if (!view) {
|
||||
return false;
|
||||
@ -643,3 +618,22 @@ bool SkImage::MakeBackendTextureFromSkImage(GrDirectContext* direct,
|
||||
// Steal the backend texture from the GrTexture, releasing the GrTexture in the process.
|
||||
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()};
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "src/gpu/GrGpuResourcePriv.h"
|
||||
#include "src/gpu/GrSurfaceProxyPriv.h"
|
||||
#include "src/gpu/GrSurfaceProxyView.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
#include "src/image/SkImage_GpuBase.h"
|
||||
|
||||
class GrDirectContext;
|
||||
@ -21,7 +20,7 @@ class GrTexture;
|
||||
|
||||
class SkBitmap;
|
||||
|
||||
class SkImage_Gpu : public SkImage_GpuBase {
|
||||
class SkImage_Gpu final : public SkImage_GpuBase {
|
||||
public:
|
||||
SkImage_Gpu(sk_sp<GrImageContext>, uint32_t uniqueID, GrSurfaceProxyView, SkColorType,
|
||||
SkAlphaType, sk_sp<SkColorSpace>);
|
||||
@ -44,16 +43,7 @@ public:
|
||||
|
||||
GrSemaphoresSubmitted onFlush(GrDirectContext*, const GrFlushInfo&) override;
|
||||
|
||||
GrTextureProxy* peekProxy() const override {
|
||||
return fView.asTextureProxy();
|
||||
}
|
||||
|
||||
const GrSurfaceProxyView* view(GrRecordingContext* context) const override {
|
||||
if (!fView.proxy()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &fView;
|
||||
}
|
||||
GrTextureProxy* peekProxy() const override { return fView.asTextureProxy(); }
|
||||
|
||||
GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
|
||||
GrSurfaceOrigin* origin) const final;
|
||||
@ -100,6 +90,10 @@ public:
|
||||
PromiseImageTextureContext textureContext);
|
||||
|
||||
private:
|
||||
std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*,
|
||||
GrMipmapped,
|
||||
GrImageTexGenPolicy) const override;
|
||||
|
||||
GrSurfaceProxyView fView;
|
||||
|
||||
using INHERITED = SkImage_GpuBase;
|
||||
|
@ -116,14 +116,13 @@ bool SkImage_GpuBase::getROPixels(GrDirectContext* dContext,
|
||||
}
|
||||
}
|
||||
|
||||
const GrSurfaceProxyView* view = this->view(dContext);
|
||||
SkASSERT(view);
|
||||
GrColorType grColorType = SkColorTypeAndFormatToGrColorType(
|
||||
fContext->priv().caps(), this->colorType(), view->proxy()->backendFormat());
|
||||
auto [view, ct] = this->asView(dContext, GrMipmapped::kNo);
|
||||
if (!view) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto sContext = GrSurfaceContext::Make(dContext,
|
||||
*view,
|
||||
{grColorType, this->alphaType(), this->refColorSpace()});
|
||||
GrColorInfo colorInfo(ct, this->alphaType(), this->refColorSpace());
|
||||
auto sContext = GrSurfaceContext::Make(dContext, std::move(view), std::move(colorInfo));
|
||||
if (!sContext) {
|
||||
return false;
|
||||
}
|
||||
@ -145,19 +144,26 @@ sk_sp<SkImage> SkImage_GpuBase::onMakeSubset(const SkIRect& subset,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const GrSurfaceProxyView* view = this->view(direct);
|
||||
SkASSERT(view && view->proxy());
|
||||
auto [view, ct] = this->asView(direct, GrMipmapped::kNo);
|
||||
SkASSERT(view);
|
||||
SkASSERT(ct == SkColorTypeToGrColorType(this->colorType()));
|
||||
|
||||
auto copyView = GrSurfaceProxyView::Copy(direct, *view, GrMipmapped::kNo, subset,
|
||||
SkBackingFit::kExact, view->proxy()->isBudgeted());
|
||||
SkBudgeted isBudgeted = view.proxy()->isBudgeted();
|
||||
auto copyView = GrSurfaceProxyView::Copy(direct,
|
||||
std::move(view),
|
||||
GrMipmapped::kNo,
|
||||
subset,
|
||||
SkBackingFit::kExact,
|
||||
isBudgeted);
|
||||
|
||||
if (!copyView) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// MDB: this call is okay bc we know 'sContext' was kExact
|
||||
return sk_make_sp<SkImage_Gpu>(sk_ref_sp(direct), kNeedNewImageUniqueID, std::move(copyView),
|
||||
this->colorType(), this->alphaType(), this->refColorSpace());
|
||||
return sk_make_sp<SkImage_Gpu>(sk_ref_sp(direct),
|
||||
kNeedNewImageUniqueID,
|
||||
std::move(copyView),
|
||||
this->imageInfo().colorInfo());
|
||||
}
|
||||
|
||||
bool SkImage_GpuBase::onReadPixels(GrDirectContext* dContext,
|
||||
@ -172,13 +178,11 @@ bool SkImage_GpuBase::onReadPixels(GrDirectContext* dContext,
|
||||
return false;
|
||||
}
|
||||
|
||||
const GrSurfaceProxyView* view = this->view(dContext);
|
||||
auto [view, ct] = this->asView(dContext, GrMipmapped::kNo);
|
||||
SkASSERT(view);
|
||||
GrColorType grColorType = SkColorTypeAndFormatToGrColorType(
|
||||
dContext->priv().caps(), this->colorType(), view->proxy()->backendFormat());
|
||||
|
||||
GrColorInfo colorInfo(grColorType, this->alphaType(), this->refColorSpace());
|
||||
auto sContext = GrSurfaceContext::Make(dContext, *view, colorInfo);
|
||||
GrColorInfo colorInfo(ct, this->alphaType(), this->refColorSpace());
|
||||
auto sContext = GrSurfaceContext::Make(dContext, std::move(view), colorInfo);
|
||||
if (!sContext) {
|
||||
return false;
|
||||
}
|
||||
@ -186,23 +190,6 @@ bool SkImage_GpuBase::onReadPixels(GrDirectContext* dContext,
|
||||
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 {
|
||||
// The base class has already checked that 'context' isn't abandoned (if it's not nullptr)
|
||||
if (fContext->priv().abandoned()) {
|
||||
|
@ -35,8 +35,6 @@ public:
|
||||
int srcY,
|
||||
CachingHint) const override;
|
||||
|
||||
GrSurfaceProxyView refView(GrRecordingContext*, GrMipmapped) const final;
|
||||
|
||||
bool onIsValid(GrRecordingContext*) const final;
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
|
@ -143,75 +143,9 @@ bool SkImage_GpuYUVA::onHasMipmaps() const {
|
||||
|
||||
GrTextureProxy* SkImage_GpuYUVA::peekProxy() const { return fRGBView.asTextureProxy(); }
|
||||
|
||||
void SkImage_GpuYUVA::flattenToRGB(GrRecordingContext* context) const {
|
||||
if (fRGBView.proxy()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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 {
|
||||
sk_sp<SkImage> SkImage_GpuYUVA::onMakeColorTypeAndColorSpace(SkColorType,
|
||||
sk_sp<SkColorSpace> targetCS,
|
||||
GrDirectContext* direct) const {
|
||||
// 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
|
||||
@ -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)));
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -21,7 +21,7 @@ class GrTexture;
|
||||
// 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
|
||||
// proxy will be stored and used for any future rendering.
|
||||
class SkImage_GpuYUVA : public SkImage_GpuBase {
|
||||
class SkImage_GpuYUVA final : public SkImage_GpuBase {
|
||||
public:
|
||||
friend class GrYUVAImageTextureMaker;
|
||||
|
||||
@ -38,8 +38,6 @@ public:
|
||||
// nullptr if they have not.
|
||||
GrTextureProxy* peekProxy() const override;
|
||||
|
||||
const GrSurfaceProxyView* view(GrRecordingContext* context) const override;
|
||||
|
||||
bool onIsTextureBacked() const override {
|
||||
// We should have YUVA proxies or a RGBA proxy,but not both.
|
||||
SkASSERT(fYUVAProxies.isValid() != SkToBool(fRGBView));
|
||||
@ -55,9 +53,6 @@ public:
|
||||
|
||||
bool setupMipmapsForPlanes(GrRecordingContext*) const;
|
||||
|
||||
// Returns a ref-ed texture proxy view with miplevels
|
||||
GrSurfaceProxyView refMippedView(GrRecordingContext*) const;
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
bool testingOnly_IsFlattened() const {
|
||||
// We should only have the flattened proxy or the planar proxies at one point in time.
|
||||
@ -79,7 +74,11 @@ public:
|
||||
private:
|
||||
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;
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "src/gpu/GrSamplerState.h"
|
||||
#include "src/gpu/GrSurfaceFillContext.h"
|
||||
#include "src/gpu/GrYUVATextureProxies.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
#include "src/gpu/effects/GrYUVtoRGBEffect.h"
|
||||
#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 {
|
||||
// TODO: can we do this more efficiently, by telling the generator we want to
|
||||
// "realize" a subset?
|
||||
@ -259,6 +247,14 @@ sk_sp<SkImage> SkImage::MakeFromGenerator(std::unique_ptr<SkImageGenerator> gene
|
||||
|
||||
#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,
|
||||
SkBudgeted budgeted) const {
|
||||
SkYUVAPixmapInfo::SupportedDataTypes supportedDataTypes(*ctx);
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "include/private/SkIDChangeListener.h"
|
||||
#include "include/private/SkMutex.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
#include "src/image/SkImage_Base.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
@ -43,9 +42,6 @@ public:
|
||||
|
||||
bool onReadPixels(GrDirectContext*, const SkImageInfo&, void*, size_t, int srcX, int srcY,
|
||||
CachingHint) const override;
|
||||
#if SK_SUPPORT_GPU
|
||||
GrSurfaceProxyView refView(GrRecordingContext*, GrMipmapped) const override;
|
||||
#endif
|
||||
sk_sp<SkData> onRefEncoded() const override;
|
||||
sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const override;
|
||||
bool getROPixels(GrDirectContext*, SkBitmap*, CachingHint) const override;
|
||||
@ -73,9 +69,12 @@ public:
|
||||
private:
|
||||
void addUniqueIDListener(sk_sp<SkIDChangeListener>) const;
|
||||
#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,
|
||||
SkYUVAPixmaps* pixmaps) const;
|
||||
GrSurfaceProxyView textureProxyViewFromPlanes(GrRecordingContext*, SkBudgeted) const;
|
||||
#endif
|
||||
|
||||
class ScopedGenerator;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "src/shaders/SkBitmapProcShader.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "src/gpu/GrBitmapTextureMaker.h"
|
||||
#include "src/gpu/GrTextureAdjuster.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
#endif
|
||||
@ -83,10 +84,6 @@ public:
|
||||
bool onPeekPixels(SkPixmap*) const override;
|
||||
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;
|
||||
sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const override;
|
||||
|
||||
@ -136,6 +133,12 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
#if SK_SUPPORT_GPU
|
||||
std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*,
|
||||
GrMipmapped,
|
||||
GrImageTexGenPolicy) const override;
|
||||
#endif
|
||||
|
||||
SkBitmap fBitmap;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
@ -143,6 +146,7 @@ private:
|
||||
mutable int32_t fPinnedCount = 0;
|
||||
mutable uint32_t fPinnedUniqueID = SK_InvalidUniqueID;
|
||||
mutable uint32_t fPinnedContextID = SK_InvalidUniqueID;
|
||||
mutable GrColorType fPinnedColorType = GrColorType::kUnknown;
|
||||
#endif
|
||||
|
||||
using INHERITED = SkImage_Base;
|
||||
@ -191,24 +195,6 @@ bool SkImage_Raster::getROPixels(GrDirectContext*, SkBitmap* dst, CachingHint) c
|
||||
}
|
||||
|
||||
#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 {
|
||||
if (fPinnedView) {
|
||||
SkASSERT(fPinnedCount > 0);
|
||||
@ -219,13 +205,15 @@ bool SkImage_Raster::onPinAsTexture(GrRecordingContext* rContext) const {
|
||||
} else {
|
||||
SkASSERT(fPinnedCount == 0);
|
||||
SkASSERT(fPinnedUniqueID == 0);
|
||||
fPinnedView = GrRefCachedBitmapView(rContext, fBitmap, GrMipmapped::kNo);
|
||||
GrBitmapTextureMaker maker(rContext, fBitmap, GrImageTexGenPolicy::kDraw);
|
||||
fPinnedView = maker.view(GrMipmapped::kNo);
|
||||
if (!fPinnedView) {
|
||||
return false;
|
||||
}
|
||||
SkASSERT(fPinnedView.asTextureProxy());
|
||||
fPinnedUniqueID = fBitmap.getGenerationID();
|
||||
fPinnedContextID = rContext->priv().contextID();
|
||||
fPinnedColorType = maker.colorType();
|
||||
}
|
||||
// Note: we only increment if the texture was successfully pinned
|
||||
++fPinnedCount;
|
||||
@ -246,13 +234,13 @@ void SkImage_Raster::onUnpinAsTexture(GrRecordingContext* rContext) const {
|
||||
fPinnedView = GrSurfaceProxyView();
|
||||
fPinnedUniqueID = SK_InvalidUniqueID;
|
||||
fPinnedContextID = SK_InvalidUniqueID;
|
||||
fPinnedColorType = GrColorType::kUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
bool SkImage_Raster::isPinnedOnContext(GrRecordingContext* rContext) const {
|
||||
return fPinnedContextID == rContext->priv().contextID();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
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));
|
||||
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
|
||||
|
@ -407,7 +407,7 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
|
||||
auto mipmapped = !GrValidCubicResampler(kernel) && mm != SkMipmapMode::kNone
|
||||
? GrMipmapped::kYes
|
||||
: GrMipmapped::kNo;
|
||||
GrSurfaceProxyView view = as_IB(fImage)->refView(args.fContext, mipmapped);
|
||||
auto [view, ct] = as_IB(fImage)->asView(args.fContext, mipmapped);
|
||||
if (!view) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -61,10 +61,10 @@ DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendSurfaceMutableStateTest, reporter, ctxIn
|
||||
kRGBA_8888_SkColorType,
|
||||
kPremul_SkAlphaType, nullptr);
|
||||
|
||||
const GrSurfaceProxyView* view = as_IB(wrappedImage)->view(dContext);
|
||||
REPORTER_ASSERT(reporter, view);
|
||||
REPORTER_ASSERT(reporter, view->proxy()->isInstantiated());
|
||||
GrTexture* texture = view->proxy()->peekTexture();
|
||||
GrSurfaceProxy* proxy = as_IB(wrappedImage)->peekProxy();
|
||||
REPORTER_ASSERT(reporter, proxy);
|
||||
REPORTER_ASSERT(reporter, proxy->isInstantiated());
|
||||
GrTexture* texture = proxy->peekTexture();
|
||||
REPORTER_ASSERT(reporter, texture);
|
||||
|
||||
// Verify that modifying the layout via the GrVkTexture is reflected in the GrBackendTexture
|
||||
|
@ -69,10 +69,10 @@ DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLTextureParameters, reporter, ctxInfo) {
|
||||
kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
|
||||
REPORTER_ASSERT(reporter, wrappedImage);
|
||||
|
||||
const GrSurfaceProxyView* view = as_IB(wrappedImage)->view(dContext);
|
||||
REPORTER_ASSERT(reporter, view);
|
||||
REPORTER_ASSERT(reporter, view->proxy()->isInstantiated());
|
||||
auto texture = static_cast<GrGLTexture*>(view->proxy()->peekTexture());
|
||||
GrSurfaceProxy* proxy = as_IB(wrappedImage)->peekProxy();
|
||||
REPORTER_ASSERT(reporter, proxy);
|
||||
REPORTER_ASSERT(reporter, proxy->isInstantiated());
|
||||
auto texture = static_cast<GrGLTexture*>(proxy->peekTexture());
|
||||
REPORTER_ASSERT(reporter, texture);
|
||||
auto parameters = texture->parameters();
|
||||
REPORTER_ASSERT(reporter, parameters);
|
||||
|
@ -86,12 +86,12 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest, reporter, ctxInfo) {
|
||||
sk_gpu_test::ManagedBackendTexture::ReleaseProc,
|
||||
mbet->releaseContext());
|
||||
REPORTER_ASSERT(reporter, (mipmapped == GrMipmapped::kYes) == image->hasMipmaps());
|
||||
const GrSurfaceProxyView* view = as_IB(image)->view(dContext);
|
||||
REPORTER_ASSERT(reporter, view);
|
||||
if (!view) {
|
||||
GrSurfaceProxy* surfaceProxy = as_IB(image)->peekProxy();
|
||||
REPORTER_ASSERT(reporter, surfaceProxy);
|
||||
if (!proxy) {
|
||||
continue;
|
||||
}
|
||||
proxy = view->asTextureProxyRef();
|
||||
proxy = sk_ref_sp(surfaceProxy->asTextureProxy());
|
||||
}
|
||||
REPORTER_ASSERT(reporter, proxy);
|
||||
if (!proxy) {
|
||||
|
@ -380,7 +380,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkImage_makeTextureImage, reporter, contextIn
|
||||
GrContextFactory otherFactory;
|
||||
ContextInfo otherContextInfo = otherFactory.getContextInfo(contextInfo.type());
|
||||
testContext->makeCurrent();
|
||||
|
||||
std::function<sk_sp<SkImage>()> imageFactories[] = {
|
||||
create_image, create_codec_image, create_data_image,
|
||||
// Create an image from a picture.
|
||||
@ -996,19 +995,21 @@ static void test_cross_context_image(skiatest::Reporter* reporter, const GrConte
|
||||
|
||||
testContext->makeCurrent();
|
||||
sk_sp<SkImage> refImg(imageMaker(dContext));
|
||||
GrSurfaceProxyView view, otherView, viewSecondRef;
|
||||
|
||||
// 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);
|
||||
|
||||
// But once it's borrowed, no other context should be able to borrow
|
||||
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);
|
||||
|
||||
// Original context (that's already borrowing) should be okay
|
||||
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);
|
||||
|
||||
// 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
|
||||
// a new context is still not able to borrow the texture.
|
||||
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);
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
// Release everything
|
||||
@ -1067,8 +1068,9 @@ DEF_GPUTEST(SkImage_CrossContextGrayAlphaConfigs, reporter, options) {
|
||||
sk_sp<SkImage> image = SkImage::MakeCrossContextFromPixmap(dContext, pixmap, false);
|
||||
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, GrColorTypeToSkColorType(viewCT) == ct);
|
||||
|
||||
bool expectAlpha = kAlpha_8_SkColorType == ct;
|
||||
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());
|
||||
|
||||
// Flatten it and repeat.
|
||||
as_IB(i2.get())->view(dContext);
|
||||
as_IB(i2.get())->asView(dContext, GrMipmapped::kNo);
|
||||
REPORTER_ASSERT(reporter,
|
||||
static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->testingOnly_IsFlattened());
|
||||
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.
|
||||
// Calling numSubmits rebases the flush count from here.
|
||||
numSubmits();
|
||||
as_IB(i2.get())->view(dContext);
|
||||
as_IB(i2.get())->asView(dContext, GrMipmapped::kNo);
|
||||
REPORTER_ASSERT(reporter,
|
||||
static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->testingOnly_IsFlattened());
|
||||
REPORTER_ASSERT(reporter, static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->isTextureBacked());
|
||||
|
@ -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.
|
||||
auto makeImageSurfaceContext = [dContext](SkSurface* surface) {
|
||||
sk_sp<SkImage> i(surface->makeImageSnapshot());
|
||||
SkImage_Gpu* gpuImage = (SkImage_Gpu*)as_IB(i);
|
||||
return GrSurfaceContext::Make(dContext,
|
||||
*gpuImage->view(dContext),
|
||||
i->imageInfo().colorInfo());
|
||||
auto gpuImage = static_cast<SkImage_Gpu*>(as_IB(i));
|
||||
auto [view, ct] = gpuImage->asView(dContext, GrMipmapped::kNo);
|
||||
GrColorInfo colorInfo(ct, i->alphaType(), i->refColorSpace());
|
||||
return GrSurfaceContext::Make(dContext, view, std::move(colorInfo));
|
||||
};
|
||||
|
||||
// Test that non-wrapped RTs are created clear.
|
||||
|
@ -72,10 +72,10 @@ DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkImageLayoutTest, reporter, ctxInfo) {
|
||||
mbet->releaseContext());
|
||||
REPORTER_ASSERT(reporter, wrappedImage.get());
|
||||
|
||||
const GrSurfaceProxyView* view = as_IB(wrappedImage)->view(dContext);
|
||||
REPORTER_ASSERT(reporter, view);
|
||||
REPORTER_ASSERT(reporter, view->proxy()->isInstantiated());
|
||||
GrTexture* texture = view->proxy()->peekTexture();
|
||||
GrSurfaceProxy* proxy = as_IB(wrappedImage)->peekProxy();
|
||||
REPORTER_ASSERT(reporter, proxy);
|
||||
REPORTER_ASSERT(reporter, proxy->isInstantiated());
|
||||
GrTexture* texture = proxy->peekTexture();
|
||||
REPORTER_ASSERT(reporter, texture);
|
||||
|
||||
// Verify that modifying the layout via the GrVkTexture is reflected in the GrBackendTexture
|
||||
|
Loading…
Reference in New Issue
Block a user