зеркало из https://github.com/mozilla/gecko-dev.git
Bug 604101 - Part 4 - Use UploadSurfaceToTexture in TextureImage. r=joe a=blocking2.0
This commit is contained in:
Родитель
8bcd4fedaf
Коммит
8ff0e949d1
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче