summaryrefslogtreecommitdiffstats
path: root/dom/canvas
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas')
-rw-r--r--dom/canvas/CanvasRenderingContext2D.cpp14
-rw-r--r--dom/canvas/CanvasRenderingContext2D.h5
-rw-r--r--dom/canvas/ImageBitmap.cpp11
-rw-r--r--dom/canvas/WebGLContextDraw.cpp21
-rw-r--r--dom/canvas/WebGLShaderValidator.cpp68
-rw-r--r--dom/canvas/WebGLShaderValidator.h6
6 files changed, 78 insertions, 47 deletions
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
index f4c4259f6..18af28e9f 100644
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -1862,8 +1862,6 @@ CanvasRenderingContext2D::GetHeight() const
NS_IMETHODIMP
CanvasRenderingContext2D::SetDimensions(int32_t aWidth, int32_t aHeight)
{
- ClearTarget();
-
// Zero sized surfaces can cause problems.
mZero = false;
if (aHeight == 0) {
@@ -1874,14 +1872,14 @@ CanvasRenderingContext2D::SetDimensions(int32_t aWidth, int32_t aHeight)
aWidth = 1;
mZero = true;
}
- mWidth = aWidth;
- mHeight = aHeight;
+
+ ClearTarget(aWidth, aHeight);
return NS_OK;
}
void
-CanvasRenderingContext2D::ClearTarget()
+CanvasRenderingContext2D::ClearTarget(int32_t aWidth, int32_t aHeight)
{
Reset();
@@ -1889,6 +1887,12 @@ CanvasRenderingContext2D::ClearTarget()
SetInitialState();
+ // Update dimensions only if new (strictly positive) values were passed.
+ if (aWidth > 0 && aHeight > 0) {
+ mWidth = aWidth;
+ mHeight = aHeight;
+ }
+
// For vertical writing-mode, unless text-orientation is sideways,
// we'll modify the initial value of textBaseline to 'middle'.
RefPtr<nsStyleContext> canvasStyle;
diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h
index d5dff8f3b..848b3ee08 100644
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -669,8 +669,11 @@ protected:
/**
* Disposes an old target and prepares to lazily create a new target.
+ *
+ * Parameters are the new dimensions to be used, or if either is negative,
+ * existing dimensions will be left unchanged.
*/
- void ClearTarget();
+ void ClearTarget(int32_t aWidth = -1, int32_t aHeight = -1);
/*
* Returns the target to the buffer provider. i.e. this will queue a frame for
diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp
index 6588e0aa3..e45cdfc6f 100644
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -950,7 +950,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
imageSize,
aCropRect,
getter_AddRefs(data));
- task->Dispatch(aRv);
+ task->Dispatch(Terminating, aRv);
}
if (NS_WARN_IF(!data)) {
@@ -1377,10 +1377,10 @@ private:
RefPtr<DecodeBlobInMainThreadSyncTask> task =
new DecodeBlobInMainThreadSyncTask(mWorkerPrivate, *mBlob, mCropRect,
getter_AddRefs(data), sourceSize);
- task->Dispatch(rv); // This is a synchronous call.
+ task->Dispatch(Terminating, rv); // This is a synchronous call.
+ // In case the worker is terminating, this rejection can be handled.
if (NS_WARN_IF(rv.Failed())) {
- // XXXbz does this really make sense if we're shutting down? Ah, well.
mPromise->MaybeReject(rv);
return nullptr;
}
@@ -2104,7 +2104,10 @@ ImageBitmap::Create(nsIGlobalObject* aGlobal,
aFormat,
aLayout,
getter_AddRefs(data));
- task->Dispatch(aRv);
+ task->Dispatch(Terminating, aRv);
+ if (aRv.Failed()) {
+ return promise.forget();
+ }
}
if (NS_WARN_IF(!data)) {
diff --git a/dom/canvas/WebGLContextDraw.cpp b/dom/canvas/WebGLContextDraw.cpp
index 867e47cbd..fd9ee4957 100644
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -216,7 +216,21 @@ WebGLContext::BindFakeBlack(uint32_t texUnit, TexTarget target, FakeBlackType fa
UniquePtr<FakeBlackTexture>& fakeBlackTex = *slot;
if (!fakeBlackTex) {
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1);
+ if (IsWebGL2()) {
+ gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_PIXELS, 0);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_ROWS, 0);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES, 0);
+ }
+
fakeBlackTex = FakeBlackTexture::Create(gl, target, fakeBlack);
+
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, mPixelStore_UnpackAlignment);
+ if (IsWebGL2()) {
+ gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_PIXELS, mPixelStore_UnpackSkipPixels);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_ROWS, mPixelStore_UnpackSkipRows);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES, mPixelStore_UnpackSkipImages);
+ }
if (!fakeBlackTex) {
return false;
}
@@ -1212,13 +1226,8 @@ WebGLContext::FakeBlackTexture::Create(gl::GLContext* gl, TexTarget target,
gl->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
gl->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
- // We allocate our zeros on the heap, and we overallocate (16 bytes instead of 4) to
- // minimize the risk of running into a driver bug in texImage2D, as it is a bit
- // unusual maybe to create 1x1 textures, and the stack may not have the alignment that
- // TexImage2D expects.
-
const webgl::DriverUnpackInfo dui = {texFormat, texFormat, LOCAL_GL_UNSIGNED_BYTE};
- UniqueBuffer zeros = moz_xcalloc(1, 16); // Infallible allocation.
+ UniqueBuffer zeros = moz_xcalloc(1, 4); // Infallible allocation.
MOZ_ASSERT(gl->IsCurrent());
diff --git a/dom/canvas/WebGLShaderValidator.cpp b/dom/canvas/WebGLShaderValidator.cpp
index 80ba359a3..fda31e212 100644
--- a/dom/canvas/WebGLShaderValidator.cpp
+++ b/dom/canvas/WebGLShaderValidator.cpp
@@ -28,20 +28,39 @@ IdentifierHashFunc(const char* name, size_t len)
return hash[0];
}
-static ShCompileOptions
+static int
ChooseValidatorCompileOptions(const ShBuiltInResources& resources,
const mozilla::gl::GLContext* gl)
{
- ShCompileOptions options = SH_VARIABLES |
- SH_ENFORCE_PACKING_RESTRICTIONS |
- SH_OBJECT_CODE |
- SH_INIT_GL_POSITION;
-
+ int options = SH_VARIABLES |
+ SH_ENFORCE_PACKING_RESTRICTIONS |
+ SH_INIT_VARYINGS_WITHOUT_STATIC_USE |
+ SH_OBJECT_CODE |
+ SH_INIT_GL_POSITION;
+
+ if (resources.MaxExpressionComplexity > 0) {
+ options |= SH_LIMIT_EXPRESSION_COMPLEXITY;
+ }
// Sampler arrays indexed with non-constant expressions are forbidden in
// GLSL 1.30 and later.
// ESSL 3 requires constant-integral-expressions for this as well.
// Just do it universally.
options |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
+
+ // Needed for driver bug detection
+ options |= SH_EMULATE_BUILT_IN_FUNCTIONS;
+
+ if (gfxPrefs::WebGLAllANGLEOptions()) {
+ return options |
+ SH_VALIDATE_LOOP_INDEXING |
+ SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX |
+ SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX |
+ SH_CLAMP_INDIRECT_ARRAY_BOUNDS |
+ SH_UNFOLD_SHORT_CIRCUIT |
+ SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS |
+ SH_INIT_OUTPUT_VARIABLES |
+ SH_REGENERATE_STRUCT_NAMES;
+ }
#ifndef XP_MACOSX
// We want to do this everywhere, but to do this on Mac, we need
@@ -55,30 +74,23 @@ ChooseValidatorCompileOptions(const ShBuiltInResources& resources,
// Work around https://bugs.webkit.org/show_bug.cgi?id=124684,
// https://chromium.googlesource.com/angle/angle/+/5e70cf9d0b1bb
options |= SH_UNFOLD_SHORT_CIRCUIT;
+
+ // OS X 10.7/10.8 specific:
+
+ // Work around bug 665578 and bug 769810
+ if (gl->Vendor() == gl::GLVendor::ATI) {
+ options |= SH_EMULATE_BUILT_IN_FUNCTIONS;
+ }
+ // Work around bug 735560
+ if (gl->Vendor() == gl::GLVendor::Intel) {
+ options |= SH_EMULATE_BUILT_IN_FUNCTIONS;
+ }
// Work around that Mac drivers handle struct scopes incorrectly.
options |= SH_REGENERATE_STRUCT_NAMES;
- options |= SH_INIT_OUTPUT_VARIABLES;
}
#endif
- if (gfxPrefs::WebGLAllANGLEOptions()) {
- options = -1;
-
- options ^= SH_INTERMEDIATE_TREE;
- options ^= SH_LINE_DIRECTIVES;
- options ^= SH_SOURCE_PATH;
-
- options ^= SH_LIMIT_EXPRESSION_COMPLEXITY;
- options ^= SH_LIMIT_CALL_STACK_DEPTH;
-
- options ^= SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS;
- options ^= SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL;
-
- options ^= SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT;
- options ^= SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3;
- }
-
if (resources.MaxExpressionComplexity > 0) {
options |= SH_LIMIT_EXPRESSION_COMPLEXITY;
}
@@ -173,7 +185,7 @@ WebGLContext::CreateShaderValidator(GLenum shaderType) const
#endif
}
- const auto compileOptions = webgl::ChooseValidatorCompileOptions(resources, gl);
+ int compileOptions = webgl::ChooseValidatorCompileOptions(resources, gl);
return webgl::ShaderValidator::Create(shaderType, spec, outputLanguage, resources,
compileOptions);
}
@@ -186,7 +198,7 @@ namespace webgl {
ShaderValidator::Create(GLenum shaderType, ShShaderSpec spec,
ShShaderOutput outputLanguage,
const ShBuiltInResources& resources,
- ShCompileOptions compileOptions)
+ int compileOptions)
{
ShHandle handle = ShConstructCompiler(shaderType, spec, outputLanguage, &resources);
if (!handle)
@@ -283,8 +295,8 @@ ShaderValidator::CanLinkTo(const ShaderValidator* prev, nsCString* const out_log
}
}
{
- const auto vertVars = sh::GetInterfaceBlocks(prev->mHandle);
- const auto fragVars = sh::GetInterfaceBlocks(mHandle);
+ const auto vertVars = ShGetInterfaceBlocks(prev->mHandle);
+ const auto fragVars = ShGetInterfaceBlocks(mHandle);
if (!vertVars || !fragVars) {
nsPrintfCString error("Could not create uniform block list.");
*out_log = error;
diff --git a/dom/canvas/WebGLShaderValidator.h b/dom/canvas/WebGLShaderValidator.h
index deb1c7c7f..ba50def28 100644
--- a/dom/canvas/WebGLShaderValidator.h
+++ b/dom/canvas/WebGLShaderValidator.h
@@ -17,7 +17,7 @@ namespace webgl {
class ShaderValidator final
{
const ShHandle mHandle;
- const ShCompileOptions mCompileOptions;
+ const int mCompileOptions;
const int mMaxVaryingVectors;
bool mHasRun;
@@ -25,10 +25,10 @@ public:
static ShaderValidator* Create(GLenum shaderType, ShShaderSpec spec,
ShShaderOutput outputLanguage,
const ShBuiltInResources& resources,
- ShCompileOptions compileOptions);
+ int compileOptions);
private:
- ShaderValidator(ShHandle handle, ShCompileOptions compileOptions,
+ ShaderValidator(ShHandle handle, int compileOptions,
int maxVaryingVectors)
: mHandle(handle)
, mCompileOptions(compileOptions)