Bug 604101 - Part 4 - Use UploadSurfaceToTexture in TextureImage. r=joe a=blocking2.0

This commit is contained in:
Matt Woodrow 2010-12-16 23:29:23 -08:00
Родитель 8bcd4fedaf
Коммит 8ff0e949d1
9 изменённых файлов: 60 добавлений и 165 удалений

Просмотреть файл

@ -331,8 +331,7 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexImage->Texture());
ColorTextureLayerProgram *program =
mOGLManager->GetBasicLayerProgram(CanUseOpaqueSurface(),
mTexImage->IsRGB());
mOGLManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
ApplyFilter(mFilter);

Просмотреть файл

@ -781,8 +781,7 @@ ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer,
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexImage->Texture());
ColorTextureLayerProgram *program =
mOGLManager->GetBasicLayerProgram(CanUseOpaqueSurface(),
mTexImage->IsRGB());
mOGLManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
ApplyFilter(mFilter);

Просмотреть файл

@ -181,18 +181,17 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
if (!mTexImage)
return;
// Note BGR: Cairo's image surfaces are always in what
// OpenGL and our shaders consider BGR format.
ColorTextureLayerProgram *program =
aManager->GetBasicLayerProgram(mLayer->CanUseOpaqueSurface(),
mTexImage->IsRGB());
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
if (!mTexImage->InUpdate() || !mTexImage->EndUpdate()) {
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexImage->Texture());
}
// Note BGR: Cairo's image surfaces are always in what
// OpenGL and our shaders consider BGR format.
ColorTextureLayerProgram *program =
aManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
float xres = mLayer->GetXResolution();
float yres = mLayer->GetYResolution();

Просмотреть файл

