mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 960378 - Allow Reading into non-tightly-packed surfaces. - r=bjacob
This commit is contained in:
parent
62bc24f9b3
commit
f68d00bf9a
@ -156,7 +156,8 @@ GLReadTexImageHelper::DidGLErrorOccur(const char* str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
GetActualReadFormats(GLContext* gl, GLenum destFormat, GLenum destType,
|
GetActualReadFormats(GLContext* gl,
|
||||||
|
GLenum destFormat, GLenum destType,
|
||||||
GLenum& readFormat, GLenum& readType)
|
GLenum& readFormat, GLenum& readType)
|
||||||
{
|
{
|
||||||
if (destFormat == LOCAL_GL_RGBA &&
|
if (destFormat == LOCAL_GL_RGBA &&
|
||||||
@ -231,16 +232,43 @@ static void SwapRAndBComponents(DataSourceSurface* surf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
CalcStride(int width, int pixelSize, int alignment)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(alignment);
|
||||||
|
|
||||||
|
int stride = width * pixelSize;
|
||||||
|
if (stride % alignment) { // Extra at the end of the line?
|
||||||
|
int alignmentCount = stride / alignment;
|
||||||
|
stride = (alignmentCount+1) * alignment;
|
||||||
|
}
|
||||||
|
return stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
GuessAlignment(int width, int pixelSize, int stride)
|
||||||
|
{
|
||||||
|
int alignment = 8; // Max GLES allows.
|
||||||
|
while (CalcStride(width, pixelSize, alignment) != stride) {
|
||||||
|
alignment /= 2;
|
||||||
|
if (!alignment) {
|
||||||
|
MOZ_ASSERT(alignment);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
|
ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
|
||||||
gl->MakeCurrent();
|
gl->MakeCurrent();
|
||||||
MOZ_ASSERT(dest->GetSize() != gfxIntSize(0, 0));
|
MOZ_ASSERT(dest->GetSize() != gfxIntSize(0, 0));
|
||||||
|
|
||||||
/* gfxImageFormat::ARGB32:
|
/* gfxImageFormat::ARGB32:
|
||||||
* RGBA+UByte: be[RGBA], le[ABGR]
|
* RGBA+UByte: be[RGBA], le[ABGR]
|
||||||
* RGBA+UInt: le[RGBA]
|
* RGBA+UInt: be[ABGR], le[RGBA]
|
||||||
* BGRA+UInt: le[BGRA]
|
* BGRA+UInt: be[ARGB], le[BGRA]
|
||||||
* BGRA+UIntRev: le[ARGB]
|
* BGRA+UIntRev: be[BGRA], le[ARGB]
|
||||||
*
|
*
|
||||||
* gfxImageFormat::RGB16_565:
|
* gfxImageFormat::RGB16_565:
|
||||||
* RGB+UShort: le[rrrrrggg,gggbbbbb]
|
* RGB+UShort: le[rrrrrggg,gggbbbbb]
|
||||||
@ -269,7 +297,7 @@ ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
|
|||||||
default:
|
default:
|
||||||
MOZ_CRASH("Bad format.");
|
MOZ_CRASH("Bad format.");
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(dest->Stride() == dest->Width() * destPixelSize);
|
MOZ_ASSERT(dest->Width() * destPixelSize <= dest->Stride());
|
||||||
|
|
||||||
GLenum readFormat = destFormat;
|
GLenum readFormat = destFormat;
|
||||||
GLenum readType = destType;
|
GLenum readType = destType;
|
||||||
@ -279,7 +307,7 @@ ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
|
|||||||
|
|
||||||
nsAutoPtr<gfxImageSurface> tempSurf;
|
nsAutoPtr<gfxImageSurface> tempSurf;
|
||||||
gfxImageSurface* readSurf = nullptr;
|
gfxImageSurface* readSurf = nullptr;
|
||||||
int readPixelSize = 0;
|
int readAlignment = 0;
|
||||||
if (needsTempSurf) {
|
if (needsTempSurf) {
|
||||||
if (gl->DebugMode()) {
|
if (gl->DebugMode()) {
|
||||||
NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!");
|
NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!");
|
||||||
@ -294,7 +322,7 @@ ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LOCAL_GL_RGB: {
|
case LOCAL_GL_RGB: {
|
||||||
MOZ_ASSERT(readPixelSize == 2);
|
MOZ_ASSERT(destPixelSize == 2);
|
||||||
MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV);
|
MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV);
|
||||||
readFormatGFX = SurfaceFormat::R5G6B5;
|
readFormatGFX = SurfaceFormat::R5G6B5;
|
||||||
break;
|
break;
|
||||||
@ -307,17 +335,17 @@ ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
|
|||||||
switch (readType) {
|
switch (readType) {
|
||||||
case LOCAL_GL_UNSIGNED_BYTE: {
|
case LOCAL_GL_UNSIGNED_BYTE: {
|
||||||
MOZ_ASSERT(readFormat == LOCAL_GL_RGBA);
|
MOZ_ASSERT(readFormat == LOCAL_GL_RGBA);
|
||||||
readPixelSize = 4;
|
readAlignment = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV: {
|
case LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV: {
|
||||||
MOZ_ASSERT(readFormat == LOCAL_GL_BGRA);
|
MOZ_ASSERT(readFormat == LOCAL_GL_BGRA);
|
||||||
readPixelSize = 4;
|
readAlignment = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV: {
|
case LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV: {
|
||||||
MOZ_ASSERT(readFormat == LOCAL_GL_RGB);
|
MOZ_ASSERT(readFormat == LOCAL_GL_RGB);
|
||||||
readPixelSize = 2;
|
readAlignment = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -330,16 +358,20 @@ ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
|
|||||||
false);
|
false);
|
||||||
readSurf = tempSurf;
|
readSurf = tempSurf;
|
||||||
} else {
|
} else {
|
||||||
readPixelSize = destPixelSize;
|
// Figure out alignment. We don't need to know why, we just need it
|
||||||
|
// to be valid.
|
||||||
|
readAlignment = GuessAlignment(dest->Width(),
|
||||||
|
destPixelSize,
|
||||||
|
dest->Stride());
|
||||||
readSurf = dest;
|
readSurf = dest;
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(readPixelSize);
|
MOZ_ASSERT(readAlignment);
|
||||||
|
|
||||||
GLint currentPackAlignment = 0;
|
GLint currentPackAlignment = 0;
|
||||||
gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, ¤tPackAlignment);
|
gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, ¤tPackAlignment);
|
||||||
|
|
||||||
if (currentPackAlignment != readPixelSize)
|
if (currentPackAlignment != readAlignment)
|
||||||
gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, readPixelSize);
|
gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, readAlignment);
|
||||||
|
|
||||||
GLsizei width = dest->Width();
|
GLsizei width = dest->Width();
|
||||||
GLsizei height = dest->Height();
|
GLsizei height = dest->Height();
|
||||||
@ -351,7 +383,7 @@ ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
|
|||||||
readSurf->Data());
|
readSurf->Data());
|
||||||
readSurf->MarkDirty();
|
readSurf->MarkDirty();
|
||||||
|
|
||||||
if (currentPackAlignment != readPixelSize)
|
if (currentPackAlignment != readAlignment)
|
||||||
gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment);
|
gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment);
|
||||||
|
|
||||||
if (readSurf != dest) {
|
if (readSurf != dest) {
|
||||||
@ -387,6 +419,8 @@ ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
|
|||||||
if (!alphaBits) {
|
if (!alphaBits) {
|
||||||
const uint32_t alphaMask = gfxPackedPixelNoPreMultiply(0xff,0,0,0);
|
const uint32_t alphaMask = gfxPackedPixelNoPreMultiply(0xff,0,0,0);
|
||||||
|
|
||||||
|
MOZ_ASSERT(dest->Width() * destPixelSize == dest->Stride());
|
||||||
|
|
||||||
dest->Flush();
|
dest->Flush();
|
||||||
uint32_t* itr = (uint32_t*)dest->Data();
|
uint32_t* itr = (uint32_t*)dest->Data();
|
||||||
uint32_t testPixel = *itr;
|
uint32_t testPixel = *itr;
|
||||||
|
Loading…
Reference in New Issue
Block a user