diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-04-11 17:58:48 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-04-11 17:58:48 +0000 |
commit | 5877ffd5ea71a3ea70096d5c11c843798defa690 (patch) | |
tree | e9c898ced0fdd91487cd265618db1be03f920844 /gpu/src | |
parent | afac88855a31bea16143028f51935d00be177dc6 (diff) |
Add APIs and plumbing for external rendertaret-textures w/ and w/out MSAA.
Review URL: http://codereview.appspot.com/4388049/
git-svn-id: http://skia.googlecode.com/svn/trunk@1102 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu/src')
-rw-r--r-- | gpu/src/GrContext.cpp | 26 | ||||
-rw-r--r-- | gpu/src/GrGLTexture.cpp | 3 | ||||
-rw-r--r-- | gpu/src/GrGpu.cpp | 12 | ||||
-rw-r--r-- | gpu/src/GrGpuGL.cpp | 135 | ||||
-rw-r--r-- | gpu/src/GrGpuGL.h | 10 |
5 files changed, 141 insertions, 45 deletions
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp index b17a238c86..8017f73eba 100644 --- a/gpu/src/GrContext.cpp +++ b/gpu/src/GrContext.cpp @@ -267,16 +267,26 @@ int GrContext::getMaxTextureDimension() { /////////////////////////////////////////////////////////////////////////////// -GrRenderTarget* GrContext::createPlatformRenderTarget( - intptr_t platformRenderTarget, - int stencilBits, - bool isMultisampled, - int width, int height) { - return fGpu->createPlatformRenderTarget(platformRenderTarget, stencilBits, - isMultisampled, - width, height); +GrResource* GrContext::createPlatformSurface(const GrPlatformSurfaceDesc& desc) { + // validate flags here so that GrGpu subclasses don't have to check + if (kTexture_GrPlatformSurfaceType == desc.fSurfaceType && + 0 != desc.fRenderTargetFlags) { + return NULL; + } + if (!(kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) && + (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) { + return NULL; + } + if (kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType && + (kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) && + !(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) { + return NULL; + } + return fGpu->createPlatformSurface(desc); } +/////////////////////////////////////////////////////////////////////////////// + bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler, int width, int height) { if (!fGpu->supports8BitPalette()) { diff --git a/gpu/src/GrGLTexture.cpp b/gpu/src/GrGLTexture.cpp index 6a5a005142..3c6504d6cb 100644 --- a/gpu/src/GrGLTexture.cpp +++ b/gpu/src/GrGLTexture.cpp @@ -108,7 +108,8 @@ GrGLTexture::GrGLTexture(GrGpuGL* gpu, textureDesc.fFormat) { fTexParams = initialTexParams; - fTexIDObj = new GrGLTexID(textureDesc.fTextureID); + fTexIDObj = new GrGLTexID(textureDesc.fTextureID, + textureDesc.fOwnsID); fUploadFormat = textureDesc.fUploadFormat; fUploadByteCount = textureDesc.fUploadByteCount; fUploadType = textureDesc.fUploadType; diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp index 4aaed7943b..2407cdf85c 100644 --- a/gpu/src/GrGpu.cpp +++ b/gpu/src/GrGpu.cpp @@ -158,6 +158,11 @@ GrRenderTarget* GrGpu::createRenderTargetFrom3DApiState() { return this->createRenderTargetFrom3DApiStateHelper(); } +GrResource* GrGpu::createPlatformSurface(const GrPlatformSurfaceDesc& desc) { + this->handleDirtyContext(); + return this->onCreatePlatformSurface(desc); +} + GrVertexBuffer* GrGpu::createVertexBuffer(uint32_t size, bool dynamic) { this->handleDirtyContext(); return this->createVertexBufferHelper(size, dynamic); @@ -183,12 +188,7 @@ bool GrGpu::readPixels(GrRenderTarget* target, GrPixelConfig config, void* buffer) { this->handleDirtyContext(); - GrRenderTarget* prevTarget = fCurrDrawState.fRenderTarget; - if (NULL != target) { - fCurrDrawState.fRenderTarget = target; - } - return this->readPixelsHelper(left, top, width, height, config, buffer); - fCurrDrawState.fRenderTarget = prevTarget; + return this->onReadPixels(target, left, top, width, height, config, buffer); } //////////////////////////////////////////////////////////////////////////////// diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp index 86d634219b..e62949b14c 100644 --- a/gpu/src/GrGpuGL.cpp +++ b/gpu/src/GrGpuGL.cpp @@ -533,6 +533,73 @@ void GrGpuGL::resetContext() { fHWDrawState.fRenderTarget = NULL; } +GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) { + + bool isTexture = kTexture_GrPlatformSurfaceType == desc.fSurfaceType || + kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType; + bool isRenderTarget = kRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType || + kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType; + + GrGLRenderTarget::GLRenderTargetIDs rtIDs; + if (isRenderTarget) { + rtIDs.fRTFBOID = desc.fPlatformRenderTarget; + if (kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) { + if (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) { + rtIDs.fTexFBOID = desc.fPlatformResolveDestination; + } else { + GrAssert(!isTexture); // this should have been filtered by GrContext + rtIDs.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID; + } + } else { + rtIDs.fTexFBOID = desc.fPlatformRenderTarget; + } + // we don't know what the RB ids are without glGets and we don't care + // since we aren't responsible for deleting them. + rtIDs.fStencilRenderbufferID = 0; + rtIDs.fMSColorRenderbufferID = 0; + + rtIDs.fOwnIDs = false; + } else { + rtIDs.reset(); + } + + if (isTexture) { + GrGLTexture::GLTextureDesc texDesc; + GrGLenum dontCare; + if (!canBeTexture(desc.fConfig, &dontCare, + &texDesc.fUploadFormat, + &texDesc.fUploadType)) { + return NULL; + } + + GrGLTexture::TexParams params; + + texDesc.fAllocWidth = texDesc.fContentWidth = desc.fWidth; + texDesc.fAllocHeight = texDesc.fContentHeight = desc.fHeight; + + texDesc.fFormat = texDesc.fFormat; + texDesc.fOrientation = GrGLTexture::kBottomUp_Orientation; + texDesc.fStencilBits = desc.fStencilBits; + texDesc.fTextureID = desc.fPlatformTexture; + texDesc.fUploadByteCount = GrBytesPerPixel(desc.fConfig); + texDesc.fOwnsID = false; + + params.invalidate(); // rather than do glGets. + + return new GrGLTexture(this, texDesc, rtIDs, params); + } else { + GrGLIRect viewport; + viewport.fLeft = 0; + viewport.fBottom = 0; + viewport.fWidth = desc.fWidth; + viewport.fHeight = desc.fHeight; + + return new GrGLRenderTarget(this, rtIDs, NULL, desc.fStencilBits, + kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags, + viewport, NULL); + } +} + GrRenderTarget* GrGpuGL::createPlatformRenderTargetHelper( intptr_t platformRenderTarget, int stencilBits, @@ -655,6 +722,7 @@ GrTexture* GrGpuGL::createTextureHelper(const TextureDesc& desc, glDesc.fAllocHeight = desc.fHeight; glDesc.fStencilBits = 0; glDesc.fFormat = desc.fFormat; + glDesc.fOwnsID = true; bool renderTarget = 0 != (desc.fFlags & kRenderTarget_TextureFlag); if (!canBeTexture(desc.fFormat, @@ -1154,21 +1222,35 @@ void GrGpuGL::forceRenderTargetFlushHelper() { flushRenderTarget(); } -bool GrGpuGL::readPixelsHelper(int left, int top, int width, int height, - GrPixelConfig config, void* buffer) { +bool GrGpuGL::onReadPixels(GrRenderTarget* target, + int left, int top, int width, int height, + GrPixelConfig config, void* buffer) { GrGLenum internalFormat; // we don't use this for glReadPixels GrGLenum format; GrGLenum type; if (!this->canBeTexture(config, &internalFormat, &format, &type)) { return false; + } + GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target); + GrAutoTPtrValueRestore<GrRenderTarget*> autoTargetRestore; + switch (tgt->getResolveType()) { + case GrGLRenderTarget::kCantResolve_ResolveType: + return false; + case GrGLRenderTarget::kAutoResolves_ResolveType: + autoTargetRestore.save(&fCurrDrawState.fRenderTarget); + fCurrDrawState.fRenderTarget = target; + flushRenderTarget(); + break; + case GrGLRenderTarget::kCanResolve_ResolveType: + resolveRenderTarget(tgt); + // we don't track the state of the READ FBO ID. + GR_GL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, tgt->textureFBOID())); + break; + default: + GrCrash("Unknown resolve type"); } - if (NULL == fCurrDrawState.fRenderTarget) { - return false; - } - flushRenderTarget(); - - const GrGLIRect& glvp = ((GrGLRenderTarget*)fCurrDrawState.fRenderTarget)->getViewport(); + const GrGLIRect& glvp = tgt->getViewport(); // the read rect is viewport-relative GrGLIRect readRect; @@ -1208,7 +1290,7 @@ void GrGpuGL::flushRenderTarget() { #if GR_COLLECT_STATS ++fStats.fRenderTargetChngCnt; #endif - rt->setDirty(true); + rt->flagAsNeedingResolve(); #if GR_DEBUG GrGLenum status = GR_GL(CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); if (status != GR_GL_FRAMEBUFFER_COMPLETE) { @@ -1316,10 +1398,9 @@ void GrGpuGL::drawNonIndexedHelper(GrPrimitiveType type, #endif } -void GrGpuGL::resolveTextureRenderTarget(GrGLTexture* texture) { - GrGLRenderTarget* rt = (GrGLRenderTarget*) texture->asRenderTarget(); +void GrGpuGL::resolveRenderTarget(GrGLRenderTarget* rt) { - if (NULL != rt && rt->needsResolve()) { + if (rt->needsResolve()) { GrAssert(kNone_MSFBO != fMSFBOType); GrAssert(rt->textureFBOID() != rt->renderFBOID()); GR_GL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, @@ -1329,32 +1410,32 @@ void GrGpuGL::resolveTextureRenderTarget(GrGLTexture* texture) { #if GR_COLLECT_STATS ++fStats.fRenderTargetChngCnt; #endif - // make sure we go through set render target + // make sure we go through flushRenderTarget() since we've modified + // the bound DRAW FBO ID. fHWDrawState.fRenderTarget = NULL; + const GrGLIRect& vp = rt->getViewport(); - GrGLint left = 0; - GrGLint right = texture->width(); - // we will have rendered to the top of the FBO. - GrGLint top = texture->allocHeight(); - GrGLint bottom = texture->allocHeight() - texture->height(); if (kAppleES_MSFBO == fMSFBOType) { // Apple's extension uses the scissor as the blit bounds. GR_GL(Enable(GR_GL_SCISSOR_TEST)); - GR_GL(Scissor(left, bottom, right-left, top-bottom)); + GR_GL(Scissor(vp.fLeft, vp.fBottom, + vp.fWidth, vp.fHeight)); GR_GL(ResolveMultisampleFramebuffer()); fHWBounds.fScissorRect.invalidate(); fHWBounds.fScissorEnabled = true; } else { if (kDesktopARB_MSFBO != fMSFBOType) { - // these respect the scissor during the blit, so disable it. + // this respects the scissor during the blit, so disable it. GrAssert(kDesktopEXT_MSFBO == fMSFBOType); flushScissor(NULL); } - GR_GL(BlitFramebuffer(left, bottom, right, top, - left, bottom, right, top, - GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); + int right = vp.fLeft + vp.fWidth; + int top = vp.fBottom + vp.fHeight; + GR_GL(BlitFramebuffer(vp.fLeft, vp.fBottom, right, top, + vp.fLeft, vp.fBottom, right, top, + GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); } - rt->setDirty(false); + rt->flagAsResolved(); } } @@ -1631,7 +1712,11 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) { // texture and now we're texuring from the rt it will still be // the last bound texture, but it needs resolving. So keep this // out of the "last != next" check. - resolveTextureRenderTarget(nextTexture); + GrGLRenderTarget* texRT = + static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget()); + if (NULL != texRT) { + resolveRenderTarget(texRT); + } if (fHWDrawState.fTextures[s] != nextTexture) { setTextureUnit(s); diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h index 1b5f7f7ac7..cffa6717bf 100644 --- a/gpu/src/GrGpuGL.h +++ b/gpu/src/GrGpuGL.h @@ -79,21 +79,21 @@ protected: bool dynamic); virtual GrIndexBuffer* createIndexBufferHelper(uint32_t size, bool dynamic); - + virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc); virtual GrRenderTarget* createPlatformRenderTargetHelper( intptr_t platformRenderTarget, int stencilBits, bool isMultisampled, int width, int height); - virtual GrRenderTarget* createRenderTargetFrom3DApiStateHelper(); virtual void eraseColorHelper(GrColor color); virtual void forceRenderTargetFlushHelper(); - virtual bool readPixelsHelper(int left, int top, int width, int height, - GrPixelConfig, void* buffer); + virtual bool onReadPixels(GrRenderTarget* target, + int left, int top, int width, int height, + GrPixelConfig, void* buffer); virtual void drawIndexedHelper(GrPrimitiveType type, uint32_t startVertex, @@ -158,7 +158,7 @@ private: void flushAAState(GrPrimitiveType type); void flushBlend(GrPrimitiveType type); - void resolveTextureRenderTarget(GrGLTexture* texture); + void resolveRenderTarget(GrGLRenderTarget* texture); bool canBeTexture(GrPixelConfig config, GrGLenum* internalFormat, |