diff options
author | 2015-09-10 08:37:20 -0700 | |
---|---|---|
committer | 2015-09-10 08:37:20 -0700 | |
commit | ff1d547c72b7c70af7bddfba01d4646b2389db7a (patch) | |
tree | a96e9b61d9b2837969825d67e170966ff94e22b0 /src | |
parent | 6c6f65885ba20ba9e8d8c36039f1c9eff4cc814b (diff) |
Calculate pixel config and stencil fmt pairs once per pixel config.
We use a temp FB and stencil buffer to test different stencil formats with
a given pixel config. We then keep a map from pixel config to desired stencil
format.
BUG=skia:
Review URL: https://codereview.chromium.org/1317443004
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrCaps.cpp | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 48 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 22 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 330 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.h | 9 |
5 files changed, 224 insertions, 191 deletions
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp index e40057686c..1bcdb20383 100644 --- a/src/gpu/GrCaps.cpp +++ b/src/gpu/GrCaps.cpp @@ -102,9 +102,9 @@ GrCaps::GrCaps(const GrContextOptions& options) { fMapBufferFlags = kNone_MapFlags; - fMaxRenderTargetSize = 0; - fMaxTextureSize = 0; - fMinTextureSize = 0; + fMaxRenderTargetSize = 1; + fMaxTextureSize = 1; + fMinTextureSize = 1; fMaxSampleCount = 0; memset(fConfigRenderSupport, 0, sizeof(fConfigRenderSupport)); diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index ea2daeed1e..e3c61385a9 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -18,7 +18,6 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions, const GrGLInterface* glInterface) : INHERITED(contextOptions) { fVerifiedColorConfigs.reset(); fStencilFormats.reset(); - fStencilVerifiedColorConfigs.reset(); fMSFBOType = kNone_MSFBOType; fInvalidateFBType = kNone_InvalidateFBType; fLATCAlias = kLATC_LATCAlias; @@ -1019,53 +1018,6 @@ void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) { fStencilFormats.push_back() = gS4; } } - SkASSERT(0 == fStencilVerifiedColorConfigs.count()); - fStencilVerifiedColorConfigs.push_back_n(fStencilFormats.count()); -} - -void GrGLCaps::markColorConfigAndStencilFormatAsVerified( - GrPixelConfig config, - const GrGLStencilAttachment::Format& format) { -#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT - return; -#endif - SkASSERT((unsigned)config < (unsigned)kGrPixelConfigCnt); - SkASSERT(fStencilFormats.count() == fStencilVerifiedColorConfigs.count()); - int count = fStencilFormats.count(); - // we expect a really small number of possible formats so linear search - // should be OK - SkASSERT(count < 16); - for (int i = 0; i < count; ++i) { - if (format.fInternalFormat == - fStencilFormats[i].fInternalFormat) { - fStencilVerifiedColorConfigs[i].markVerified(config); - return; - } - } - SkFAIL("Why are we seeing a stencil format that " - "GrGLCaps doesn't know about."); -} - -bool GrGLCaps::isColorConfigAndStencilFormatVerified( - GrPixelConfig config, - const GrGLStencilAttachment::Format& format) const { -#if !GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT - return false; -#endif - SkASSERT((unsigned)config < (unsigned)kGrPixelConfigCnt); - int count = fStencilFormats.count(); - // we expect a really small number of possible formats so linear search - // should be OK - SkASSERT(count < 16); - for (int i = 0; i < count; ++i) { - if (format.fInternalFormat == - fStencilFormats[i].fInternalFormat) { - return fStencilVerifiedColorConfigs[i].isVerified(config); - } - } - SkFAIL("Why are we seeing a stencil format that " - "GLCaps doesn't know about."); - return false; } SkString GrGLCaps::dump() const { diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index bbfdaef9b0..80a3577db3 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -115,24 +115,6 @@ public: } /** - * Call to note that a color config / stencil format pair passed - * FBO status check. We may skip calling glCheckFramebufferStatus for - * this combination in the future using - * isColorConfigAndStencilFormatVerified(). - */ - void markColorConfigAndStencilFormatAsVerified( - GrPixelConfig config, - const GrGLStencilAttachment::Format& format); - - /** - * Call to check whether color config / stencil format pair has already - * passed FBO status check. - */ - bool isColorConfigAndStencilFormatVerified( - GrPixelConfig config, - const GrGLStencilAttachment::Format& format) const; - - /** * Reports the type of MSAA FBO support. */ MSFBOType msFBOType() const { return fMSFBOType; } @@ -343,10 +325,6 @@ private: VerifiedColorConfigs fVerifiedColorConfigs; SkTArray<StencilFormat, true> fStencilFormats; - // tracks configs that have been verified to pass the FBO completeness when - // used as a color attachment when a particular stencil format is used - // as a stencil attachment. - SkTArray<VerifiedColorConfigs, true> fStencilVerifiedColorConfigs; int fMaxFragmentUniformVectors; int fMaxVertexAttributes; diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 602eeca56d..0eac373f2e 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -159,6 +159,15 @@ bool GrGLGpu::BlendCoeffReferencesConstant(GrBlendCoeff coeff) { /////////////////////////////////////////////////////////////////////////////// +// Used in the map of pixel configs to stencil format indices. This value is used to +// indicate that a stencil format has not yet been set for the given config. +static const int kUnknownStencilIndex = -1; +// This value is used as the stencil index when no stencil configs are supported with the +// given pixel config. +static const int kUnsupportedStencilIndex = -2; + +/////////////////////////////////////////////////////////////////////////////// + GrGpu* GrGLGpu::Create(GrBackendContext backendContext, const GrContextOptions& options, GrContext* context) { SkAutoTUnref<const GrGLInterface> glInterface( @@ -211,7 +220,9 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context) SkASSERT(this->glCaps().maxVertexAttributes() >= GrGeometryProcessor::kMaxVertexAttribs); - fLastSuccessfulStencilFmtIdx = 0; + for (int i = 0; i < kGrPixelConfigCnt; ++i) { + fPixelConfigToStencilIndex[i] = kUnknownStencilIndex; + } fHWProgramID = 0; fTempSrcFBOID = 0; fTempDstFBOID = 0; @@ -1169,120 +1180,223 @@ void inline get_stencil_rb_sizes(const GrGLInterface* gl, } } -bool GrGLGpu::createStencilAttachmentForRenderTarget(GrRenderTarget* rt, int width, int height) { - // All internally created RTs are also textures. We don't create - // SBs for a client's standalone RT (that is a RT that isn't also a texture). - SkASSERT(rt->asTexture()); - SkASSERT(width >= rt->width()); - SkASSERT(height >= rt->height()); - - int samples = rt->numStencilSamples(); - GrGLStencilAttachment::IDDesc sbDesc; +int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) { + int size = this->caps()->minTextureSize(); + if (kUnknownStencilIndex == fPixelConfigToStencilIndex[config]) { + // Default to unsupported + fPixelConfigToStencilIndex[config] = kUnsupportedStencilIndex; + // Create color texture + GrGLuint colorID; + GL_CALL(GenTextures(1, &colorID)); + this->setScratchTextureUnit(); + GL_CALL(BindTexture(GR_GL_TEXTURE_2D, colorID)); + GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, + GR_GL_TEXTURE_MAG_FILTER, + GR_GL_NEAREST)); + GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, + GR_GL_TEXTURE_MIN_FILTER, + GR_GL_NEAREST)); + GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, + GR_GL_TEXTURE_WRAP_S, + GR_GL_CLAMP_TO_EDGE)); + GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, + GR_GL_TEXTURE_WRAP_T, + GR_GL_CLAMP_TO_EDGE)); - int stencilFmtCnt = this->glCaps().stencilFormats().count(); - for (int i = 0; i < stencilFmtCnt; ++i) { - if (!sbDesc.fRenderbufferID) { - GL_CALL(GenRenderbuffers(1, &sbDesc.fRenderbufferID)); + GrGLenum internalFormat = 0x0; // suppress warning + GrGLenum externalFormat = 0x0; // suppress warning + GrGLenum externalType = 0x0; // suppress warning + if (!this->configToGLFormats(config, false, &internalFormat, + &externalFormat, &externalType)) { + GL_CALL(DeleteTextures(1, &colorID)); + fPixelConfigToStencilIndex[config] = kUnsupportedStencilIndex; + return kUnsupportedStencilIndex; } - if (!sbDesc.fRenderbufferID) { - return false; - } - GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); - // we start with the last stencil format that succeeded in hopes - // that we won't go through this loop more than once after the - // first (painful) stencil creation. - int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt; - const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[sIdx]; + CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); - // we do this "if" so that we don't call the multisample - // version on a GL that doesn't have an MSAA extension. - bool created; - if (samples > 0) { - created = renderbuffer_storage_msaa(*fGLContext, - samples, - sFmt.fInternalFormat, - width, height); - } else { + GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, + 0, internalFormat, + size, + size, + 0, + externalFormat, + externalType, + NULL)); + if (GR_GL_NO_ERROR != GR_GL_GET_ERROR(this->glInterface())) { + GL_CALL(DeleteTextures(1, &colorID)); + fPixelConfigToStencilIndex[config] = kUnsupportedStencilIndex; + return kUnsupportedStencilIndex; + } + + // unbind the texture from the texture unit before binding it to the frame buffer + GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0)); + + // Create Framebuffer + GrGLuint fb; + GL_CALL(GenFramebuffers(1, &fb)); + GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fb)); + fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; + GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, + GR_GL_COLOR_ATTACHMENT0, + GR_GL_TEXTURE_2D, + colorID, + 0)); + + // look over formats till I find a compatible one + int stencilFmtCnt = this->glCaps().stencilFormats().count(); + GrGLuint sbRBID = 0; + for (int i = 0; i < stencilFmtCnt; ++i) { + const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[i]; + + GL_CALL(GenRenderbuffers(1, &sbRBID)); + if (!sbRBID) { + break; + } + GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbRBID)); + CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER, sFmt.fInternalFormat, - width, height)); - created = (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glInterface())); - } - if (created) { - fStats.incStencilAttachmentCreates(); - // After sized formats we attempt an unsized format and take - // whatever sizes GL gives us. In that case we query for the size. - GrGLStencilAttachment::Format format = sFmt; - get_stencil_rb_sizes(this->glInterface(), &format); - SkAutoTUnref<GrGLStencilAttachment> sb( - new GrGLStencilAttachment(this, sbDesc, width, height, samples, format)); - if (this->attachStencilAttachmentToRenderTarget(sb, rt)) { - fLastSuccessfulStencilFmtIdx = sIdx; - rt->renderTargetPriv().didAttachStencilAttachment(sb); -// This work around is currently breaking on windows 7 hd2000 bot when we bind a color buffer -#if 0 - // Clear the stencil buffer. We use a special purpose FBO for this so that the - // entire stencil buffer is cleared, even if it is attached to an FBO with a - // smaller color target. - if (0 == fStencilClearFBOID) { - GL_CALL(GenFramebuffers(1, &fStencilClearFBOID)); - } - - GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBOID)); - fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; - fStats.incRenderTargetBinds(); + size, size)); + if (GR_GL_NO_ERROR == GR_GL_GET_ERROR(this->glInterface())) { GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT, - GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); + GR_GL_RENDERBUFFER, sbRBID)); if (sFmt.fPacked) { GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_DEPTH_ATTACHMENT, - GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); - } - - GL_CALL(ClearStencil(0)); - // Many GL implementations seem to have trouble with clearing an FBO with only - // a stencil buffer. - GrGLuint tempRB; - GL_CALL(GenRenderbuffers(1, &tempRB)); - GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, tempRB)); - if (samples > 0) { - renderbuffer_storage_msaa(fGLContext, samples, GR_GL_RGBA8, width, height); + GR_GL_RENDERBUFFER, sbRBID)); } else { - GL_CALL(RenderbufferStorage(GR_GL_RENDERBUFFER, GR_GL_RGBA8, width, height)); - } - GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_COLOR_ATTACHMENT0, - GR_GL_RENDERBUFFER, tempRB)); - - GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); - - GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_COLOR_ATTACHMENT0, - GR_GL_RENDERBUFFER, 0)); - GL_CALL(DeleteRenderbuffers(1, &tempRB)); - - // Unbind the SB from the FBO so that we don't keep it alive. - GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_STENCIL_ATTACHMENT, - GR_GL_RENDERBUFFER, 0)); - if (sFmt.fPacked) { GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_DEPTH_ATTACHMENT, GR_GL_RENDERBUFFER, 0)); } -#endif - return true; + GrGLenum status; + GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); + if (status != GR_GL_FRAMEBUFFER_COMPLETE) { + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_STENCIL_ATTACHMENT, + GR_GL_RENDERBUFFER, 0)); + if (sFmt.fPacked) { + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_DEPTH_ATTACHMENT, + GR_GL_RENDERBUFFER, 0)); + } + } else { + fPixelConfigToStencilIndex[config] = i; + break; + } } - // Remove the scratch key from this resource so we don't grab it from the cache ever - // again. - sb->resourcePriv().removeScratchKey(); - // Set this to 0 since we handed the valid ID off to the failed stencil buffer resource. - sbDesc.fRenderbufferID = 0; + sbRBID = 0; } + GL_CALL(DeleteTextures(1, &colorID)); + GL_CALL(DeleteRenderbuffers(1, &sbRBID)); + GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0)); + GL_CALL(DeleteFramebuffers(1, &fb)); } - GL_CALL(DeleteRenderbuffers(1, &sbDesc.fRenderbufferID)); - return false; + SkASSERT(kUnknownStencilIndex != fPixelConfigToStencilIndex[config]); + return fPixelConfigToStencilIndex[config]; +} + +bool GrGLGpu::createStencilAttachmentForRenderTarget(GrRenderTarget* rt, int width, int height) { + // All internally created RTs are also textures. We don't create + // SBs for a client's standalone RT (that is a RT that isn't also a texture). + SkASSERT(rt->asTexture()); + SkASSERT(width >= rt->width()); + SkASSERT(height >= rt->height()); + + int samples = rt->numStencilSamples(); + GrGLStencilAttachment::IDDesc sbDesc; + + int sIdx = this->getCompatibleStencilIndex(rt->config()); + if (sIdx == kUnsupportedStencilIndex) { + return false; + } + + if (!sbDesc.fRenderbufferID) { + GL_CALL(GenRenderbuffers(1, &sbDesc.fRenderbufferID)); + } + if (!sbDesc.fRenderbufferID) { + return false; + } + GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); + const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[sIdx]; + CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); + // we do this "if" so that we don't call the multisample + // version on a GL that doesn't have an MSAA extension. + if (samples > 0) { + SkAssertResult(renderbuffer_storage_msaa(*fGLContext, + samples, + sFmt.fInternalFormat, + width, height)); + } else { + GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER, + sFmt.fInternalFormat, + width, height)); + SkASSERT(GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glInterface())); + } + fStats.incStencilAttachmentCreates(); + // After sized formats we attempt an unsized format and take + // whatever sizes GL gives us. In that case we query for the size. + GrGLStencilAttachment::Format format = sFmt; + get_stencil_rb_sizes(this->glInterface(), &format); + SkAutoTUnref<GrGLStencilAttachment> sb( + new GrGLStencilAttachment(this, sbDesc, width, height, samples, format)); + SkAssertResult(this->attachStencilAttachmentToRenderTarget(sb, rt)); + rt->renderTargetPriv().didAttachStencilAttachment(sb); + // This work around is currently breaking on windows 7 hd2000 bot when we bind a color buffer +#if 0 + // Clear the stencil buffer. We use a special purpose FBO for this so that the + // entire stencil buffer is cleared, even if it is attached to an FBO with a + // smaller color target. + if (0 == fStencilClearFBOID) { + GL_CALL(GenFramebuffers(1, &fStencilClearFBOID)); + } + + GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBOID)); + fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; + fStats.incRenderTargetBinds(); + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_STENCIL_ATTACHMENT, + GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); + if (sFmt.fPacked) { + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_DEPTH_ATTACHMENT, + GR_GL_RENDERBUFFER, sbDesc.fRenderbufferID)); + } + + GL_CALL(ClearStencil(0)); + // Many GL implementations seem to have trouble with clearing an FBO with only + // a stencil buffer. + GrGLuint tempRB; + GL_CALL(GenRenderbuffers(1, &tempRB)); + GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, tempRB)); + if (samples > 0) { + renderbuffer_storage_msaa(fGLContext, samples, GR_GL_RGBA8, width, height); + } else { + GL_CALL(RenderbufferStorage(GR_GL_RENDERBUFFER, GR_GL_RGBA8, width, height)); + } + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_COLOR_ATTACHMENT0, + GR_GL_RENDERBUFFER, tempRB)); + + GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); + + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_COLOR_ATTACHMENT0, + GR_GL_RENDERBUFFER, 0)); + GL_CALL(DeleteRenderbuffers(1, &tempRB)); + + // Unbind the SB from the FBO so that we don't keep it alive. + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_STENCIL_ATTACHMENT, + GR_GL_RENDERBUFFER, 0)); + if (sFmt.fPacked) { + GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, + GR_GL_DEPTH_ATTACHMENT, + GR_GL_RENDERBUFFER, 0)); + } +#endif + return true; } bool GrGLGpu::attachStencilAttachmentToRenderTarget(GrStencilAttachment* sb, GrRenderTarget* rt) { @@ -1325,25 +1439,11 @@ bool GrGLGpu::attachStencilAttachmentToRenderTarget(GrStencilAttachment* sb, GrR GR_GL_RENDERBUFFER, 0)); } +#ifdef SK_DEBUG GrGLenum status; - if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(), glsb->format())) { - GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); - if (status != GR_GL_FRAMEBUFFER_COMPLETE) { - GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_STENCIL_ATTACHMENT, - GR_GL_RENDERBUFFER, 0)); - if (glsb->format().fPacked) { - GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, - GR_GL_DEPTH_ATTACHMENT, - GR_GL_RENDERBUFFER, 0)); - } - return false; - } else { - fGLContext->caps()->markColorConfigAndStencilFormatAsVerified( - rt->config(), - glsb->format()); - } - } + GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); + SkASSERT(GR_GL_FRAMEBUFFER_COMPLETE == status); +#endif return true; } } diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 8a04467391..eaf762d0e2 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -126,6 +126,9 @@ private: bool createStencilAttachmentForRenderTarget(GrRenderTarget* rt, int width, int height) override; bool attachStencilAttachmentToRenderTarget(GrStencilAttachment* sb, GrRenderTarget* rt) override; + // Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a + // compatible stencil format. + int getCompatibleStencilIndex(GrPixelConfig config); void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override; @@ -489,9 +492,9 @@ private: ///@} - // we record what stencil format worked last time to hopefully exit early - // from our loop that tries stencil formats and calls check fb status. - int fLastSuccessfulStencilFmtIdx; + // Mapping of pixel configs to known supported stencil formats to be used + // when adding a stencil buffer to a framebuffer. + int fPixelConfigToStencilIndex[kGrPixelConfigCnt]; typedef GrGpu INHERITED; friend class GrGLPathRendering; // For accessing setTextureUnit. |