Bug 1305832 - Only glClear for ANGLE's ANGLE_depth_texture textures. - r=ethlin
MozReview-Commit-ID: H6yE1ib2TRI
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -2216,77 +2216,55 @@ Intersect(uint32_t srcSize, int32_t dstS
// [=====|==] // dst box
// ^-----^
*out_intStartInDst = std::max<int32_t>(0, 0 - dstStartInSrc);
int32_t intEndInSrc = std::min<int32_t>(srcSize, dstStartInSrc + dstSize);
*out_intSize = std::max<int32_t>(0, intEndInSrc - *out_intStartInSrc);
}
-static bool
-ZeroTexImageWithClear(WebGLContext* webgl, GLContext* gl, TexImageTarget target,
- GLuint tex, uint32_t level, const webgl::FormatUsageInfo* usage,
- uint32_t width, uint32_t height)
+static void
+ZeroANGLEDepthTexture(WebGLContext* webgl, GLuint tex,
+ const webgl::FormatUsageInfo* usage, uint32_t width,
+ uint32_t height)
{
- MOZ_ASSERT(gl->IsCurrent());
-
- ScopedFramebuffer scopedFB(gl);
- ScopedBindFramebuffer scopedBindFB(gl, scopedFB.FB());
-
- const auto format = usage->format;
-
+ const auto& format = usage->format;
GLenum attachPoint = 0;
GLbitfield clearBits = 0;
- if (format->IsColorFormat()) {
- attachPoint = LOCAL_GL_COLOR_ATTACHMENT0;
- clearBits = LOCAL_GL_COLOR_BUFFER_BIT;
- }
-
if (format->d) {
attachPoint = LOCAL_GL_DEPTH_ATTACHMENT;
clearBits |= LOCAL_GL_DEPTH_BUFFER_BIT;
}
if (format->s) {
attachPoint = (format->d ? LOCAL_GL_DEPTH_STENCIL_ATTACHMENT
: LOCAL_GL_STENCIL_ATTACHMENT);
clearBits |= LOCAL_GL_STENCIL_BUFFER_BIT;
}
MOZ_RELEASE_ASSERT(attachPoint && clearBits, "GFX: No bits cleared.");
- {
- gl::GLContext::LocalErrorScope errorScope(*gl);
- MOZ_ASSERT(target != LOCAL_GL_TEXTURE_2D_ARRAY &&
- target != LOCAL_GL_TEXTURE_3D);
- gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachPoint, target.get(), tex,
- level);
- if (errorScope.GetError()) {
- MOZ_ASSERT(false);
- return false;
- }
- }
-
- auto status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
- if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
- return false;
-
- {
- gl::GLContext::LocalErrorScope errorScope(*gl);
-
- const bool fakeNoAlpha = false;
- webgl->ForceClearFramebufferWithDefaultValues(clearBits, fakeNoAlpha);
- if (errorScope.GetError()) {
- MOZ_ASSERT(false);
- return false;
- }
- }
-
- return true;
+ ////
+ const auto& gl = webgl->gl;
+ MOZ_ASSERT(gl->IsCurrent());
+
+ ScopedFramebuffer scopedFB(gl);
+ ScopedBindFramebuffer scopedBindFB(gl, scopedFB.FB());
+
+ gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachPoint, LOCAL_GL_TEXTURE_2D,
+ tex, 0);
+
+ const auto& status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
+ MOZ_RELEASE_ASSERT(status == LOCAL_GL_FRAMEBUFFER_COMPLETE);
+
+ ////
+
+ const bool fakeNoAlpha = false;
+ webgl->ForceClearFramebufferWithDefaultValues(clearBits, fakeNoAlpha);
}
bool
ZeroTextureData(WebGLContext* webgl, const char* funcName, GLuint tex,
TexImageTarget target, uint32_t level,
const webgl::FormatUsageInfo* usage, uint32_t width, uint32_t height,
uint32_t depth)
{
@@ -2355,22 +2333,26 @@ ZeroTextureData(WebGLContext* webgl, con
width, height, depth, sizedFormat,
byteCount, zeros.get());
return !error;
}
const auto driverUnpackInfo = usage->idealUnpack;
MOZ_RELEASE_ASSERT(driverUnpackInfo, "GFX: ideal unpack info not set.");
- if (!webgl->IsWebGL2() && usage->format->d) {
+ if (webgl->IsExtensionEnabled(WebGLExtensionID::WEBGL_depth_texture) &&
+ gl->IsANGLE() &&
+ usage->format->d)
+ {
// ANGLE_depth_texture does not allow uploads, so we have to clear.
- const bool success = ZeroTexImageWithClear(webgl, gl, target, tex, level, usage,
- width, height);
- MOZ_ASSERT(success);
- return success;
+ // (Restriction because of D3D9)
+ MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D);
+ MOZ_ASSERT(level == 0);
+ ZeroANGLEDepthTexture(webgl, tex, usage, width, height);
+ return true;
}
const webgl::PackingInfo packing = driverUnpackInfo->ToPacking();
const auto bytesPerPixel = webgl::BytesPerPixel(packing);
CheckedUint32 checkedByteCount = bytesPerPixel;
checkedByteCount *= width;
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -1952,26 +1952,39 @@ DoCopyTexOrSubImage(WebGLContext* webgl,
Intersect(srcTotalHeight, yWithinSrc, dstHeight, &readY, &writeY, &rwHeight);
////
GLenum error = 0;
do {
const auto& idealUnpack = dstUsage->idealUnpack;
if (!isSubImage) {
- const auto& pi = idealUnpack->ToPacking();
- const auto& bpp = BytesPerPixel(pi);
- const UniqueBuffer zeros(calloc(1, dstWidth * dstHeight * bpp));
- if (!zeros.get()) {
- webgl->ErrorOutOfMemory("%s: Ran out of memory allocating zeros.",
- funcName);
- return false;
+ UniqueBuffer buffer;
+
+ if (rwWidth != dstWidth || rwHeight != dstHeight) {
+ const auto& pi = idealUnpack->ToPacking();
+ CheckedUint32 byteCount = BytesPerPixel(pi);
+ byteCount *= dstWidth;
+ byteCount *= dstHeight;
+
+ if (byteCount.isValid()) {
+ buffer = calloc(1, byteCount.value());
+ }
+
+ if (!buffer.get()) {
+ webgl->ErrorOutOfMemory("%s: Ran out of memory allocating zeros.",
+ funcName);
+ return false;
+ }
}
+
+ const ScopedUnpackReset unpackReset(webgl);
+ gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1);
error = DoTexImage(gl, target, level, idealUnpack, dstWidth, dstHeight, 1,
- zeros.get());
+ buffer.get());
if (error)
break;
}
if (!rwWidth || !rwHeight) {
// There aren't any pixels to copy, so we're 'done'.
return true;
}