@ -536,8 +536,6 @@ BasicTextureImage::~BasicTextureImage()
mGLContext->MakeCurrent();
mGLContext->fDeleteTextures(1, &mTexture);
}
mBackingSurface = nsnull;
}
gfxContext*
@ -549,20 +547,12 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
ImageFormat format =
(GetContentType() == gfxASurface::CONTENT_COLOR) ?
gfxASurface::ImageFormatRGB24 : gfxASurface::ImageFormatARGB32;
PRBool repaintEverything = PR_FALSE;
if (mGLContext->IsExtensionSupported(gl::GLContext::APPLE_client_storage)) {
repaintEverything =
!(mBackingSurface &&
mBackingSurface->GetSize() == gfxIntSize(mSize.width, mSize.height) &&
mBackingSurface->Format() == format);
}
if (!mTextureInited || repaintEverything)
if (!mTextureInited)
{
// if the texture hasn't been initialized yet, or something important
// changed, we need to recreate our backing surface and force the
// client to paint everything
mUpdateRect = nsIntRect(nsIntPoint(0, 0), mSize);
mTextureInited = PR_FALSE;
} else {
mUpdateRect = aRegion.GetBounds();
}
@ -600,72 +590,21 @@ BasicTextureImage::EndUpdate()
// but important if we ever do anything directly with the surface.
originalSurface->SetDeviceOffset(gfxPoint(0, 0));
nsRefPtr<gfxImageSurface> uploadImage = GetImageForUpload(originalSurface);
if (!uploadImage)
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);
DEBUG_GL_ERROR_CHECK(mGLContext);
if (!mTextureInited)
{
// If we can use the client storage extension, we should.
if (mGLContext->IsExtensionSupported(gl::GLContext::APPLE_client_storage)) {
mGLContext->fPixelStorei(LOCAL_GL_UNPACK_CLIENT_STORAGE_APPLE,
LOCAL_GL_TRUE);
DEBUG_GL_ERROR_CHECK(mGLContext);
}
mGLContext->fTexImage2D(LOCAL_GL_TEXTURE_2D,
0,
LOCAL_GL_RGBA,
mUpdateRect.width,
mUpdateRect.height,
0,
LOCAL_GL_RGBA,
LOCAL_GL_UNSIGNED_BYTE,
uploadImage->Data());
DEBUG_GL_ERROR_CHECK(mGLContext);
mTextureInited = PR_TRUE;
// Reset the pixel store attribute, and hold on to the update surface
// because we're using the client storage extension.
if (mGLContext->IsExtensionSupported(gl::GLContext::APPLE_client_storage)) {
mBackingSurface = uploadImage;
mGLContext->fPixelStorei(LOCAL_GL_UNPACK_CLIENT_STORAGE_APPLE,
LOCAL_GL_FALSE);
DEBUG_GL_ERROR_CHECK(mGLContext);
}
} else {
// By default, mUpdateOffset is initialized to (0, 0), so we will
// upload from the origin of the update surface. Subclasses can set
// mUpdateOffset in an overridden BeginUpdate or EndUpdate to change
// this.
unsigned char* data = uploadImage->Data() + mUpdateOffset.x * 4 +
mUpdateOffset.y * uploadImage->Stride();
mGLContext->fTexSubImage2D(LOCAL_GL_TEXTURE_2D,
0,
mUpdateRect.x,
mUpdateRect.y,
mUpdateRect.width,
mUpdateRect.height,
LOCAL_GL_RGBA,
LOCAL_GL_UNSIGNED_BYTE,
data);
// The rect to upload from the surface is mUpdateRect sized and located at mUpdateOffset.
nsIntRect surfaceRect(mUpdateOffset.x, mUpdateOffset.y, mUpdateRect.width, mUpdateRect.height);
if (!mTextureInited) {
surfaceRect.x = 0;
surfaceRect.y = 0;
}
mUpdateContext = NULL;
// Reset pixel store attributes to use the defaults.
mGLContext->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
mShaderType =
mGLContext->UploadSurfaceToTexture(originalSurface,
surfaceRect,
mTexture,
!mTextureInited,
mUpdateRect.TopLeft());
mUpdateContext = nsnull;
mTextureInited = PR_TRUE;
return PR_TRUE; // mTexture is bound
}
@ -1274,7 +1213,7 @@ GLContext::UploadSurfaceToTexture(gfxASurface *aSurface,
bool textureInited = aOverwrite ? false : true;
MakeCurrent();
fActiveTexture(LOCAL_GL_TEXTURE0);
if (!aTexture) {
fGenTextures(1, &aTexture);
fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);

Просмотреть файл

@ -117,6 +117,19 @@ protected:
PlatformLookupFunction mLookupFunc;
};
enum ShaderProgramType {
RGBALayerProgramType,
BGRALayerProgramType,
RGBXLayerProgramType,
BGRXLayerProgramType,
RGBARectLayerProgramType,
ColorLayerProgramType,
YCbCrLayerProgramType,
Copy2DProgramType,
Copy2DRectProgramType,
NumProgramTypes
};
/**
* A TextureImage encapsulates a surface that can be drawn to by a
@ -200,6 +213,16 @@ public:
*/
GLuint Texture() { return mTexture; }
/**
* Returns the shader program type that should be used to render
* this texture. Only valid after a matching BeginUpdate/EndUpdate
* pair have been called.
*/
virtual ShaderProgramType GetShaderProgramType()
{
return mShaderType;
}
/** Can be called safely at any time. */
/**
@ -240,6 +263,7 @@ protected:
GLenum mWrapMode;
ContentType mContentType;
PRPackedBool mIsRGBFormat;
ShaderProgramType mShaderType;
};
/**
@ -280,12 +304,8 @@ protected:
virtual already_AddRefed<gfxASurface>
CreateUpdateSurface(const gfxIntSize& aSize, ImageFormat aFmt) = 0;
virtual already_AddRefed<gfxImageSurface>
GetImageForUpload(gfxASurface* aUpdateSurface) = 0;
PRBool mTextureInited;
GLContext* mGLContext;
nsRefPtr<gfxImageSurface> mBackingSurface;
nsRefPtr<gfxContext> mUpdateContext;
nsIntRect mUpdateRect;
@ -355,19 +375,6 @@ struct THEBES_API ContextFormat
int colorBits() const { return red + green + blue; }
};
enum ShaderProgramType {
RGBALayerProgramType,
BGRALayerProgramType,
RGBXLayerProgramType,
BGRXLayerProgramType,
RGBARectLayerProgramType,
ColorLayerProgramType,
YCbCrLayerProgramType,
Copy2DProgramType,
Copy2DRectProgramType,
NumProgramTypes
};
class GLContext
: public LibrarySymbolLoader
{

Просмотреть файл

@ -305,9 +305,8 @@ protected:
else
format = gfxASurface::ImageFormatARGB32;
if (!mTextureInited || !mBackingSurface || !mUpdateSurface ||
nsIntSize(mBackingSurface->Width(), mBackingSurface->Height()) < mSize ||
mBackingSurface->Format() != format)
if (!mTextureInited || !mUpdateSurface ||
mUpdateSurface->GetContentType() != GetContentType())
{
mUpdateSurface = nsnull;
mUpdateOffset = nsIntPoint(0, 0);
@ -315,6 +314,15 @@ protected:
return BasicTextureImage::BeginUpdate(aRegion);
}
nsRefPtr<gfxImageSurface> imageSurface = mUpdateSurface->GetAsImageSurface();
if (!imageSurface ||
nsIntSize(imageSurface->Width(), imageSurface->Height()) < mSize) {
mUpdateSurface = nsnull;
mUpdateOffset = nsIntPoint(0, 0);
// We need to (re)create our backing store. Let the base class to that.
return BasicTextureImage::BeginUpdate(aRegion);
}
// the basic impl can only upload updates to rectangles
mUpdateRect = aRegion.GetBounds();
aRegion = nsIntRegion(mUpdateRect);
@ -354,31 +362,6 @@ protected:
return gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
}
virtual already_AddRefed<gfxImageSurface>
GetImageForUpload(gfxASurface* aUpdateSurface)
{
nsRefPtr<gfxImageSurface> image = aUpdateSurface->GetAsImageSurface();
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<gfxContext> tmpContext = new gfxContext(image);
tmpContext->SetSource(aUpdateSurface);
tmpContext->SetOperator(gfxContext::OPERATOR_SOURCE);
tmpContext->Paint();
}
return image.forget();
}
private:
TextureImageCGL(GLuint aTexture,
const nsIntSize& aSize,

Просмотреть файл

@ -970,6 +970,9 @@ public:
if (gUseBackingSurface) {
CreateBackingSurface(gfxIntSize(aSize.width, aSize.height));
}
// We currently always use BGRA type textures
mShaderType = BGRALayerProgramType;
}
virtual ~TextureImageEGL()

Просмотреть файл

@ -426,22 +426,6 @@ protected:
return gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
}
virtual already_AddRefed<gfxImageSurface>
GetImageForUpload(gfxASurface* aUpdateSurface)
{
nsRefPtr<gfxImageSurface> image =
new gfxImageSurface(gfxIntSize(mUpdateRect.width,
mUpdateRect.height),
mUpdateFormat);
nsRefPtr<gfxContext> tmpContext = new gfxContext(image);
tmpContext->SetSource(aUpdateSurface);
tmpContext->SetOperator(gfxContext::OPERATOR_SOURCE);
tmpContext->Paint();
return image.forget();
}
private:
TextureImageGLX(GLuint aTexture,
const nsIntSize& aSize,

Просмотреть файл

@ -464,24 +464,6 @@ protected:
return gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
}
virtual already_AddRefed<gfxImageSurface>
GetImageForUpload(gfxASurface* aUpdateSurface)
{
nsRefPtr<gfxImageSurface> uploadImage;
if (aUpdateSurface->GetType() == gfxASurface::SurfaceTypeWin32) {
uploadImage = aUpdateSurface->GetAsImageSurface();
} else {
uploadImage = new gfxImageSurface(mUpdateSize, mUpdateFormat);
nsRefPtr<gfxContext> cx(new gfxContext(uploadImage));
cx->SetSource(aUpdateSurface);
cx->SetOperator(gfxContext::OPERATOR_SOURCE);
cx->Paint();
}
return uploadImage.forget();
}
private:
TextureImageWGL(GLuint aTexture,
const nsIntSize& aSize,