Add support for GL_EXT_multisampled_render_to_texture.
R=robertphillips@google.com Review URL: https://codereview.chromium.org/14091008 git-svn-id: http://skia.googlecode.com/svn/trunk@8939 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
8fc729f8a2
commit
347c382d58
@ -286,7 +286,7 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
|
||||
fShaderDerivativeSupport = ctxInfo.hasExtension("GL_OES_standard_derivatives");
|
||||
}
|
||||
|
||||
if (GrGLCaps::kImaginationES_MSFBOType == fMSFBOType) {
|
||||
if (GrGLCaps::kES_IMG_MsToTexture_MSFBOType == fMSFBOType) {
|
||||
GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES_IMG, &fMaxSampleCount);
|
||||
} else if (GrGLCaps::kNone_MSFBOType != fMSFBOType) {
|
||||
GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxSampleCount);
|
||||
@ -345,19 +345,21 @@ void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterfa
|
||||
if (ctxInfo.hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
|
||||
// chrome's extension is equivalent to the EXT msaa
|
||||
// and fbo_blit extensions.
|
||||
fMSFBOType = kDesktopEXT_MSFBOType;
|
||||
fMSFBOType = kDesktop_EXT_MSFBOType;
|
||||
} else if (ctxInfo.hasExtension("GL_APPLE_framebuffer_multisample")) {
|
||||
fMSFBOType = kAppleES_MSFBOType;
|
||||
fMSFBOType = kES_Apple_MSFBOType;
|
||||
} else if (ctxInfo.hasExtension("GL_EXT_multisampled_render_to_texture")) {
|
||||
fMSFBOType = kES_EXT_MsToTexture_MSFBOType;
|
||||
} else if (ctxInfo.hasExtension("GL_IMG_multisampled_render_to_texture")) {
|
||||
fMSFBOType = kImaginationES_MSFBOType;
|
||||
fMSFBOType = kES_IMG_MsToTexture_MSFBOType;
|
||||
}
|
||||
} else {
|
||||
if ((ctxInfo.version() >= GR_GL_VER(3,0)) ||
|
||||
ctxInfo.hasExtension("GL_ARB_framebuffer_object")) {
|
||||
fMSFBOType = GrGLCaps::kDesktopARB_MSFBOType;
|
||||
fMSFBOType = GrGLCaps::kDesktop_ARB_MSFBOType;
|
||||
} else if (ctxInfo.hasExtension("GL_EXT_framebuffer_multisample") &&
|
||||
ctxInfo.hasExtension("GL_EXT_framebuffer_blit")) {
|
||||
fMSFBOType = GrGLCaps::kDesktopEXT_MSFBOType;
|
||||
fMSFBOType = GrGLCaps::kDesktop_EXT_MSFBOType;
|
||||
}
|
||||
// TODO: We could populate fMSAACoverageModes using GetInternalformativ
|
||||
// on GL 4.2+. It's format-specific, though. See also
|
||||
@ -520,16 +522,18 @@ void GrGLCaps::print() const {
|
||||
}
|
||||
|
||||
GR_STATIC_ASSERT(0 == kNone_MSFBOType);
|
||||
GR_STATIC_ASSERT(1 == kDesktopARB_MSFBOType);
|
||||
GR_STATIC_ASSERT(2 == kDesktopEXT_MSFBOType);
|
||||
GR_STATIC_ASSERT(3 == kAppleES_MSFBOType);
|
||||
GR_STATIC_ASSERT(4 == kImaginationES_MSFBOType);
|
||||
GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
|
||||
GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
|
||||
GR_STATIC_ASSERT(3 == kES_Apple_MSFBOType);
|
||||
GR_STATIC_ASSERT(4 == kES_IMG_MsToTexture_MSFBOType);
|
||||
GR_STATIC_ASSERT(5 == kES_EXT_MsToTexture_MSFBOType);
|
||||
static const char* gMSFBOExtStr[] = {
|
||||
"None",
|
||||
"ARB",
|
||||
"EXT",
|
||||
"Apple",
|
||||
"IMG",
|
||||
"IMG MS To Texture",
|
||||
"EXT MS To Texture",
|
||||
};
|
||||
GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]);
|
||||
GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
|
||||
|
@ -56,19 +56,27 @@ public:
|
||||
/**
|
||||
* GL3.0-style MSAA FBO (GL_ARB_framebuffer_object)
|
||||
*/
|
||||
kDesktopARB_MSFBOType,
|
||||
kDesktop_ARB_MSFBOType,
|
||||
/**
|
||||
* earlier GL_EXT_framebuffer* extensions
|
||||
*/
|
||||
kDesktopEXT_MSFBOType,
|
||||
kDesktop_EXT_MSFBOType,
|
||||
/**
|
||||
* GL_APPLE_framebuffer_multisample ES extension
|
||||
*/
|
||||
kAppleES_MSFBOType,
|
||||
kES_Apple_MSFBOType,
|
||||
/**
|
||||
* GL_IMG_multisampled_render_to_texture
|
||||
* GL_IMG_multisampled_render_to_texture. This variation does not have MSAA renderbuffers.
|
||||
* Instead the texture is multisampled when bound to the FBO and then resolved automatically
|
||||
* when read. It also defines an alternate value for GL_MAX_SAMPLES (which we call
|
||||
* GR_GL_MAX_SAMPLES_IMG).
|
||||
*/
|
||||
kImaginationES_MSFBOType,
|
||||
kES_IMG_MsToTexture_MSFBOType,
|
||||
/**
|
||||
* GL_EXT_multisampled_render_to_texture. Same as the IMG one above but uses the standard
|
||||
* GL_MAX_SAMPLES value.
|
||||
*/
|
||||
kES_EXT_MsToTexture_MSFBOType,
|
||||
};
|
||||
|
||||
enum CoverageAAType {
|
||||
@ -144,6 +152,24 @@ public:
|
||||
*/
|
||||
MSFBOType msFBOType() const { return fMSFBOType; }
|
||||
|
||||
/**
|
||||
* Does the supported MSAA FBO extension have MSAA renderbuffers?
|
||||
*/
|
||||
bool usesMSAARenderBuffers() const {
|
||||
return kNone_MSFBOType != fMSFBOType &&
|
||||
kES_IMG_MsToTexture_MSFBOType != fMSFBOType &&
|
||||
kES_EXT_MsToTexture_MSFBOType != fMSFBOType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the MSAA FBO extension one where the texture is multisampled when bound to an FBO and
|
||||
* then implicitly resolved when read.
|
||||
*/
|
||||
bool usesImplicitMSAAResolve() const {
|
||||
return kES_IMG_MsToTexture_MSFBOType == fMSFBOType ||
|
||||
kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the type of coverage sample AA support.
|
||||
*/
|
||||
|
@ -333,7 +333,8 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (extensions.has("GL_IMG_multisampled_render_to_texture")) {
|
||||
if (extensions.has("GL_IMG_multisampled_render_to_texture") ||
|
||||
extensions.has("GL_EXT_multisampled_render_to_texture")) {
|
||||
if (NULL == fRenderbufferStorageMultisample ||
|
||||
NULL == fFramebufferTexture2DMultisample) {
|
||||
return false;
|
||||
|
@ -781,6 +781,10 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
|
||||
|
||||
GrGLenum msColorFormat = 0; // suppress warning
|
||||
|
||||
if (desc->fSampleCnt > 0 && GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType()) {
|
||||
goto FAILED;
|
||||
}
|
||||
|
||||
GL_CALL(GenFramebuffers(1, &desc->fTexFBOID));
|
||||
if (!desc->fTexFBOID) {
|
||||
goto FAILED;
|
||||
@ -791,10 +795,7 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
|
||||
// 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;
|
||||
}
|
||||
if (desc->fSampleCnt > 0 && this->glCaps().usesMSAARenderBuffers()) {
|
||||
GL_CALL(GenFramebuffers(1, &desc->fRTFBOID));
|
||||
GL_CALL(GenRenderbuffers(1, &desc->fMSColorRenderbufferID));
|
||||
if (!desc->fRTFBOID ||
|
||||
@ -802,7 +803,9 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
|
||||
!this->configToGLFormats(desc->fConfig,
|
||||
// GLES requires sized internal formats
|
||||
kES2_GrGLBinding == this->glBinding(),
|
||||
&msColorFormat, NULL, NULL)) {
|
||||
&msColorFormat,
|
||||
NULL,
|
||||
NULL)) {
|
||||
goto FAILED;
|
||||
}
|
||||
} else {
|
||||
@ -836,7 +839,7 @@ bool GrGpuGL::createRenderTargetObjects(int width, int height,
|
||||
}
|
||||
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, desc->fTexFBOID));
|
||||
|
||||
if (GrGLCaps::kImaginationES_MSFBOType == this->glCaps().msFBOType() && desc->fSampleCnt > 0) {
|
||||
if (this->glCaps().usesImplicitMSAAResolve() && desc->fSampleCnt > 0) {
|
||||
GL_CALL(FramebufferTexture2DMultisample(GR_GL_FRAMEBUFFER,
|
||||
GR_GL_COLOR_ATTACHMENT0,
|
||||
GR_GL_TEXTURE_2D,
|
||||
@ -1681,9 +1684,8 @@ void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) {
|
||||
void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
|
||||
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
|
||||
if (rt->needsResolve()) {
|
||||
// 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());
|
||||
// Some extensions automatically resolves the texture when it is read.
|
||||
if (this->glCaps().usesMSAARenderBuffers()) {
|
||||
GrAssert(rt->textureFBOID() != rt->renderFBOID());
|
||||
GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, rt->renderFBOID()));
|
||||
GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID()));
|
||||
@ -1697,7 +1699,7 @@ void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
|
||||
dirtyRect.width(), dirtyRect.height(), target->origin());
|
||||
|
||||
GrAutoTRestore<ScissorState> asr;
|
||||
if (GrGLCaps::kAppleES_MSFBOType == this->glCaps().msFBOType()) {
|
||||
if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
|
||||
// Apple's extension uses the scissor as the blit bounds.
|
||||
asr.reset(&fScissorState);
|
||||
fScissorState.fEnabled = true;
|
||||
@ -1705,9 +1707,8 @@ void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
|
||||
this->flushScissor();
|
||||
GL_CALL(ResolveMultisampleFramebuffer());
|
||||
} else {
|
||||
if (GrGLCaps::kDesktopARB_MSFBOType != this->glCaps().msFBOType()) {
|
||||
if (GrGLCaps::kDesktop_EXT_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();
|
||||
@ -2233,9 +2234,9 @@ inline bool can_blit_framebuffer(const GrSurface* dst,
|
||||
const GrSurface* src,
|
||||
const GrGpuGL* gpu,
|
||||
bool* wouldNeedTempFBO = NULL) {
|
||||
if (gpu->isConfigRenderable(dst->config()) && gpu->isConfigRenderable(src->config()) &&
|
||||
(GrGLCaps::kDesktopEXT_MSFBOType == gpu->glCaps().msFBOType() ||
|
||||
GrGLCaps::kDesktopARB_MSFBOType == gpu->glCaps().msFBOType())) {
|
||||
if (gpu->isConfigRenderable(dst->config()) &&
|
||||
gpu->isConfigRenderable(src->config()) &&
|
||||
gpu->glCaps().usesMSAARenderBuffers()) {
|
||||
if (NULL != wouldNeedTempFBO) {
|
||||
*wouldNeedTempFBO = NULL == dst->asRenderTarget() || NULL == src->asRenderTarget();
|
||||
}
|
||||
@ -2411,7 +2412,7 @@ bool GrGpuGL::onCopySurface(GrSurface* dst,
|
||||
dst->origin());
|
||||
|
||||
GrAutoTRestore<ScissorState> asr;
|
||||
if (GrGLCaps::kDesktopEXT_MSFBOType == this->glCaps().msFBOType()) {
|
||||
if (GrGLCaps::kDesktop_EXT_MSFBOType == this->glCaps().msFBOType()) {
|
||||
// The EXT version applies the scissor during the blit, so disable it.
|
||||
asr.reset(&fScissorState);
|
||||
fScissorState.fEnabled = false;
|
||||
|
@ -4,6 +4,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "gl/GrGLExtensions.h"
|
||||
#include "gl/GrGLInterface.h"
|
||||
|
||||
#ifndef GL_GLEXT_PROTOTYPES
|
||||
@ -18,6 +19,10 @@
|
||||
const GrGLInterface* GrGLCreateNativeInterface() {
|
||||
static SkAutoTUnref<GrGLInterface> glInterface;
|
||||
if (!glInterface.get()) {
|
||||
GrGLExtensions extensions;
|
||||
if (!extensions.init(kES2_GrGLBinding, glGetString, NULL, glGetIntegerv)) {
|
||||
return NULL;
|
||||
}
|
||||
GrGLInterface* interface = new GrGLInterface;
|
||||
glInterface.reset(interface);
|
||||
interface->fBindingsExported = kES2_GrGLBinding;
|
||||
@ -128,10 +133,23 @@ 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;
|
||||
if (extensions.has("GL_EXT_multisampled_render_to_texture")) {
|
||||
#if GL_EXT_multisampled_render_to_texture
|
||||
interface->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleEXT;
|
||||
interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT;
|
||||
#else
|
||||
interface->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleEXT");
|
||||
interface->fRenderbufferStorageMultisample = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleEXT");
|
||||
#endif
|
||||
} else if (extensions.has("GL_IMG_multisampled_render_to_texture")) {
|
||||
#if GL_IMG_multisampled_render_to_texture
|
||||
interface->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleIMG;
|
||||
interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleIMG;
|
||||
#else
|
||||
interface->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleIMG");
|
||||
interface->fRenderbufferStorageMultisample = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleIMG");
|
||||
#endif
|
||||
}
|
||||
interface->fGenFramebuffers = glGenFramebuffers;
|
||||
interface->fGenRenderbuffers = glGenRenderbuffers;
|
||||
interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
|
||||
|
Loading…
Reference in New Issue
Block a user