Bug 575521 - Draw to a clipped context backed by the surface uploaded to OpenGL using APPLE_client_storage to avoid slowdowns in glTexSubImage2D. r=jrmuizel a=b

This commit is contained in:
Joe Drew 2010-11-11 15:31:23 -05:00
Родитель dc6ad712d5
Коммит 9b8e840e64
3 изменённых файлов: 58 добавлений и 3 удалений

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

@ -534,8 +534,7 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
mUpdateRect = aRegion.GetBounds();
}
// the basic impl can't upload updates to disparate regions,
// only rects
// the basic impl can only upload updates to rectangles
aRegion = nsIntRegion(mUpdateRect);
nsIntSize rgnSize = mUpdateRect.Size();
@ -614,6 +613,12 @@ BasicTextureImage::EndUpdate()
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,
@ -622,7 +627,7 @@ BasicTextureImage::EndUpdate()
mUpdateRect.height,
LOCAL_GL_RGBA,
LOCAL_GL_UNSIGNED_BYTE,
uploadImage->Data());
data);
}
mUpdateContext = NULL;

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

@ -268,6 +268,7 @@ protected:
: TextureImage(aTexture, aSize, aContentType)
, mTextureInited(PR_FALSE)
, mGLContext(aContext)
, mUpdateOffset(0, 0)
{}
virtual already_AddRefed<gfxASurface>
@ -281,6 +282,9 @@ protected:
nsRefPtr<gfxImageSurface> mBackingSurface;
nsRefPtr<gfxContext> mUpdateContext;
nsIntRect mUpdateRect;
// The offset into the update surface at which the update rect is located.
nsIntPoint mUpdateOffset;
};
struct THEBES_API ContextFormat

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

@ -272,6 +272,51 @@ class TextureImageCGL : public BasicTextureImage
GLContext*);
protected:
virtual gfxContext*
BeginUpdate(nsIntRegion& aRegion)
{
ImageFormat format;
if (GetContentType() == gfxASurface::CONTENT_COLOR)
format = gfxASurface::ImageFormatRGB24;
else
format = gfxASurface::ImageFormatARGB32;
if (!mTextureInited || !mBackingSurface || !mUpdateSurface ||
nsIntSize(mBackingSurface->Width(), mBackingSurface->Height()) < mSize ||
mBackingSurface->Format() != format)
{
mUpdateSurface = nsnull;
mClippedRect = nsIntRect(0, 0, 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);
if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(mUpdateRect)) {
NS_ERROR("update outside of image");
return NULL;
}
mUpdateContext = new gfxContext(mUpdateSurface);
mUpdateContext->Clip(gfxRect(mUpdateRect.x, mUpdateRect.y,
mUpdateRect.width, mUpdateRect.height));
mUpdateOffset = mUpdateRect.TopLeft();
return mUpdateContext;
}
virtual PRBool
EndUpdate()
{
if (!mUpdateSurface)
mUpdateSurface = mUpdateContext->OriginalSurface();
return BasicTextureImage::EndUpdate();
}
virtual already_AddRefed<gfxASurface>
CreateUpdateSurface(const gfxIntSize& aSize, ImageFormat aFmt)
{
@ -313,6 +358,7 @@ private:
{}
ImageFormat mUpdateFormat;
nsRefPtr<gfxASurface> mUpdateSurface;
};
already_AddRefed<TextureImage>