Skip to content

Commit

Permalink
Add texture-specific flags for External & Rectangle textures
Browse files Browse the repository at this point in the history
For DDLs, Ganesh needs to know about External & Rectangle textures prior to instantiation (or PromiseImage fulfillment). These new flags allow the client to provide this information when the lazyProxy is created.

The new texture flags work analogously to the render target flags:
   GrSurface and GrSurfaceProxy get a new set of accessors for the new flags
   The new flags are set appropriately on a GrGLTexture when it is created
   For wrapped texture proxies the flags are just copied off of the GrSurface
   For lazy-proxies/promise-images the flags are computed up front and passed to the proxy
   The GrSurfaceProxy/GrSurface flags equivalence is verified in GrSurfaceProxy::assign

Change-Id: Ia8e1998aa0a36ce4481bfd9e56be21f990e83148
Reviewed-on: https://skia-review.googlesource.com/114985
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
  • Loading branch information
rphilli authored and Skia Commit-Bot committed Mar 21, 2018
1 parent e65a5cd commit abf7b76
Show file tree
Hide file tree
Showing 18 changed files with 172 additions and 77 deletions.
14 changes: 14 additions & 0 deletions include/gpu/GrSurface.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ class SK_API GrSurface : public GrGpuResource {
GrMipMapped, bool useNextPow2 = false);

protected:
void setDoesNotSupportMipMaps() {
SkASSERT(this->asTexture());
fSurfaceFlags |= GrInternalSurfaceFlags::kDoesNotSupportMipMaps;
}
bool doesNotSupportMipMaps() const {
return fSurfaceFlags & GrInternalSurfaceFlags::kDoesNotSupportMipMaps;
}

void setIsClampOnly() {
SkASSERT(this->asTexture());
fSurfaceFlags |= GrInternalSurfaceFlags::kIsClampOnly;
}
bool isClampOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kIsClampOnly; }

void setHasMixedSamples() {
SkASSERT(this->asRenderTarget());
fSurfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
Expand Down
14 changes: 14 additions & 0 deletions include/private/GrSurfaceProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,20 @@ class GrSurfaceProxy : public GrIORefProxy {
bool instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt, bool needsStencil,
GrSurfaceDescFlags descFlags, GrMipMapped, const GrUniqueKey*);

void setDoesNotSupportMipMaps() {
SkASSERT(this->asTextureProxy());
fSurfaceFlags |= GrInternalSurfaceFlags::kDoesNotSupportMipMaps;
}
bool doesNotSupportMipMaps() const {
return fSurfaceFlags & GrInternalSurfaceFlags::kDoesNotSupportMipMaps;
}

void setIsClampOnly() {
SkASSERT(this->asTextureProxy());
fSurfaceFlags |= GrInternalSurfaceFlags::kIsClampOnly;
}
bool isClampOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kIsClampOnly; }

