Fixes for iOS / Ganesh (consistent fs/vs uni precision decl and don't use stencil-only fbo for clear)

Review URL: http://codereview.appspot.com/4850043/


git-svn-id: http://skia.googlecode.com/svn/trunk@2050 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2011-08-05 15:46:40 +00:00
parent c7e6d08fd2
commit edc177df61
5 changed files with 25 additions and 79 deletions

View File

@ -493,6 +493,8 @@ protected:
// GrGpu subclass removes the clip from the stencil buffer // GrGpu subclass removes the clip from the stencil buffer
virtual void clearStencilClip(const GrIRect& rect) = 0; virtual void clearStencilClip(const GrIRect& rect) = 0;
// clears the entire stencil buffer to 0
virtual void clearStencil() = 0;
private: private:
GrContext* fContext; // not reffed (context refs gpu) GrContext* fContext; // not reffed (context refs gpu)

View File

@ -1082,7 +1082,8 @@ void GrGLProgram::genStageCode(int stageNum,
kernelName.c_str(), desc.fKernelWidth); kernelName.c_str(), desc.fKernelWidth);
segments->fFSUnis.appendf("uniform vec2 %s;\n", segments->fFSUnis.appendf("uniform vec2 %s;\n",
imageIncrementName.c_str()); imageIncrementName.c_str());
segments->fVSUnis.appendf("uniform vec2 %s;\n", segments->fVSUnis.appendf("uniform %s vec2 %s;\n",
GrPrecision(),
imageIncrementName.c_str()); imageIncrementName.c_str());
locations->fKernelUni = kUseUniform; locations->fKernelUni = kUseUniform;
locations->fImageIncrementUni = kUseUniform; locations->fImageIncrementUni = kUseUniform;

View File

