Revert "Revert "Mark wrapped textures imported into SkImages as "read only".""

This reverts commit ff4ccaa9fc.

Bug: skia:8509
Change-Id: If4a059d6e6e412ec1d6be2c70663d59c362e91d2
Reviewed-on: https://skia-review.googlesource.com/c/175249
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2018-12-06 10:00:03 -05:00 committed by Skia Commit-Bot
parent 23885d2133
commit c67c31ced1
54 changed files with 318 additions and 115 deletions

View File

@ -65,6 +65,12 @@ public:
static size_t ComputeSize(GrPixelConfig config, int width, int height, int colorSamplesPerPixel,
GrMipMapped, bool useNextPow2 = false);
/**
* The pixel values of this surface cannot be modified (e.g. doesn't support write pixels or
* MIP map level regen).
*/
bool readOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kReadOnly; }
protected:
void setHasMixedSamples() {
SkASSERT(this->asRenderTarget());
@ -88,6 +94,11 @@ protected:
return fSurfaceFlags & GrInternalSurfaceFlags::kGLRTFBOIDIs0;
}
void setReadOnly() {
SkASSERT(!this->asRenderTarget());
fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
}
// Methods made available via GrSurfacePriv
bool hasPendingRead() const;
bool hasPendingWrite() const;

View File

@ -365,6 +365,12 @@ public:
*/
SkBudgeted isBudgeted() const { return fBudgeted; }
/**
* The pixel values of this proxy's surface cannot be modified (e.g. doesn't support write
* pixels or MIP map level regen),
*/
bool readOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kReadOnly; }
void setLastOpList(GrOpList* opList);
GrOpList* getLastOpList() { return fLastOpList; }
@ -432,7 +438,7 @@ protected:
const GrBackendFormat& format, const GrSurfaceDesc&, GrSurfaceOrigin,
SkBackingFit, SkBudgeted, GrInternalSurfaceFlags);
// Wrapped version
// Wrapped version.
GrSurfaceProxy(sk_sp<GrSurface>, GrSurfaceOrigin, SkBackingFit);
virtual ~GrSurfaceProxy();

View File

