Backed out 8 changesets (bug 959154) for various oranges.

Backed out changeset 00e465be0552 (bug 959154)
Backed out changeset 0f9be8d2caaf (bug 959154)
Backed out changeset 6ca9ba706c94 (bug 959154)
Backed out changeset c6ec9df2d729 (bug 959154)
Backed out changeset 53da6aef5629 (bug 959154)
Backed out changeset 88a6337fc8fb (bug 959154)
Backed out changeset b2535f63d78e (bug 959154)
Backed out changeset fffb200a94bc (bug 959154)
This commit is contained in:
Ryan VanderMeulen 2014-02-14 13:30:39 -05:00
Родитель fc03ed3787
Коммит f373429333
7 изменённых файлов: 249 добавлений и 176 удалений

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

@ -90,9 +90,14 @@ TextureImage::UpdateFromDataSource(gfx::DataSourceSurface *aSurface,
: nsIntRect(0, 0,
aSurface->GetSize().width,
aSurface->GetSize().height);
gfx::IntPoint srcPoint = aSrcPoint ? *aSrcPoint
: gfx::IntPoint(0, 0);
return DirectUpdate(aSurface, destRegion, srcPoint);
nsIntPoint thebesSrcPoint = aSrcPoint ? nsIntPoint(aSrcPoint->x, aSrcPoint->y)
: nsIntPoint(0, 0);
RefPtr<gfxASurface> thebesSurf
= new gfxImageSurface(aSurface->GetData(),
ThebesIntSize(aSurface->GetSize()),
aSurface->Stride(),
SurfaceFormatToImageFormat(aSurface->GetFormat()));
return DirectUpdate(thebesSurf, destRegion, thebesSrcPoint);
}
gfx::IntRect TextureImage::GetTileRect() {
@ -119,10 +124,10 @@ BasicTextureImage::~BasicTextureImage()
}
}
gfx::DrawTarget*
gfxASurface*
BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
{
NS_ASSERTION(!mUpdateDrawTarget, "BeginUpdate() without EndUpdate()?");
NS_ASSERTION(!mUpdateSurface, "BeginUpdate() without EndUpdate()?");
// determine the region the client will need to repaint
if (CanUploadSubTextures(mGLContext)) {
@ -139,13 +144,20 @@ BasicTextureImage::BeginUpdate(nsIntRegion& aRegion)
return nullptr;
}
gfx::SurfaceFormat format =
ImageFormat format =
(GetContentType() == gfxContentType::COLOR) ?
gfx::SurfaceFormat::B8G8R8X8 : gfx::SurfaceFormat::B8G8R8A8;
mUpdateDrawTarget =
GetDrawTargetForUpdate(gfx::IntSize(rgnSize.width, rgnSize.height), format);
gfxImageFormat::RGB24 : gfxImageFormat::ARGB32;
mUpdateSurface =
GetSurfaceForUpdate(gfxIntSize(rgnSize.width, rgnSize.height), format);
return mUpdateDrawTarget;
if (!mUpdateSurface || mUpdateSurface->CairoStatus()) {
mUpdateSurface = nullptr;
return nullptr;
}
mUpdateSurface->SetDeviceOffset(gfxPoint(-rgnSize.x, -rgnSize.y));
return mUpdateSurface;
}
void
@ -161,18 +173,19 @@ BasicTextureImage::GetUpdateRegion(nsIntRegion& aForRegion)
void
BasicTextureImage::EndUpdate()
{
NS_ASSERTION(!!mUpdateDrawTarget, "EndUpdate() without BeginUpdate()?");
NS_ASSERTION(!!mUpdateSurface, "EndUpdate() without BeginUpdate()?");
// FIXME: this is the slow boat. Make me fast (with GLXPixmap?).
RefPtr<gfx::SourceSurface> updateSnapshot = mUpdateDrawTarget->Snapshot();
RefPtr<gfx::DataSourceSurface> updateData = updateSnapshot->GetDataSurface();
// Undo the device offset that BeginUpdate set; doesn't much matter for us here,
// but important if we ever do anything directly with the surface.
mUpdateSurface->SetDeviceOffset(gfxPoint(0, 0));
bool relative = FinishedSurfaceUpdate();
mTextureFormat =
UploadSurfaceToTexture(mGLContext,
updateData,
mUpdateSurface,
mUpdateRegion,
mTexture,
mTextureState == Created,
@ -180,7 +193,7 @@ BasicTextureImage::EndUpdate()
relative);
FinishedSurfaceUpload();
mUpdateDrawTarget = nullptr;
mUpdateSurface = nullptr;
mTextureState = Valid;
}
@ -192,10 +205,12 @@ BasicTextureImage::BindTexture(GLenum aTextureUnit)
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
}
TemporaryRef<gfx::DrawTarget>
BasicTextureImage::GetDrawTargetForUpdate(const gfx::IntSize& aSize, gfx::SurfaceFormat aFmt)
already_AddRefed<gfxASurface>
BasicTextureImage::GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt)
{
return gfx::Factory::CreateDrawTarget(gfx::BackendType::CAIRO, aSize, aFmt);
return gfxPlatform::GetPlatform()->
CreateOffscreenSurface(aSize.ToIntSize(),
gfxASurface::ContentFromFormat(aFmt));
}
bool
@ -210,7 +225,7 @@ BasicTextureImage::FinishedSurfaceUpload()
}
bool
BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0, 0) */)
BasicTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom /* = nsIntPoint(0, 0) */)
{
nsIntRect bounds = aRegion.GetBounds();
nsIntRegion region;
@ -227,7 +242,7 @@ BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion
region,
mTexture,
mTextureState == Created,
bounds.TopLeft() + nsIntPoint(aFrom.x, aFrom.y),
bounds.TopLeft() + aFrom,
false);
mTextureState = Valid;
return true;
@ -236,7 +251,7 @@ BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion
void
BasicTextureImage::Resize(const gfx::IntSize& aSize)
{
NS_ASSERTION(!mUpdateDrawTarget, "Resize() while in update?");
NS_ASSERTION(!mUpdateSurface, "Resize() while in update?");
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
@ -345,7 +360,7 @@ TiledTextureImage::~TiledTextureImage()
}
bool
TiledTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0, 0) */)
TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom /* = nsIntPoint(0, 0) */)
{
if (mSize.width == 0 || mSize.height == 0) {
return true;
@ -383,7 +398,7 @@ TiledTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion
}
result &= mImages[mCurrentImage]->
DirectUpdate(aSurf, tileRegion, aFrom + gfx::IntPoint(xPos, yPos));
DirectUpdate(aSurf, tileRegion, aFrom + nsIntPoint(xPos, yPos));
if (mCurrentImage == mImages.Length() - 1) {
// We know we're done, but we still need to ensure that the callback
@ -441,7 +456,7 @@ TiledTextureImage::GetUpdateRegion(nsIntRegion& aForRegion)
aForRegion = newRegion;
}
gfx::DrawTarget*
gfxASurface*
TiledTextureImage::BeginUpdate(nsIntRegion& aRegion)
{
NS_ASSERTION(!mInUpdate, "nested update");
@ -472,14 +487,18 @@ TiledTextureImage::BeginUpdate(nsIntRegion& aRegion)
// adjust for tile offset
aRegion.MoveBy(-xPos, -yPos);
// forward the actual call
RefPtr<gfx::DrawTarget> drawTarget = mImages[i]->BeginUpdate(aRegion);
nsRefPtr<gfxASurface> surface = mImages[i]->BeginUpdate(aRegion);
// caller expects container space
aRegion.MoveBy(xPos, yPos);
// Correct the device offset
gfxPoint offset = surface->GetDeviceOffset();
surface->SetDeviceOffset(gfxPoint(offset.x - xPos,
offset.y - yPos));
// we don't have a temp surface
mUpdateDrawTarget = nullptr;
mUpdateSurface = nullptr;
// remember which image to EndUpdate
mCurrentImage = i;
return drawTarget.get();
return surface.get();
}
}
@ -490,21 +509,22 @@ TiledTextureImage::BeginUpdate(nsIntRegion& aRegion)
bounds = aRegion.GetBounds();
// update covers multiple Images - create a temp surface to paint in
gfx::SurfaceFormat format =
gfxImageFormat format =
(GetContentType() == gfxContentType::COLOR) ?
gfx::SurfaceFormat::B8G8R8X8: gfx::SurfaceFormat::B8G8R8A8;
mUpdateDrawTarget = gfx::Factory::CreateDrawTarget(gfx::BackendType::CAIRO,
bounds.Size().ToIntSize(),
format);
gfxImageFormat::RGB24 : gfxImageFormat::ARGB32;
mUpdateSurface = gfxPlatform::GetPlatform()->
CreateOffscreenSurface(bounds.Size().ToIntSize(),
gfxASurface::ContentFromFormat(format));
mUpdateSurface->SetDeviceOffset(gfxPoint(-bounds.x, -bounds.y));
return mUpdateDrawTarget;;
return mUpdateSurface;
}
void
TiledTextureImage::EndUpdate()
{
NS_ASSERTION(mInUpdate, "EndUpdate not in update");
if (!mUpdateDrawTarget) { // update was to a single TextureImage
if (!mUpdateSurface) { // update was to a single TextureImage
mImages[mCurrentImage]->EndUpdate();
mInUpdate = false;
mTextureState = Valid;
@ -512,13 +532,6 @@ TiledTextureImage::EndUpdate()
return;
}
RefPtr<gfx::SourceSurface> updateSnapshot = mUpdateDrawTarget->Snapshot();
RefPtr<gfx::DataSourceSurface> updateData = updateSnapshot->GetDataSurface();
nsRefPtr<gfxASurface> updateSurface = new gfxImageSurface(updateData->GetData(),
gfx::ThebesIntSize(updateData->GetSize()),
updateData->Stride(),
gfx::SurfaceFormatToImageFormat(updateData->GetFormat()));
// upload tiles from temp surface
for (unsigned i = 0; i < mImages.Length(); i++) {
int xPos = (i % mColumns) * mTileSize;
@ -531,17 +544,17 @@ TiledTextureImage::EndUpdate()
if (subregion.IsEmpty())
continue;
subregion.MoveBy(-xPos, -yPos); // Tile-local space
// copy tile from temp target
gfx::DrawTarget* drawTarget = mImages[i]->BeginUpdate(subregion);
nsRefPtr<gfxContext> ctx = new gfxContext(drawTarget);
// copy tile from temp surface
gfxASurface* surf = mImages[i]->BeginUpdate(subregion);
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
gfxUtils::ClipToRegion(ctx, subregion);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetSource(updateSurface, gfxPoint(-xPos, -yPos));
ctx->SetSource(mUpdateSurface, gfxPoint(-xPos, -yPos));
ctx->Paint();
mImages[i]->EndUpdate();
}
mUpdateDrawTarget = nullptr;
mUpdateSurface = nullptr;
mInUpdate = false;
mTextureFormat = mImages[0]->GetTextureFormat();
mTextureState = Valid;

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

@ -13,14 +13,12 @@
#include "GLContextTypes.h"
#include "GraphicsFilter.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/RefPtr.h"
class gfxASurface;
namespace mozilla {
namespace gfx {
class DataSourceSurface;
class DrawTarget;
}
}
@ -102,7 +100,7 @@ public:
* inconsistent state. Unsuccessful BeginUpdate()s must not be
* followed by EndUpdate().
*/
virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion) = 0;
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion) = 0;
/**
* Retrieves the region that will require updating, given a
* region that needs to be updated. This can be used for
@ -178,7 +176,8 @@ public:
* aRegion - the region in this image to update
* aFrom - offset in the source to update from
*/
virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0)) = 0;
virtual bool DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0)) = 0;
// Moz2D equivalent
bool UpdateFromDataSource(gfx::DataSourceSurface *aSurf,
const nsIntRegion* aDstRegion = nullptr,
const gfx::IntPoint* aSrcOffset = nullptr);
@ -280,13 +279,14 @@ public:
virtual void BindTexture(GLenum aTextureUnit);
virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion);
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
virtual void GetUpdateRegion(nsIntRegion& aForRegion);
virtual void EndUpdate();
virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0));
virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0));
virtual GLuint GetTextureID() { return mTexture; }
virtual TemporaryRef<gfx::DrawTarget>
GetDrawTargetForUpdate(const gfx::IntSize& aSize, gfx::SurfaceFormat aFmt);
// Returns a surface to draw into
virtual already_AddRefed<gfxASurface>
GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt);
virtual void MarkValid() { mTextureState = Valid; }
@ -298,7 +298,7 @@ public:
// Call after surface data has been uploaded to a texture.
virtual void FinishedSurfaceUpload();
virtual bool InUpdate() const { return !!mUpdateDrawTarget; }
virtual bool InUpdate() const { return !!mUpdateSurface; }
virtual void Resize(const gfx::IntSize& aSize);
@ -306,7 +306,7 @@ protected:
GLuint mTexture;
TextureState mTextureState;
nsRefPtr<GLContext> mGLContext;
RefPtr<gfx::DrawTarget> mUpdateDrawTarget;
nsRefPtr<gfxASurface> mUpdateSurface;
nsIntRegion mUpdateRegion;
// The offset into the update surface at which the update rect is located.
@ -329,7 +329,7 @@ public:
TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown);
~TiledTextureImage();
void DumpDiv();
virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion);
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
virtual void GetUpdateRegion(nsIntRegion& aForRegion);
virtual void EndUpdate();
virtual void Resize(const gfx::IntSize& aSize);
@ -342,7 +342,7 @@ public:
virtual GLuint GetTextureID() {
return mImages[mCurrentImage]->GetTextureID();
}
virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0));
virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0));
virtual bool InUpdate() const { return mInUpdate; }
virtual void BindTexture(GLenum);
@ -358,8 +358,8 @@ protected:
unsigned int mTileSize;
unsigned int mRows, mColumns;
GLContext* mGL;
// A temporary draw target to faciliate cross-tile updates.
RefPtr<gfx::DrawTarget> mUpdateDrawTarget;
// A temporary surface to faciliate cross-tile updates.
nsRefPtr<gfxASurface> mUpdateSurface;
// The region of update requested
nsIntRegion mUpdateRegion;
TextureState mTextureState;

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

