diff --git a/gfx/webrender_bindings/RenderCompositorSWGL.cpp b/gfx/webrender_bindings/RenderCompositorSWGL.cpp index 2f2050cbe096..ec5be61f4d10 100644 --- a/gfx/webrender_bindings/RenderCompositorSWGL.cpp +++ b/gfx/webrender_bindings/RenderCompositorSWGL.cpp @@ -50,7 +50,7 @@ bool RenderCompositorSWGL::BeginFrame() { // Set up a temporary region representing the entire window surface in case a // dirty region is not supplied. ClearMappedBuffer(); - mDirtyRegion = LayoutDeviceIntRect(LayoutDeviceIntPoint(), GetBufferSize()); + mRegion = LayoutDeviceIntRect(LayoutDeviceIntPoint(), GetBufferSize()); wr_swgl_make_current(mContext); return true; } @@ -60,10 +60,11 @@ bool RenderCompositorSWGL::AllocateMappedBuffer( // Request a new draw target to use from the widget... MOZ_ASSERT(!mDT); layers::BufferMode bufferMode = layers::BufferMode::BUFFERED; - mDT = mWidget->StartRemoteDrawingInRegion(mDirtyRegion, &bufferMode); + mDT = mWidget->StartRemoteDrawingInRegion(mRegion, &bufferMode); if (!mDT) { return false; } + mWidget->ClearBeforePaint(mDT, mRegion); // Attempt to lock the underlying buffer directly from the draw target. // Verify that the size at least matches what the widget claims and that // the format is BGRA8 as SWGL requires. @@ -80,7 +81,7 @@ bool RenderCompositorSWGL::AllocateMappedBuffer( mDT->ReleaseBits(data); data = nullptr; } - LayoutDeviceIntRect bounds = mDirtyRegion.GetBounds(); + LayoutDeviceIntRect bounds = mRegion.GetBounds(); // If locking succeeded above, just use that. if (data) { mMappedData = data; @@ -105,7 +106,7 @@ bool RenderCompositorSWGL::AllocateMappedBuffer( gfx::DataSourceSurface::MappedSurface map = {nullptr, 0}; if (!mSurface || !mSurface->Map(gfx::DataSourceSurface::READ_WRITE, &map)) { // We failed mapping the data surface, so need to cancel the frame. - mWidget->EndRemoteDrawingInRegion(mDT, mDirtyRegion); + mWidget->EndRemoteDrawingInRegion(mDT, mRegion); ClearMappedBuffer(); return false; } @@ -123,13 +124,15 @@ bool RenderCompositorSWGL::AllocateMappedBuffer( rect.size.width, rect.size.height)); } - LayoutDeviceIntRegion clear = mWidget->GetTransparentRegion(); - clear.AndWith(mDirtyRegion); - clear.SubOut(opaque); + RefPtr dt = gfx::Factory::CreateDrawTargetForData( + BackendType::SKIA, mMappedData, bounds.Size().ToUnknownSize(), + mMappedStride, SurfaceFormat::B8G8R8A8, false); + + LayoutDeviceIntRegion clear; + clear.Sub(mRegion, opaque); for (auto iter = clear.RectIter(); !iter.Done(); iter.Next()) { - const auto& rect = iter.Get(); - wr_swgl_clear_color_rect(mContext, 0, rect.x, rect.y, rect.width, - rect.height, 0, 0, 0, 0); + dt->ClearRect( + IntRectToRect((iter.Get() - bounds.TopLeft()).ToUnknownRect())); } return true; @@ -142,19 +145,19 @@ void RenderCompositorSWGL::StartCompositing( // Cancel any existing buffers that might accidentally be left from updates CommitMappedBuffer(false); // Reset the region to the widget bounds - mDirtyRegion = LayoutDeviceIntRect(LayoutDeviceIntPoint(), GetBufferSize()); + mRegion = LayoutDeviceIntRect(LayoutDeviceIntPoint(), GetBufferSize()); } if (aNumDirtyRects) { // Install the dirty rects into the bounds of the existing region - auto bounds = mDirtyRegion.GetBounds(); - mDirtyRegion.SetEmpty(); + auto bounds = mRegion.GetBounds(); + mRegion.SetEmpty(); for (size_t i = 0; i < aNumDirtyRects; i++) { const auto& rect = aDirtyRects[i]; - mDirtyRegion.OrWith(LayoutDeviceIntRect( - rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)); + mRegion.OrWith(LayoutDeviceIntRect(rect.origin.x, rect.origin.y, + rect.size.width, rect.size.height)); } // Ensure the region lies within the widget bounds - mDirtyRegion.AndWith(bounds); + mRegion.AndWith(bounds); } // Now that the dirty rects have been supplied and the composition region // is known, allocate and install a framebuffer encompassing the composition @@ -186,12 +189,12 @@ void RenderCompositorSWGL::CommitMappedBuffer(bool aDirty) { // that is offset from the origin to the actual bounds of the dirty // region. The destination DT may also be an offset partial region, but we // must check to see if its size matches the region bounds to verify this. - LayoutDeviceIntRect bounds = mDirtyRegion.GetBounds(); + LayoutDeviceIntRect bounds = mRegion.GetBounds(); gfx::IntPoint srcOffset = bounds.TopLeft().ToUnknownPoint(); gfx::IntPoint dstOffset = mDT->GetSize() == bounds.Size().ToUnknownSize() ? srcOffset : gfx::IntPoint(0, 0); - for (auto iter = mDirtyRegion.RectIter(); !iter.Done(); iter.Next()) { + for (auto iter = mRegion.RectIter(); !iter.Done(); iter.Next()) { gfx::IntRect dirtyRect = iter.Get().ToUnknownRect(); mDT->CopySurface(mSurface, dirtyRect - srcOffset, dirtyRect.TopLeft() - dstOffset); @@ -202,7 +205,7 @@ void RenderCompositorSWGL::CommitMappedBuffer(bool aDirty) { mDT->ReleaseBits(mMappedData); } // Done with the DT. Hand it back to the widget and clear out any trace of it. - mWidget->EndRemoteDrawingInRegion(mDT, mDirtyRegion); + mWidget->EndRemoteDrawingInRegion(mDT, mRegion); ClearMappedBuffer(); } diff --git a/gfx/webrender_bindings/RenderCompositorSWGL.h b/gfx/webrender_bindings/RenderCompositorSWGL.h index f628d95586a3..b0f53520e05d 100644 --- a/gfx/webrender_bindings/RenderCompositorSWGL.h +++ b/gfx/webrender_bindings/RenderCompositorSWGL.h @@ -60,7 +60,7 @@ class RenderCompositorSWGL : public RenderCompositor { private: void* mContext = nullptr; RefPtr mDT; - LayoutDeviceIntRegion mDirtyRegion; + LayoutDeviceIntRegion mRegion; RefPtr mSurface; uint8_t* mMappedData = nullptr; int32_t mMappedStride = 0; diff --git a/gfx/webrender_bindings/src/swgl_bindings.rs b/gfx/webrender_bindings/src/swgl_bindings.rs index 8a567432cba2..c5a9434b9b3a 100644 --- a/gfx/webrender_bindings/src/swgl_bindings.rs +++ b/gfx/webrender_bindings/src/swgl_bindings.rs @@ -91,22 +91,6 @@ pub extern "C" fn wr_swgl_set_texture_buffer( ); } -#[no_mangle] -pub extern "C" fn wr_swgl_clear_color_rect( - ctx: *mut c_void, - fbo: u32, - x: i32, - y: i32, - width: i32, - height: i32, - r: f32, - g: f32, - b: f32, - a: f32, -) { - swgl::Context::from(ctx).clear_color_rect(fbo, x, y, width, height, r, g, b, a); -} - /// Descriptor for a locked surface that will be directly composited by SWGL. #[repr(C)] struct WrSWGLCompositeSurfaceInfo { @@ -1636,11 +1620,15 @@ impl Compositor for SwCompositor { /// frame will not have overlap dependencies assigned and so must instead /// be added to the late_surfaces queue to be processed at the end of the /// frame. - fn start_compositing(&mut self, dirty_rects: &[DeviceIntRect], _opaque_rects: &[DeviceIntRect]) { + fn start_compositing( + &mut self, + dirty_rects: &[DeviceIntRect], + _opaque_rects: &[DeviceIntRect], + ) { // Opaque rects are currently only computed here, not by WR itself, so we // ignore the passed parameter and forward our own version onto the native // compositor. - let mut opaque_rects: Vec = Vec::new(); + let mut opaque_rects : Vec = Vec::new(); for &(ref id, ref transform, ref clip_rect, _filter) in &self.frame_surfaces { if let Some(surface) = self.surfaces.get(id) { if !surface.is_opaque { diff --git a/gfx/wr/swgl/src/gl.cc b/gfx/wr/swgl/src/gl.cc index 1165b15542cc..9eea22b3af5b 100644 --- a/gfx/wr/swgl/src/gl.cc +++ b/gfx/wr/swgl/src/gl.cc @@ -600,7 +600,7 @@ struct Texture { uint32_t* cleared_rows = nullptr; void init_depth_runs(uint16_t z); - void fill_depth_runs(uint16_t z, const IntRect& scissor); + void fill_depth_runs(uint16_t z); void enable_delayed_clear(uint32_t val) { delay_clear = height; @@ -904,7 +904,7 @@ struct Context { bool scissortest = false; IntRect scissor = {0, 0, 0, 0}; - GLfloat clearcolor[4] = {0, 0, 0, 0}; + uint32_t clearcolor = 0; GLdouble cleardepth = 1; int unpack_row_length = 0; @@ -1290,15 +1290,10 @@ void Disable(GLenum cap) { GLenum GetError() { return GL_NO_ERROR; } static const char* const extensions[] = { - "GL_ARB_blend_func_extended", - "GL_ARB_clear_texture", - "GL_ARB_copy_image", - "GL_ARB_draw_instanced", - "GL_ARB_explicit_attrib_location", - "GL_ARB_instanced_arrays", - "GL_ARB_invalidate_subdata", - "GL_ARB_texture_storage", - "GL_EXT_timer_query", + "GL_ARB_blend_func_extended", "GL_ARB_copy_image", + "GL_ARB_draw_instanced", "GL_ARB_explicit_attrib_location", + "GL_ARB_instanced_arrays", "GL_ARB_invalidate_subdata", + "GL_ARB_texture_storage", "GL_EXT_timer_query", "GL_APPLE_rgb_422", }; @@ -1489,10 +1484,8 @@ void SetScissor(GLint x, GLint y, GLsizei width, GLsizei height) { } void ClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { - ctx->clearcolor[0] = r; - ctx->clearcolor[1] = g; - ctx->clearcolor[2] = b; - ctx->clearcolor[3] = a; + I32 c = round_pixel((Float){b, g, r, a}); + ctx->clearcolor = bit_cast(CONVERT(c, U8)); } void ClearDepth(GLdouble depth) { ctx->cleardepth = depth; } @@ -2378,6 +2371,14 @@ static void clear_buffer(Texture& t, T value, int layer, IntRect bb, } } +template +static inline void clear_buffer(Texture& t, T value, int layer = 0) { + IntRect bb = ctx->apply_scissor(t); + if (bb.width() > 0) { + clear_buffer(t, value, layer, bb); + } +} + template static inline void force_clear_row(Texture& t, int y, int skip_start = 0, int skip_end = 0) { @@ -2465,35 +2466,30 @@ static void prepare_texture(Texture& t, const IntRect* skip) { } } +static inline bool clear_requires_scissor(Texture& t) { + return ctx->scissortest && !ctx->scissor.contains(t.offset_bounds()); +} + // Setup a clear on a texture. This may either force an immediate clear or // potentially punt to a delayed clear, if applicable. template -static void request_clear(Texture& t, int layer, T value, - const IntRect& scissor) { +static void request_clear(Texture& t, int layer, T value) { // If the clear would require a scissor, force clear anything outside // the scissor, and then immediately clear anything inside the scissor. - if (!scissor.contains(t.offset_bounds())) { - IntRect skip = scissor - t.offset; + if (clear_requires_scissor(t)) { + IntRect skip = ctx->scissor - t.offset; force_clear(t, &skip); - clear_buffer(t, value, layer, skip.intersection(t.bounds())); + clear_buffer(t, value, layer); } else if (t.depth > 1) { // Delayed clear is not supported on texture arrays. t.disable_delayed_clear(); - clear_buffer(t, value, layer, t.bounds()); + clear_buffer(t, value, layer); } else { // Do delayed clear for 2D texture without scissor. t.enable_delayed_clear(value); } } -template -static inline void request_clear(Texture& t, int layer, T value) { - // If scissoring is enabled, use the scissor rect. Otherwise, just scissor to - // the entire texture bounds. - request_clear(t, layer, value, - ctx->scissortest ? ctx->scissor : t.offset_bounds()); -} - // Initialize a depth texture by setting the first run in each row to encompass // the entire row. void Texture::init_depth_runs(uint16_t depth) { @@ -2513,10 +2509,10 @@ static ALWAYS_INLINE void fill_depth_run(DepthRun* dst, size_t n, } // Fills a scissored region of a depth texture with a given depth. -void Texture::fill_depth_runs(uint16_t depth, const IntRect& scissor) { +void Texture::fill_depth_runs(uint16_t depth) { if (!buf) return; assert(cleared()); - IntRect bb = bounds().intersection(scissor - offset); + IntRect bb = ctx->apply_scissor(*this); DepthRun* runs = (DepthRun*)sample_ptr(0, bb.y0); for (int rows = bb.height(); rows > 0; rows--) { if (bb.width() >= width) { @@ -2591,182 +2587,42 @@ GLenum CheckFramebufferStatus(GLenum target) { return GL_FRAMEBUFFER_COMPLETE; } -void ClearTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, GLsizei height, - GLsizei depth, GLenum format, GLenum type, - const void* data) { - if (level != 0) { - assert(false); - return; - } - Texture& t = ctx->textures[texture]; - assert(!t.locked); - if (zoffset < 0) { - depth += zoffset; - zoffset = 0; - } - if (zoffset + depth > max(t.depth, 1)) { - depth = max(t.depth, 1) - zoffset; - } - if (width <= 0 || height <= 0 || depth <= 0) { - return; - } - IntRect scissor = {xoffset, yoffset, xoffset + width, yoffset + height}; - if (t.internal_format == GL_DEPTH_COMPONENT16) { - uint16_t value = 0xFFFF; - switch (format) { - case GL_DEPTH_COMPONENT: - switch (type) { - case GL_DOUBLE: - value = uint16_t(*(const GLdouble*)data * 0xFFFF); - break; - case GL_FLOAT: - value = uint16_t(*(const GLfloat*)data * 0xFFFF); - break; - case GL_UNSIGNED_SHORT: - value = uint16_t(*(const GLushort*)data); - break; - default: - assert(false); - break; - } - break; - default: - assert(false); - break; - } - assert(zoffset == 0 && depth == 1); - if (t.cleared() && !scissor.contains(t.offset_bounds())) { - // If we need to scissor the clear and the depth buffer was already - // initialized, then just fill runs for that scissor area. - t.fill_depth_runs(value, scissor); - } else { - // Otherwise, the buffer is either uninitialized or the clear would - // encompass the entire buffer. If uninitialized, we can safely fill - // the entire buffer with any value and thus ignore any scissoring. - t.init_depth_runs(value); - } - return; - } - - uint32_t color = 0xFF000000; - switch (type) { - case GL_FLOAT: { - const GLfloat* f = (const GLfloat*)data; - Float v = {0.0f, 0.0f, 0.0f, 1.0f}; - switch (format) { - case GL_RGBA: - v.w = f[3]; // alpha - FALLTHROUGH; - case GL_RGB: - v.z = f[2]; // blue - FALLTHROUGH; - case GL_RG: - v.y = f[1]; // green - FALLTHROUGH; - case GL_RED: - v.x = f[0]; // red - break; - default: - assert(false); - break; - } - color = bit_cast(CONVERT(round_pixel(v), U8)); - break; - } - case GL_UNSIGNED_BYTE: { - const GLubyte* b = (const GLubyte*)data; - switch (format) { - case GL_RGBA: - color = (color & ~0xFF000000) | (uint32_t(b[3]) << 24); // alpha - FALLTHROUGH; - case GL_RGB: - color = (color & ~0x00FF0000) | (uint32_t(b[2]) << 16); // blue - FALLTHROUGH; - case GL_RG: - color = (color & ~0x0000FF00) | (uint32_t(b[1]) << 8); // green - FALLTHROUGH; - case GL_RED: - color = (color & ~0x000000FF) | uint32_t(b[0]); // red - break; - default: - assert(false); - break; - } - break; - } - default: - assert(false); - break; - } - - for (int layer = zoffset; layer < zoffset + depth; layer++) { - switch (t.internal_format) { - case GL_RGBA8: - // Clear color needs to swizzle to BGRA. - request_clear(t, layer, - (color & 0xFF00FF00) | - ((color << 16) & 0xFF0000) | - ((color >> 16) & 0xFF), - scissor); - break; - case GL_R8: - request_clear(t, layer, uint8_t(color & 0xFF), scissor); - break; - case GL_RG8: - request_clear(t, layer, uint16_t(color & 0xFFFF), scissor); - break; - default: - assert(false); - break; - } - } -} - -void ClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, - const void* data) { - Texture& t = ctx->textures[texture]; - IntRect scissor = t.offset_bounds(); - ClearTexSubImage(texture, level, scissor.x0, scissor.y0, 0, scissor.width(), - scissor.height(), max(t.depth, 1), format, type, data); -} - void Clear(GLbitfield mask) { Framebuffer& fb = *get_framebuffer(GL_DRAW_FRAMEBUFFER); if ((mask & GL_COLOR_BUFFER_BIT) && fb.color_attachment) { Texture& t = ctx->textures[fb.color_attachment]; - IntRect scissor = ctx->scissortest - ? ctx->scissor.intersection(t.offset_bounds()) - : t.offset_bounds(); - ClearTexSubImage(fb.color_attachment, 0, scissor.x0, scissor.y0, fb.layer, - scissor.width(), scissor.height(), 1, GL_RGBA, GL_FLOAT, - ctx->clearcolor); + assert(!t.locked); + if (t.internal_format == GL_RGBA8) { + uint32_t color = ctx->clearcolor; + request_clear(t, fb.layer, color); + } else if (t.internal_format == GL_R8) { + uint8_t color = uint8_t((ctx->clearcolor >> 16) & 0xFF); + request_clear(t, fb.layer, color); + } else if (t.internal_format == GL_RG8) { + uint16_t color = uint16_t((ctx->clearcolor & 0xFF00) | + ((ctx->clearcolor >> 16) & 0xFF)); + request_clear(t, fb.layer, color); + } else { + assert(false); + } } if ((mask & GL_DEPTH_BUFFER_BIT) && fb.depth_attachment) { Texture& t = ctx->textures[fb.depth_attachment]; - IntRect scissor = ctx->scissortest - ? ctx->scissor.intersection(t.offset_bounds()) - : t.offset_bounds(); - ClearTexSubImage(fb.depth_attachment, 0, scissor.x0, scissor.y0, 0, - scissor.width(), scissor.height(), 1, GL_DEPTH_COMPONENT, - GL_DOUBLE, &ctx->cleardepth); + assert(t.internal_format == GL_DEPTH_COMPONENT16); + uint16_t depth = uint16_t(0xFFFF * ctx->cleardepth); + if (t.cleared() && clear_requires_scissor(t)) { + // If we need to scissor the clear and the depth buffer was already + // initialized, then just fill runs for that scissor area. + t.fill_depth_runs(depth); + } else { + // Otherwise, the buffer is either uninitialized or the clear would + // encompass the entire buffer. If uninitialized, we can safely fill + // the entire buffer with any value and thus ignore any scissoring. + t.init_depth_runs(depth); + } } } -void ClearColorRect(GLuint fbo, GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLfloat r, GLfloat g, GLfloat b, - GLfloat a) { - GLfloat color[] = {r, g, b, a}; - Framebuffer& fb = ctx->framebuffers[fbo]; - Texture& t = ctx->textures[fb.color_attachment]; - IntRect scissor = - IntRect{xoffset, yoffset, xoffset + width, yoffset + height}.intersection( - t.offset_bounds()); - ClearTexSubImage(fb.color_attachment, 0, scissor.x0, scissor.y0, fb.layer, - scissor.width(), scissor.height(), 1, GL_RGBA, GL_FLOAT, - color); -} - void InvalidateFramebuffer(GLenum target, GLsizei num_attachments, const GLenum* attachments) { Framebuffer* fb = get_framebuffer(target); diff --git a/gfx/wr/swgl/src/gl_defs.h b/gfx/wr/swgl/src/gl_defs.h index f3df7c80aa28..f5c2fb21d952 100644 --- a/gfx/wr/swgl/src/gl_defs.h +++ b/gfx/wr/swgl/src/gl_defs.h @@ -44,7 +44,6 @@ typedef intptr_t GLintptr; #define GL_INT 0x1404 #define GL_UNSIGNED_INT 0x1405 #define GL_FLOAT 0x1406 -#define GL_DOUBLE 0x1408 #define GL_RED 0x1903 #define GL_GREEN 0x1904 diff --git a/gfx/wr/swgl/src/swgl_fns.rs b/gfx/wr/swgl/src/swgl_fns.rs index f56b6c4c6b28..21bfc21e84fc 100644 --- a/gfx/wr/swgl/src/swgl_fns.rs +++ b/gfx/wr/swgl/src/swgl_fns.rs @@ -15,11 +15,8 @@ macro_rules! debug { } #[repr(C)] -struct LockedTexture { - _private: [u8; 0], -} +struct LockedTexture { _private: [u8; 0] } -#[allow(dead_code)] extern "C" { fn ActiveTexture(texture: GLenum); fn BindTexture(target: GLenum, texture: GLuint); @@ -65,7 +62,11 @@ extern "C" { level: GLint, ); fn CheckFramebufferStatus(target: GLenum) -> GLenum; - fn InvalidateFramebuffer(target: GLenum, num_attachments: GLsizei, attachments: *const GLenum); + fn InvalidateFramebuffer( + target: GLenum, + num_attachments: GLsizei, + attachments: *const GLenum, + ); fn TexStorage3D( target: GLenum, levels: GLint, @@ -185,31 +186,6 @@ extern "C" { fn ClearColor(r: GLfloat, g: GLfloat, b: GLfloat, a: GLfloat); fn ClearDepth(depth: GLdouble); fn Clear(mask: GLbitfield); - fn ClearTexSubImage( - target: GLenum, - level: GLint, - xoffset: GLint, - yoffset: GLint, - zoffset: GLint, - width: GLsizei, - height: GLsizei, - depth: GLsizei, - format: GLenum, - ty: GLenum, - data: *const c_void, - ); - fn ClearTexImage(target: GLenum, level: GLint, format: GLenum, ty: GLenum, data: *const c_void); - fn ClearColorRect( - fbo: GLuint, - xoffset: GLint, - yoffset: GLint, - width: GLsizei, - height: GLsizei, - r: GLfloat, - g: GLfloat, - b: GLfloat, - a: GLfloat, - ); fn PixelStorei(name: GLenum, param: GLint); fn ReadPixels( x: GLint, @@ -413,34 +389,11 @@ impl Context { let mut width: i32 = 0; let mut height: i32 = 0; let mut stride: i32 = 0; - let data_ptr = GetColorBuffer( - fbo, - flush as GLboolean, - &mut width, - &mut height, - &mut stride, - ); + let data_ptr = GetColorBuffer(fbo, flush as GLboolean, &mut width, &mut height, &mut stride); (data_ptr, width, height, stride) } } - pub fn clear_color_rect( - &self, - fbo: GLuint, - xoffset: GLint, - yoffset: GLint, - width: GLsizei, - height: GLsizei, - r: f32, - g: f32, - b: f32, - a: f32, - ) { - unsafe { - ClearColorRect(fbo, xoffset, yoffset, width, height, r, g, b, a); - } - } - pub fn set_texture_buffer( &self, tex: GLuint, @@ -602,8 +555,8 @@ impl Gl for Context { let u = str::from_utf8(s).unwrap(); const PREFIX: &'static str = "// shader: "; if let Some(start) = u.find(PREFIX) { - if let Some(end) = u[start..].find('\n') { - let name = u[start + PREFIX.len()..start + end].trim(); + if let Some(end) = u[start ..].find('\n') { + let name = u[start + PREFIX.len() .. start + end].trim(); debug!("shader name: {}", name); unsafe { let c_string = CString::new(name).unwrap(); @@ -1595,7 +1548,13 @@ impl Gl for Context { fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei) { unsafe { - DrawElementsInstanced(mode, count, NONE, first as GLintptr, 1); + DrawElementsInstanced( + mode, + count, + NONE, + first as GLintptr, + 1, + ); } } @@ -1607,7 +1566,13 @@ impl Gl for Context { primcount: GLsizei, ) { unsafe { - DrawElementsInstanced(mode, count, NONE, first as GLintptr, primcount); + DrawElementsInstanced( + mode, + count, + NONE, + first as GLintptr, + primcount, + ); } } @@ -1624,7 +1589,13 @@ impl Gl for Context { ); //panic!(); unsafe { - DrawElementsInstanced(mode, count, element_type, indices_offset as GLintptr, 1); + DrawElementsInstanced( + mode, + count, + element_type, + indices_offset as GLintptr, + 1, + ); } } @@ -2506,17 +2477,14 @@ impl LockedResource { impl Clone for LockedResource { fn clone(&self) -> Self { - unsafe { - LockResource(self.0); - } + unsafe { LockResource(self.0); } LockedResource(self.0) } } impl Drop for LockedResource { fn drop(&mut self) { - unsafe { - UnlockResource(self.0); - } + unsafe { UnlockResource(self.0); } } } + diff --git a/widget/CompositorWidget.cpp b/widget/CompositorWidget.cpp index 2ea984ae6586..f4785699de5a 100644 --- a/widget/CompositorWidget.cpp +++ b/widget/CompositorWidget.cpp @@ -61,17 +61,5 @@ RefPtr CompositorWidget::GetVsyncObserver() const { return nullptr; } -LayoutDeviceIntRegion CompositorWidget::GetTransparentRegion() { - // By default, we check the transparency mode to determine if the widget is - // transparent, and if so, designate the entire widget drawing area as - // transparent. Widgets wanting more complex transparency region determination - // should override this method. - auto* widget = RealWidget(); - if (!widget || widget->GetTransparencyMode() != eTransparencyOpaque) { - return LayoutDeviceIntRect(LayoutDeviceIntPoint(0, 0), GetClientSize()); - } - return LayoutDeviceIntRegion(); -} - } // namespace widget } // namespace mozilla diff --git a/widget/CompositorWidget.h b/widget/CompositorWidget.h index 846b598a7d22..1ae80029c714 100644 --- a/widget/CompositorWidget.h +++ b/widget/CompositorWidget.h @@ -165,10 +165,10 @@ class CompositorWidget { /** * Some widgets (namely Gtk) may need clean up underlying surface - * before painting to draw transparent objects correctly. Return - * the transparent region where this clearing is required. + * before painting to draw transparent objects correctly. */ - virtual LayoutDeviceIntRegion GetTransparentRegion(); + virtual void ClearBeforePaint(RefPtr aTarget, + const LayoutDeviceIntRegion& aRegion) {} /** * Called when shutting down the LayerManager to clean-up any cached diff --git a/widget/gtk/GtkCompositorWidget.cpp b/widget/gtk/GtkCompositorWidget.cpp index 06187072f21b..bfb970ec472d 100644 --- a/widget/gtk/GtkCompositorWidget.cpp +++ b/widget/gtk/GtkCompositorWidget.cpp @@ -125,16 +125,22 @@ void GtkCompositorWidget::SetEGLNativeWindowSize( } #endif -LayoutDeviceIntRegion GtkCompositorWidget::GetTransparentRegion() { +void GtkCompositorWidget::ClearBeforePaint( + RefPtr aTarget, const LayoutDeviceIntRegion& aRegion) { // We need to clear target buffer alpha values of popup windows as // SW-WR paints with alpha blending (see Bug 1674473). if (mWidget->IsPopup()) { - return LayoutDeviceIntRect(LayoutDeviceIntPoint(0, 0), GetClientSize()); + for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) { + aTarget->ClearRect(gfx::Rect(iter.Get().ToUnknownRect())); + } } // Clear background of titlebar area to render titlebar // transparent corners correctly. - return mWidget->GetTitlebarRect(); + gfx::Rect rect; + if (mWidget->GetTitlebarRect(rect)) { + aTarget->ClearRect(rect); + } } } // namespace widget diff --git a/widget/gtk/GtkCompositorWidget.h b/widget/gtk/GtkCompositorWidget.h index 25cbc9a13eed..f0cb15fbfc79 100644 --- a/widget/gtk/GtkCompositorWidget.h +++ b/widget/gtk/GtkCompositorWidget.h @@ -61,7 +61,8 @@ class GtkCompositorWidget : public CompositorWidget, EGLNativeWindowType GetEGLNativeWindow(); int32_t GetDepth(); - LayoutDeviceIntRegion GetTransparentRegion() override; + void ClearBeforePaint(RefPtr aTarget, + const LayoutDeviceIntRegion& aRegion) override; #if defined(MOZ_X11) Display* XDisplay() const { return mXDisplay; } diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 0171d5cce9b0..0613dc687695 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -5896,12 +5896,13 @@ nsresult nsWindow::UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect, return NS_OK; } -LayoutDeviceIntRect nsWindow::GetTitlebarRect() { +bool nsWindow::GetTitlebarRect(mozilla::gfx::Rect& aRect) { if (!mGdkWindow || !mDrawInTitlebar) { - return LayoutDeviceIntRect(); + return false; } - return LayoutDeviceIntRect(0, 0, mBounds.width, TITLEBAR_SHAPE_MASK_HEIGHT); + aRect = gfx::Rect(0, 0, mBounds.width, TITLEBAR_SHAPE_MASK_HEIGHT); + return true; } void nsWindow::UpdateTitlebarTransparencyBitmap() { diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 9be7d4bb4ada..387696b408d5 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -380,7 +380,7 @@ class nsWindow final : public nsBaseWidget { virtual nsresult SetNonClientMargins( LayoutDeviceIntMargin& aMargins) override; void SetDrawsInTitlebar(bool aState) override; - LayoutDeviceIntRect GetTitlebarRect(); + bool GetTitlebarRect(mozilla::gfx::Rect& aRect); virtual void UpdateWindowDraggingRegion( const LayoutDeviceIntRegion& aRegion) override;