Backed out changeset 20b75bf44c1e (bug 997014)

This commit is contained in:
Carsten "Tomcat" Book 2014-04-17 08:43:43 +02:00
parent 810846820e
commit 502139c768
8 changed files with 49 additions and 119 deletions

View File

@ -1034,7 +1034,7 @@ protected:
if (mPixelStoreColorspaceConversion == LOCAL_GL_NONE)
flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
if (!mPixelStorePremultiplyAlpha)
flags |= nsLayoutUtils::SFE_PREFER_NO_PREMULTIPLY_ALPHA;
flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA;
return nsLayoutUtils::SurfaceFromElement(aElement, flags);
}
template<class ElementType>

View File

@ -29,7 +29,6 @@
#include "nsLayoutUtils.h"
#include "CanvasUtils.h"
#include "gfxUtils.h"
#include "jsfriendapi.h"
@ -2522,10 +2521,6 @@ WebGLContext::SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromE
return NS_OK;
}
if (!mPixelStorePremultiplyAlpha && res.mIsPremultiplied) {
data = gfxUtils::UnpremultiplyDataSurface(data);
}
// We disallow loading cross-domain images and videos that have not been validated
// with CORS as WebGL textures. The reason for doing that is that timing
// attacks on WebGL shaders are able to retrieve approximations of the

View File

@ -26,9 +26,6 @@ namespace layers {
class CanvasLayer;
class LayerManager;
}
namespace gfx {
class SourceSurface;
}
namespace dom {
@ -169,7 +166,6 @@ public:
NS_IMETHOD RenderContextsExternal(gfxContext *aContext,
GraphicsFilter aFilter,
uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
virtual TemporaryRef<gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr);
virtual bool ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,

View File

@ -38,7 +38,6 @@
#endif
using namespace mozilla::layers;
using namespace mozilla::gfx;
NS_IMPL_NS_NEW_HTML_ELEMENT(Canvas)
@ -950,14 +949,5 @@ HTMLCanvasElement::RenderContextsExternal(gfxContext *aContext, GraphicsFilter a
return mCurrentContext->Render(aContext, aFilter, aFlags);
}
TemporaryRef<SourceSurface>
HTMLCanvasElement::GetSurfaceSnapshot(bool* aPremultAlpha)
{
if (!mCurrentContext)
return nullptr;
return mCurrentContext->GetSurfaceSnapshot(aPremultAlpha);
}
} // namespace dom
} // namespace mozilla

View File

