aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-19 19:06:09 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-19 19:06:09 +0000
commitf3a60c09b975f50bbd14215df10effffd2fd46e8 (patch)
treecbe688acf9cdecd769c92a7f3fbe860eb399711b /src/gpu
parent4c75f241cb75f202cfa51569ba8dc4749a28a9f7 (diff)
Add support for IMG's MSAA extension.
Review URL: https://codereview.chromium.org/12875005 git-svn-id: http://skia.googlecode.com/svn/trunk@8241 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/gl/GrGLCaps.cpp4
-rw-r--r--src/gpu/gl/GrGLCaps.h4
-rw-r--r--src/gpu/gl/GrGLDefines.h2
-rw-r--r--src/gpu/gl/GrGLInterface.cpp6
-rw-r--r--src/gpu/gl/GrGpuGL.cpp131
-rw-r--r--src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp4
6 files changed, 88 insertions, 63 deletions
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 04c2c3c720..a115b5d12e 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -251,6 +251,8 @@ void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterfa
fMSFBOType = kDesktopEXT_MSFBOType;
} else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
fMSFBOType = kAppleES_MSFBOType;
+ } else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
+ fMSFBOType = kImaginationES_MSFBOType;
}
} else {
if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
@@ -420,11 +422,13 @@ void GrGLCaps::print() const {
GR_STATIC_ASSERT(1 == kDesktopARB_MSFBOType);
GR_STATIC_ASSERT(2 == kDesktopEXT_MSFBOType);
GR_STATIC_ASSERT(3 == kAppleES_MSFBOType);
+ GR_STATIC_ASSERT(4 == kImaginationES_MSFBOType);
static const char* gMSFBOExtStr[] = {
"None",
"ARB",
"EXT",
"Apple",
+ "IMG",
};
GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]);
GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 2ecfb85840..83f4650c97 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -62,6 +62,10 @@ public:
* GL_APPLE_framebuffer_multisample ES extension
*/
kAppleES_MSFBOType,
+ /**
+ * GL_IMG_multisampled_render_to_texture
+ */
+ kImaginationES_MSFBOType,
};
enum CoverageAAType {
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index e0e8398795..2ab9570818 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -658,6 +658,8 @@
#define GR_GL_DEPTH24_STENCIL8 0x88F0
#define GR_GL_MAX_SAMPLES 0x8D57
+// GL_IMG_multisampled_render_to_texture uses a different value for GL_MAX_SAMPLES
+#define GR_GL_MAX_SAMPLES_IMG 0x9135
#define GR_GL_RENDERBUFFER_WIDTH 0x8D42
#define GR_GL_RENDERBUFFER_HEIGHT 0x8D43
diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp
index 0119a1e760..0c6bd8604d 100644
--- a/src/gpu/gl/GrGLInterface.cpp
+++ b/src/gpu/gl/GrGLInterface.cpp
@@ -323,6 +323,12 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
return false;
}
}
+ if (extensions.has("GL_IMG_multisampled_render_to_texture")) {
+ if (NULL == fRenderbufferStorageMultisample ||
+ NULL == fFramebufferTexture2DMultisample) {
+ return false;
+ }
+ }
}
// On ES buffer mapping is an extension. On Desktop
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 8882934459..e202a14e40 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -285,11 +285,12 @@ void GrGpuGL::initCaps() {
caps->fGeometryShaderSupport = this->glVersion() >= GR_GL_VER(3,2) &&
this->glslGeneration() >= k150_GrGLSLGeneration;
} else {
- caps->fShaderDerivativeSupport =
- this->hasExtension("GL_OES_standard_derivatives");
+ caps->fShaderDerivativeSupport = this->hasExtension("GL_OES_standard_derivatives");
}
- if (GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType()) {
+ if (GrGLCaps::kImaginationES_MSFBOType == this->glCaps().msFBOType()) {
+ GR_GL_GetIntegerv(this->glInterface(), GR_GL_MAX_SAMPLES_IMG, &caps->fMaxSampleCount);
+ } else if (GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType()) {
GR_GL_GetIntegerv(this->glInterface(), GR_GL_MAX_SAMPLES, &caps->fMaxSampleCount);
}
}
@@ -879,9 +880,11 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
}
- // If we are using multisampling we will create two FBOS. We render
- // to one and then resolve to the texture bound to the other.
- if (desc->fSampleCnt > 0) {
+ // If we are using multisampling we will create two FBOS. We render to one and then resolve to
+ // the texture bound to the other. The exception is the IMG multisample extension. With this
+ // extension the texture is multisampled when rendered to and then auto-resolves it when it is
+ // rendered from.
+ if (desc->fSampleCnt > 0 && GrGLCaps::kImaginationES_MSFBOType != this->glCaps().msFBOType()) {
if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
goto FAILED;
}
@@ -921,16 +924,22 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
goto FAILED;
}
- fGLContext.info().caps().markConfigAsValidColorAttachment(
- desc->fConfig);
+ fGLContext.info().caps().markConfigAsValidColorAttachment(desc->fConfig);
}
}
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID));
- GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
- GR_GL_COLOR_ATTACHMENT0,
- GR_GL_TEXTURE_2D,
- texID, 0));
+ if (GrGLCaps::kImaginationES_MSFBOType == this->glCaps().msFBOType() && desc->fSampleCnt > 0) {
+ GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
+ GR_GL_COLOR_ATTACHMENT0,
+ GR_GL_TEXTURE_2D,
+ texID, 0, desc->fSampleCnt));
+ } else {
+ GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER,
+ GR_GL_COLOR_ATTACHMENT0,
+ GR_GL_TEXTURE_2D,
+ texID, 0));
+ }
if (!this->glCaps().isConfigVerifiedColorAttachment(desc->fConfig)) {
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
@@ -1172,8 +1181,7 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
return false;
}
-bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
- GrRenderTarget* rt) {
+bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb, GrRenderTarget* rt) {
GrGLRenderTarget* glrt = (GrGLRenderTarget*) rt;
GrGLuint fbo = glrt->renderFBOID();
@@ -1181,11 +1189,11 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
if (NULL == sb) {
if (NULL != rt->getStencilBuffer()) {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_STENCIL_ATTACHMENT,
- GR_GL_RENDERBUFFER, 0));
+ GR_GL_STENCIL_ATTACHMENT,
+ GR_GL_RENDERBUFFER, 0));
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_DEPTH_ATTACHMENT,
- GR_GL_RENDERBUFFER, 0));
+ GR_GL_DEPTH_ATTACHMENT,
+ GR_GL_RENDERBUFFER, 0));
#if GR_DEBUG
GrGLenum status;
GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
@@ -1194,27 +1202,26 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
}
return true;
} else {
- GrGLStencilBuffer* glsb = (GrGLStencilBuffer*) sb;
+ GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb);
GrGLuint rb = glsb->renderbufferID();
fHWBoundRenderTarget = NULL;
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo));
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_STENCIL_ATTACHMENT,
- GR_GL_RENDERBUFFER, rb));
+ GR_GL_STENCIL_ATTACHMENT,
+ GR_GL_RENDERBUFFER, rb));
if (glsb->format().fPacked) {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_DEPTH_ATTACHMENT,
- GR_GL_RENDERBUFFER, rb));
+ GR_GL_DEPTH_ATTACHMENT,
+ GR_GL_RENDERBUFFER, rb));
} else {
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
- GR_GL_DEPTH_ATTACHMENT,
- GR_GL_RENDERBUFFER, 0));
+ GR_GL_DEPTH_ATTACHMENT,
+ GR_GL_RENDERBUFFER, 0));
}
GrGLenum status;
- if (!this->glCaps().isColorConfigAndStencilFormatVerified(rt->config(),
- glsb->format())) {
+ 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,
@@ -1767,47 +1774,45 @@ void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) {
}
void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
-
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
-
if (rt->needsResolve()) {
- GrAssert(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType());
- GrAssert(rt->textureFBOID() != rt->renderFBOID());
- GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER,
- rt->renderFBOID()));
- GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER,
- rt->textureFBOID()));
- // make sure we go through flushRenderTarget() since we've modified
- // the bound DRAW FBO ID.
- fHWBoundRenderTarget = NULL;
- const GrGLIRect& vp = rt->getViewport();
- const GrIRect dirtyRect = rt->getResolveRect();
- GrGLIRect r;
- r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
- dirtyRect.width(), dirtyRect.height(), target->origin());
-
- GrAutoTRestore<ScissorState> asr;
- if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) {
- // Apple's extension uses the scissor as the blit bounds.
- asr.reset(&fScissorState);
- fScissorState.fEnabled = true;
- fScissorState.fRect = dirtyRect;
- this->flushScissor();
- GL_CALL(ResolveMultisampleFramebuffer());
- } else {
- if (GrGLCaps::kDesktopARB_MSFBOType != this->glCaps().msFBOType()) {
- // this respects the scissor during the blit, so disable it.
- GrAssert(GrGLCaps::kDesktopEXT_MSFBOType ==
- this->glCaps().msFBOType());
+ // The IMG extension automatically resolves the texture when it is read.
+ if (GrGLCaps::kImaginationES_MSFBOType != this->glCaps().msFBOType()) {
+ GrAssert(GrGLCaps::kNone_MSFBOType != this->glCaps().msFBOType());
+ GrAssert(rt->textureFBOID() != rt->renderFBOID());
+ GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
+ GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()));
+ // make sure we go through flushRenderTarget() since we've modified
+ // the bound DRAW FBO ID.
+ fHWBoundRenderTarget = NULL;
+ const GrGLIRect& vp = rt->getViewport();
+ const GrIRect dirtyRect = rt->getResolveRect();
+ GrGLIRect r;
+ r.setRelativeTo(vp, dirtyRect.fLeft, dirtyRect.fTop,
+ dirtyRect.width(), dirtyRect.height(), target->origin());
+
+ GrAutoTRestore<ScissorState> asr;
+ if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) {
+ // Apple's extension uses the scissor as the blit bounds.
asr.reset(&fScissorState);
- fScissorState.fEnabled = false;
+ fScissorState.fEnabled = true;
+ fScissorState.fRect = dirtyRect;
this->flushScissor();
+ GL_CALL(ResolveMultisampleFramebuffer());
+ } else {
+ if (GrGLCaps::kDesktopARB_MSFBOType != this->glCaps().msFBOType()) {
+ // this respects the scissor during the blit, so disable it.
+ GrAssert(GrGLCaps::kDesktopEXT_MSFBOType == this->glCaps().msFBOType());
+ asr.reset(&fScissorState);
+ fScissorState.fEnabled = false;
+ this->flushScissor();
+ }
+ int right = r.fLeft + r.fWidth;
+ int top = r.fBottom + r.fHeight;
+ GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top,
+ r.fLeft, r.fBottom, right, top,
+ GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
}
- int right = r.fLeft + r.fWidth;
- int top = r.fBottom + r.fHeight;
- GL_CALL(BlitFramebuffer(r.fLeft, r.fBottom, right, top,
- r.fLeft, r.fBottom, right, top,
- GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST));
}
rt->flagAsResolved();
}
diff --git a/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp b/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp
index 6fa9053cb8..6f81cab41c 100644
--- a/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp
+++ b/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp
@@ -124,6 +124,10 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fDeleteRenderbuffers = glDeleteRenderbuffers;
interface->fFramebufferRenderbuffer = glFramebufferRenderbuffer;
interface->fFramebufferTexture2D = glFramebufferTexture2D;
+#if GL_IMG_multisampled_render_to_texture
+ interface->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleIMG;
+ interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleIMG;
+#endif
interface->fGenFramebuffers = glGenFramebuffers;
interface->fGenRenderbuffers = glGenRenderbuffers;
interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;