aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2015-02-23 09:06:38 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-02-23 09:06:38 -0800
commit6bc1b5fab8554a9cb643277b4867965dd4535cd6 (patch)
tree3179261534d7db7a8264735b327daa59593e1dd0 /src
parent42380174ca509e78ab932fa8c6dae953e1eaaa5a (diff)
Dynamically create stencil buffer when needed.
Diffstat (limited to 'src')
-rw-r--r--src/effects/SkAlphaThresholdFilter.cpp2
-rw-r--r--src/effects/SkDisplacementMapEffect.cpp2
-rw-r--r--src/effects/SkGpuBlurUtils.cpp2
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp2
-rw-r--r--src/effects/SkXfermodeImageFilter.cpp2
-rw-r--r--src/gpu/GrClipMaskManager.cpp9
-rwxr-xr-xsrc/gpu/GrContext.cpp68
-rw-r--r--src/gpu/GrDrawTarget.cpp19
-rw-r--r--src/gpu/GrDrawTarget.h2
-rw-r--r--src/gpu/GrGpu.cpp25
-rw-r--r--src/gpu/GrGpu.h6
-rw-r--r--src/gpu/GrRenderTarget.cpp25
-rw-r--r--src/gpu/GrRenderTargetPriv.h51
-rw-r--r--src/gpu/GrStencilAndCoverPathRenderer.cpp3
-rw-r--r--src/gpu/GrSurfacePriv.h6
-rw-r--r--src/gpu/GrTexture.cpp10
-rw-r--r--src/gpu/SkGr.cpp8
-rw-r--r--src/gpu/SkGrPixelRef.cpp2
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp3
-rw-r--r--src/gpu/gl/GrGLGpu.cpp16
-rw-r--r--src/gpu/gl/GrGLRenderTarget.h3
21 files changed, 148 insertions, 118 deletions
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index a5b564f57b..f78c9c0b8c 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -273,7 +273,7 @@ bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp,
} else {
maskDesc.fConfig = kRGBA_8888_GrPixelConfig;
}
- maskDesc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+ maskDesc.fFlags = kRenderTarget_GrSurfaceFlag;
// Add one pixel of border to ensure that clamp mode will be all zeros
// the outside.
maskDesc.fWidth = texture->width();
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index 07bd33d360..0463fb08b8 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -417,7 +417,7 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src,
GrContext* context = color->getContext();
GrSurfaceDesc desc;
- desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = bounds.width();
desc.fHeight = bounds.height();
desc.fConfig = kSkia8888_GrPixelConfig;
diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp
index 1c2ce5e0e8..77e225888c 100644
--- a/src/effects/SkGpuBlurUtils.cpp
+++ b/src/effects/SkGpuBlurUtils.cpp
@@ -167,7 +167,7 @@ GrTexture* GaussianBlur(GrContext* context,
kAlpha_8_GrPixelConfig == srcTexture->config());
GrSurfaceDesc desc;
- desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = SkScalarFloorToInt(srcRect.width());
desc.fHeight = SkScalarFloorToInt(srcRect.height());
desc.fConfig = srcTexture->config();
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 3e0c600c94..8c46aae757 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -657,7 +657,7 @@ bool apply_morphology(const SkBitmap& input,
SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height());
GrSurfaceDesc desc;
- desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = rect.width();
desc.fHeight = rect.height();
desc.fConfig = kSkia8888_GrPixelConfig;
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index 19a905b445..ce6e790250 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -145,7 +145,7 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
GrFragmentProcessor* xferProcessor = NULL;
GrSurfaceDesc desc;
- desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = src.width();
desc.fHeight = src.height();
desc.fConfig = kSkia8888_GrPixelConfig;
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index f69c8717f8..10414b5f2b 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -13,6 +13,7 @@
#include "GrPaint.h"
#include "GrPathRenderer.h"
#include "GrRenderTarget.h"
+#include "GrRenderTargetPriv.h"
#include "GrStencilBuffer.h"
#include "GrSWMaskHelper.h"
#include "SkRasterClip.h"
@@ -675,8 +676,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
SkASSERT(rt);
- // TODO: dynamically attach a SB when needed.
- GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
+ GrStencilBuffer* stencilBuffer = rt->renderTargetPriv().attachStencilBuffer();
if (NULL == stencilBuffer) {
return false;
}
@@ -905,9 +905,9 @@ void GrClipMaskManager::setPipelineBuilderStencil(GrPipelineBuilder* pipelineBui
settings = pipelineBuilder->getStencil();
}
- // TODO: dynamically attach a stencil buffer
int stencilBits = 0;
- GrStencilBuffer* stencilBuffer = pipelineBuilder->getRenderTarget()->getStencilBuffer();
+ GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
+ GrStencilBuffer* stencilBuffer = rt->renderTargetPriv().attachStencilBuffer();
if (stencilBuffer) {
stencilBits = stencilBuffer->bits();
}
@@ -1084,7 +1084,6 @@ void GrClipMaskManager::setClipTarget(GrClipTarget* clipTarget) {
void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBuffer,
GrStencilSettings* settings) {
- // TODO: dynamically attach a stencil buffer
if (stencilBuffer) {
int stencilBits = stencilBuffer->bits();
this->adjustStencilParams(settings, fClipMode, stencilBits);
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index a4679a923c..98e78d9926 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -23,6 +23,7 @@
#include "GrOvalRenderer.h"
#include "GrPathRenderer.h"
#include "GrPathUtils.h"
+#include "GrRenderTargetPriv.h"
#include "GrResourceCache.h"
#include "GrSoftwarePathRenderer.h"
#include "GrStencilAndCoverTextContext.h"
@@ -213,9 +214,11 @@ GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget,
const SkDeviceProperties&
leakyProperties,
bool enableDistanceFieldFonts) {
- if (fGpu->caps()->pathRenderingSupport() && renderTarget->getStencilBuffer() &&
- renderTarget->isMultisampled()) {
- return GrStencilAndCoverTextContext::Create(this, leakyProperties);
+ if (fGpu->caps()->pathRenderingSupport() && renderTarget->isMultisampled()) {
+ GrStencilBuffer* sb = renderTarget->renderTargetPriv().attachStencilBuffer();
+ if (sb) {
+ return GrStencilAndCoverTextContext::Create(this, leakyProperties);
+ }
}
return GrDistanceFieldTextContext::Create(this, leakyProperties, enableDistanceFieldFonts);
@@ -278,14 +281,10 @@ GrTexture* GrContext::refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMat
GrTexture* GrContext::internalRefScratchTexture(const GrSurfaceDesc& inDesc, uint32_t flags) {
SkASSERT(!GrPixelConfigIsCompressed(inDesc.fConfig));
- // kNoStencil has no meaning if kRT isn't set.
- SkASSERT((inDesc.fFlags & kRenderTarget_GrSurfaceFlag) ||
- !(inDesc.fFlags & kNoStencil_GrSurfaceFlag));
SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc);
if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
- GrSurfaceFlags origFlags = desc->fFlags;
if (!(kExact_ScratchTextureFlag & flags)) {
// bin by pow2 with a reasonable min
static const int MIN_SIZE = 16;
@@ -294,44 +293,25 @@ GrTexture* GrContext::internalRefScratchTexture(const GrSurfaceDesc& inDesc, uin
wdesc->fHeight = SkTMax(MIN_SIZE, GrNextPow2(desc->fHeight));
}
- do {
- GrScratchKey key;
- GrTexturePriv::ComputeScratchKey(*desc, &key);
- uint32_t scratchFlags = 0;
- if (kNoPendingIO_ScratchTextureFlag & flags) {
- scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
- } else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
- // If it is not a render target then it will most likely be populated by
- // writePixels() which will trigger a flush if the texture has pending IO.
- scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
- }
- GrGpuResource* resource = fResourceCache->findAndRefScratchResource(key, scratchFlags);
- if (resource) {
- GrSurface* surface = static_cast<GrSurface*>(resource);
- GrRenderTarget* rt = surface->asRenderTarget();
- if (rt && fGpu->caps()->discardRenderTargetSupport()) {
- rt->discard();
- }
- return surface->asTexture();
- }
-
- if (kExact_ScratchTextureFlag & flags) {
- break;
- }
- // We had a cache miss and we are in approx mode, relax the fit of the flags.
-
- // We no longer try to reuse textures that were previously used as render targets in
- // situations where no RT is needed; doing otherwise can confuse the video driver and
- // cause significant performance problems in some cases.
- if (desc->fFlags & kNoStencil_GrSurfaceFlag) {
- desc.writable()->fFlags = desc->fFlags & ~kNoStencil_GrSurfaceFlag;
- } else {
- break;
+ GrScratchKey key;
+ GrTexturePriv::ComputeScratchKey(*desc, &key);
+ uint32_t scratchFlags = 0;
+ if (kNoPendingIO_ScratchTextureFlag & flags) {
+ scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
+ } else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
+ // If it is not a render target then it will most likely be populated by
+ // writePixels() which will trigger a flush if the texture has pending IO.
+ scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
+ }
+ GrGpuResource* resource = fResourceCache->findAndRefScratchResource(key, scratchFlags);
+ if (resource) {
+ GrSurface* surface = static_cast<GrSurface*>(resource);
+ GrRenderTarget* rt = surface->asRenderTarget();
+ if (rt && fGpu->caps()->discardRenderTargetSupport()) {
+ rt->discard();
}
-
- } while (true);
-
- desc.writable()->fFlags = origFlags;
+ return surface->asTexture();
+ }
}
if (!(kNoCreate_ScratchTextureFlag & flags)) {
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index ffdd4dcdcd..ee111a6535 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -14,6 +14,7 @@
#include "GrPath.h"
#include "GrPipeline.h"
#include "GrRenderTarget.h"
+#include "GrRenderTargetPriv.h"
#include "GrSurfacePriv.h"
#include "GrTemplates.h"
#include "GrTexture.h"
@@ -607,9 +608,9 @@ void GrDrawTarget::stencilPath(GrPipelineBuilder* pipelineBuilder,
// set stencil settings for path
GrStencilSettings stencilSettings;
- this->getPathStencilSettingsForFilltype(fill,
- pipelineBuilder->getRenderTarget()->getStencilBuffer(),
- &stencilSettings);
+ GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
+ GrStencilBuffer* sb = rt->renderTargetPriv().attachStencilBuffer();
+ this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
this->onStencilPath(*pipelineBuilder, pathProc, path, scissorState, stencilSettings);
}
@@ -636,9 +637,9 @@ void GrDrawTarget::drawPath(GrPipelineBuilder* pipelineBuilder,
// set stencil settings for path
GrStencilSettings stencilSettings;
- this->getPathStencilSettingsForFilltype(fill,
- pipelineBuilder->getRenderTarget()->getStencilBuffer(),
- &stencilSettings);
+ GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
+ GrStencilBuffer* sb = rt->renderTargetPriv().attachStencilBuffer();
+ this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
GrDrawTarget::PipelineInfo pipelineInfo(pipelineBuilder, &scissorState, pathProc, &devBounds,
this);
@@ -676,9 +677,9 @@ void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder,
// set stencil settings for path
GrStencilSettings stencilSettings;
- this->getPathStencilSettingsForFilltype(fill,
- pipelineBuilder->getRenderTarget()->getStencilBuffer(),
- &stencilSettings);
+ GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
+ GrStencilBuffer* sb = rt->renderTargetPriv().attachStencilBuffer();
+ this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
// Don't compute a bounding box for dst copy texture, we'll opt
// instead for it to just copy the entire dst. Realistically this is a moot
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index e52ee6648f..2da63d80ad 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -726,7 +726,7 @@ private:
void initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* dstDesc) {
if (!this->onInitCopySurfaceDstDesc(src, dstDesc)) {
dstDesc->fOrigin = kDefault_GrSurfaceOrigin;
- dstDesc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+ dstDesc->fFlags = kRenderTarget_GrSurfaceFlag;
dstDesc->fConfig = src->config();
}
}
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index d22399f81c..efe1a618e6 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -15,6 +15,7 @@
#include "GrGpuResourcePriv.h"
#include "GrIndexBuffer.h"
#include "GrResourceCache.h"
+#include "GrRenderTargetPriv.h"
#include "GrStencilBuffer.h"
#include "GrVertexBuffer.h"
@@ -61,16 +62,6 @@ GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc, bool budgeted,
} else {
this->handleDirtyContext();
tex = this->onCreateTexture(desc, budgeted, srcData, rowBytes);
- if (tex &&
- (kRenderTarget_GrSurfaceFlag & desc.fFlags) &&
- !(kNoStencil_GrSurfaceFlag & desc.fFlags)) {
- SkASSERT(tex->asRenderTarget());
- // TODO: defer this and attach dynamically
- if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) {
- tex->unref();
- return NULL;
- }
- }
}
if (!this->caps()->reuseScratchTextures() && !isRT) {
tex->resourcePriv().removeScratchKey();
@@ -85,7 +76,7 @@ GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc, bool budgeted,
}
bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
- SkASSERT(NULL == rt->getStencilBuffer());
+ SkASSERT(NULL == rt->renderTargetPriv().getStencilBuffer());
GrUniqueKey sbKey;
int width = rt->width();
@@ -99,12 +90,11 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
SkAutoTUnref<GrStencilBuffer> sb(static_cast<GrStencilBuffer*>(
this->getContext()->getResourceCache()->findAndRefUniqueResource(sbKey)));
if (sb) {
- rt->setStencilBuffer(sb);
- bool attached = this->attachStencilBufferToRenderTarget(sb, rt);
- if (!attached) {
- rt->setStencilBuffer(NULL);
+ if (this->attachStencilBufferToRenderTarget(sb, rt)) {
+ rt->renderTargetPriv().didAttachStencilBuffer(sb);
+ return true;
}
- return attached;
+ return false;
}
if (this->createStencilBufferForRenderTarget(rt, width, height)) {
// Right now we're clearing the stencil buffer here after it is
@@ -116,7 +106,8 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
// FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
// FBO status.
this->clearStencil(rt);
- rt->getStencilBuffer()->resourcePriv().setUniqueKey(sbKey);
+ GrStencilBuffer* sb = rt->renderTargetPriv().getStencilBuffer();
+ sb->resourcePriv().setUniqueKey(sbKey);
return true;
} else {
return false;
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index a0950e001c..eb97b4fa08 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -405,6 +405,9 @@ public:
void saveActiveTraceMarkers();
void restoreActiveTraceMarkers();
+ // Given a rt, find or create a stencil buffer and attach it
+ bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
+
protected:
// Functions used to map clip-respecting stencil tests into normal
// stencil funcs supported by GPUs.
@@ -489,9 +492,6 @@ private:
// clears target's entire stencil buffer to 0
virtual void clearStencil(GrRenderTarget* target) = 0;
- // Given a rt, find or create a stencil buffer and attach it
- bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
-
virtual void didAddGpuTraceMarker() = 0;
virtual void didRemoveGpuTraceMarker() = 0;
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index 386bd2e779..042e19f6ad 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -11,6 +11,7 @@
#include "GrContext.h"
#include "GrGpu.h"
+#include "GrRenderTargetPriv.h"
#include "GrStencilBuffer.h"
void GrRenderTarget::discard() {
@@ -46,18 +47,30 @@ void GrRenderTarget::overrideResolveRect(const SkIRect rect) {
}
}
-void GrRenderTarget::setStencilBuffer(GrStencilBuffer* stencilBuffer) {
- SkRefCnt_SafeAssign(fStencilBuffer, stencilBuffer);
-}
-
void GrRenderTarget::onRelease() {
- this->setStencilBuffer(NULL);
+ this->renderTargetPriv().didAttachStencilBuffer(NULL);
INHERITED::onRelease();
}
void GrRenderTarget::onAbandon() {
- this->setStencilBuffer(NULL);
+ this->renderTargetPriv().didAttachStencilBuffer(NULL);
INHERITED::onAbandon();
}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrRenderTargetPriv::didAttachStencilBuffer(GrStencilBuffer* stencilBuffer) {
+ SkRefCnt_SafeAssign(fRenderTarget->fStencilBuffer, stencilBuffer);
+}
+
+GrStencilBuffer* GrRenderTargetPriv::attachStencilBuffer() const {
+ if (fRenderTarget->fStencilBuffer) {
+ return fRenderTarget->fStencilBuffer;
+ }
+ if (!fRenderTarget->wasDestroyed() && fRenderTarget->canAttemptStencilAttachment()) {
+ fRenderTarget->getGpu()->attachStencilBufferToRenderTarget(fRenderTarget);
+ }
+ return fRenderTarget->fStencilBuffer;
+}
diff --git a/src/gpu/GrRenderTargetPriv.h b/src/gpu/GrRenderTargetPriv.h
new file mode 100644
index 0000000000..92ee30e49f
--- /dev/null
+++ b/src/gpu/GrRenderTargetPriv.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrRenderTargetPriv_DEFINED
+#define GrRenderTargetPriv_DEFINED
+
+#include "GrRenderTarget.h"
+
+/** Class that adds methods to GrRenderTarget that are only intended for use internal to Skia.
+ This class is purely a privileged window into GrRenderTarget. It should never have additional
+ data members or virtual methods. */
+class GrRenderTargetPriv {
+public:
+ /**
+ * GrStencilBuffer is not part of the public API.
+ */
+ GrStencilBuffer* getStencilBuffer() const { return fRenderTarget->fStencilBuffer; }
+
+ /**
+ * If this render target already has a stencil buffer, return it. Otherwise attempt to attach
+ * one.
+ */
+ GrStencilBuffer* attachStencilBuffer() const;
+
+ void didAttachStencilBuffer(GrStencilBuffer*);
+
+private:
+ explicit GrRenderTargetPriv(GrRenderTarget* renderTarget) : fRenderTarget(renderTarget) {}
+ GrRenderTargetPriv(const GrRenderTargetPriv&) {} // unimpl
+ GrRenderTargetPriv& operator=(const GrRenderTargetPriv&); // unimpl
+
+ // No taking addresses of this type.
+ const GrRenderTargetPriv* operator&() const;
+ GrRenderTargetPriv* operator&();
+
+ GrRenderTarget* fRenderTarget;
+
+ friend class GrRenderTarget; // to construct/copy this type.
+};
+
+inline GrRenderTargetPriv GrRenderTarget::renderTargetPriv() { return GrRenderTargetPriv(this); }
+
+inline const GrRenderTargetPriv GrRenderTarget::renderTargetPriv () const {
+ return GrRenderTargetPriv(const_cast<GrRenderTarget*>(this));
+}
+
+#endif
diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp
index 0cef788355..aed1743af2 100644
--- a/src/gpu/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp
@@ -12,6 +12,8 @@
#include "GrDrawTargetCaps.h"
#include "GrGpu.h"
#include "GrPath.h"
+#include "GrRenderTarget.h"
+#include "GrRenderTargetPriv.h"
#include "SkStrokeRec.h"
/*
@@ -58,7 +60,6 @@ bool GrStencilAndCoverPathRenderer::canDrawPath(const GrDrawTarget* target,
bool antiAlias) const {
return !stroke.isHairlineStyle() &&
!antiAlias && // doesn't do per-path AA, relies on the target having MSAA
- pipelineBuilder->getRenderTarget()->getStencilBuffer() &&
pipelineBuilder->getStencil().isDisabled();
}
diff --git a/src/gpu/GrSurfacePriv.h b/src/gpu/GrSurfacePriv.h
index 3c1e9c1e95..cd1f6b92ba 100644
--- a/src/gpu/GrSurfacePriv.h
+++ b/src/gpu/GrSurfacePriv.h
@@ -34,9 +34,9 @@ public:
bool hasPendingIO() const { return fSurface->hasPendingIO(); }
private:
- GrSurfacePriv(GrSurface* surface) : fSurface(surface) { }
- GrSurfacePriv(const GrSurfacePriv& that) : fSurface(that.fSurface) { }
- GrSurfacePriv& operator=(const GrSurface&); // unimpl
+ explicit GrSurfacePriv(GrSurface* surface) : fSurface(surface) {}
+ GrSurfacePriv(const GrSurfacePriv&); // unimpl
+ GrSurfacePriv& operator=(const GrSurfacePriv&); // unimpl
// No taking addresses of this type.
const GrSurfacePriv* operator&() const;
diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp
index 4b43fc8513..dfa5626d1b 100644
--- a/src/gpu/GrTexture.cpp
+++ b/src/gpu/GrTexture.cpp
@@ -10,6 +10,8 @@
#include "GrDrawTargetCaps.h"
#include "GrGpu.h"
#include "GrResourceKey.h"
+#include "GrRenderTarget.h"
+#include "GrRenderTargetPriv.h"
#include "GrTexture.h"
#include "GrTexturePriv.h"
@@ -49,17 +51,9 @@ void GrTexture::validateDesc() const {
if (this->asRenderTarget()) {
// This texture has a render target
SkASSERT(0 != (fDesc.fFlags & kRenderTarget_GrSurfaceFlag));
-
- if (this->asRenderTarget()->getStencilBuffer()) {
- SkASSERT(0 != (fDesc.fFlags & kNoStencil_GrSurfaceFlag));
- } else {
- SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrSurfaceFlag));
- }
-
SkASSERT(fDesc.fSampleCnt == this->asRenderTarget()->numSamples());
} else {
SkASSERT(0 == (fDesc.fFlags & kRenderTarget_GrSurfaceFlag));
- SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrSurfaceFlag));
SkASSERT(0 == fDesc.fSampleCnt);
}
}
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index e13c2c7adc..d069fe0434 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -198,9 +198,7 @@ GrTexture* stretch_texture_to_next_pot(GrTexture* inputTexture, Stretch stretch,
// Either it's a cache miss or the original wasn't cached to begin with.
GrSurfaceDesc rtDesc = inputTexture->desc();
- rtDesc.fFlags = rtDesc.fFlags |
- kRenderTarget_GrSurfaceFlag |
- kNoStencil_GrSurfaceFlag;
+ rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
rtDesc.fWidth = GrNextPow2(rtDesc.fWidth);
rtDesc.fHeight = GrNextPow2(rtDesc.fHeight);
rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
@@ -377,9 +375,7 @@ static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKe
}
GrSurfaceDesc rtDesc = desc;
- rtDesc.fFlags = rtDesc.fFlags |
- kRenderTarget_GrSurfaceFlag |
- kNoStencil_GrSurfaceFlag;
+ rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
GrTexture* result = create_texture_for_bmp(ctx, optionalKey, rtDesc, pixelRef, NULL, 0);
if (!result) {
diff --git a/src/gpu/SkGrPixelRef.cpp b/src/gpu/SkGrPixelRef.cpp
index bc17879967..b0e89092cb 100644
--- a/src/gpu/SkGrPixelRef.cpp
+++ b/src/gpu/SkGrPixelRef.cpp
@@ -77,7 +77,7 @@ static SkGrPixelRef* copy_to_new_texture_pixelref(GrTexture* texture, SkColorTyp
desc.fHeight = subset->height();
srcRect = *subset;
}
- desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, kPremul_SkAlphaType, dstPT);
GrTexture* dst = context->createTexture(desc, false, NULL, 0);
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index 48119d1718..46dde19646 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -181,8 +181,7 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
}
GrSurfaceDesc desc;
- desc.fFlags = kRenderTarget_GrSurfaceFlag |
- kNoStencil_GrSurfaceFlag;
+ desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = 256;
desc.fHeight = 256;
desc.fConfig = kRGBA_8888_GrPixelConfig;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index ef4423ba6b..8710931301 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -11,6 +11,7 @@
#include "GrGLTextureRenderTarget.h"
#include "GrGpuResourcePriv.h"
#include "GrPipeline.h"
+#include "GrRenderTargetPriv.h"
#include "GrSurfacePriv.h"
#include "GrTemplates.h"
#include "GrTexturePriv.h"
@@ -454,7 +455,7 @@ GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
desc.fHeight,
desc.fSampleCnt,
format));
- tgt->setStencilBuffer(sb);
+ tgt->renderTargetPriv().didAttachStencilBuffer(sb);
sb->unref();
}
return tgt;
@@ -1175,7 +1176,7 @@ bool GrGLGpu::createStencilBufferForRenderTarget(GrRenderTarget* rt, int width,
(this, sbDesc, width, height, samples, format)));
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
fLastSuccessfulStencilFmtIdx = sIdx;
- rt->setStencilBuffer(sb);
+ rt->renderTargetPriv().didAttachStencilBuffer(sb);
return true;
}
// Remove the scratch key from this resource so we don't grab it from the cache ever
@@ -1195,7 +1196,7 @@ bool GrGLGpu::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTar
GrGLuint fbo = glrt->renderFBOID();
if (NULL == sb) {
- if (rt->getStencilBuffer()) {
+ if (rt->renderTargetPriv().getStencilBuffer()) {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_STENCIL_ATTACHMENT,
GR_GL_RENDERBUFFER, 0));
@@ -1570,10 +1571,11 @@ void GrGLGpu::clearStencil(GrRenderTarget* target) {
void GrGLGpu::onClearStencilClip(GrRenderTarget* target, const SkIRect& rect, bool insideClip) {
SkASSERT(target);
+ GrStencilBuffer* sb = target->renderTargetPriv().getStencilBuffer();
// this should only be called internally when we know we have a
// stencil buffer.
- SkASSERT(target->getStencilBuffer());
- GrGLint stencilBitCount = target->getStencilBuffer()->bits();
+ SkASSERT(sb);
+ GrGLint stencilBitCount = sb->bits();
#if 0
SkASSERT(stencilBitCount > 0);
GrGLint clipStencilMask = (1 << (stencilBitCount - 1));
@@ -2560,7 +2562,7 @@ bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
// then we set up for that, otherwise fail.
if (this->caps()->isConfigRenderable(kBGRA_8888_GrPixelConfig, false)) {
desc->fOrigin = kDefault_GrSurfaceOrigin;
- desc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+ desc->fFlags = kRenderTarget_GrSurfaceFlag;
desc->fConfig = kBGRA_8888_GrPixelConfig;
return true;
}
@@ -2576,7 +2578,7 @@ bool GrGLGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc)
// fail.
if (this->caps()->isConfigRenderable(src->config(), false)) {
desc->fOrigin = kDefault_GrSurfaceOrigin;
- desc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
+ desc->fFlags = kRenderTarget_GrSurfaceFlag;
desc->fConfig = src->config();
return true;
}
diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h
index 4d08c1493a..7e7349257f 100644
--- a/src/gpu/gl/GrGLRenderTarget.h
+++ b/src/gpu/gl/GrGLRenderTarget.h
@@ -54,6 +54,9 @@ public:
}
}
+ /** When we don't own the FBO ID we don't attempt to modify its attachments. */
+ bool canAttemptStencilAttachment() const SK_OVERRIDE { return !fIsWrapped; }
+
protected:
// The public constructor registers this object with the cache. However, only the most derived
// class should register with the cache. This constructor does not do the registration and