Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
index c77b2ef547f60a506bb3fdd6ac1c9677198d3d28..9bcb1cbd1ceac3b2f4a164fe3310d2a1429aaaec 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
@@ -77,6 +77,7 @@ |
#include "ui/gfx/overlay_transform.h" |
#include "ui/gfx/transform.h" |
#include "ui/gl/ca_renderer_layer_params.h" |
+#include "ui/gl/dc_renderer_layer_params.h" |
#include "ui/gl/gl_bindings.h" |
#include "ui/gl/gl_context.h" |
#include "ui/gl/gl_fence.h" |
@@ -2165,6 +2166,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
// The GL_CHROMIUM_schedule_ca_layer extension requires that SwapBuffers and |
// equivalent functions reset shared state. |
void ClearScheduleCALayerState(); |
+ void ClearScheduleDCLayerState(); |
// Helper method to call glClear workaround. |
void ClearFramebufferForWorkaround(GLbitfield mask); |
@@ -2462,6 +2464,16 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
std::unique_ptr<CALayerSharedState> ca_layer_shared_state_; |
+ struct DCLayerSharedState { |
+ float opacity; |
+ bool is_clipped; |
+ gfx::Rect clip_rect; |
+ int z_order; |
+ gfx::Transform transform; |
+ }; |
+ |
+ std::unique_ptr<DCLayerSharedState> dc_layer_shared_state_; |
+ |
DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); |
}; |
@@ -11805,6 +11817,7 @@ void GLES2DecoderImpl::DoSwapBuffersWithBoundsCHROMIUM( |
} |
ClearScheduleCALayerState(); |
+ ClearScheduleDCLayerState(); |
std::vector<gfx::Rect> bounds(count); |
for (GLsizei i = 0; i < count; ++i) { |
@@ -11841,6 +11854,7 @@ error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( |
} |
ClearScheduleCALayerState(); |
+ ClearScheduleDCLayerState(); |
if (supports_async_swap_) { |
TRACE_EVENT_ASYNC_BEGIN0("cc", "GLES2DecoderImpl::AsyncSwapBuffers", this); |
@@ -11984,6 +11998,91 @@ error::Error GLES2DecoderImpl::HandleScheduleCALayerCHROMIUM( |
return error::kNoError; |
} |
+error::Error GLES2DecoderImpl::HandleScheduleDCLayerSharedStateCHROMIUM( |
+ uint32_t immediate_data_size, |
+ const volatile void* cmd_data) { |
+ const volatile gles2::cmds::ScheduleDCLayerSharedStateCHROMIUM& c = |
+ *static_cast< |
+ const volatile gles2::cmds::ScheduleDCLayerSharedStateCHROMIUM*>( |
+ cmd_data); |
+ |
+ const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset, |
+ 20 * sizeof(GLfloat)); |
+ if (!mem) { |
+ return error::kOutOfBounds; |
+ } |
+ gfx::RectF clip_rect(mem[0], mem[1], mem[2], mem[3]); |
+ gfx::Transform transform(mem[4], mem[8], mem[12], mem[16], mem[5], mem[9], |
+ mem[13], mem[17], mem[6], mem[10], mem[14], mem[18], |
+ mem[7], mem[11], mem[15], mem[19]); |
+ dc_layer_shared_state_.reset(new DCLayerSharedState); |
+ dc_layer_shared_state_->opacity = c.opacity; |
+ dc_layer_shared_state_->is_clipped = c.is_clipped ? true : false; |
+ dc_layer_shared_state_->clip_rect = gfx::ToEnclosingRect(clip_rect); |
+ dc_layer_shared_state_->z_order = c.z_order; |
+ dc_layer_shared_state_->transform = transform; |
+ return error::kNoError; |
+} |
+ |
+error::Error GLES2DecoderImpl::HandleScheduleDCLayerCHROMIUM( |
+ uint32_t immediate_data_size, |
+ const volatile void* cmd_data) { |
+ const volatile gles2::cmds::ScheduleDCLayerCHROMIUM& c = |
+ *static_cast<const volatile gles2::cmds::ScheduleDCLayerCHROMIUM*>( |
+ cmd_data); |
+ GLuint filter = c.filter; |
+ if (filter != GL_NEAREST && filter != GL_LINEAR) { |
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM", |
+ "invalid filter"); |
+ return error::kNoError; |
+ } |
+ |
+ if (!dc_layer_shared_state_) { |
+ LOCAL_SET_GL_ERROR( |
+ GL_INVALID_OPERATION, "glScheduleDCLayerCHROMIUM", |
+ "glScheduleDCLayerSharedStateCHROMIUM has not been called"); |
+ return error::kNoError; |
+ } |
+ |
+ gl::GLImage* image = nullptr; |
+ GLuint contents_texture_id = c.contents_texture_id; |
+ if (contents_texture_id) { |
+ TextureRef* ref = texture_manager()->GetTexture(contents_texture_id); |
+ if (!ref) { |
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM", |
+ "unknown texture"); |
+ return error::kNoError; |
+ } |
+ Texture::ImageState image_state; |
+ image = ref->texture()->GetLevelImage(ref->texture()->target(), 0, |
+ &image_state); |
+ if (!image) { |
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glScheduleDCLayerCHROMIUM", |
+ "unsupported texture format"); |
+ return error::kNoError; |
+ } |
+ } |
+ |
+ const GLfloat* mem = GetSharedMemoryAs<const GLfloat*>(c.shm_id, c.shm_offset, |
+ 8 * sizeof(GLfloat)); |
+ if (!mem) { |
+ return error::kOutOfBounds; |
+ } |
+ gfx::RectF contents_rect(mem[0], mem[1], mem[2], mem[3]); |
+ gfx::RectF bounds_rect(mem[4], mem[5], mem[6], mem[7]); |
+ |
+ ui::DCRendererLayerParams params = ui::DCRendererLayerParams( |
+ dc_layer_shared_state_->is_clipped, dc_layer_shared_state_->clip_rect, |
+ dc_layer_shared_state_->z_order, dc_layer_shared_state_->transform, image, |
+ contents_rect, gfx::ToEnclosingRect(bounds_rect), c.background_color, |
+ c.edge_aa_mask, dc_layer_shared_state_->opacity, filter); |
+ if (!surface_->ScheduleDCLayer(params)) { |
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glScheduleDCLayerCHROMIUM", |
+ "failed to schedule DCLayer"); |
+ } |
+ return error::kNoError; |
+} |
+ |
void GLES2DecoderImpl::DoScheduleCALayerInUseQueryCHROMIUM( |
GLsizei count, |
const volatile GLuint* textures) { |
@@ -15305,6 +15404,7 @@ void GLES2DecoderImpl::DoSwapBuffers() { |
} |
ClearScheduleCALayerState(); |
+ ClearScheduleDCLayerState(); |
// If offscreen then don't actually SwapBuffers to the display. Just copy |
// the rendered frame to another frame buffer. |
@@ -15425,6 +15525,7 @@ void GLES2DecoderImpl::DoCommitOverlayPlanes() { |
return; |
} |
ClearScheduleCALayerState(); |
+ ClearScheduleDCLayerState(); |
if (supports_async_swap_) { |
surface_->CommitOverlayPlanesAsync(base::Bind( |
&GLES2DecoderImpl::FinishSwapBuffers, base::AsWeakPtr(this))); |
@@ -19201,6 +19302,10 @@ void GLES2DecoderImpl::ClearScheduleCALayerState() { |
ca_layer_shared_state_.reset(); |
} |
+void GLES2DecoderImpl::ClearScheduleDCLayerState() { |
+ dc_layer_shared_state_.reset(); |
+} |
+ |
void GLES2DecoderImpl::ClearFramebufferForWorkaround(GLbitfield mask) { |
ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround", |
GetErrorState()); |