@ -141,66 +141,6 @@ gfxUtils::UnpremultiplyImageSurface(gfxImageSurface *aSourceSurface,
}
}
TemporaryRef<DataSourceSurface>
gfxUtils::UnpremultiplyDataSurface(DataSourceSurface* aSurface)
{
// Only premultiply ARGB32
if (aSurface->GetFormat() != SurfaceFormat::B8G8R8A8) {
return aSurface;
}
DataSourceSurface::MappedSurface map;
if (!aSurface->Map(DataSourceSurface::MapType::READ, &map)) {
return nullptr;
}
RefPtr<DataSourceSurface> dest = Factory::CreateDataSourceSurfaceWithStride(aSurface->GetSize(),
aSurface->GetFormat(),
map.mStride);
DataSourceSurface::MappedSurface destMap;
if (!dest->Map(DataSourceSurface::MapType::WRITE, &destMap)) {
aSurface->Unmap();
return nullptr;
}
uint8_t *src = map.mData;
uint8_t *dst = destMap.mData;
for (int32_t i = 0; i < aSurface->GetSize().height; ++i) {
uint8_t *srcRow = src + (i * map.mStride);
uint8_t *dstRow = dst + (i * destMap.mStride);
for (int32_t j = 0; j < aSurface->GetSize().width; ++j) {
#ifdef IS_LITTLE_ENDIAN
uint8_t b = *srcRow++;
uint8_t g = *srcRow++;
uint8_t r = *srcRow++;
uint8_t a = *srcRow++;
*dstRow++ = UnpremultiplyValue(a, b);
*dstRow++ = UnpremultiplyValue(a, g);
*dstRow++ = UnpremultiplyValue(a, r);
*dstRow++ = a;
#else
uint8_t a = *srcRow++;
uint8_t r = *srcRow++;
uint8_t g = *srcRow++;
uint8_t b = *srcRow++;
*dstRow++ = a;
*dstRow++ = UnpremultiplyValue(a, r);
*dstRow++ = UnpremultiplyValue(a, g);
*dstRow++ = UnpremultiplyValue(a, b);
#endif
}
}
aSurface->Unmap();
dest->Unmap();
return dest;
}
void
gfxUtils::ConvertBGRAtoRGBA(gfxImageSurface *aSourceSurface,
gfxImageSurface *aDestSurface) {

View File

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

View File

@ -5387,10 +5387,8 @@ nsLayoutUtils::SurfaceFromElement(nsIImageLoadingContent* aElement,
uint32_t frameFlags = imgIContainer::FLAG_SYNC_DECODE;
if (aSurfaceFlags & SFE_NO_COLORSPACE_CONVERSION)
frameFlags |= imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION;
if (aSurfaceFlags & SFE_PREFER_NO_PREMULTIPLY_ALPHA) {
if (aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA)
frameFlags |= imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
result.mIsPremultiplied = false;
}
int32_t imgWidth, imgHeight;
rv = imgContainer->GetWidth(&imgWidth);
@ -5452,28 +5450,52 @@ nsLayoutUtils::SurfaceFromElement(HTMLCanvasElement* aElement,
DrawTarget* aTarget)
{
SurfaceFromElementResult result;
nsresult rv;
bool* isPremultiplied = nullptr;
if (aSurfaceFlags & SFE_PREFER_NO_PREMULTIPLY_ALPHA) {
isPremultiplied = &result.mIsPremultiplied;
}
bool premultAlpha = (aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA) == 0;
gfxIntSize size = aElement->GetSize();
result.mSourceSurface = aElement->GetSurfaceSnapshot(isPremultiplied);
if (!result.mSourceSurface) {
// If the element doesn't have a context then we won't get a snapshot. The canvas spec wants us to not error and just
// draw nothing, so return an empty surface.
DrawTarget *ref = aTarget ? aTarget : gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
RefPtr<DrawTarget> dt = ref->CreateSimilarDrawTarget(IntSize(size.width, size.height),
SurfaceFormat::B8G8R8A8);
if (dt) {
result.mSourceSurface = dt->Snapshot();
if (premultAlpha && aElement->CountContexts() == 1) {
nsICanvasRenderingContextInternal *srcCanvas = aElement->GetContextAtIndex(0);
result.mSourceSurface = srcCanvas->GetSurfaceSnapshot();
}
} else if (aTarget) {
RefPtr<SourceSurface> opt = aTarget->OptimizeSourceSurface(result.mSourceSurface);
if (opt) {
result.mSourceSurface = opt;
if (!result.mSourceSurface) {
nsRefPtr<gfxContext> ctx;
RefPtr<DrawTarget> dt;
if (premultAlpha) {
if (aTarget) {
dt = aTarget->CreateSimilarDrawTarget(IntSize(size.width, size.height), SurfaceFormat::B8G8R8A8);
} else {
dt = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize(size.width, size.height),
SurfaceFormat::B8G8R8A8);
}
if (!dt) {
return result;
}
ctx = new gfxContext(dt);
} else {
// TODO: RenderContextsExternal expects to get a gfxImageFormat
// so that it can un-premultiply.
RefPtr<DataSourceSurface> data = Factory::CreateDataSourceSurface(IntSize(size.width, size.height),
SurfaceFormat::B8G8R8A8);
memset(data->GetData(), 0, data->Stride() * size.height);
result.mSourceSurface = data;
nsRefPtr<gfxImageSurface> image = new gfxImageSurface(data->GetData(),
gfxIntSize(size.width, size.height),
data->Stride(),
gfxImageFormat::ARGB32);
ctx = new gfxContext(image);
}
// XXX shouldn't use the external interface, but maybe we can layerify this
uint32_t flags = premultAlpha ? HTMLCanvasElement::RenderFlagPremultAlpha : 0;
rv = aElement->RenderContextsExternal(ctx, GraphicsFilter::FILTER_NEAREST, flags);
if (NS_FAILED(rv))
return result;
if (premultAlpha) {
result.mSourceSurface = dt->Snapshot();
}
}
@ -5495,7 +5517,7 @@ nsLayoutUtils::SurfaceFromElement(HTMLVideoElement* aElement,
{
SurfaceFromElementResult result;
NS_WARN_IF_FALSE((aSurfaceFlags & SFE_PREFER_NO_PREMULTIPLY_ALPHA) == 0, "We can't support non-premultiplied alpha for video!");
NS_WARN_IF_FALSE((aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA) == 0, "We can't support non-premultiplied alpha for video!");
uint16_t readyState;
if (NS_SUCCEEDED(aElement->GetReadyState(&readyState)) &&
@ -5519,13 +5541,6 @@ nsLayoutUtils::SurfaceFromElement(HTMLVideoElement* aElement,
if (!result.mSourceSurface)
return result;
if (aTarget) {
RefPtr<SourceSurface> opt = aTarget->OptimizeSourceSurface(result.mSourceSurface);
if (opt) {
result.mSourceSurface = opt;
}
}
result.mCORSUsed = aElement->GetCORSMode() != CORS_NONE;
result.mSize = ThebesIntSize(size);
result.mPrincipal = principal.forget();
@ -6494,10 +6509,7 @@ nsLayoutUtils::WantSubAPZC()
nsLayoutUtils::SurfaceFromElementResult::SurfaceFromElementResult()
// Use safe default values here
: mIsWriteOnly(true)
, mIsStillLoading(false)
, mCORSUsed(false)
, mIsPremultiplied(true)
: mIsWriteOnly(true), mIsStillLoading(false), mCORSUsed(false)
{
}

View File

@ -1695,10 +1695,10 @@ public:
SFE_WANT_FIRST_FRAME = 1 << 1,
/* Whether we should skip colorspace/gamma conversion */
SFE_NO_COLORSPACE_CONVERSION = 1 << 2,
/* Specifies that the caller wants unpremultiplied pixel data.
If this is can be done efficiently, the result will be a
DataSourceSurface and mIsPremultiplied with be set to false. */
SFE_PREFER_NO_PREMULTIPLY_ALPHA = 1 << 3,
/* Whether we should skip premultiplication -- the resulting
image will always be an image surface, and must not be given to
Thebes for compositing! */
SFE_NO_PREMULTIPLY_ALPHA = 1 << 3,
/* Whether we should skip getting a surface for vector images and
return a DirectDrawInfo containing an imgIContainer instead. */
SFE_NO_RASTERIZING_VECTORS = 1 << 4
@ -1736,8 +1736,6 @@ public:
bool mIsStillLoading;
/* Whether the element used CORS when loading. */
bool mCORSUsed;
/* Whether the returned image contains premultiplied pixel data */
bool mIsPremultiplied;
};
static SurfaceFromElementResult SurfaceFromElement(mozilla::dom::Element *aElement,