@ -7,56 +7,42 @@
#include "GLContext.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Tools.h" // For BytesPerPixel
#include "gfxASurface.h"
#include "gfxUtils.h"
#include "gfxContext.h"
#include "nsRegion.h"
namespace mozilla {
using namespace gfx;
using gfx::SurfaceFormat;
namespace gl {
/* These two techniques are suggested by "Bit Twiddling Hacks"
*/
/**
* Returns true if |aNumber| is a power of two
* 0 is incorreclty considered a power of two
*/
static bool
IsPowerOfTwo(int aNumber)
{
return (aNumber & (aNumber - 1)) == 0;
}
/**
* Returns the first integer greater than |aNumber| which is a power of two
* Undefined for |aNumber| < 0
*/
static int
NextPowerOfTwo(int aNumber)
{
#if defined(__arm__)
return 1 << (32 - __builtin_clz(aNumber - 1));
#else
--aNumber;
aNumber |= aNumber >> 1;
aNumber |= aNumber >> 2;
aNumber |= aNumber >> 4;
aNumber |= aNumber >> 8;
aNumber |= aNumber >> 16;
return ++aNumber;
#endif
}
static unsigned int
DataOffset(const nsIntPoint &aPoint, int32_t aStride, SurfaceFormat aFormat)
DataOffset(const nsIntPoint &aPoint, int32_t aStride, gfxImageFormat aFormat)
{
unsigned int data = aPoint.y * aStride;
data += aPoint.x * BytesPerPixel(aFormat);
data += aPoint.x * gfxASurface::BytePerPixelFromFormat(aFormat);
return data;
}
static gfxImageFormat
ImageFormatForSurfaceFormat(gfx::SurfaceFormat aFormat)
{
switch (aFormat) {
case gfx::SurfaceFormat::B8G8R8A8:
return gfxImageFormat::ARGB32;
case gfx::SurfaceFormat::B8G8R8X8:
return gfxImageFormat::RGB24;
case gfx::SurfaceFormat::R5G6B5:
return gfxImageFormat::RGB16_565;
case gfx::SurfaceFormat::A8:
return gfxImageFormat::A8;
default:
return gfxImageFormat::Unknown;
}
}
static GLint GetAddressAlignment(ptrdiff_t aAddress)
{
if (!(aAddress & 0x7)) {
@ -285,13 +271,13 @@ TexImage2DHelper(GLContext *gl,
if (!CanUploadNonPowerOfTwo(gl)
&& (stride != width * pixelsize
|| !IsPowerOfTwo(width)
|| !IsPowerOfTwo(height))) {
|| !gfx::IsPowerOfTwo(width)
|| !gfx::IsPowerOfTwo(height))) {
// Pad out texture width and height to the next power of two
// as we don't support/want non power of two texture uploads
GLsizei paddedWidth = NextPowerOfTwo(width);
GLsizei paddedHeight = NextPowerOfTwo(height);
GLsizei paddedWidth = gfx::NextPowerOfTwo(width);
GLsizei paddedHeight = gfx::NextPowerOfTwo(height);
GLvoid* paddedPixels = new unsigned char[paddedWidth * paddedHeight * pixelsize];
@ -383,7 +369,7 @@ SurfaceFormat
UploadImageDataToTexture(GLContext* gl,
unsigned char* aData,
int32_t aStride,
SurfaceFormat aFormat,
gfxImageFormat aFormat,
const nsIntRegion& aDstRegion,
GLuint& aTexture,
bool aOverwrite,
@ -425,54 +411,54 @@ UploadImageDataToTexture(GLContext* gl,
GLenum format;
GLenum internalFormat;
GLenum type;
int32_t pixelSize = BytesPerPixel(aFormat);
int32_t pixelSize = gfxASurface::BytePerPixelFromFormat(aFormat);
SurfaceFormat surfaceFormat;
MOZ_ASSERT(gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA ||
gl->GetPreferredARGB32Format() == LOCAL_GL_RGBA);
switch (aFormat) {
case SurfaceFormat::B8G8R8A8:
case gfxImageFormat::ARGB32:
if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
format = LOCAL_GL_BGRA;
surfaceFormat = SurfaceFormat::R8G8B8A8;
surfaceFormat = gfx::SurfaceFormat::R8G8B8A8;
type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
} else {
format = LOCAL_GL_RGBA;
surfaceFormat = SurfaceFormat::B8G8R8A8;
surfaceFormat = gfx::SurfaceFormat::B8G8R8A8;
type = LOCAL_GL_UNSIGNED_BYTE;
}
internalFormat = LOCAL_GL_RGBA;
break;
case SurfaceFormat::B8G8R8X8:
// Treat BGRX surfaces as BGRA except for the surface
case gfxImageFormat::RGB24:
// Treat RGB24 surfaces as RGBA32 except for the surface
// format used.
if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
format = LOCAL_GL_BGRA;
surfaceFormat = SurfaceFormat::R8G8B8X8;
surfaceFormat = gfx::SurfaceFormat::R8G8B8X8;
type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
} else {
format = LOCAL_GL_RGBA;
surfaceFormat = SurfaceFormat::B8G8R8X8;
surfaceFormat = gfx::SurfaceFormat::B8G8R8X8;
type = LOCAL_GL_UNSIGNED_BYTE;
}
internalFormat = LOCAL_GL_RGBA;
break;
case SurfaceFormat::R5G6B5:
case gfxImageFormat::RGB16_565:
internalFormat = format = LOCAL_GL_RGB;
type = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
surfaceFormat = SurfaceFormat::R5G6B5;
surfaceFormat = gfx::SurfaceFormat::R5G6B5;
break;
case SurfaceFormat::A8:
case gfxImageFormat::A8:
internalFormat = format = LOCAL_GL_LUMINANCE;
type = LOCAL_GL_UNSIGNED_BYTE;
// We don't have a specific luminance shader
surfaceFormat = SurfaceFormat::A8;
surfaceFormat = gfx::SurfaceFormat::A8;
break;
default:
NS_ASSERTION(false, "Unhandled image surface format!");
format = 0;
type = 0;
surfaceFormat = SurfaceFormat::UNKNOWN;
surfaceFormat = gfx::SurfaceFormat::UNKNOWN;
}
nsIntRegionRectIterator iter(paintRegion);
@ -526,7 +512,62 @@ UploadImageDataToTexture(GLContext* gl,
SurfaceFormat
UploadSurfaceToTexture(GLContext* gl,
DataSourceSurface *aSurface,
gfxASurface *aSurface,
const nsIntRegion& aDstRegion,
GLuint& aTexture,
bool aOverwrite,
const nsIntPoint& aSrcPoint,
bool aPixelBuffer,
GLenum aTextureUnit,
GLenum aTextureTarget)
{
nsRefPtr<gfxImageSurface> imageSurface = aSurface->GetAsImageSurface();
unsigned char* data = nullptr;
if (!imageSurface ||
(imageSurface->Format() != gfxImageFormat::ARGB32 &&
imageSurface->Format() != gfxImageFormat::RGB24 &&
imageSurface->Format() != gfxImageFormat::RGB16_565 &&
imageSurface->Format() != gfxImageFormat::A8)) {
// We can't get suitable pixel data for the surface, make a copy
nsIntRect bounds = aDstRegion.GetBounds();
imageSurface =
new gfxImageSurface(gfxIntSize(bounds.width, bounds.height),
gfxImageFormat::ARGB32);
nsRefPtr<gfxContext> context = new gfxContext(imageSurface);
context->Translate(-gfxPoint(aSrcPoint.x, aSrcPoint.y));
context->SetSource(aSurface);
context->Paint();
data = imageSurface->Data();
NS_ASSERTION(!aPixelBuffer,
"Must be using an image compatible surface with pixel buffers!");
} else {
// If a pixel buffer is bound the data pointer parameter is relative
// to the start of the data block.
if (!aPixelBuffer) {
data = imageSurface->Data();
}
data += DataOffset(aSrcPoint, imageSurface->Stride(),
imageSurface->Format());
}
MOZ_ASSERT(imageSurface);
imageSurface->Flush();
return UploadImageDataToTexture(gl,
data,
imageSurface->Stride(),
imageSurface->Format(),
aDstRegion, aTexture, aOverwrite,
aPixelBuffer, aTextureUnit, aTextureTarget);
}
SurfaceFormat
UploadSurfaceToTexture(GLContext* gl,
gfx::DataSourceSurface *aSurface,
const nsIntRegion& aDstRegion,
GLuint& aTexture,
bool aOverwrite,
@ -537,7 +578,8 @@ UploadSurfaceToTexture(GLContext* gl,
{
unsigned char* data = aPixelBuffer ? nullptr : aSurface->GetData();
int32_t stride = aSurface->Stride();
SurfaceFormat format = aSurface->GetFormat();
gfxImageFormat format =
ImageFormatForSurfaceFormat(aSurface->GetFormat());
data += DataOffset(aSrcPoint, stride, format);
return UploadImageDataToTexture(gl, data, stride, format,
aDstRegion, aTexture, aOverwrite,
@ -557,4 +599,4 @@ CanUploadNonPowerOfTwo(GLContext* gl)
}
}
}
}

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

@ -7,9 +7,11 @@
#define GLUploadHelpers_h_
#include "GLDefs.h"
#include "gfxTypes.h"
#include "mozilla/gfx/Types.h"
#include "nsPoint.h"
class gfxASurface;
class nsIntRegion;
namespace mozilla {
@ -57,7 +59,7 @@ gfx::SurfaceFormat
UploadImageDataToTexture(GLContext* gl,
unsigned char* aData,
int32_t aStride,
gfx::SurfaceFormat aFormat,
gfxImageFormat aFormat,
const nsIntRegion& aDstRegion,
GLuint& aTexture,
bool aOverwrite = false,
@ -65,6 +67,20 @@ UploadImageDataToTexture(GLContext* gl,
GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D);
/**
* Convenience wrapper around UploadImageDataToTexture for gfxASurfaces.
*/
gfx::SurfaceFormat
UploadSurfaceToTexture(GLContext* gl,
gfxASurface *aSurface,
const nsIntRegion& aDstRegion,
GLuint& aTexture,
bool aOverwrite = false,
const nsIntPoint& aSrcPoint = nsIntPoint(0, 0),
bool aPixelBuffer = false,
GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D);
/**
* Convenience wrapper around UploadImageDataToTexture for gfx::DataSourceSurface's.
*/

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

@ -15,34 +15,35 @@ namespace mozilla {
namespace gl {
static GLenum
GLFormatForImage(gfx::SurfaceFormat aFormat)
GLFormatForImage(gfxImageFormat aFormat)
{
switch (aFormat) {
case gfx::SurfaceFormat::B8G8R8A8:
case gfx::SurfaceFormat::B8G8R8X8:
case gfxImageFormat::ARGB32:
case gfxImageFormat::RGB24:
// Thebes only supports RGBX, not packed RGB.
return LOCAL_GL_RGBA;
case gfx::SurfaceFormat::R5G6B5:
case gfxImageFormat::RGB16_565:
return LOCAL_GL_RGB;
case gfx::SurfaceFormat::A8:
case gfxImageFormat::A8:
return LOCAL_GL_LUMINANCE;
default:
NS_WARNING("Unknown GL format for Surface format");
NS_WARNING("Unknown GL format for Image format");
}
return 0;
}
static GLenum
GLTypeForImage(gfx::SurfaceFormat aFormat)
GLTypeForImage(gfxImageFormat aFormat)
{
switch (aFormat) {
case gfx::SurfaceFormat::B8G8R8A8:
case gfx::SurfaceFormat::B8G8R8X8:
case gfx::SurfaceFormat::A8:
case gfxImageFormat::ARGB32:
case gfxImageFormat::RGB24:
case gfxImageFormat::A8:
return LOCAL_GL_UNSIGNED_BYTE;
case gfx::SurfaceFormat::R5G6B5:
case gfxImageFormat::RGB16_565:
return LOCAL_GL_UNSIGNED_SHORT_5_6_5;
default:
NS_WARNING("Unknown GL format for Surface format");
NS_WARNING("Unknown GL format for Image format");
}
return 0;
}
@ -57,7 +58,7 @@ TextureImageEGL::TextureImageEGL(GLuint aTexture,
TextureImage::ImageFormat aImageFormat)
: TextureImage(aSize, aWrapMode, aContentType, aFlags)
, mGLContext(aContext)
, mUpdateFormat(gfx::ImageFormatToSurfaceFormat(aImageFormat))
, mUpdateFormat(aImageFormat)
, mEGLImage(nullptr)
, mTexture(aTexture)
, mSurface(nullptr)
@ -65,14 +66,16 @@ TextureImageEGL::TextureImageEGL(GLuint aTexture,
, mTextureState(aTextureState)
, mBound(false)
{
if (mUpdateFormat == gfx::SurfaceFormat::UNKNOWN) {
mUpdateFormat = gfx::ImageFormatToSurfaceFormat(
gfxPlatform::GetPlatform()->OptimalFormatForContent(GetContentType()));
if (mUpdateFormat == gfxImageFormat::Unknown) {
mUpdateFormat = gfxPlatform::GetPlatform()->OptimalFormatForContent(GetContentType());
}
if (mUpdateFormat == gfx::SurfaceFormat::R5G6B5) {
if (mUpdateFormat == gfxImageFormat::RGB16_565) {
mTextureFormat = gfx::SurfaceFormat::R8G8B8X8;
} else if (mUpdateFormat == gfx::SurfaceFormat::B8G8R8X8) {
} else if (mUpdateFormat == gfxImageFormat::RGB24) {
// RGB24 means really RGBX for Thebes, which means we have to
// use the right shader and ignore the uninitialized alpha
// value.
mTextureFormat = gfx::SurfaceFormat::B8G8R8X8;
} else {
mTextureFormat = gfx::SurfaceFormat::B8G8R8A8;
@ -111,10 +114,10 @@ TextureImageEGL::GetUpdateRegion(nsIntRegion& aForRegion)
aForRegion = nsIntRegion(aForRegion.GetBounds());
}
gfx::DrawTarget*
gfxASurface*
TextureImageEGL::BeginUpdate(nsIntRegion& aRegion)
{
NS_ASSERTION(!mUpdateDrawTarget, "BeginUpdate() without EndUpdate()?");
NS_ASSERTION(!mUpdateSurface, "BeginUpdate() without EndUpdate()?");
// determine the region the client will need to repaint
GetUpdateRegion(aRegion);
@ -128,17 +131,19 @@ TextureImageEGL::BeginUpdate(nsIntRegion& aRegion)
//printf_stderr("creating image surface %dx%d format %d\n", mUpdateRect.width, mUpdateRect.height, mUpdateFormat);
mUpdateDrawTarget = gfx::Factory::CreateDrawTarget(gfx::BackendType::CAIRO,
gfx::IntSize(mUpdateRect.width, mUpdateRect.height),
mUpdateFormat);
mUpdateSurface =
new gfxImageSurface(gfxIntSize(mUpdateRect.width, mUpdateRect.height),
mUpdateFormat);
return mUpdateDrawTarget;
mUpdateSurface->SetDeviceOffset(gfxPoint(-mUpdateRect.x, -mUpdateRect.y));
return mUpdateSurface;
}
void
TextureImageEGL::EndUpdate()
{
NS_ASSERTION(!!mUpdateDrawTarget, "EndUpdate() without BeginUpdate()?");
NS_ASSERTION(!!mUpdateSurface, "EndUpdate() without BeginUpdate()?");
//printf_stderr("EndUpdate: slow path");
@ -146,15 +151,19 @@ TextureImageEGL::EndUpdate()
// a fast mapping between our cairo target surface and the GL
// texture, so we have to upload data.
RefPtr<gfx::SourceSurface> updateSurface = nullptr;
RefPtr<gfx::DataSourceSurface> uploadImage = nullptr;
gfx::IntSize updateSize(mUpdateRect.width, mUpdateRect.height);
// Undo the device offset that BeginUpdate set; doesn't much
// matter for us here, but important if we ever do anything
// directly with the surface.
mUpdateSurface->SetDeviceOffset(gfxPoint(0, 0));
NS_ASSERTION(mUpdateDrawTarget->GetSize() == updateSize,
"Upload image is the wrong size!");
nsRefPtr<gfxImageSurface> uploadImage = nullptr;
gfxIntSize updateSize(mUpdateRect.width, mUpdateRect.height);
updateSurface = mUpdateDrawTarget->Snapshot();
uploadImage = updateSurface->GetDataSurface();
NS_ASSERTION(mUpdateSurface->GetType() == gfxSurfaceType::Image &&
mUpdateSurface->GetSize() == updateSize,
"Upload image isn't an image surface when one is expected, or is wrong size!");
uploadImage = static_cast<gfxImageSurface*>(mUpdateSurface.get());
if (!uploadImage) {
return;
@ -174,9 +183,9 @@ TextureImageEGL::EndUpdate()
mUpdateRect.width,
mUpdateRect.height,
0,
GLFormatForImage(uploadImage->GetFormat()),
GLTypeForImage(uploadImage->GetFormat()),
uploadImage->GetData());
GLFormatForImage(uploadImage->Format()),
GLTypeForImage(uploadImage->Format()),
uploadImage->Data());
} else {
mGLContext->fTexSubImage2D(LOCAL_GL_TEXTURE_2D,
0,
@ -184,18 +193,18 @@ TextureImageEGL::EndUpdate()
mUpdateRect.y,
mUpdateRect.width,
mUpdateRect.height,
GLFormatForImage(uploadImage->GetFormat()),
GLTypeForImage(uploadImage->GetFormat()),
uploadImage->GetData());
GLFormatForImage(uploadImage->Format()),
GLTypeForImage(uploadImage->Format()),
uploadImage->Data());
}
mUpdateDrawTarget = nullptr;
mUpdateSurface = nullptr;
mTextureState = Valid;
return; // mTexture is bound
}
bool
TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom /* = gfx::IntPoint(0,0) */)
TextureImageEGL::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom /* = nsIntPoint(0, 0) */)
{
nsIntRect bounds = aRegion.GetBounds();
@ -213,7 +222,7 @@ TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion&
region,
mTexture,
mTextureState == Created,
bounds.TopLeft() + nsIntPoint(aFrom.x, aFrom.y),
bounds.TopLeft() + aFrom,
false);
mTextureState = Valid;
@ -236,7 +245,7 @@ TextureImageEGL::BindTexture(GLenum aTextureUnit)
void
TextureImageEGL::Resize(const gfx::IntSize& aSize)
{
NS_ASSERTION(!mUpdateDrawTarget, "Resize() while in update?");
NS_ASSERTION(!mUpdateSurface, "Resize() while in update?");
if (mSize == aSize && mTextureState != Created)
return;

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

@ -28,11 +28,11 @@ public:
virtual void GetUpdateRegion(nsIntRegion& aForRegion);
virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion);
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
virtual void EndUpdate();
virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0));
virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom /* = nsIntPoint(0, 0) */);
virtual void BindTexture(GLenum aTextureUnit);
@ -45,7 +45,7 @@ public:
return mTexture;
};
virtual bool InUpdate() const { return !!mUpdateDrawTarget; }
virtual bool InUpdate() const { return !!mUpdateSurface; }
virtual void Resize(const gfx::IntSize& aSize);
@ -66,8 +66,8 @@ protected:
GLContext* mGLContext;
nsIntRect mUpdateRect;
gfx::SurfaceFormat mUpdateFormat;
RefPtr<gfx::DrawTarget> mUpdateDrawTarget;
ImageFormat mUpdateFormat;
nsRefPtr<gfxASurface> mUpdateSurface;
EGLImage mEGLImage;
GLuint mTexture;
EGLSurface mSurface;

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

@ -740,18 +740,11 @@ TextureImageDeprecatedTextureHostOGL::UpdateImpl(const SurfaceDescriptor& aImage
} else {
updateRegion = *aRegion;
}
gfx::IntPoint offset;
nsIntPoint offset;
if (aOffset) {
offset.x = aOffset->x;
offset.y = aOffset->y;
offset = *aOffset;
}
nsRefPtr<gfxImageSurface> thebesSurf = surf.GetAsImage();
RefPtr<DataSourceSurface> sourceSurf =
gfx::Factory::CreateWrappingDataSourceSurface(thebesSurf->Data(),
thebesSurf->Stride(),
ToIntSize(thebesSurf->GetSize()),
ImageFormatToSurfaceFormat(thebesSurf->Format()));
mTexture->DirectUpdate(sourceSurf, updateRegion, offset);
mTexture->DirectUpdate(surf.Get(), updateRegion, offset);
mFormat = mTexture->GetTextureFormat();
if (mTexture->InUpdate()) {