void setHasMixedSamples() {
SkASSERT(this->asRenderTargetProxy());
fSurfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
Expand Down
22 changes: 16 additions & 6 deletions include/private/GrTypesPriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -672,14 +672,24 @@ enum GrAccessPattern {

// Flags shared between the GrSurface & GrSurfaceProxy class hierarchies
enum class GrInternalSurfaceFlags {
kNone = 0,
kNone = 0,

// Surface-level
kNoPendingIO = 1 << 0,
kNoPendingIO = 1 << 0,

// Texture-only
// Texture-only flags

/* coming soon */
// This flag is set when the internal texture target doesn't support mipmaps (e.g.,
// external and rectangle textures). Note that Ganesh does not internally
// create resources with this limitation - this flag will only appear on resources passed
// into Ganesh.
kDoesNotSupportMipMaps = 1 << 1,

// This flag is set when the internal texture target only supports the clamp wrap mode (e.g.,
// external and rectangle textures). Note that Ganesh does not internally
// create resources with this limitation - this flag will only appear on resources passed
// into Ganesh.
kIsClampOnly = 1 << 2,

// RT-only

Expand All @@ -689,14 +699,14 @@ enum class GrInternalSurfaceFlags {
// this is disabled for FBO0
// but, otherwise, is enabled whenever MSAA is enabled and GrCaps reports mixed samples
// are supported
kMixedSampled = 1 << 3,
kMixedSampled = 1 << 3,

// For internal resources:
// this is enabled whenever GrCaps reports window rect support
// For wrapped resources1
// this is disabled for FBO0
// but, otherwise, is enabled whenever GrCaps reports window rect support
kWindowRectsSupport = 1 << 4
kWindowRectsSupport = 1 << 4
};
GR_MAKE_BITFIELD_CLASS_OPS(GrInternalSurfaceFlags)

Expand Down
10 changes: 9 additions & 1 deletion src/core/SkDeferredDisplayListRecorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ bool SkDeferredDisplayListRecorder::init() {
// proxy, when instantiated, will use the GrRenderTarget that backs the SkSurface that the
// DDL is being replayed into.

GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone;
if (fContext->caps()->usesMixedSamples() && desc.fSampleCnt > 1) {
surfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
}
if (fContext->caps()->maxWindowRectangles() > 0) {
surfaceFlags |= GrInternalSurfaceFlags::kWindowRectsSupport;
}

sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
[lazyProxyData](GrResourceProvider* resourceProvider) {
if (!resourceProvider) {
Expand All @@ -106,7 +114,7 @@ bool SkDeferredDisplayListRecorder::init() {
},
desc,
fCharacterization.origin(),
GrInternalSurfaceFlags::kNone,
surfaceFlags,
GrProxyProvider::Textureable(fCharacterization.isTextureable()),
GrMipMapped::kNo,
SkBackingFit::kExact,
Expand Down
17 changes: 16 additions & 1 deletion src/gpu/GrGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "GrStencilSettings.h"
#include "GrSurfacePriv.h"
#include "GrTexturePriv.h"
#include "GrTextureProxyPriv.h"
#include "GrTracing.h"
#include "SkJSONWriter.h"
#include "SkMathPriv.h"
Expand All @@ -44,11 +45,25 @@ void GrGpu::disconnect(DisconnectType) {}

////////////////////////////////////////////////////////////////////////////////

bool GrGpu::IsACopyNeededForTextureParams(const GrCaps* caps,
bool GrGpu::IsACopyNeededForTextureParams(const GrCaps* caps, GrTextureProxy* texProxy,
int width, int height,
const GrSamplerState& textureParams,
GrTextureProducer::CopyParams* copyParams,
SkScalar scaleAdjust[2]) {

if (texProxy) {
// If the texture format itself doesn't support repeat wrap mode or mipmapping (and
// those capabilities are required) force a copy.
if ((textureParams.isRepeated() && texProxy->texPriv().isClampOnly()) ||
(GrSamplerState::Filter::kMipMap == textureParams.filter() &&
texProxy->texPriv().doesNotSupportMipMaps())) {
copyParams->fFilter = GrSamplerState::Filter::kNearest;
copyParams->fWidth = texProxy->width();
copyParams->fHeight = texProxy->height();
return true;
}
}

if (textureParams.isRepeated() && !caps->npotTextureTileSupport() &&
(!SkIsPow2(width) || !SkIsPow2(height))) {
SkASSERT(scaleAdjust);
Expand Down
26 changes: 3 additions & 23 deletions src/gpu/GrGpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,26 +506,12 @@ class GrGpu : public SkRefCnt {
virtual void clearStencil(GrRenderTarget* target, int clearValue) = 0;

// Determines whether a texture will need to be rescaled in order to be used with the
// GrSamplerState. This variation is called when the caller will create a new texture using the
// resource provider from a non-texture src (cpu-backed image, ...).
static bool IsACopyNeededForTextureParams(const GrCaps*, int width, int height,
// GrSamplerState.
static bool IsACopyNeededForTextureParams(const GrCaps*, GrTextureProxy* texProxy,
int width, int height,
const GrSamplerState&, GrTextureProducer::CopyParams*,
SkScalar scaleAdjust[2]);

// Like the above but this variation should be called when the caller is not creating the
// original texture but rather was handed the original texture. It adds additional checks
// relevant to original textures that were created external to Skia via
// GrResourceProvider::wrap methods.
bool isACopyNeededForTextureParams(GrTextureProxy* proxy, const GrSamplerState& params,
GrTextureProducer::CopyParams* copyParams,
SkScalar scaleAdjust[2]) const {
if (IsACopyNeededForTextureParams(this->caps(), proxy->width(), proxy->height(), params,
copyParams, scaleAdjust)) {
return true;
}
return this->onIsACopyNeededForTextureParams(proxy, params, copyParams, scaleAdjust);
}

void handleDirtyContext() {
if (fResetBits) {
this->resetContext();
Expand Down Expand Up @@ -578,12 +564,6 @@ class GrGpu : public SkRefCnt {
virtual GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
const void* data) = 0;

virtual bool onIsACopyNeededForTextureParams(GrTextureProxy* proxy, const GrSamplerState&,
GrTextureProducer::CopyParams*,
SkScalar scaleAdjust[2]) const {
return false;
}

virtual bool onGetReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
size_t rowBytes, GrColorType, DrawPreference*,
ReadPixelTempDrawInfo*) = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/gpu/GrSurfacePriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class GrSurfacePriv {

GrInternalSurfaceFlags flags() const { return fSurface->fSurfaceFlags; }

bool doesNotSupportMipMaps() const { return fSurface->doesNotSupportMipMaps(); }
bool isClampOnly() const { return fSurface->isClampOnly(); }

private:
explicit GrSurfacePriv(GrSurface* surface) : fSurface(surface) {}
GrSurfacePriv(const GrSurfacePriv&); // unimpl
Expand Down
9 changes: 5 additions & 4 deletions src/gpu/GrSurfaceProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ sk_sp<GrSurface> GrSurfaceProxy::createSurfaceImpl(

void GrSurfaceProxy::assign(sk_sp<GrSurface> surface) {
SkASSERT(!fTarget && surface);

// Check that our a priori computation matched the ultimate reality
SkASSERT((fSurfaceFlags & ~GrInternalSurfaceFlags::kNoPendingIO) ==
surface->surfacePriv().flags());

fTarget = surface.release();

this->INHERITED::transferRefs();
Expand Down Expand Up @@ -222,10 +227,6 @@ bool GrSurfaceProxy::instantiateImpl(GrResourceProvider* resourceProvider, int s

this->assign(std::move(surface));

// Check that our a priori computation matched the ultimate reality
SkASSERT((fSurfaceFlags & ~GrInternalSurfaceFlags::kNoPendingIO) ==
fTarget->surfacePriv().flags());

return true;
}

Expand Down
10 changes: 3 additions & 7 deletions src/gpu/GrTextureAdjuster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,9 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxySafeForParams(const GrSa
return nullptr;
}

// DDL TODO: remove the need for the GrGpu in this method
GrGpu* gpu = fContext->contextPriv().getGpu();
if (!gpu) {
return proxy;
}

if (!gpu->isACopyNeededForTextureParams(proxy.get(), params, &copyParams, scaleAdjust)) {
if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(),
proxy.get(), proxy->width(), proxy->height(),
params, &copyParams, scaleAdjust)) {
return proxy;
}

Expand Down
9 changes: 5 additions & 4 deletions src/gpu/GrTextureMaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerSt
sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
AllowedTexGenType::kCheap));
if (original) {
GrGpu* gpu = fContext->contextPriv().getGpu();

if (!gpu->isACopyNeededForTextureParams(original.get(), params, &copyParams, scaleAdjust)) {
if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(), original.get(),
original->width(), original->height(),
params, &copyParams, scaleAdjust)) {
return original;
}
} else {
if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(), this->width(), this->height(),
if (!GrGpu::IsACopyNeededForTextureParams(fContext->caps(), nullptr,
this->width(), this->height(),
params, &copyParams, scaleAdjust)) {
return this->refOriginalTextureProxy(willBeMipped, dstColorSpace,
AllowedTexGenType::kAny);
Expand Down
3 changes: 3 additions & 0 deletions src/gpu/GrTextureProxyPriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class GrTextureProxyPriv {
// been instantiated or not.
GrMipMapped proxyMipMapped() const { return fTextureProxy->fMipMapped; }

bool doesNotSupportMipMaps() const { return fTextureProxy->doesNotSupportMipMaps(); }
bool isClampOnly() const { return fTextureProxy->isClampOnly(); }

private:
explicit GrTextureProxyPriv(GrTextureProxy* textureProxy) : fTextureProxy(textureProxy) {}
GrTextureProxyPriv(const GrTextureProxyPriv&) {} // unimpl
Expand Down
24 changes: 0 additions & 24 deletions src/gpu/gl/GrGLGpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4553,30 +4553,6 @@ GrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLG
return attribState;
}

bool GrGLGpu::onIsACopyNeededForTextureParams(GrTextureProxy* proxy,
const GrSamplerState& textureParams,
GrTextureProducer::CopyParams* copyParams,
SkScalar scaleAdjust[2]) const {
const GrTexture* texture = proxy->priv().peekTexture();
if (!texture) {
// The only way to get and EXTERNAL or RECTANGLE texture in Ganesh is to wrap them.
// In that case the proxy should already be instantiated.
return false;
}

if (textureParams.isRepeated() || GrSamplerState::Filter::kMipMap == textureParams.filter()) {
const GrGLTexture* glTexture = static_cast<const GrGLTexture*>(texture);
if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() ||
GR_GL_TEXTURE_RECTANGLE == glTexture->target()) {
copyParams->fFilter = GrSamplerState::Filter::kNearest;
copyParams->fWidth = texture->width();
copyParams->fHeight = texture->height();
return true;
}
}
return false;
}

void GrGLGpu::onFinishFlush(bool insertedSemaphore) {
// If we inserted semaphores during the flush, we need to call GLFlush.
if (insertedSemaphore) {
Expand Down
4 changes: 0 additions & 4 deletions src/gpu/gl/GrGLGpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,6 @@ class GrGLGpu final : public GrGpu, private GrMesh::SendToGpuImpl {
GrGLTexture::TexParams* initialTexParams, const GrMipLevel texels[],
int mipLevelCount, GrMipMapsStatus* mipMapsStatus);

bool onIsACopyNeededForTextureParams(GrTextureProxy*, const GrSamplerState&,
GrTextureProducer::CopyParams*,
SkScalar scaleAdjust[2]) const override;

// Checks whether glReadPixels can be called to get pixel values in readConfig from the
// render target.
bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig);
Expand Down
5 changes: 5 additions & 0 deletions src/gpu/gl/GrGLTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc&
void GrGLTexture::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
SkASSERT(0 != idDesc.fInfo.fID);
SkASSERT(0 != idDesc.fInfo.fFormat);
if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_RECTANGLE ||
idDesc.fInfo.fTarget == GR_GL_TEXTURE_EXTERNAL) {
this->setDoesNotSupportMipMaps();
this->setIsClampOnly();
}
fTexParams.invalidate();
fTexParamsTimestamp = GrGpu::kExpiredTimestamp;
fInfo = idDesc.fInfo;
Expand Down
16 changes: 15 additions & 1 deletion src/image/SkImage_Gpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "GrTexture.h"
#include "GrTexturePriv.h"
#include "GrTextureProxy.h"
#include "gl/GrGLDefines.h"
#include "effects/GrNonlinearColorSpaceXformEffect.h"
#include "effects/GrYUVtoRGBEffect.h"
#include "SkCanvas.h"
Expand Down Expand Up @@ -617,6 +618,17 @@ class PromiseImageHelper {
sk_sp<GrReleaseProcHelper> fDoneHelper;
};

static GrInternalSurfaceFlags get_flags_from_format(const GrBackendFormat& backendFormat) {
if (const GrGLenum* target = backendFormat.getGLTarget()) {
if (GR_GL_TEXTURE_RECTANGLE == *target || GR_GL_TEXTURE_EXTERNAL == *target) {
return GrInternalSurfaceFlags::kDoesNotSupportMipMaps |
GrInternalSurfaceFlags::kIsClampOnly;
}
}

return GrInternalSurfaceFlags::kNone;
}

sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
const GrBackendFormat& backendFormat,
int width,
Expand Down Expand Up @@ -661,6 +673,8 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
PromiseImageHelper promiseHelper(textureFulfillProc, textureReleaseProc, promiseDoneProc,
textureContext);

GrInternalSurfaceFlags formatFlags = get_flags_from_format(backendFormat);

sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
[promiseHelper, config] (GrResourceProvider* resourceProvider) mutable {
if (!resourceProvider) {
Expand All @@ -669,7 +683,7 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
}

return promiseHelper.getTexture(resourceProvider, config);
}, desc, origin, mipMapped, GrInternalSurfaceFlags::kNone, SkBackingFit::kExact,
}, desc, origin, mipMapped, formatFlags, SkBackingFit::kExact,
SkBudgeted::kNo, GrSurfaceProxy::LazyInstantiationType::kUninstantiate);

if (!proxy) {
Expand Down
Loading

0 comments on commit abf7b76

Please sign in to comment.