@ -825,11 +825,19 @@ enum class GrInternalSurfaceFlags {
kNone = 0,
// Surface-level
kNoPendingIO = 1 << 0,
kSurfaceMask = kNoPendingIO,
// RT-only
// Texture-level
// Means the pixels in the texture are read-only. Cannot also be a GrRenderTarget[Proxy].
kReadOnly = 1 << 1,
kTextureMask = kReadOnly,
// RT-level
// For internal resources:
// this is enabled whenever MSAA is enabled and GrCaps reports mixed samples are supported

View File

@ -574,8 +574,8 @@ sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::makeProxy(GrContext* cont
const bool isProtectedContent = fIsProtectedContent;
sk_sp<GrTextureProxy> texProxy = proxyProvider->createLazyProxy(
[context, hardwareBuffer, width, height, pixelConfig, isProtectedContent, backendFormat]
(GrResourceProvider* resourceProvider) {
[context, hardwareBuffer, width, height, pixelConfig, isProtectedContent,
backendFormat](GrResourceProvider* resourceProvider) {
if (!resourceProvider) {
AHardwareBuffer_release(hardwareBuffer);
return sk_sp<GrTexture>();
@ -596,7 +596,8 @@ sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::makeProxy(GrContext* cont
SkASSERT(deleteImageProc && deleteImageCtx);
backendTex.fConfig = pixelConfig;
sk_sp<GrTexture> tex = resourceProvider->wrapBackendTexture(backendTex);
sk_sp<GrTexture> tex = resourceProvider->wrapBackendTexture(
backendTex, kBorrow_GrWrapOwnership, kRead_GrIOType);
if (!tex) {
deleteImageProc(deleteImageCtx);
return sk_sp<GrTexture>();
@ -610,8 +611,8 @@ sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::makeProxy(GrContext* cont
return tex;
},
backendFormat, desc, fSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
SkBudgeted::kNo);
backendFormat, desc, fSurfaceOrigin, GrMipMapped::kNo,
GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo);
if (!texProxy) {
AHardwareBuffer_release(hardwareBuffer);

View File

@ -138,8 +138,8 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture(
SkASSERT(format.isValid());
sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
[refHelper, releaseProcHelper, semaphore, backendTexture]
(GrResourceProvider* resourceProvider) {
[refHelper, releaseProcHelper, semaphore,
backendTexture](GrResourceProvider* resourceProvider) {
if (!resourceProvider) {
return sk_sp<GrTexture>();
}
@ -163,9 +163,8 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture(
// informs us that the context is done with it. This is unfortunate - we'll have
// two texture objects referencing the same GPU object. However, no client can
// ever see the original texture, so this should be safe.
tex = resourceProvider->wrapBackendTexture(backendTexture,
kBorrow_GrWrapOwnership,
true);
tex = resourceProvider->wrapBackendTexture(
backendTexture, kBorrow_GrWrapOwnership, kRead_GrIOType, true);
if (!tex) {
return sk_sp<GrTexture>();
}
@ -176,7 +175,8 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture(
return tex;
},
format, desc, fSurfaceOrigin, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo);
format, desc, fSurfaceOrigin, mipMapped, GrInternalSurfaceFlags::kReadOnly,
SkBackingFit::kExact, SkBudgeted::kNo);
if (!proxy) {
return nullptr;

View File

@ -6,9 +6,10 @@
*/
#include "GrCaps.h"
#include "GrBackendSurface.h"
#include "GrContextOptions.h"
#include "GrSurface.h"
#include "GrSurfaceProxy.h"
#include "GrTypesPriv.h"
#include "GrWindowRectangles.h"
#include "SkJSONWriter.h"
@ -242,6 +243,15 @@ void GrCaps::dumpJSON(SkJSONWriter* writer) const {
void GrCaps::dumpJSON(SkJSONWriter* writer) const { }
#endif
bool GrCaps::surfaceSupportsWritePixels(const GrSurface* surface) const {
return surface->readOnly() ? false : this->onSurfaceSupportsWritePixels(surface);
}
bool GrCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
return dst->readOnly() ? false : this->onCanCopySurface(dst, src, srcRect, dstPoint);
}
bool GrCaps::validateSurfaceDesc(const GrSurfaceDesc& desc, GrMipMapped mipped) const {
if (!this->isConfigTexturable(desc.fConfig)) {
return false;

View File

@ -192,7 +192,7 @@ public:
* If this returns false then the caller should implement a fallback where a temporary texture
* is created, pixels are written to it, and then that is copied or drawn into the the surface.
*/
virtual bool surfaceSupportsWritePixels(const GrSurface*) const = 0;
bool surfaceSupportsWritePixels(const GrSurface*) const;
/**
* Backends may have restrictions on what types of surfaces support GrGpu::readPixels().
@ -246,8 +246,8 @@ public:
/**
* Returns whether or not we will be able to do a copy given the passed in params
*/
virtual bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const = 0;
bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const;
bool dynamicStateArrayGeometryProcessorTextureSupport() const {
return fDynamicStateArrayGeometryProcessorTextureSupport;
@ -389,6 +389,9 @@ protected:
private:
virtual void onApplyOptionsOverrides(const GrContextOptions&) {}
virtual void onDumpJSON(SkJSONWriter*) const {}
virtual bool onSurfaceSupportsWritePixels(const GrSurface*) const = 0;
virtual bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const = 0;
// Backends should implement this if they have any extra requirements for use of window
// rectangles for a specific GrBackendRenderTarget outside of basic support.

View File

@ -928,7 +928,8 @@ sk_sp<GrTextureContext> GrContextPriv::makeBackendTextureContext(const GrBackend
sk_sp<SkColorSpace> colorSpace) {
ASSERT_SINGLE_OWNER_PRIV
sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendTexture(tex, origin);
sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendTexture(
tex, origin, kBorrow_GrWrapOwnership, kRW_GrIOType);
if (!proxy) {
return nullptr;
}

View File

@ -145,7 +145,9 @@ sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc, SkBudgeted budg
sk_sp<GrTexture> GrGpu::wrapBackendTexture(const GrBackendTexture& backendTex,
GrWrapOwnership ownership,
GrIOType ioType,
bool purgeImmediately) {
SkASSERT(ioType != kWrite_GrIOType);
this->handleDirtyContext();
if (!this->caps()->isConfigTexturable(backendTex.config())) {
return nullptr;
@ -154,7 +156,7 @@ sk_sp<GrTexture> GrGpu::wrapBackendTexture(const GrBackendTexture& backendTex,
backendTex.height() > this->caps()->maxTextureSize()) {
return nullptr;
}
return this->onWrapBackendTexture(backendTex, ownership, purgeImmediately);
return this->onWrapBackendTexture(backendTex, ownership, ioType, purgeImmediately);
}
sk_sp<GrTexture> GrGpu::wrapRenderableBackendTexture(const GrBackendTexture& backendTex,
@ -214,7 +216,13 @@ bool GrGpu::copySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
bool canDiscardOutsideDstRect) {
GR_CREATE_TRACE_MARKER_CONTEXT("GrGpu", "copySurface", fContext);
SkASSERT(dst && src);
if (dst->readOnly()) {
return false;
}
this->handleDirtyContext();
return this->onCopySurface(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint,
canDiscardOutsideDstRect);
}
@ -239,6 +247,11 @@ bool GrGpu::readPixels(GrSurface* surface, int left, int top, int width, int hei
bool GrGpu::writePixels(GrSurface* surface, int left, int top, int width, int height,
GrColorType srcColorType, const GrMipLevel texels[], int mipLevelCount) {
SkASSERT(surface);
if (surface->readOnly()) {
return false;
}
if (1 == mipLevelCount) {
// We require that if we are not mipped, then the write region is contained in the surface
SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
@ -271,8 +284,13 @@ bool GrGpu::writePixels(GrSurface* surface, int left, int top, int width, int he
bool GrGpu::transferPixels(GrTexture* texture, int left, int top, int width, int height,
GrColorType bufferColorType, GrBuffer* transferBuffer, size_t offset,
size_t rowBytes) {
SkASSERT(texture);
SkASSERT(transferBuffer);
if (texture->readOnly()) {
return false;
}
// We require that the write region is contained in the texture
SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height());
@ -298,6 +316,9 @@ bool GrGpu::regenerateMipMapLevels(GrTexture* texture) {
SkASSERT(texture->texturePriv().mipMapped() == GrMipMapped::kYes);
SkASSERT(texture->texturePriv().mipMapsAreDirty());
SkASSERT(!texture->asRenderTarget() || !texture->asRenderTarget()->needsResolve());
if (texture->readOnly()) {
return false;
}
if (this->onRegenerateMipMapLevels(texture)) {
texture->texturePriv().markMipMapsClean();
return true;
@ -314,6 +335,7 @@ void GrGpu::resolveRenderTarget(GrRenderTarget* target) {
void GrGpu::didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkIRect* bounds,
uint32_t mipLevels) const {
SkASSERT(surface);
SkASSERT(!surface->readOnly());
// Mark any MIP chain and resolve buffer as dirty if and only if there is a non-empty bounds.
if (nullptr == bounds || !bounds->isEmpty()) {
if (GrRenderTarget* target = surface->asRenderTarget()) {

View File

@ -104,7 +104,7 @@ public:
/**
* Implements GrResourceProvider::wrapBackendTexture
*/
sk_sp<GrTexture> wrapBackendTexture(const GrBackendTexture&, GrWrapOwnership,
sk_sp<GrTexture> wrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrIOType,
bool purgeImmediately);
/**
@ -445,7 +445,7 @@ private:
const GrMipLevel texels[], int mipLevelCount) = 0;
virtual sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership,
bool purgeImmediately) = 0;
GrIOType, bool purgeImmediately) = 0;
virtual sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
int sampleCnt,
GrWrapOwnership) = 0;

View File

@ -415,8 +415,10 @@ sk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrBackendFormat& format
sk_sp<GrTextureProxy> GrProxyProvider::wrapBackendTexture(const GrBackendTexture& backendTex,
GrSurfaceOrigin origin,
GrWrapOwnership ownership,
GrIOType ioType,
ReleaseProc releaseProc,
ReleaseContext releaseCtx) {
SkASSERT(ioType != kWrite_GrIOType);
if (this->isAbandoned()) {
return nullptr;
}
@ -426,7 +428,7 @@ sk_sp<GrTextureProxy> GrProxyProvider::wrapBackendTexture(const GrBackendTexture
return nullptr;
}
sk_sp<GrTexture> tex = fResourceProvider->wrapBackendTexture(backendTex, ownership);
sk_sp<GrTexture> tex = fResourceProvider->wrapBackendTexture(backendTex, ownership, ioType);
if (!tex) {
return nullptr;
}

View File

@ -104,11 +104,12 @@ public:
typedef void (*ReleaseProc)(ReleaseContext);
/*
* Create a texture proxy that wraps a (non-renderable) backend texture.
* Create a texture proxy that wraps a (non-renderable) backend texture. GrIOType must be
* kRead or kRW.
*/
sk_sp<GrTextureProxy> wrapBackendTexture(const GrBackendTexture&, GrSurfaceOrigin,
GrWrapOwnership = kBorrow_GrWrapOwnership,
ReleaseProc = nullptr, ReleaseContext = nullptr);
GrWrapOwnership, GrIOType, ReleaseProc = nullptr,
ReleaseContext = nullptr);
/*
* Create a texture proxy that wraps a backend texture and is both texture-able and renderable

View File

@ -226,12 +226,13 @@ sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc
sk_sp<GrTexture> GrResourceProvider::wrapBackendTexture(const GrBackendTexture& tex,
GrWrapOwnership ownership,
GrIOType ioType,
bool purgeImmediately) {
ASSERT_SINGLE_OWNER
if (this->isAbandoned()) {
return nullptr;
}
return fGpu->wrapBackendTexture(tex, ownership, purgeImmediately);
return fGpu->wrapBackendTexture(tex, ownership, ioType, purgeImmediately);
}
sk_sp<GrTexture> GrResourceProvider::wrapRenderableBackendTexture(const GrBackendTexture& tex,

View File

@ -98,13 +98,17 @@ public:
/**
* Wraps an existing texture with a GrTexture object.
*
* GrIOType must either be kRead or kRW. kRead blocks any operations that would modify the
* pixels (e.g. dst for a copy, regenerating MIP levels, write pixels).
*
* OpenGL: if the object is a texture Gr may change its GL texture params
* when it is drawn.
*
* @return GrTexture object or NULL on failure.
*/
sk_sp<GrTexture> wrapBackendTexture(const GrBackendTexture& tex,
GrWrapOwnership = kBorrow_GrWrapOwnership,
GrWrapOwnership /* = kBorrow_GrWrapOwnership*/,
GrIOType,
bool purgeImmediately = false);
/**

View File

@ -25,6 +25,7 @@ GrTextureOpList::GrTextureOpList(GrResourceProvider* resourceProvider,
GrAuditTrail* auditTrail)
: INHERITED(resourceProvider, std::move(opMemoryPool), proxy, auditTrail) {
SkASSERT(fOpMemoryPool);
SkASSERT(!proxy->readOnly());
}
void GrTextureOpList::deleteOp(int index) {

View File

@ -173,7 +173,14 @@ void GrTextureProxy::onValidateSurface(const GrSurface* surface) {
SkASSERT(surface->asTexture());
SkASSERT(GrMipMapped::kNo == this->proxyMipMapped() ||
GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
SkASSERT(surface->asTexture()->texturePriv().textureType() == this->textureType());
GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags();
SkASSERT((proxyFlags & GrInternalSurfaceFlags::kTextureMask) ==
(surfaceFlags & GrInternalSurfaceFlags::kTextureMask));
}
#endif

View File

@ -124,11 +124,19 @@ void GrTextureRenderTargetProxy::onValidateSurface(const GrSurface* surface) {
SkASSERT(surface->asRenderTarget());
SkASSERT(surface->asRenderTarget()->numStencilSamples() == this->numStencilSamples());
SkASSERT(surface->asTexture()->texturePriv().textureType() == this->textureType());
GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags();
// Only non-RT textures can be read only.
SkASSERT(!(proxyFlags & GrInternalSurfaceFlags::kReadOnly));
SkASSERT(!(surfaceFlags & GrInternalSurfaceFlags::kReadOnly));
SkASSERT((proxyFlags & GrInternalSurfaceFlags::kRenderTargetMask) ==
(surfaceFlags & GrInternalSurfaceFlags::kRenderTargetMask));
SkASSERT(surface->asTexture()->texturePriv().textureType() == this->textureType());
SkASSERT((proxyFlags & GrInternalSurfaceFlags::kTextureMask) ==
(surfaceFlags & GrInternalSurfaceFlags::kTextureMask));
}
#endif

View File

@ -2172,7 +2172,7 @@ static bool has_msaa_render_buffer(const GrSurfaceProxy* surf, const GrGLCaps& g
!rt->rtPriv().glRTFBOIDIs0();
}
bool GrGLCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
bool GrGLCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
GrSurfaceOrigin dstOrigin = dst->origin();
GrSurfaceOrigin srcOrigin = src->origin();
@ -2756,7 +2756,7 @@ void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
}
}
bool GrGLCaps::surfaceSupportsWritePixels(const GrSurface* surface) const {
bool GrGLCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
if (fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO) {
if (auto tex = static_cast<const GrGLTexture*>(surface->asTexture())) {
if (tex->hasBaseLevelBeenBoundToFBO()) {

View File

@ -311,7 +311,6 @@ public:
/// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; }
bool surfaceSupportsWritePixels(const GrSurface*) const override;
bool surfaceSupportsReadPixels(const GrSurface*) const override;
GrColorType supportedReadPixelsColorType(GrPixelConfig, GrColorType) const override;
@ -419,9 +418,6 @@ public:
const SkIRect& srcRect, const SkIPoint& dstPoint) const;
bool canCopyAsDraw(GrPixelConfig dstConfig, bool srcIsTextureable) const;
bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
bool* rectsMustMatch, bool* disallowSubrect) const override;
@ -480,6 +476,9 @@ private:
// This must be called after initFSAASupport().
void initConfigTable(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*,
GrShaderCaps*);
bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
GrGLStandard fStandard;

View File

@ -652,7 +652,8 @@ static bool check_backend_texture(const GrBackendTexture& backendTex, const GrGL
}
sk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
GrWrapOwnership ownership, bool purgeImmediately) {
GrWrapOwnership ownership, GrIOType ioType,
bool purgeImmediately) {
GrGLTexture::IDDesc idDesc;
if (!check_backend_texture(backendTex, this->glCaps(), &idDesc)) {
return nullptr;
@ -676,7 +677,7 @@ sk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTexture& backendTe
GrMipMapsStatus mipMapsStatus = backendTex.hasMipMaps() ? GrMipMapsStatus::kValid
: GrMipMapsStatus::kNotAllocated;
auto texture = GrGLTexture::MakeWrapped(this, surfDesc, mipMapsStatus, idDesc,
auto texture = GrGLTexture::MakeWrapped(this, surfDesc, mipMapsStatus, idDesc, ioType,
purgeImmediately);
// We don't know what parameters are already set on wrapped textures.
texture->textureParamsModified();

View File

@ -189,7 +189,7 @@ private:
GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
const void* data) override;
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership,
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrIOType,
bool purgeImmediately) override;
sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
int sampleCnt,

View File

@ -51,12 +51,15 @@ GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc&
}
GrGLTexture::GrGLTexture(GrGLGpu* gpu, Wrapped, const GrSurfaceDesc& desc,
GrMipMapsStatus mipMapsStatus, const IDDesc& idDesc,
GrMipMapsStatus mipMapsStatus, const IDDesc& idDesc, GrIOType ioType,
bool purgeImmediately)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus) {
this->init(desc, idDesc);
this->registerWithCacheWrapped(purgeImmediately);
if (ioType == kRead_GrIOType) {
this->setReadOnly();
}
}
GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc,
@ -111,9 +114,9 @@ GrBackendFormat GrGLTexture::backendFormat() const {
sk_sp<GrGLTexture> GrGLTexture::MakeWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
GrMipMapsStatus mipMapsStatus, const IDDesc& idDesc,
bool purgeImmediately) {
return sk_sp<GrGLTexture>(new GrGLTexture(gpu, kWrapped, desc, mipMapsStatus, idDesc,
purgeImmediately));
GrIOType ioType, bool purgeImmediately) {
return sk_sp<GrGLTexture>(
new GrGLTexture(gpu, kWrapped, desc, mipMapsStatus, idDesc, ioType, purgeImmediately));
}
bool GrGLTexture::onStealBackendTexture(GrBackendTexture* backendTexture,

View File

@ -100,7 +100,7 @@ public:
void baseLevelWasBoundToFBO() { fBaseLevelHasBeenBoundToFBO = true; }
static sk_sp<GrGLTexture> MakeWrapped(GrGLGpu*, const GrSurfaceDesc&, GrMipMapsStatus,
const IDDesc&, bool purgeImmediately);
const IDDesc&, GrIOType, bool purgeImmediately);
void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override;
@ -110,7 +110,7 @@ protected:
enum Wrapped { kWrapped };
// Constructor for instances wrapping backend objects.
GrGLTexture(GrGLGpu*, Wrapped, const GrSurfaceDesc&, GrMipMapsStatus, const IDDesc&,
GrGLTexture(GrGLGpu*, Wrapped, const GrSurfaceDesc&, GrMipMapsStatus, const IDDesc&, GrIOType,
bool purgeImmediately);
void init(const GrSurfaceDesc&, const IDDesc&);

View File

@ -66,14 +66,8 @@ public:
return 0;
}
bool surfaceSupportsWritePixels(const GrSurface*) const override { return true; }
bool surfaceSupportsReadPixels(const GrSurface*) const override { return true; }
bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override {
return true;
}
bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
bool* rectsMustMatch, bool* disallowSubrect) const override {
return false;
@ -142,6 +136,11 @@ private:
SkAssertResult(backendTex.getMockTextureInfo(&mockInfo));
return GrBackendFormat::MakeMock(mockInfo.fConfig);
}
bool onSurfaceSupportsWritePixels(const GrSurface*) const override { return true; }
bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override {
return true;
}
static const int kMaxSampleCnt = 16;

View File

@ -103,7 +103,8 @@ sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgete
}
sk_sp<GrTexture> GrMockGpu::onWrapBackendTexture(const GrBackendTexture& tex,
GrWrapOwnership ownership, bool purgeImmediately) {
GrWrapOwnership ownership, GrIOType ioType,
bool purgeImmediately) {
GrSurfaceDesc desc;
desc.fWidth = tex.width();
desc.fHeight = tex.height();
@ -116,7 +117,7 @@ sk_sp<GrTexture> GrMockGpu::onWrapBackendTexture(const GrBackendTexture& tex,
: GrMipMapsStatus::kNotAllocated;
return sk_sp<GrTexture>(new GrMockTexture(this, GrMockTexture::kWrapped, desc, mipMapsStatus,
info, purgeImmediately));
info, ioType, purgeImmediately));
}
sk_sp<GrTexture> GrMockGpu::onWrapRenderableBackendTexture(const GrBackendTexture& tex,

View File

@ -59,7 +59,7 @@ private:
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, SkBudgeted, const GrMipLevel[],
int mipLevelCount) override;
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership,
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrIOType,
bool purgeImmediately) override;
sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,

View File

@ -23,10 +23,12 @@ public:
}
enum Wrapped { kWrapped };
GrMockTexture(GrMockGpu* gpu, Wrapped, const GrSurfaceDesc& desc,
GrMipMapsStatus mipMapsStatus, const GrMockTextureInfo& info,
bool purgeImmediately)
GrMockTexture(GrMockGpu* gpu, Wrapped, const GrSurfaceDesc& desc, GrMipMapsStatus mipMapsStatus,
const GrMockTextureInfo& info, GrIOType ioType, bool purgeImmediately)
: GrMockTexture(gpu, desc, mipMapsStatus, info) {
if (ioType == kRead_GrIOType) {
this->setReadOnly();
}
this->registerWithCacheWrapped(purgeImmediately);
}

View File

@ -33,7 +33,6 @@ public:
int getRenderTargetSampleCount(int requestedCount, GrPixelConfig) const override;
int maxRenderTargetSampleCount(GrPixelConfig) const override;
bool surfaceSupportsWritePixels(const GrSurface*) const override { return true; }
bool surfaceSupportsReadPixels(const GrSurface*) const override { return true; }
bool isConfigCopyable(GrPixelConfig config) const override {
@ -58,9 +57,6 @@ public:
bool canCopyAsDrawThenBlit(GrPixelConfig dstConfig, GrPixelConfig srcConfig,
bool srcIsTextureable) const;
bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
bool* rectsMustMatch, bool* disallowSubrect) const override {
return false;
@ -109,6 +105,10 @@ private:
void initConfigTable();
bool onSurfaceSupportsWritePixels(const GrSurface*) const override { return true; }
bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
struct ConfigInfo {
ConfigInfo() : fFlags(0) {}

View File

@ -166,7 +166,7 @@ bool GrMtlCaps::canCopyAsDrawThenBlit(GrPixelConfig dstConfig, GrPixelConfig src
return true;
}
bool GrMtlCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
bool GrMtlCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
GrSurfaceOrigin dstOrigin = dst->origin();
GrSurfaceOrigin srcOrigin = src->origin();

View File

@ -132,7 +132,7 @@ private:
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
const GrMipLevel texels[], int mipLevelCount) override;
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership,
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrIOType,
bool purgeImmediately) override;
sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,

View File

@ -338,7 +338,8 @@ static inline void init_surface_desc(GrSurfaceDesc* surfaceDesc, id<MTLTexture>
}
sk_sp<GrTexture> GrMtlGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
GrWrapOwnership ownership, bool purgeImmediately) {
GrWrapOwnership ownership, GrIOType ioType,
bool purgeImmediately) {
id<MTLTexture> mtlTexture = get_texture_from_backend(backendTex, ownership);
if (!mtlTexture) {
return nullptr;
@ -347,7 +348,7 @@ sk_sp<GrTexture> GrMtlGpu::onWrapBackendTexture(const GrBackendTexture& backendT
GrSurfaceDesc surfDesc;
init_surface_desc(&surfDesc, mtlTexture, false, backendTex.config());
return GrMtlTexture::MakeWrappedTexture(this, surfDesc, mtlTexture, purgeImmediately);
return GrMtlTexture::MakeWrappedTexture(this, surfDesc, mtlTexture, ioType, purgeImmediately);
}
sk_sp<GrTexture> GrMtlGpu::onWrapRenderableBackendTexture(const GrBackendTexture& backendTex,

View File

@ -21,8 +21,8 @@ public:
MTLTextureDescriptor*,
GrMipMapsStatus);
static sk_sp<GrMtlTexture> MakeWrappedTexture(GrMtlGpu*, const GrSurfaceDesc&,
id<MTLTexture>, bool purgeImmediately);
static sk_sp<GrMtlTexture> MakeWrappedTexture(GrMtlGpu*, const GrSurfaceDesc&, id<MTLTexture>,
GrIOType, bool purgeImmediately);
~GrMtlTexture() override;
@ -65,7 +65,7 @@ private:
GrMipMapsStatus);
GrMtlTexture(GrMtlGpu*, Wrapped, const GrSurfaceDesc&, id<MTLTexture>, GrMipMapsStatus,
bool purgeImmediately);
GrIOType, bool purgeImmediately);
id<MTLTexture> fTexture;

View File

@ -28,11 +28,15 @@ GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu,
const GrSurfaceDesc& desc,
id<MTLTexture> texture,
GrMipMapsStatus mipMapsStatus,
GrIOType ioType,
bool purgeImmediately)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, GrTextureType::k2D, mipMapsStatus)
, fTexture(texture) {
SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == texture.mipmapLevelCount));
if (ioType == kRead_GrIOType) {
this->setReadOnly();
}
this->registerWithCacheWrapped(purgeImmediately);
}
@ -63,6 +67,7 @@ sk_sp<GrMtlTexture> GrMtlTexture::CreateNewTexture(GrMtlGpu* gpu, SkBudgeted bud
sk_sp<GrMtlTexture> GrMtlTexture::MakeWrappedTexture(GrMtlGpu* gpu,
const GrSurfaceDesc& desc,
id<MTLTexture> texture,
GrIOType ioType,
bool purgeImmediately) {
if (desc.fSampleCnt > 1) {
SkASSERT(false); // Currently we don't support msaa
@ -72,7 +77,7 @@ sk_sp<GrMtlTexture> GrMtlTexture::MakeWrappedTexture(GrMtlGpu* gpu,
SkASSERT(MTLTextureUsageShaderRead & texture.usage);
GrMipMapsStatus mipMapsStatus = texture.mipmapLevelCount > 1 ? GrMipMapsStatus::kValid
: GrMipMapsStatus::kNotAllocated;
return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, kWrapped, desc, texture, mipMapsStatus,
return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, kWrapped, desc, texture, mipMapsStatus, ioType,
purgeImmediately));
}

View File

@ -158,7 +158,7 @@ bool GrVkCaps::canCopyAsDraw(GrPixelConfig dstConfig, bool dstIsRenderable,
return true;
}
bool GrVkCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
bool GrVkCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
GrSurfaceOrigin dstOrigin = dst->origin();
GrSurfaceOrigin srcOrigin = src->origin();
@ -698,7 +698,7 @@ int GrVkCaps::maxRenderTargetSampleCount(GrPixelConfig config) const {
return table[table.count() - 1];
}
bool GrVkCaps::surfaceSupportsWritePixels(const GrSurface* surface) const {
bool GrVkCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
if (auto rt = surface->asRenderTarget()) {
return rt->numColorSamples() <= 1 && SkToBool(surface->asTexture());
}

View File

@ -43,7 +43,6 @@ public:
int getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const override;
int maxRenderTargetSampleCount(GrPixelConfig config) const override;
bool surfaceSupportsWritePixels(const GrSurface*) const override;
bool surfaceSupportsReadPixels(const GrSurface*) const override { return true; }
bool isConfigTexturableLinearly(GrPixelConfig config) const {
@ -151,9 +150,6 @@ public:
bool canCopyAsDraw(GrPixelConfig dstConfig, bool dstIsRenderable,
GrPixelConfig srcConfig, bool srcIsTextureable) const;
bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*,
bool* rectsMustMatch, bool* disallowSubrect) const override;
@ -201,6 +197,10 @@ private:
void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&);
bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
struct ConfigInfo {
ConfigInfo() : fOptimalFlags(0), fLinearFlags(0) {}

View File

@ -888,7 +888,8 @@ static bool check_image_info(const GrVkCaps& caps,
}
sk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
GrWrapOwnership ownership, bool purgeImmediately) {
GrWrapOwnership ownership, GrIOType ioType,
bool purgeImmediately) {
GrVkImageInfo imageInfo;
if (!backendTex.getVkImageInfo(&imageInfo)) {
return nullptr;
@ -907,7 +908,7 @@ sk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTexture& backendTe
sk_sp<GrVkImageLayout> layout = backendTex.getGrVkImageLayout();
SkASSERT(layout);
return GrVkTexture::MakeWrappedTexture(this, surfDesc, ownership, purgeImmediately,
return GrVkTexture::MakeWrappedTexture(this, surfDesc, ownership, ioType, purgeImmediately,
imageInfo, std::move(layout));
}

View File

@ -170,7 +170,7 @@ private:
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, SkBudgeted, const GrMipLevel[],
int mipLevelCount) override;
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership,
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrIOType,
bool purgeImmediately) override;
sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
int sampleCnt,

View File

@ -41,12 +41,16 @@ GrVkTexture::GrVkTexture(GrVkGpu* gpu,
const GrVkImageView* view,
GrMipMapsStatus mipMapsStatus,
GrBackendObjectOwnership ownership,
GrIOType ioType,
bool purgeImmediately)
: GrSurface(gpu, desc)
, GrVkImage(info, std::move(layout), ownership)
, INHERITED(gpu, desc, GrTextureType::k2D, mipMapsStatus)
, fTextureView(view) {
SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == info.fLevelCount));
if (ioType == kRead_GrIOType) {
this->setReadOnly();
}
this->registerWithCacheWrapped(purgeImmediately);
}
@ -92,6 +96,7 @@ sk_sp<GrVkTexture> GrVkTexture::MakeNewTexture(GrVkGpu* gpu, SkBudgeted budgeted
sk_sp<GrVkTexture> GrVkTexture::MakeWrappedTexture(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrWrapOwnership wrapOwnership,
GrIOType ioType,
bool purgeImmediately,
const GrVkImageInfo& info,
sk_sp<GrVkImageLayout> layout) {
@ -111,7 +116,7 @@ sk_sp<GrVkTexture> GrVkTexture::MakeWrappedTexture(GrVkGpu* gpu,
GrBackendObjectOwnership ownership = kBorrow_GrWrapOwnership == wrapOwnership
? GrBackendObjectOwnership::kBorrowed : GrBackendObjectOwnership::kOwned;
return sk_sp<GrVkTexture>(new GrVkTexture(gpu, kWrapped, desc, info, std::move(layout),
imageView, mipMapsStatus, ownership,
imageView, mipMapsStatus, ownership, ioType,
purgeImmediately));
}

View File

@ -25,8 +25,8 @@ public:
const GrVkImage::ImageDesc&,
GrMipMapsStatus);
static sk_sp<GrVkTexture> MakeWrappedTexture(GrVkGpu*, const GrSurfaceDesc&,
GrWrapOwnership, bool purgeImmediatley,
static sk_sp<GrVkTexture> MakeWrappedTexture(GrVkGpu*, const GrSurfaceDesc&, GrWrapOwnership,
GrIOType, bool purgeImmediately,
const GrVkImageInfo&, sk_sp<GrVkImageLayout>);
~GrVkTexture() override;
@ -66,7 +66,7 @@ private:
GrMipMapsStatus);
GrVkTexture(GrVkGpu*, Wrapped, const GrSurfaceDesc&, const GrVkImageInfo&,
sk_sp<GrVkImageLayout> layout, const GrVkImageView* imageView, GrMipMapsStatus,
GrBackendObjectOwnership, bool purgeImmediately);
GrBackendObjectOwnership, GrIOType ioType, bool purgeImmediately);
const GrVkImageView* fTextureView;

View File

@ -74,8 +74,8 @@ static sk_sp<SkImage> new_wrapped_texture_common(GrContext* ctx,
}
GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
sk_sp<GrTextureProxy> proxy = proxyProvider->wrapBackendTexture(backendTex, origin, ownership,
releaseProc, releaseCtx);
sk_sp<GrTextureProxy> proxy = proxyProvider->wrapBackendTexture(
backendTex, origin, ownership, kRead_GrIOType, releaseProc, releaseCtx);
if (!proxy) {
return nullptr;
}
@ -373,6 +373,7 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
desc.fHeight = height;
desc.fConfig = config;
// We pass kReadOnly here since we should treat content of the client's texture as immutable.
sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
[promiseHelper, config](GrResourceProvider* resourceProvider) mutable {
if (!resourceProvider) {
@ -382,7 +383,7 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
return promiseHelper.getTexture(resourceProvider, config);
},
backendFormat, desc, origin, mipMapped, GrInternalSurfaceFlags::kNone,
backendFormat, desc, origin, mipMapped, GrInternalSurfaceFlags::kReadOnly,
SkBackingFit::kExact, SkBudgeted::kNo,
GrSurfaceProxy::LazyInstantiationType::kUninstantiate);
@ -534,7 +535,7 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseYUVATexture(GrContext* context,
},
yuvaFormats[yuvaIndices[SkYUVAIndex::kY_Index].fIndex],
desc, imageOrigin, GrMipMapped::kNo,
GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo,
GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
GrSurfaceProxy::LazyInstantiationType::kUninstantiate);
if (!proxy) {

View File

@ -320,7 +320,8 @@ bool SkImage_GpuBase::MakeTempTextureProxies(GrContext* ctx, const GrBackendText
SkASSERT(yuvaTexturesCopy[textureIndex].isValid());
tempTextureProxies[textureIndex] =
proxyProvider->wrapBackendTexture(yuvaTexturesCopy[textureIndex], imageOrigin);
proxyProvider->wrapBackendTexture(yuvaTexturesCopy[textureIndex], imageOrigin,
kBorrow_GrWrapOwnership, kRead_GrIOType);
if (!tempTextureProxies[textureIndex]) {
return false;
}
@ -400,7 +401,8 @@ sk_sp<GrTexture> SkPromiseImageHelper::getTexture(GrResourceProvider* resourcePr
return sk_sp<GrTexture>();
}
tex = resourceProvider->wrapBackendTexture(fBackendTex, kBorrow_GrWrapOwnership);
tex = resourceProvider->wrapBackendTexture(fBackendTex, kBorrow_GrWrapOwnership,
kRead_GrIOType);
if (!tex) {
// Even though the GrBackendTexture is not valid, we must call the release
// proc to keep our contract of always calling Fulfill and Release in pairs.
@ -412,7 +414,8 @@ sk_sp<GrTexture> SkPromiseImageHelper::getTexture(GrResourceProvider* resourcePr
fReleaseHelper->weak_ref();
} else {
SkASSERT(fBackendTex.isValid());
tex = resourceProvider->wrapBackendTexture(fBackendTex, kBorrow_GrWrapOwnership);
tex = resourceProvider->wrapBackendTexture(fBackendTex, kBorrow_GrWrapOwnership,
kRead_GrIOType);
if (!tex) {
// We weren't able to make a texture here, but since we are in this branch
// of the calls (promiseHelper.fReleaseHelper is valid) there is already a

View File

@ -310,7 +310,7 @@ sk_sp<SkImage> SkImage_GpuYUVA::MakePromiseYUVATexture(GrContext* context,
desc.fSampleCnt = 1;
proxies[texIdx] = proxyProvider->createLazyProxy(
std::move(lazyInstCallback), yuvaFormats[texIdx], desc, imageOrigin,
GrMipMapped::kNo, GrInternalSurfaceFlags::kNone,
GrMipMapped::kNo, GrInternalSurfaceFlags::kReadOnly,
SkBackingFit::kExact, SkBudgeted::kNo,
GrSurfaceProxy::LazyInstantiationType::kUninstantiate);
if (!proxies[texIdx]) {

View File

@ -1068,8 +1068,8 @@ DEF_GPUTEST(PorterDuffNoDualSourceBlending, reporter, options) {
GrXferProcessor::DstProxy fakeDstProxy;
{
sk_sp<GrTextureProxy> proxy =
proxyProvider->wrapBackendTexture(backendTex, kTopLeft_GrSurfaceOrigin);
sk_sp<GrTextureProxy> proxy = proxyProvider->wrapBackendTexture(
backendTex, kTopLeft_GrSurfaceOrigin, kBorrow_GrWrapOwnership, kRead_GrIOType);
fakeDstProxy.setProxy(std::move(proxy));
}

View File

@ -5,8 +5,6 @@
* found in the LICENSE file.
*/
#include "SkTypes.h"
#include "GrContext.h"
#include "GrContextPriv.h"
#include "GrGpu.h"
@ -14,7 +12,10 @@
#include "GrRenderTarget.h"
#include "GrResourceProvider.h"
#include "GrTexture.h"
#include "GrTexturePriv.h"
#include "SkAutoPixmapStorage.h"
#include "SkMipMap.h"
#include "SkTypes.h"
#include "Test.h"
// Tests that GrSurface::asTexture(), GrSurface::asRenderTarget(), and static upcasting of texture
@ -236,3 +237,94 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(InitialTextureClear, reporter, context_info)
}
}
}
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadOnlyTexture, reporter, context_info) {
auto fillPixels = [](const SkPixmap* p, const std::function<uint32_t(int x, int y)>& f) {
for (int y = 0; y < p->height(); ++y) {
for (int x = 0; x < p->width(); ++x) {
*p->writable_addr32(x, y) = f(x, y);
}
}
};
auto comparePixels = [](const SkPixmap& p1, const SkPixmap& p2, skiatest::Reporter* reporter) {
SkASSERT(p1.info() == p2.info());
for (int y = 0; y < p1.height(); ++y) {
for (int x = 0; x < p1.width(); ++x) {
REPORTER_ASSERT(reporter, p1.getColor(x, y) == p2.getColor(x, y));
if (p1.getColor(x, y) != p2.getColor(x, y)) {
return;
}
}
}
};
static constexpr int kSize = 100;
SkAutoPixmapStorage pixels;
pixels.alloc(SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
fillPixels(&pixels,
[](int x, int y) { return (0xFFU << 24) | (x << 16) | (y << 8) | uint8_t(x * y); });
GrContext* context = context_info.grContext();
GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
// We test both kRW in addition to kRead mostly to ensure that the calls are structured such
// that they'd succeed if the texture wasn't kRead. We want to be sure we're failing with
// kRead for the right reason.
for (auto ioType : {kRead_GrIOType, kRW_GrIOType}) {
auto backendTex = context->contextPriv().getGpu()->createTestingOnlyBackendTexture(
pixels.addr(), kSize, kSize, kRGBA_8888_SkColorType, true, GrMipMapped::kNo);
auto proxy = proxyProvider->wrapBackendTexture(backendTex, kTopLeft_GrSurfaceOrigin,
kBorrow_GrWrapOwnership, ioType);
auto surfContext = context->contextPriv().makeWrappedSurfaceContext(proxy);
// Read pixels should work with a read-only texture.
SkAutoPixmapStorage read;
read.alloc(pixels.info());
auto readResult = surfContext->readPixels(pixels.info(), read.writable_addr(), 0, 0, 0);
REPORTER_ASSERT(reporter, readResult);
if (readResult) {
comparePixels(pixels, read, reporter);
}
// Write pixels should not work with a read-only texture.
SkAutoPixmapStorage write;
write.alloc(pixels.info());
fillPixels(&write, [&pixels](int x, int y) { return ~*pixels.addr32(); });
auto writeResult = surfContext->writePixels(pixels.info(), pixels.addr(), 0, 0, 0);
REPORTER_ASSERT(reporter, writeResult == (ioType == kRW_GrIOType));
// Try the low level write.
context->flush();
auto gpuWriteResult = context->contextPriv().getGpu()->writePixels(
proxy->peekTexture(), 0, 0, kSize, kSize, GrColorType::kRGBA_8888, write.addr32(),
0);
REPORTER_ASSERT(reporter, gpuWriteResult == (ioType == kRW_GrIOType));
// Copies should not work with a read-only texture
auto copySrc = proxyProvider->createTextureProxy(
SkImage::MakeFromRaster(write, nullptr, nullptr), kNone_GrSurfaceFlags, 1,
SkBudgeted::kYes, SkBackingFit::kExact);
REPORTER_ASSERT(reporter, copySrc);
auto copyResult = surfContext->copy(copySrc.get());
REPORTER_ASSERT(reporter, copyResult == (ioType == kRW_GrIOType));
// Try the low level copy.
context->flush();
auto gpuCopyResult = context->contextPriv().getGpu()->copySurface(
proxy->peekTexture(), kTopLeft_GrSurfaceOrigin, copySrc->peekTexture(),
kTopLeft_GrSurfaceOrigin, SkIRect::MakeWH(kSize, kSize), {0, 0});
REPORTER_ASSERT(reporter, gpuCopyResult == (ioType == kRW_GrIOType));
// Mip regen should not work with a read only texture.
if (context->contextPriv().caps()->mipMapSupport()) {
backendTex = context->contextPriv().getGpu()->createTestingOnlyBackendTexture(
nullptr, kSize, kSize, kRGBA_8888_SkColorType, true, GrMipMapped::kYes);
proxy = proxyProvider->wrapBackendTexture(backendTex, kTopLeft_GrSurfaceOrigin,
kBorrow_GrWrapOwnership, ioType);
context->flush();
proxy->peekTexture()->texturePriv().markMipMapsDirty(); // avoids assert in GrGpu.
auto regenResult =
context->contextPriv().getGpu()->regenerateMipMapLevels(proxy->peekTexture());
REPORTER_ASSERT(reporter, regenResult == (ioType == kRW_GrIOType));
}
}
}

View File

@ -50,9 +50,8 @@ void testing_only_texture_test(skiatest::Reporter* reporter, GrContext* context,
wrappedTex = gpu->wrapRenderableBackendTexture(backendTex, 1,
GrWrapOwnership::kAdopt_GrWrapOwnership);
} else {
wrappedTex = gpu->wrapBackendTexture(backendTex,
GrWrapOwnership::kAdopt_GrWrapOwnership,
false);
wrappedTex = gpu->wrapBackendTexture(backendTex, GrWrapOwnership::kAdopt_GrWrapOwnership,
kRead_GrIOType, false);
}
REPORTER_ASSERT(reporter, wrappedTex);

View File

@ -469,7 +469,8 @@ DEF_GPUTEST(LazyProxyUninstantiateTest, reporter, /* options */) {
return sk_sp<GrTexture>();
}
sk_sp<GrTexture> texture = rp->wrapBackendTexture(backendTex);
sk_sp<GrTexture> texture = rp->wrapBackendTexture(
backendTex, kBorrow_GrWrapOwnership, kRead_GrIOType);
if (!texture) {
return sk_sp<GrTexture>();
}
@ -478,7 +479,7 @@ DEF_GPUTEST(LazyProxyUninstantiateTest, reporter, /* options */) {
return texture;
},
format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
REPORTER_ASSERT(reporter, lazyProxy.get());

View File

@ -317,7 +317,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) {
false, GrMipMapped::kNo);
sk_sp<GrSurfaceProxy> sProxy = proxyProvider->wrapBackendTexture(
backendTex, origin, kBorrow_GrWrapOwnership, nullptr, nullptr);
backendTex, origin, kBorrow_GrWrapOwnership, kRead_GrIOType);
if (!sProxy) {
gpu->deleteTestingOnlyBackendTexture(backendTex);
continue;

View File

@ -135,7 +135,8 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(RectangleTexture, reporter, ctxInfo) {
}
}
sk_sp<GrTextureProxy> rectProxy = proxyProvider->wrapBackendTexture(rectangleTex, origin);
sk_sp<GrTextureProxy> rectProxy = proxyProvider->wrapBackendTexture(
rectangleTex, origin, kBorrow_GrWrapOwnership, kRW_GrIOType);
if (!rectProxy) {
ERRORF(reporter, "Error creating proxy for rectangle texture.");

View File

@ -69,7 +69,8 @@ static GrSurfaceProxy* make_backend(GrContext* context, const ProxyParams& p,
return nullptr;
}
auto tmp = proxyProvider->wrapBackendTexture(*backendTex, p.fOrigin);
auto tmp = proxyProvider->wrapBackendTexture(*backendTex, p.fOrigin, kBorrow_GrWrapOwnership,
kRead_GrIOType);
if (!tmp) {
return nullptr;
}

View File

@ -223,10 +223,10 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheWrappedResources, reporter, ctxI
context->resetContext();
sk_sp<GrTexture> borrowed(resourceProvider->wrapBackendTexture(
backendTextures[0], kBorrow_GrWrapOwnership));
backendTextures[0], kBorrow_GrWrapOwnership, kRead_GrIOType));
sk_sp<GrTexture> adopted(resourceProvider->wrapBackendTexture(
backendTextures[1], kAdopt_GrWrapOwnership));
backendTextures[1], kAdopt_GrWrapOwnership, kRead_GrIOType));
REPORTER_ASSERT(reporter, borrowed != nullptr && adopted != nullptr);
if (!borrowed || !adopted) {

View File

@ -112,7 +112,8 @@ static sk_sp<GrTextureProxy> create_wrapped_backend(GrContext* context, SkBackin
GrBackendTexture backendTex = (*backingSurface)->getBackendTexture();
backendTex.setPixelConfig(desc.fConfig);
return proxyProvider->wrapBackendTexture(backendTex, kBottomLeft_GrSurfaceOrigin);
return proxyProvider->wrapBackendTexture(backendTex, kBottomLeft_GrSurfaceOrigin,
kBorrow_GrWrapOwnership, kRead_GrIOType);
}

View File

@ -128,7 +128,7 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_unownedGLTexture, report
idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed;
auto texture = GrGLTexture::MakeWrapped(gpu, desc, GrMipMapsStatus::kNotAllocated, idDesc,
false);
kRead_GrIOType, false);
ValidateMemoryDumps(reporter, context, texture->gpuMemorySize(), false /* isOwned */);
}

View File

@ -42,7 +42,8 @@ void wrap_tex_test(skiatest::Reporter* reporter, GrContext* context) {
GrVkImageInfo imageInfo;
SkAssertResult(origBackendTex.getVkImageInfo(&imageInfo));
sk_sp<GrTexture> tex = gpu->wrapBackendTexture(origBackendTex, kBorrow_GrWrapOwnership, false);
sk_sp<GrTexture> tex =
gpu->wrapBackendTexture(origBackendTex, kBorrow_GrWrapOwnership, kRead_GrIOType, false);
REPORTER_ASSERT(reporter, tex);
// image is null
@ -51,9 +52,9 @@ void wrap_tex_test(skiatest::Reporter* reporter, GrContext* context) {
backendCopy.fImage = VK_NULL_HANDLE;
GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy);
backendTex.setPixelConfig(kPixelConfig);
tex = gpu->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership, false);
tex = gpu->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership, kRead_GrIOType, false);
REPORTER_ASSERT(reporter, !tex);
tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, false);
tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, kRead_GrIOType, false);
REPORTER_ASSERT(reporter, !tex);
}
@ -63,9 +64,9 @@ void wrap_tex_test(skiatest::Reporter* reporter, GrContext* context) {
backendCopy.fAlloc = GrVkAlloc();
GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy);
backendTex.setPixelConfig(kPixelConfig);
tex = gpu->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership, false);
tex = gpu->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership, kRead_GrIOType, false);
REPORTER_ASSERT(reporter, !tex);
tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, false);
tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, kRead_GrIOType, false);
REPORTER_ASSERT(reporter, !tex);
}
@ -74,7 +75,7 @@ void wrap_tex_test(skiatest::Reporter* reporter, GrContext* context) {
GrVkImageInfo backendCopy = imageInfo;
GrBackendTexture backendTex = GrBackendTexture(kW, kH, backendCopy);
backendTex.setPixelConfig(kPixelConfig);
tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, false);
tex = gpu->wrapBackendTexture(backendTex, kAdopt_GrWrapOwnership, kRead_GrIOType, false);
REPORTER_ASSERT(reporter, tex);
}

View File

@ -36,7 +36,7 @@ sk_sp<GrTextureProxy> MakeTextureProxyFromData(GrContext* context, bool isRT, in
backendTex, origin, 1, kAdopt_GrWrapOwnership);
} else {
proxy = context->contextPriv().proxyProvider()->wrapBackendTexture(
backendTex, origin, kAdopt_GrWrapOwnership);
backendTex, origin, kAdopt_GrWrapOwnership, kRW_GrIOType);
}
if (!proxy) {