From ac3ba026a45ae1e21c213cc1d9a920266378e448 Mon Sep 17 00:00:00 2001 From: Joe Drew Date: Thu, 11 Nov 2010 15:31:23 -0500 Subject: [PATCH] Bug 575521 - Use gfxASurface::GetAsImageSurface in TextureImageCGL to make it faster. r=jrmuizel --- gfx/thebes/GLContext.cpp | 11 +++++++++++ gfx/thebes/GLContextProviderCGL.mm | 27 ++++++++++++++++++--------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/gfx/thebes/GLContext.cpp b/gfx/thebes/GLContext.cpp index 9a8d8b415c6b..c22b9af3377f 100644 --- a/gfx/thebes/GLContext.cpp +++ b/gfx/thebes/GLContext.cpp @@ -564,6 +564,13 @@ BasicTextureImage::EndUpdate() return PR_FALSE; mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture); + + // The images that come out of the cairo quartz surface are 16-byte aligned + // for performance. We know this is an RGBA surface, so we divide the + // stride by 4 to represent the number of elements long the row is. + mGLContext->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, + uploadImage->Stride() / 4); + if (!mTextureInited) { mGLContext->fTexImage2D(LOCAL_GL_TEXTURE_2D, @@ -588,6 +595,10 @@ BasicTextureImage::EndUpdate() uploadImage->Data()); } mUpdateContext = NULL; + + // Reset row length to use the default. + mGLContext->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0); + return PR_TRUE; // mTexture is bound } diff --git a/gfx/thebes/GLContextProviderCGL.mm b/gfx/thebes/GLContextProviderCGL.mm index 0f92eace85c0..c0a87147a893 100644 --- a/gfx/thebes/GLContextProviderCGL.mm +++ b/gfx/thebes/GLContextProviderCGL.mm @@ -42,6 +42,7 @@ #include #include "gfxASurface.h" #include "gfxImageSurface.h" +#include "gfxQuartzSurface.h" #include "gfxPlatform.h" namespace mozilla { @@ -281,16 +282,24 @@ protected: virtual already_AddRefed GetImageForUpload(gfxASurface* aUpdateSurface) { - // FIXME/bug 575521: make me fast! - nsRefPtr image = - new gfxImageSurface(gfxIntSize(mUpdateRect.width, - mUpdateRect.height), - mUpdateFormat); - nsRefPtr tmpContext = new gfxContext(image); + nsRefPtr image = aUpdateSurface->GetAsImageSurface(); - tmpContext->SetSource(aUpdateSurface); - tmpContext->SetOperator(gfxContext::OPERATOR_SOURCE); - tmpContext->Paint(); + if (image && image->Format() != mUpdateFormat) { + image = nsnull; + } + + // If we don't get an image directly from the quartz surface, we have + // to take the slow boat. + if (!image) { + image = new gfxImageSurface(gfxIntSize(mUpdateRect.width, + mUpdateRect.height), + mUpdateFormat); + nsRefPtr tmpContext = new gfxContext(image); + + tmpContext->SetSource(aUpdateSurface); + tmpContext->SetOperator(gfxContext::OPERATOR_SOURCE); + tmpContext->Paint(); + } return image.forget(); }