@ -156,8 +156,23 @@ GrTexture* GrGpu::createTexture(const GrTextureDesc& desc,
bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) { bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
// TODO: use a cache of stencil buffers rather than create per-rt. // TODO: use a cache of stencil buffers rather than create per-rt.
return this->createStencilBufferForRenderTarget(rt, rt->width(), bool ret = this->createStencilBufferForRenderTarget(rt, rt->width(),
rt->height()); rt->height());
if (ret) {
// Right now we're clearing the stencil buffer here after it is
// attached to an RT for the first time. When we start matching
// stencil buffers with smaller color targets this will no longer
// be correct because it won't be guaranteed to clear the entire
// sb.
// We used to clear down in the GL subclass using a special purpose
// FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
// FBO status.
GrRenderTarget* oldRT = fCurrDrawState.fRenderTarget;
fCurrDrawState.fRenderTarget = rt;
this->clearStencil();
fCurrDrawState.fRenderTarget = oldRT;
}
return ret;
} }
GrRenderTarget* GrGpu::createRenderTargetFrom3DApiState() { GrRenderTarget* GrGpu::createRenderTargetFrom3DApiState() {

View File

@ -516,14 +516,9 @@ GrGpuGL::GrGpuGL()
} }
fLastSuccessfulStencilFmtIdx = 0; fLastSuccessfulStencilFmtIdx = 0;
fStencilClearFBO = 0;
} }
GrGpuGL::~GrGpuGL() { GrGpuGL::~GrGpuGL() {
if (fStencilClearFBO) {
GR_GL(DeleteFramebuffers(1, &fStencilClearFBO));
}
} }
void GrGpuGL::resetContext() { void GrGpuGL::resetContext() {
@ -595,21 +590,6 @@ void GrGpuGL::resetContext() {
fHWDrawState.fRenderTarget = NULL; fHWDrawState.fRenderTarget = NULL;
} }
void GrGpuGL::abandonResources() {
INHERITED::abandonResources();
fStencilClearFBO = 0;
}
void GrGpuGL::releaseResources() {
INHERITED::releaseResources();
if (fStencilClearFBO) {
GR_GL(DeleteFramebuffers(1, &fStencilClearFBO));
fStencilClearFBO = 0;
}
}
GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) { GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) {
bool isTexture = kTexture_GrPlatformSurfaceType == desc.fSurfaceType || bool isTexture = kTexture_GrPlatformSurfaceType == desc.fSurfaceType ||
@ -1374,56 +1354,6 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
if (this->attachStencilBufferToRenderTarget(sb, rt)) { if (this->attachStencilBufferToRenderTarget(sb, rt)) {
fLastSuccessfulStencilFmtIdx = sIdx; fLastSuccessfulStencilFmtIdx = sIdx;
sb->unref(); sb->unref();
fHWDrawState.fRenderTarget = NULL;
// initial clear zeros the entire sb by attaching it alone
// to an fbo (that we create here on demand).
if (!fStencilClearFBO) {
GR_GL(GenFramebuffers(1, &fStencilClearFBO));
if (0 == fStencilClearFBO) {
rt->setStencilBuffer(NULL);
return false;
}
GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBO));
if (GR_GL_SUPPORT_DESKTOP) {
// We won't be binding a color buffer, set the draw
// buffer to NONE to avoid
// FRAMEBUFFER_INCOMPLETE_READ_BUFFER.
GR_GL(DrawBuffer(GR_GL_NONE));
// We bind to FRAMEBUFFER not DRAW_FRAMEBUFFER or
// READ_FRAMEBUFFER because earlier versions of desktop
// GL and unextended ES only have FRAMEBUFFER. But this
// means we're binding both READ and DRAW when
// FramebufferBlit is supported. So to avoid
// FRAMEBUFFER_INCOMPLETE_READ_BUFFER status we also set
// the read buffer to none.
GR_GL(ReadBuffer(GR_GL_NONE));
// DrawBuffer and ReadBuffer are framebuffer state so
// we only have to set these the first time.
}
} else {
GR_GL(BindFramebuffer(GR_GL_FRAMEBUFFER, fStencilClearFBO));
}
GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_STENCIL_ATTACHMENT,
GR_GL_RENDERBUFFER, sbID));
if (fStencilFormats[sIdx].fPacked) {
GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_DEPTH_ATTACHMENT,
GR_GL_RENDERBUFFER, sbID));
} else {
GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_DEPTH_ATTACHMENT,
GR_GL_RENDERBUFFER, 0));
}
#if GR_DEBUG
GrGLenum status =
GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
GrAssert(GR_GL_FRAMEBUFFER_COMPLETE == status);
#endif
this->flushScissor(NULL);
GR_GL(ClearStencil(0));
GR_GL(Clear(GR_GL_STENCIL_BUFFER_BIT));
return true; return true;
} }
sb->abandon(); // otherwise we lose sbID sb->abandon(); // otherwise we lose sbID
@ -1600,7 +1530,7 @@ void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
GR_GL(Clear(GR_GL_COLOR_BUFFER_BIT)); GR_GL(Clear(GR_GL_COLOR_BUFFER_BIT));
} }
void GrGpuGL::clearStencil(uint32_t value, uint32_t mask) { void GrGpuGL::clearStencil() {
if (NULL == fCurrDrawState.fRenderTarget) { if (NULL == fCurrDrawState.fRenderTarget) {
return; return;
} }
@ -1611,8 +1541,8 @@ void GrGpuGL::clearStencil(uint32_t value, uint32_t mask) {
GR_GL(Disable(GR_GL_SCISSOR_TEST)); GR_GL(Disable(GR_GL_SCISSOR_TEST));
fHWBounds.fScissorEnabled = false; fHWBounds.fScissorEnabled = false;
} }
GR_GL(StencilMask(mask)); GR_GL(StencilMask(0xffffffff));
GR_GL(ClearStencil(value)); GR_GL(ClearStencil(0));
GR_GL(Clear(GR_GL_STENCIL_BUFFER_BIT)); GR_GL(Clear(GR_GL_STENCIL_BUFFER_BIT));
fHWDrawState.fStencilSettings.invalidate(); fHWDrawState.fStencilSettings.invalidate();
} }

View File

@ -70,8 +70,6 @@ protected:
// GrGpu overrides // GrGpu overrides
virtual void resetContext(); virtual void resetContext();
virtual void abandonResources();
virtual void releaseResources();
virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
const void* srcData, const void* srcData,
@ -104,7 +102,7 @@ protected:
uint32_t vertexCount, uint32_t vertexCount,
uint32_t numVertices); uint32_t numVertices);
virtual void flushScissor(const GrIRect* rect); virtual void flushScissor(const GrIRect* rect);
void clearStencil(uint32_t value, uint32_t mask); virtual void clearStencil();
virtual void clearStencilClip(const GrIRect& rect); virtual void clearStencilClip(const GrIRect& rect);
virtual int getMaxEdges() const; virtual int getMaxEdges() const;