Bug 1219985 - The canvas rendering context 2d should be opaque if either the moz-opaque attribute is set or if it has been initialized with alpha:false. r=jrmuizel

If the canvas is cleared by setting the width or height attributes, its
opaqueness should not be affected.

This patch keeps support for moz-opaque, and also keeps the behavior that
changing the moz-opaque attribute clears the canvas, even if this does not
affect the actual opaqueness of the canvas.

MozReview-Commit-ID: LOlsJxiP9kc

--HG--
extra : rebase_source : 8bb95b1d5932c39a8085e007f9fd1b88b97afe55
This commit is contained in:
Markus Stange 2018-05-02 11:23:53 -04:00
Родитель ee4b5de796
Коммит 90d2624508
20 изменённых файлов: 211 добавлений и 17 удалений

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

@ -1085,7 +1085,10 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(layers::LayersBackend aCompos
, mCompositorBackend(aCompositorBackend)
// these are the default values from the Canvas spec
, mWidth(0), mHeight(0)
, mZero(false), mOpaque(false)
, mZero(false)
, mOpaqueAttrValue(false)
, mContextAttributesHasAlpha(true)
, mOpaque(false)
, mResetLayer(true)
, mIPC(false)
, mIsSkiaGL(false)
@ -1995,14 +1998,21 @@ CanvasRenderingContext2D::InitializeWithDrawTarget(nsIDocShell* aShell,
}
void
CanvasRenderingContext2D::SetIsOpaque(bool aIsOpaque)
CanvasRenderingContext2D::SetOpaqueValueFromOpaqueAttr(bool aOpaqueAttrValue)
{
if (aIsOpaque != mOpaque) {
mOpaque = aIsOpaque;
ClearTarget();
if (aOpaqueAttrValue != mOpaqueAttrValue) {
mOpaqueAttrValue = aOpaqueAttrValue;
UpdateIsOpaque();
}
}
void
CanvasRenderingContext2D::UpdateIsOpaque()
{
mOpaque = !mContextAttributesHasAlpha || mOpaqueAttrValue;
ClearTarget();
}
NS_IMETHODIMP
CanvasRenderingContext2D::SetIsIPC(bool aIsIPC)
{
@ -2043,9 +2053,8 @@ CanvasRenderingContext2D::SetContextOptions(JSContext* aCx,
}
}
if (!attributes.mAlpha) {
SetIsOpaque(true);
}
mContextAttributesHasAlpha = attributes.mAlpha;
UpdateIsOpaque();
return NS_OK;
}

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

@ -460,7 +460,7 @@ public:
return mTarget->Snapshot();
}
virtual void SetIsOpaque(bool aIsOpaque) override;
virtual void SetOpaqueValueFromOpaqueAttr(bool aOpaqueAttrValue) override;
bool GetIsOpaque() override { return mOpaque; }
NS_IMETHOD Reset() override;
already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
@ -619,6 +619,9 @@ protected:
// Returns whether the font was successfully updated.
bool SetFontInternal(const nsAString& aFont, mozilla::ErrorResult& aError);
// Clears the target and updates mOpaque based on mOpaqueAttrValue and
// mContextAttributesHasAlpha.
void UpdateIsOpaque();
/**
* Creates the error target, if it doesn't exist
@ -764,6 +767,17 @@ protected:
// specific behavior on some operations.
bool mZero;
// The two ways to set the opaqueness of the canvas.
// mOpaqueAttrValue: Whether the <canvas> element has the moz-opaque attribute
// set. Can change during the lifetime of the context. Non-standard, should
// hopefully go away soon.
// mContextAttributesHasAlpha: The standard way of setting canvas opaqueness.
// Set at context initialization time and never changes.
bool mOpaqueAttrValue;
bool mContextAttributesHasAlpha;
// Determines the context's opaqueness. Is computed from mOpaqueAttrValue and
// mContextAttributesHasAlpha in UpdateIsOpaque().
bool mOpaque;
// This is true when the next time our layer is retrieved we need to

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

@ -231,7 +231,7 @@ CanvasRenderingContextHelper::UpdateContext(JSContext* aCx,
nsCOMPtr<nsICanvasRenderingContextInternal> currentContext = mCurrentContext;
currentContext->SetIsOpaque(GetOpaqueAttr());
currentContext->SetOpaqueValueFromOpaqueAttr(GetOpaqueAttr());
nsresult rv = currentContext->SetContextOptions(aCx, aNewContextOptions,
aRvForDictionaryInit);

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

@ -189,8 +189,9 @@ ImageBitmapRenderingContext::GetSurfaceSnapshot(gfxAlphaType* const aOutAlphaTyp
}
void
ImageBitmapRenderingContext::SetIsOpaque(bool aIsOpaque)
ImageBitmapRenderingContext::SetOpaqueValueFromOpaqueAttr(bool aOpaqueAttrValue)
{
// ignored
}
bool

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

@ -66,7 +66,7 @@ public:
virtual already_AddRefed<mozilla::gfx::SourceSurface>
GetSurfaceSnapshot(gfxAlphaType* aOutAlphaType) override;
virtual void SetIsOpaque(bool aIsOpaque) override;
virtual void SetOpaqueValueFromOpaqueAttr(bool aOpaqueAttrValue) override;
virtual bool GetIsOpaque() override;
NS_IMETHOD Reset() override;
virtual already_AddRefed<Layer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,

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

@ -380,7 +380,7 @@ public:
virtual already_AddRefed<mozilla::gfx::SourceSurface>
GetSurfaceSnapshot(gfxAlphaType* out_alphaType) override;
virtual void SetIsOpaque(bool) override {};
virtual void SetOpaqueValueFromOpaqueAttr(bool) override {};
bool GetIsOpaque() override { return !mOptions.alpha; }
NS_IMETHOD SetContextOptions(JSContext* cx,
JS::Handle<JS::Value> options,

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

@ -126,11 +126,16 @@ public:
virtual already_AddRefed<mozilla::gfx::SourceSurface>
GetSurfaceSnapshot(gfxAlphaType* out_alphaType = nullptr) = 0;
// If this context is opaque, the backing store of the canvas should
// If this is called with true, the backing store of the canvas should
// be created as opaque; all compositing operators should assume the
// dst alpha is always 1.0. If this is never called, the context
// defaults to false (not opaque).
virtual void SetIsOpaque(bool isOpaque) = 0;
// dst alpha is always 1.0. If this is never called, the context's
// opaqueness is determined by the context attributes that it's initialized
// with.
virtual void SetOpaqueValueFromOpaqueAttr(bool aOpaqueAttrValue) = 0;
// Returns whether the context is opaque. This value can be based both on
// the value of the moz-opaque attribute and on the context's initialization
// attributes.
virtual bool GetIsOpaque() = 0;
// Invalidate this context and release any held resources, in preperation

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

@ -0,0 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Basic transparent rendering</title>
<div style="width: 200px; height: 200px; background-color: red;">
<canvas id="c" width="200" height="200"></canvas>
</div>
<script>
var c = document.getElementById('c');
var ctx = c.getContext('2d', { alpha: true });
ctx.fillStyle = 'green';
ctx.fillRect(50, 50, 100, 100);
</script>

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

@ -0,0 +1,17 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Setting the canvas size should clear the canvas</title>
<div style="width: 200px; height: 200px; background-color: red;">
<canvas id="c" width="200" height="200"></canvas>
</div>
<script>
var c = document.getElementById('c');
var ctx = c.getContext('2d', { alpha: true });
ctx.fillStyle = 'green';
ctx.fillRect(50, 50, 100, 100);
c.width = 200;
</script>

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

@ -0,0 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Basic rendering into a non-alpha canvas</title>
<div style="width: 200px; height: 200px; background-color: red;">
<canvas id="c" width="200" height="200"></canvas>
</div>
<script>
var c = document.getElementById('c');
var ctx = c.getContext('2d', { alpha: false });
ctx.fillStyle = 'green';
ctx.fillRect(50, 50, 100, 100);
</script>

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

@ -0,0 +1,17 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Setting the canvas size on a non-alpha should clear the canvas to opaque black</title>
<div style="width: 200px; height: 200px; background-color: red;">
<canvas id="c" width="200" height="200"></canvas>
</div>
<script>
var c = document.getElementById('c');
var ctx = c.getContext('2d', { alpha: false });
ctx.fillStyle = 'green';
ctx.fillRect(50, 50, 100, 100);
c.width = 200;
</script>

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

@ -0,0 +1,17 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Only the context attributes from the first getContext call should be respected.</title>
<div style="width: 200px; height: 200px; background-color: red;">
<canvas id="c" width="200" height="200"></canvas>
</div>
<script>
var c = document.getElementById('c');
var ctx = c.getContext('2d', { alpha: true });
ctx = c.getContext('2d', { alpha: false });
ctx.fillStyle = 'green';
ctx.fillRect(50, 50, 100, 100);
</script>

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

@ -0,0 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: moz-opaque should have the same effect as alpha:false</title>
<div style="width: 200px; height: 200px; background-color: red;">
<canvas id="c" width="200" height="200" moz-opaque="true"></canvas>
</div>
<script>
var c = document.getElementById('c');
var ctx = c.getContext('2d', { alpha: true });
ctx.fillStyle = 'green';
ctx.fillRect(50, 50, 100, 100);
</script>

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

@ -0,0 +1,17 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Unsetting moz-opaque should clear the canvas</title>
<div style="width: 200px; height: 200px; background-color: red;">
<canvas id="c" width="200" height="200" moz-opaque="true"></canvas>
</div>
<script>
var c = document.getElementById('c');
var ctx = c.getContext('2d', { alpha: true });
ctx.fillStyle = 'green';
ctx.fillRect(50, 50, 100, 100);
c.removeAttribute("moz-opaque");
</script>

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

@ -0,0 +1,17 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Unsetting moz-opaque should clear the canvas even if the canvas has been created with alpha:false, and the canvas should stay opaque.</title>
<div style="width: 200px; height: 200px; background-color: red;">
<canvas id="c" width="200" height="200" moz-opaque="true"></canvas>
</div>
<script>
var c = document.getElementById('c');
var ctx = c.getContext('2d', { alpha: false });
ctx.fillStyle = 'green';
ctx.fillRect(50, 50, 100, 100);
c.removeAttribute("moz-opaque");
</script>

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

@ -0,0 +1,5 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Reference for an opaque canvas with nothing rendered in it</title>
<div style="width: 200px; height: 200px; background: black"></div>

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

@ -0,0 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Reference for an opaque canvas with a green square rendered in it</title>
<div style="width: 200px; height: 200px; background: black; display: flex;">
<div style="width: 100px; height: 100px; margin: auto; background: green;"></div>
</div>

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

@ -0,0 +1,5 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Reference for a regular (non-opaque) canvas with nothing rendered in it. The red background behind the canvas is visible.</title>
<div style="width: 200px; height: 200px; background: red"></div>

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

@ -0,0 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Bug 1219985: Reference for a regular (non-opaque) canvas with a green square rendered in it. The red background behind the canvas is visible.</title>
<div style="width: 200px; height: 200px; background: red; display: flex;">
<div style="width: 100px; height: 100px; margin: auto; background: green;"></div>
</div>

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

@ -1959,6 +1959,14 @@ fuzzy-if(skiaContent,1,1) == 1202512-2.html 1202512-2-ref.html
== 1209994-2.html 1209994-2-ref.html
== 1209994-3.html 1209994-3-ref.html
== 1209994-4.html 1209994-4-ref.html
== 1219985-1.html 1219985-ref-transparent-with-rendering.html
== 1219985-2.html 1219985-ref-transparent-clear.html
== 1219985-3.html 1219985-ref-opaque-with-rendering.html
== 1219985-4.html 1219985-ref-opaque-clear.html
== 1219985-5.html 1219985-ref-transparent-with-rendering.html
== 1219985-6.html 1219985-ref-opaque-with-rendering.html
== 1219985-7.html 1219985-ref-transparent-clear.html
== 1219985-8.html 1219985-ref-opaque-clear.html
== 1222226-1.html 1222226-1-ref.html
pref(layout.css.overflow-clip-box.enabled,true) == 1226278.html 1226278-ref.html
== 1230466.html about:blank