зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1689245) for causing merge conflicts.
Backed out changeset 56cb5f428fb5 (bug 1689245) Backed out changeset b1303a0086cd (bug 1689245)
This commit is contained in:
Родитель
b2bd266cde
Коммит
27de9a114b
|
@ -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<DrawTarget> 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();
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class RenderCompositorSWGL : public RenderCompositor {
|
|||
private:
|
||||
void* mContext = nullptr;
|
||||
RefPtr<gfx::DrawTarget> mDT;
|
||||
LayoutDeviceIntRegion mDirtyRegion;
|
||||
LayoutDeviceIntRegion mRegion;
|
||||
RefPtr<gfx::DataSourceSurface> mSurface;
|
||||
uint8_t* mMappedData = nullptr;
|
||||
int32_t mMappedStride = 0;
|
||||
|
|
|
@ -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<DeviceIntRect> = Vec::new();
|
||||
let mut opaque_rects : Vec<DeviceIntRect> = 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 {
|
||||
|
|
|
@ -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<uint32_t>(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 <typename T>
|
||||
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>(t, value, layer, bb);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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 <typename T>
|
||||
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>(t, &skip);
|
||||
clear_buffer<T>(t, value, layer, skip.intersection(t.bounds()));
|
||||
clear_buffer<T>(t, value, layer);
|
||||
} else if (t.depth > 1) {
|
||||
// Delayed clear is not supported on texture arrays.
|
||||
t.disable_delayed_clear();
|
||||
clear_buffer<T>(t, value, layer, t.bounds());
|
||||
clear_buffer<T>(t, value, layer);
|
||||
} else {
|
||||
// Do delayed clear for 2D texture without scissor.
|
||||
t.enable_delayed_clear(value);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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<uint32_t>(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<uint32_t>(t, layer,
|
||||
(color & 0xFF00FF00) |
|
||||
((color << 16) & 0xFF0000) |
|
||||
((color >> 16) & 0xFF),
|
||||
scissor);
|
||||
break;
|
||||
case GL_R8:
|
||||
request_clear<uint8_t>(t, layer, uint8_t(color & 0xFF), scissor);
|
||||
break;
|
||||
case GL_RG8:
|
||||
request_clear<uint16_t>(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<uint32_t>(t, fb.layer, color);
|
||||
} else if (t.internal_format == GL_R8) {
|
||||
uint8_t color = uint8_t((ctx->clearcolor >> 16) & 0xFF);
|
||||
request_clear<uint8_t>(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<uint16_t>(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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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); }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,17 +61,5 @@ RefPtr<VsyncObserver> 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
|
||||
|
|
|
@ -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<gfx::DrawTarget> aTarget,
|
||||
const LayoutDeviceIntRegion& aRegion) {}
|
||||
|
||||
/**
|
||||
* Called when shutting down the LayerManager to clean-up any cached
|
||||
|
|
|
@ -125,16 +125,22 @@ void GtkCompositorWidget::SetEGLNativeWindowSize(
|
|||
}
|
||||
#endif
|
||||
|
||||
LayoutDeviceIntRegion GtkCompositorWidget::GetTransparentRegion() {
|
||||
void GtkCompositorWidget::ClearBeforePaint(
|
||||
RefPtr<gfx::DrawTarget> 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
|
||||
|
|
|
@ -61,7 +61,8 @@ class GtkCompositorWidget : public CompositorWidget,
|
|||
EGLNativeWindowType GetEGLNativeWindow();
|
||||
int32_t GetDepth();
|
||||
|
||||
LayoutDeviceIntRegion GetTransparentRegion() override;
|
||||
void ClearBeforePaint(RefPtr<gfx::DrawTarget> aTarget,
|
||||
const LayoutDeviceIntRegion& aRegion) override;
|
||||
|
||||
#if defined(MOZ_X11)
|
||||
Display* XDisplay() const { return mXDisplay; }
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче