aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-04-11 17:58:48 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-04-11 17:58:48 +0000
commit5877ffd5ea71a3ea70096d5c11c843798defa690 (patch)
treee9c898ced0fdd91487cd265618db1be03f920844 /gpu/src
parentafac88855a31bea16143028f51935d00be177dc6 (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.cpp26
-rw-r--r--gpu/src/GrGLTexture.cpp3
-rw-r--r--gpu/src/GrGpu.cpp12
-rw-r--r--gpu/src/GrGpuGL.cpp135
-rw-r--r--gpu/src/GrGpuGL.h10
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,