зеркало из https://github.com/mozilla/gecko-dev.git
Bug 715232: Don't attempt to CopyTexImage from an RGB framebuffer to an RGBA texture. r=joedrew
This commit is contained in:
Родитель
a7cc927633
Коммит
c8932ced3b
|
@ -214,6 +214,7 @@ ContainerRender(Container* aContainer,
|
|||
framebufferRect -= childOffset;
|
||||
aManager->CreateFBOWithTexture(framebufferRect,
|
||||
mode,
|
||||
aPreviousFrameBuffer,
|
||||
&frameBuffer,
|
||||
&containerSurface);
|
||||
childOffset.x = visibleRect.x;
|
||||
|
|
|
@ -1132,8 +1132,33 @@ LayerManagerOGL::SetLayerProgramProjectionMatrix(const gfx3DMatrix& aMatrix)
|
|||
} FOR_EACH_LAYER_PROGRAM_END
|
||||
}
|
||||
|
||||
static GLenum
|
||||
GetFrameBufferInternalFormat(GLContext* gl,
|
||||
GLuint aCurrentFrameBuffer,
|
||||
nsIWidget* aWidget)
|
||||
{
|
||||
if (aCurrentFrameBuffer == 0) { // default framebuffer
|
||||
return aWidget->GetGLFrameBufferFormat();
|
||||
}
|
||||
return LOCAL_GL_RGBA;
|
||||
}
|
||||
|
||||
static bool
|
||||
AreFormatsCompatibleForCopyTexImage2D(GLenum aF1, GLenum aF2)
|
||||
{
|
||||
// GL requires that the implementation has to handle copies between
|
||||
// different formats, so all are "compatible". GLES does not
|
||||
// require that.
|
||||
#ifdef USE_GLES2
|
||||
return (aF1 == aF2);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerOGL::CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
|
||||
GLuint aCurrentFrameBuffer,
|
||||
GLuint *aFBO, GLuint *aTexture)
|
||||
{
|
||||
GLuint tex, fbo;
|
||||
|
@ -1142,12 +1167,40 @@ LayerManagerOGL::CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
|
|||
mGLContext->fGenTextures(1, &tex);
|
||||
mGLContext->fBindTexture(mFBOTextureTarget, tex);
|
||||
if (aInit == InitModeCopy) {
|
||||
mGLContext->fCopyTexImage2D(mFBOTextureTarget,
|
||||
0,
|
||||
LOCAL_GL_RGBA,
|
||||
aRect.x, aRect.y,
|
||||
aRect.width, aRect.height,
|
||||
0);
|
||||
// We're going to create an RGBA temporary fbo. But to
|
||||
// CopyTexImage() from the current framebuffer, the framebuffer's
|
||||
// format has to be compatible with the new texture's. So we
|
||||
// check the format of the framebuffer here and take a slow path
|
||||
// if it's incompatible.
|
||||
GLenum format =
|
||||
GetFrameBufferInternalFormat(gl(), aCurrentFrameBuffer, mWidget);
|
||||
if (AreFormatsCompatibleForCopyTexImage2D(format, LOCAL_GL_RGBA)) {
|
||||
mGLContext->fCopyTexImage2D(mFBOTextureTarget,
|
||||
0,
|
||||
LOCAL_GL_RGBA,
|
||||
aRect.x, aRect.y,
|
||||
aRect.width, aRect.height,
|
||||
0);
|
||||
} else {
|
||||
// Curses, incompatible formats. Take a slow path.
|
||||
//
|
||||
// XXX Technically CopyTexSubImage2D also has the requirement of
|
||||
// matching formats, but it doesn't seem to affect us in the
|
||||
// real world.
|
||||
mGLContext->fTexImage2D(mFBOTextureTarget,
|
||||
0,
|
||||
LOCAL_GL_RGBA,
|
||||
aRect.width, aRect.height,
|
||||
0,
|
||||
LOCAL_GL_RGBA,
|
||||
LOCAL_GL_UNSIGNED_BYTE,
|
||||
NULL);
|
||||
mGLContext->fCopyTexSubImage2D(mFBOTextureTarget,
|
||||
0, // level
|
||||
0, 0, // offset
|
||||
aRect.x, aRect.y,
|
||||
aRect.width, aRect.height);
|
||||
}
|
||||
} else {
|
||||
mGLContext->fTexImage2D(mFBOTextureTarget,
|
||||
0,
|
||||
|
|
|
@ -308,6 +308,7 @@ public:
|
|||
* texture types.
|
||||
*/
|
||||
void CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
|
||||
GLuint aCurrentFrameBuffer,
|
||||
GLuint *aFBO, GLuint *aTexture);
|
||||
|
||||
GLuint QuadVBO() { return mQuadVBO; }
|
||||
|
|
|
@ -449,3 +449,15 @@ nsWindow::UserActivity()
|
|||
mIdleService->ResetIdleTimeOut();
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsWindow::GetGLFrameBufferFormat()
|
||||
{
|
||||
if (mLayerManager &&
|
||||
mLayerManager->GetBackendType() == LayerManager::LAYERS_OPENGL) {
|
||||
// We directly map the hardware fb on Gonk. The hardware fb
|
||||
// has RGB format.
|
||||
return LOCAL_GL_RGB;
|
||||
}
|
||||
return LOCAL_GL_NONE;
|
||||
}
|
||||
|
|
|
@ -126,6 +126,8 @@ public:
|
|||
const InputContextAction& aAction);
|
||||
NS_IMETHOD_(InputContext) GetInputContext();
|
||||
|
||||
virtual PRUint32 GetGLFrameBufferFormat() MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
nsWindow* mParent;
|
||||
bool mVisible;
|
||||
|
|
|
@ -1510,6 +1510,12 @@ class nsIWidget : public nsISupports {
|
|||
* parent widget
|
||||
*/
|
||||
NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) = 0;
|
||||
|
||||
/**
|
||||
* Return the internal format of the default framebuffer for this
|
||||
* widget.
|
||||
*/
|
||||
virtual PRUint32 GetGLFrameBufferFormat() { return 0; /*GL_NONE*/ }
|
||||
protected:
|
||||
|
||||
// keep the list of children. We also keep track of our siblings.
|
||||
|
|
|
@ -1259,6 +1259,18 @@ nsBaseWidget::BeginMoveDrag(nsMouseEvent* aEvent)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsBaseWidget::GetGLFrameBufferFormat()
|
||||
{
|
||||
if (mLayerManager &&
|
||||
mLayerManager->GetBackendType() == LayerManager::LAYERS_OPENGL) {
|
||||
// Assume that the default framebuffer has RGBA format. Specific
|
||||
// backends that know differently will override this method.
|
||||
return LOCAL_GL_RGBA;
|
||||
}
|
||||
return LOCAL_GL_NONE;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
|
@ -201,6 +201,9 @@ public:
|
|||
}
|
||||
|
||||
NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) = 0;
|
||||
|
||||
virtual PRUint32 GetGLFrameBufferFormat() MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Use this when GetLayerManager() returns a BasicLayerManager
|
||||
* (nsBaseWidget::GetLayerManager() does). This sets up the widget's
|
||||
|
|
Загрузка…
Ссылка в новой задаче