aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-01-31 13:35:56 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-01-31 13:35:56 +0000
commit75f9f25d8bf2adc0494f9afbbd5965809ee13aca (patch)
treeac1c54a28cbc3a8e1b6cc6bbf2ae6b148aa1b87d
parent75942098c500904edd0b52a56d344a63f5814631 (diff)
Add code path for Gr client to resolve an Gr-created MSAA render target.
Review URL: http://codereview.appspot.com/5580049/ git-svn-id: http://skia.googlecode.com/svn/trunk@3112 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/gpu/GrContext.h14
-rw-r--r--include/gpu/GrRenderTarget.h8
-rw-r--r--src/gpu/GrContext.cpp10
-rw-r--r--src/gpu/GrGpu.cpp7
-rw-r--r--src/gpu/GrGpu.h8
-rw-r--r--src/gpu/GrGpuGL.cpp8
-rw-r--r--src/gpu/GrGpuGL.h6
-rw-r--r--src/gpu/GrRenderTarget.cpp9
-rw-r--r--src/gpu/SkGpuDevice.cpp2
9 files changed, 66 insertions, 6 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index ca440a6243..3fb47750cf 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -562,6 +562,20 @@ public:
* @param dst the render target to copy to.
*/
void copyTexture(GrTexture* src, GrRenderTarget* dst);
+
+ /**
+ * Resolves a render target that has MSAA. The intermediate MSAA buffer is
+ * downsampled to the associated GrTexture (accessible via
+ * GrRenderTarget::asTexture()). Any pending draws to the render target will
+ * be executed before the resolve.
+ *
+ * This is only necessary when a client wants to access the object directly
+ * using the underlying graphics API. GrContext will detect when it must
+ * perform a resolve to a GrTexture used as the source of a draw or before
+ * reading pixels back from a GrTexture or GrRenderTarget.
+ */
+ void resolveRenderTarget(GrRenderTarget* target);
+
/**
* Applies a 1D convolution kernel in the X direction to a rectangle of
* pixels from a given texture.
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index 13b2160f79..909adb3e7d 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -112,6 +112,14 @@ public:
*/
const GrIRect& getResolveRect() const { return fResolveRect; }
+ /**
+ * If the render target is multisampled this will perform a multisample
+ * resolve. Any pending draws to the target are first flushed. This only
+ * applies to render targets that are associated with GrTextures. After the
+ * function returns the GrTexture will contain the resolved pixels.
+ */
+ void resolve();
+
// GrResource overrides
virtual size_t sizeInBytes() const;
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 1e87cab35e..dd1b276806 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -1900,6 +1900,16 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target,
config, buffer, rowBytes, flipY);
}
+void GrContext::resolveRenderTarget(GrRenderTarget* target) {
+ GrAssert(target);
+ ASSERT_OWNED_RESOURCE(target);
+ // In the future we may track whether there are any pending draws to this
+ // target. We don't today so we always perform a flush. We don't promise
+ // this to our clients, though.
+ this->flush();
+ fGpu->resolveRenderTarget(target);
+}
+
void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) {
if (NULL == src || NULL == dst) {
return;
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 27a4497e7b..39960de054 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -260,6 +260,13 @@ void GrGpu::writeTexturePixels(GrTexture* texture,
config, buffer, rowBytes);
}
+void GrGpu::resolveRenderTarget(GrRenderTarget* target) {
+ GrAssert(target);
+ this->handleDirtyContext();
+ this->onResolveRenderTarget(target);
+}
+
+
////////////////////////////////////////////////////////////////////////////////
static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 8c23daa2f0..e617efb8e4 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -172,6 +172,11 @@ public:
const GrVertexBuffer* getUnitSquareVertexBuffer() const;
/**
+ * Resolves MSAA.
+ */
+ void resolveRenderTarget(GrRenderTarget* target);
+
+ /**
* Ensures that the current render target is actually set in the
* underlying 3D API. Used when client wants to use 3D API to directly
* render to the RT.
@@ -433,6 +438,9 @@ protected:
GrPixelConfig config, const void* buffer,
size_t rowBytes) = 0;
+ // overridden by API-specific derived class to perform the resolve
+ virtual void onResolveRenderTarget(GrRenderTarget* target) = 0;
+
// called to program the vertex data, indexCount will be 0 if drawing non-
// indexed geometry. The subclass may adjust the startVertex and/or
// startIndex since it may have already accounted for these in the setup.
diff --git a/src/gpu/GrGpuGL.cpp b/src/gpu/GrGpuGL.cpp
index a4a49ac59b..70d28d6785 100644
--- a/src/gpu/GrGpuGL.cpp
+++ b/src/gpu/GrGpuGL.cpp
@@ -1452,7 +1452,7 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
this->flushRenderTarget(&GrIRect::EmptyIRect());
break;
case GrGLRenderTarget::kCanResolve_ResolveType:
- this->resolveRenderTarget(tgt);
+ this->onResolveRenderTarget(tgt);
// we don't track the state of the READ FBO ID.
GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
tgt->textureFBOID()));
@@ -1666,7 +1666,9 @@ void GrGpuGL::onGpuDrawNonIndexed(GrPrimitiveType type,
#endif
}
-void GrGpuGL::resolveRenderTarget(GrGLRenderTarget* rt) {
+void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
+
+ GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
if (rt->needsResolve()) {
GrAssert(GLCaps::kNone_MSFBO != fGLCaps.fMSFBOType);
@@ -2050,7 +2052,7 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
GrGLRenderTarget* texRT =
static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget());
if (NULL != texRT) {
- resolveRenderTarget(texRT);
+ this->onResolveRenderTarget(texRT);
}
if (fHWDrawState.getTexture(s) != nextTexture) {
diff --git a/src/gpu/GrGpuGL.h b/src/gpu/GrGpuGL.h
index 3196c89c47..6ac48090c1 100644
--- a/src/gpu/GrGpuGL.h
+++ b/src/gpu/GrGpuGL.h
@@ -41,6 +41,7 @@ public:
GrPixelConfig config,
size_t rowBytes) const SK_OVERRIDE;
virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
+
protected:
GrGpuGL(const GrGLInterface* glInterface, GrGLBinding glBinding);
@@ -193,6 +194,9 @@ protected:
GrPixelConfig config, const void* buffer,
size_t rowBytes) SK_OVERRIDE;
+ virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE;
+
+
virtual void onGpuDrawIndexed(GrPrimitiveType type,
uint32_t startVertex,
uint32_t startIndex,
@@ -276,8 +280,6 @@ private:
void flushStencil();
void flushAAState(GrPrimitiveType type);
- void resolveRenderTarget(GrGLRenderTarget* texture);
-
bool configToGLFormats(GrPixelConfig config,
bool getSizedInternal,
GrGLenum* internalFormat,
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index 7901648d3a..ed1a018a02 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -41,6 +41,15 @@ void GrRenderTarget::writePixels(int left, int top, int width, int height,
config, buffer, rowBytes);
}
+void GrRenderTarget::resolve() {
+ // go through context so that all necessary flushing occurs
+ GrContext* context = this->getContext();
+ if (NULL == context) {
+ return;
+ }
+ context->resolveRenderTarget(this);
+}
+
size_t GrRenderTarget::sizeInBytes() const {
int colorBits;
if (kUnknown_GrPixelConfig == fConfig) {
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index d34ef6a194..da97fde820 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1769,7 +1769,7 @@ bool SkGpuDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
}
void SkGpuDevice::flush() {
- fContext->flush(false);
+ fContext->resolveRenderTarget(fRenderTarget);
}
///////////////////////////////////////////////////////////////////////////////