Bug 1006198 - Add PremultiplyDataSurface. r=nical

This commit is contained in:
Matt Woodrow 2014-05-13 14:20:26 +12:00
parent 5fbdfc89f5
commit f2b9c64192
3 changed files with 50 additions and 3 deletions

View File

@ -21,7 +21,7 @@
#include "nsISupportsImpl.h" // for gfxContext::AddRef, etc
#include "nsRect.h" // for nsIntRect
#include "nsSize.h" // for nsIntSize
#include "LayerUtils.h"
#include "gfxUtils.h"
using namespace mozilla::gfx;
using namespace mozilla::gl;
@ -126,7 +126,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
Factory::CreateWrappingDataSourceSurface(destData, destStride, destSize, destFormat);
mGLContext->Screen()->Readback(sharedSurf, data);
if (needsPremult) {
PremultiplySurface(data);
gfxUtils::PremultiplyDataSurface(data);
}
aDestTarget->ReleaseBits(destData);
return;
@ -144,7 +144,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
// Readback handles Flush/MarkDirty.
mGLContext->Screen()->Readback(sharedSurf, data);
if (needsPremult) {
PremultiplySurface(data);
gfxUtils::PremultiplyDataSurface(data);
}
resultSurf = data;
}

View File

@ -89,6 +89,52 @@ gfxUtils::PremultiplyImageSurface(gfxImageSurface *aSourceSurface,
}
}
void
gfxUtils::PremultiplyDataSurface(DataSourceSurface *aSurface)
{
// Only premultiply ARGB32
if (aSurface->GetFormat() != SurfaceFormat::B8G8R8A8) {
return;
}
DataSourceSurface::MappedSurface map;
if (!aSurface->Map(DataSourceSurface::MapType::READ_WRITE, &map)) {
return;
}
MOZ_ASSERT(map.mStride == aSurface->GetSize().width * 4,
"Source surface stride isn't tightly packed");
uint8_t *src = map.mData;
uint8_t *dst = map.mData;
uint32_t dim = aSurface->GetSize().width * aSurface->GetSize().height;
for (uint32_t i = 0; i < dim; ++i) {
#ifdef IS_LITTLE_ENDIAN
uint8_t b = *src++;
uint8_t g = *src++;
uint8_t r = *src++;
uint8_t a = *src++;
*dst++ = PremultiplyValue(a, b);
*dst++ = PremultiplyValue(a, g);
*dst++ = PremultiplyValue(a, r);
*dst++ = a;
#else
uint8_t a = *src++;
uint8_t r = *src++;
uint8_t g = *src++;
uint8_t b = *src++;
*dst++ = a;
*dst++ = PremultiplyValue(a, r);
*dst++ = PremultiplyValue(a, g);
*dst++ = PremultiplyValue(a, b);
#endif
}
aSurface->Unmap();
}
void
gfxUtils::UnpremultiplyImageSurface(gfxImageSurface *aSourceSurface,
gfxImageSurface *aDestSurface)

View File

@ -42,6 +42,7 @@ public:
*/
static void PremultiplyImageSurface(gfxImageSurface *aSourceSurface,
gfxImageSurface *aDestSurface = nullptr);
static void PremultiplyDataSurface(DataSourceSurface *aSurface);
static void UnpremultiplyImageSurface(gfxImageSurface *aSurface,
gfxImageSurface *aDestSurface = nullptr);
static mozilla::TemporaryRef<DataSourceSurface> UnpremultiplyDataSurface(DataSourceSurface* aSurface);