Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 The Chromium Authors. All rights reserved. | 1 // Copyright 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/output/gl_renderer.h" | 5 #include "cc/output/gl_renderer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" | 60 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" |
| 61 #include "ui/gfx/geometry/quad_f.h" | 61 #include "ui/gfx/geometry/quad_f.h" |
| 62 #include "ui/gfx/geometry/rect_conversions.h" | 62 #include "ui/gfx/geometry/rect_conversions.h" |
| 63 #include "ui/gfx/skia_util.h" | 63 #include "ui/gfx/skia_util.h" |
| 64 | 64 |
| 65 using gpu::gles2::GLES2Interface; | 65 using gpu::gles2::GLES2Interface; |
| 66 | 66 |
| 67 namespace cc { | 67 namespace cc { |
| 68 namespace { | 68 namespace { |
| 69 | 69 |
| 70 class ScopedFramebufferDeleter { | |
| 71 public: | |
| 72 ScopedFramebufferDeleter(GLuint fbo, gpu::gles2::GLES2Interface* gl) | |
| 73 : fbo_(fbo), gl_(gl) {} | |
| 74 ~ScopedFramebufferDeleter() { gl_->DeleteFramebuffers(1, &fbo_); } | |
| 75 | |
| 76 private: | |
| 77 GLuint fbo_; | |
| 78 gpu::gles2::GLES2Interface* gl_; | |
| 79 }; | |
| 80 | |
| 70 Float4 UVTransform(const TextureDrawQuad* quad) { | 81 Float4 UVTransform(const TextureDrawQuad* quad) { |
| 71 gfx::PointF uv0 = quad->uv_top_left; | 82 gfx::PointF uv0 = quad->uv_top_left; |
| 72 gfx::PointF uv1 = quad->uv_bottom_right; | 83 gfx::PointF uv1 = quad->uv_bottom_right; |
| 73 Float4 xform = {{uv0.x(), uv0.y(), uv1.x() - uv0.x(), uv1.y() - uv0.y()}}; | 84 Float4 xform = {{uv0.x(), uv0.y(), uv1.x() - uv0.x(), uv1.y() - uv0.y()}}; |
| 74 if (quad->y_flipped) { | 85 if (quad->y_flipped) { |
| 75 xform.data[1] = 1.0f - xform.data[1]; | 86 xform.data[1] = 1.0f - xform.data[1]; |
| 76 xform.data[3] = -xform.data[3]; | 87 xform.data[3] = -xform.data[3]; |
| 77 } | 88 } |
| 78 return xform; | 89 return xform; |
| 79 } | 90 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 // Parameters needed to draw a RenderPassDrawQuad. | 165 // Parameters needed to draw a RenderPassDrawQuad. |
| 155 struct DrawRenderPassDrawQuadParams { | 166 struct DrawRenderPassDrawQuadParams { |
| 156 DrawRenderPassDrawQuadParams() {} | 167 DrawRenderPassDrawQuadParams() {} |
| 157 ~DrawRenderPassDrawQuadParams() {} | 168 ~DrawRenderPassDrawQuadParams() {} |
| 158 | 169 |
| 159 // Required Inputs. | 170 // Required Inputs. |
| 160 const RenderPassDrawQuad* quad = nullptr; | 171 const RenderPassDrawQuad* quad = nullptr; |
| 161 const Resource* contents_texture = nullptr; | 172 const Resource* contents_texture = nullptr; |
| 162 const gfx::QuadF* clip_region = nullptr; | 173 const gfx::QuadF* clip_region = nullptr; |
| 163 bool flip_texture = false; | 174 bool flip_texture = false; |
| 164 | |
| 165 gfx::Transform window_matrix; | 175 gfx::Transform window_matrix; |
| 166 gfx::Transform projection_matrix; | 176 gfx::Transform projection_matrix; |
| 177 gfx::Transform quad_to_target_transform; | |
| 167 | 178 |
| 168 // |frame| is needed for background effects. | 179 // |frame| is only used for background effects. |
| 169 DirectRenderer::DrawingFrame* frame = nullptr; | 180 DirectRenderer::DrawingFrame* frame = nullptr; |
| 170 | 181 |
| 171 // Whether the texture to be sampled from needs to be flipped. | 182 // Whether the texture to be sampled from needs to be flipped. |
| 172 bool source_needs_flip = false; | 183 bool source_needs_flip = false; |
| 173 | 184 |
| 174 float edge[24]; | 185 float edge[24]; |
| 175 SkScalar color_matrix[20]; | 186 SkScalar color_matrix[20]; |
| 176 | 187 |
| 177 // Blending refers to modifications to the backdrop. | 188 // Blending refers to modifications to the backdrop. |
| 178 bool use_shaders_for_blending = false; | 189 bool use_shaders_for_blending = false; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 209 GLuint background_image_id = 0; | 220 GLuint background_image_id = 0; |
| 210 | 221 |
| 211 // Whether the original background texture is needed for the mask. | 222 // Whether the original background texture is needed for the mask. |
| 212 bool mask_for_background = false; | 223 bool mask_for_background = false; |
| 213 | 224 |
| 214 // Whether a color matrix needs to be applied by the shaders when drawing | 225 // Whether a color matrix needs to be applied by the shaders when drawing |
| 215 // the RPDQ. | 226 // the RPDQ. |
| 216 bool use_color_matrix = false; | 227 bool use_color_matrix = false; |
| 217 | 228 |
| 218 gfx::QuadF surface_quad; | 229 gfx::QuadF surface_quad; |
| 230 | |
| 219 gfx::Transform contents_device_transform; | 231 gfx::Transform contents_device_transform; |
| 220 }; | 232 }; |
| 221 | 233 |
| 222 static GLint GetActiveTextureUnit(GLES2Interface* gl) { | 234 static GLint GetActiveTextureUnit(GLES2Interface* gl) { |
| 223 GLint active_unit = 0; | 235 GLint active_unit = 0; |
| 224 gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit); | 236 gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit); |
| 225 return active_unit; | 237 return active_unit; |
| 226 } | 238 } |
| 227 | 239 |
| 228 class GLRenderer::ScopedUseGrContext { | 240 class GLRenderer::ScopedUseGrContext { |
| (...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1062 // See above comments about texture flipping. When the input is a | 1074 // See above comments about texture flipping. When the input is a |
| 1063 // render pass, it needs to an extra flip to be oriented correctly. | 1075 // render pass, it needs to an extra flip to be oriented correctly. |
| 1064 params.flip_texture = true; | 1076 params.flip_texture = true; |
| 1065 params.contents_texture = contents_texture; | 1077 params.contents_texture = contents_texture; |
| 1066 DrawRenderPassQuadInternal(¶ms); | 1078 DrawRenderPassQuadInternal(¶ms); |
| 1067 } | 1079 } |
| 1068 } | 1080 } |
| 1069 | 1081 |
| 1070 void GLRenderer::DrawRenderPassQuadInternal( | 1082 void GLRenderer::DrawRenderPassQuadInternal( |
| 1071 DrawRenderPassDrawQuadParams* params) { | 1083 DrawRenderPassDrawQuadParams* params) { |
| 1084 params->quad_to_target_transform = | |
| 1085 params->quad->shared_quad_state->quad_to_target_transform; | |
| 1072 if (!InitializeRPDQParameters(params)) | 1086 if (!InitializeRPDQParameters(params)) |
| 1073 return; | 1087 return; |
| 1074 UpdateRPDQShadersForBlending(params); | 1088 UpdateRPDQShadersForBlending(params); |
| 1075 if (!UpdateRPDQWithSkiaFilters(params)) | 1089 if (!UpdateRPDQWithSkiaFilters(params)) |
| 1076 return; | 1090 return; |
| 1077 UseRenderPass(params->frame, params->frame->current_render_pass); | 1091 UseRenderPass(params->frame, params->frame->current_render_pass); |
| 1078 SetViewport(); | 1092 SetViewport(); |
| 1079 UpdateRPDQTexturesForSampling(params); | 1093 UpdateRPDQTexturesForSampling(params); |
| 1080 UpdateRPDQBlendMode(params); | 1094 UpdateRPDQBlendMode(params); |
| 1081 ChooseRPDQProgram(params); | 1095 ChooseRPDQProgram(params); |
| 1082 UpdateRPDQUniforms(params); | 1096 UpdateRPDQUniforms(params); |
| 1083 DrawRPDQ(*params); | 1097 DrawRPDQ(*params); |
| 1084 } | 1098 } |
| 1085 | 1099 |
| 1086 bool GLRenderer::InitializeRPDQParameters( | 1100 bool GLRenderer::InitializeRPDQParameters( |
| 1087 DrawRenderPassDrawQuadParams* params) { | 1101 DrawRenderPassDrawQuadParams* params) { |
| 1088 const RenderPassDrawQuad* quad = params->quad; | 1102 const RenderPassDrawQuad* quad = params->quad; |
| 1089 SkMatrix scale_matrix; | 1103 SkMatrix scale_matrix; |
| 1090 scale_matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); | 1104 scale_matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); |
| 1091 gfx::Rect dst_rect = quad->filters.MapRect(quad->rect, scale_matrix); | 1105 gfx::Rect dst_rect = quad->filters.MapRect(quad->rect, scale_matrix); |
| 1092 params->dst_rect.SetRect(static_cast<float>(dst_rect.x()), | 1106 params->dst_rect.SetRect(static_cast<float>(dst_rect.x()), |
| 1093 static_cast<float>(dst_rect.y()), | 1107 static_cast<float>(dst_rect.y()), |
| 1094 static_cast<float>(dst_rect.width()), | 1108 static_cast<float>(dst_rect.width()), |
| 1095 static_cast<float>(dst_rect.height())); | 1109 static_cast<float>(dst_rect.height())); |
| 1096 gfx::Transform quad_rect_matrix; | 1110 gfx::Transform quad_rect_matrix; |
| 1097 QuadRectTransform(&quad_rect_matrix, | 1111 QuadRectTransform(&quad_rect_matrix, params->quad_to_target_transform, |
| 1098 quad->shared_quad_state->quad_to_target_transform, | |
| 1099 params->dst_rect); | 1112 params->dst_rect); |
| 1100 params->contents_device_transform = | 1113 params->contents_device_transform = |
| 1101 params->window_matrix * params->projection_matrix * quad_rect_matrix; | 1114 params->window_matrix * params->projection_matrix * quad_rect_matrix; |
| 1102 params->contents_device_transform.FlattenTo2d(); | 1115 params->contents_device_transform.FlattenTo2d(); |
| 1103 | 1116 |
| 1104 // Can only draw surface if device matrix is invertible. | 1117 // Can only draw surface if device matrix is invertible. |
| 1105 if (!params->contents_device_transform.IsInvertible()) | 1118 if (!params->contents_device_transform.IsInvertible()) |
| 1106 return false; | 1119 return false; |
| 1107 | 1120 |
| 1108 params->surface_quad = SharedGeometryQuad(); | 1121 params->surface_quad = SharedGeometryQuad(); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1211 // locally in the compositor and process the rest of the DAG (if any) | 1224 // locally in the compositor and process the rest of the DAG (if any) |
| 1212 // in Skia. | 1225 // in Skia. |
| 1213 params->use_color_matrix = true; | 1226 params->use_color_matrix = true; |
| 1214 filter = sk_ref_sp(filter->getInput(0)); | 1227 filter = sk_ref_sp(filter->getInput(0)); |
| 1215 } | 1228 } |
| 1216 if (filter) { | 1229 if (filter) { |
| 1217 gfx::Rect clip_rect = quad->shared_quad_state->clip_rect; | 1230 gfx::Rect clip_rect = quad->shared_quad_state->clip_rect; |
| 1218 if (clip_rect.IsEmpty()) { | 1231 if (clip_rect.IsEmpty()) { |
| 1219 clip_rect = current_draw_rect_; | 1232 clip_rect = current_draw_rect_; |
| 1220 } | 1233 } |
| 1221 gfx::Transform transform = | 1234 gfx::Transform transform = params->quad_to_target_transform; |
| 1222 quad->shared_quad_state->quad_to_target_transform; | |
| 1223 gfx::QuadF clip_quad = gfx::QuadF(gfx::RectF(clip_rect)); | 1235 gfx::QuadF clip_quad = gfx::QuadF(gfx::RectF(clip_rect)); |
| 1224 gfx::QuadF local_clip = MapQuadToLocalSpace(transform, clip_quad); | 1236 gfx::QuadF local_clip = MapQuadToLocalSpace(transform, clip_quad); |
| 1225 params->dst_rect.Intersect(local_clip.BoundingBox()); | 1237 params->dst_rect.Intersect(local_clip.BoundingBox()); |
| 1226 // If we've been fully clipped out (by crop rect or clipping), there's | 1238 // If we've been fully clipped out (by crop rect or clipping), there's |
| 1227 // nothing to draw. | 1239 // nothing to draw. |
| 1228 if (params->dst_rect.IsEmpty()) { | 1240 if (params->dst_rect.IsEmpty()) { |
| 1229 return false; | 1241 return false; |
| 1230 } | 1242 } |
| 1231 SkIPoint offset; | 1243 SkIPoint offset; |
| 1232 SkIRect subset; | 1244 SkIRect subset; |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1493 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), | 1505 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), |
| 1494 params->shader_background_sampler_lock->target()); | 1506 params->shader_background_sampler_lock->target()); |
| 1495 } | 1507 } |
| 1496 } | 1508 } |
| 1497 | 1509 |
| 1498 SetShaderOpacity(params->quad->shared_quad_state->opacity, locations.alpha); | 1510 SetShaderOpacity(params->quad->shared_quad_state->opacity, locations.alpha); |
| 1499 SetShaderQuadF(params->surface_quad, locations.quad); | 1511 SetShaderQuadF(params->surface_quad, locations.quad); |
| 1500 } | 1512 } |
| 1501 | 1513 |
| 1502 void GLRenderer::DrawRPDQ(const DrawRenderPassDrawQuadParams& params) { | 1514 void GLRenderer::DrawRPDQ(const DrawRenderPassDrawQuadParams& params) { |
| 1503 DrawQuadGeometry(params.projection_matrix, | 1515 DrawQuadGeometry(params.projection_matrix, params.quad_to_target_transform, |
| 1504 params.quad->shared_quad_state->quad_to_target_transform, | |
| 1505 params.dst_rect, params.locations.matrix); | 1516 params.dst_rect, params.locations.matrix); |
| 1506 | 1517 |
| 1507 // Flush the compositor context before the filter bitmap goes out of | 1518 // Flush the compositor context before the filter bitmap goes out of |
| 1508 // scope, so the draw gets processed before the filter texture gets deleted. | 1519 // scope, so the draw gets processed before the filter texture gets deleted. |
| 1509 if (params.filter_image) | 1520 if (params.filter_image) |
| 1510 gl_->Flush(); | 1521 gl_->Flush(); |
| 1511 | 1522 |
| 1512 if (!params.use_shaders_for_blending) | 1523 if (!params.use_shaders_for_blending) |
| 1513 RestoreBlendFuncToDefault(params.quad->shared_quad_state->blend_mode); | 1524 RestoreBlendFuncToDefault(params.quad->shared_quad_state->blend_mode); |
| 1514 } | 1525 } |
| (...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2722 | 2733 |
| 2723 ScheduleCALayers(frame); | 2734 ScheduleCALayers(frame); |
| 2724 ScheduleOverlays(frame); | 2735 ScheduleOverlays(frame); |
| 2725 } | 2736 } |
| 2726 | 2737 |
| 2727 void GLRenderer::FinishDrawingQuadList() { | 2738 void GLRenderer::FinishDrawingQuadList() { |
| 2728 FlushTextureQuadCache(SHARED_BINDING); | 2739 FlushTextureQuadCache(SHARED_BINDING); |
| 2729 } | 2740 } |
| 2730 | 2741 |
| 2731 bool GLRenderer::FlippedFramebuffer(const DrawingFrame* frame) const { | 2742 bool GLRenderer::FlippedFramebuffer(const DrawingFrame* frame) const { |
| 2743 if (force_drawing_frame_framebuffer_unflipped_) | |
| 2744 return false; | |
| 2732 if (frame->current_render_pass != frame->root_render_pass) | 2745 if (frame->current_render_pass != frame->root_render_pass) |
| 2733 return true; | 2746 return true; |
| 2734 return FlippedRootFramebuffer(); | 2747 return FlippedRootFramebuffer(); |
| 2735 } | 2748 } |
| 2736 | 2749 |
| 2737 bool GLRenderer::FlippedRootFramebuffer() const { | 2750 bool GLRenderer::FlippedRootFramebuffer() const { |
| 2738 // GL is normally flipped, so a flipped output results in an unflipping. | 2751 // GL is normally flipped, so a flipped output results in an unflipping. |
| 2739 return !output_surface_->capabilities().flipped_output_surface; | 2752 return !output_surface_->capabilities().flipped_output_surface; |
| 2740 } | 2753 } |
| 2741 | 2754 |
| (...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3771 } | 3784 } |
| 3772 | 3785 |
| 3773 bool GLRenderer::IsContextLost() { | 3786 bool GLRenderer::IsContextLost() { |
| 3774 return gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR; | 3787 return gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR; |
| 3775 } | 3788 } |
| 3776 | 3789 |
| 3777 void GLRenderer::ScheduleCALayers(DrawingFrame* frame) { | 3790 void GLRenderer::ScheduleCALayers(DrawingFrame* frame) { |
| 3778 scoped_refptr<CALayerOverlaySharedState> shared_state; | 3791 scoped_refptr<CALayerOverlaySharedState> shared_state; |
| 3779 size_t copied_render_pass_count = 0; | 3792 size_t copied_render_pass_count = 0; |
| 3780 for (const CALayerOverlay& ca_layer_overlay : frame->ca_layer_overlay_list) { | 3793 for (const CALayerOverlay& ca_layer_overlay : frame->ca_layer_overlay_list) { |
| 3781 if (!overlay_resource_pool_) { | 3794 if (ca_layer_overlay.rpdq) { |
| 3782 overlay_resource_pool_ = ResourcePool::CreateForGpuMemoryBufferResources( | 3795 ScheduleRenderPassDrawQuad(&ca_layer_overlay, frame); |
| 3783 resource_provider_, base::ThreadTaskRunnerHandle::Get().get(), | 3796 shared_state = nullptr; |
| 3784 gfx::BufferUsage::SCANOUT); | 3797 ++copied_render_pass_count; |
| 3798 continue; | |
| 3785 } | 3799 } |
| 3786 | 3800 |
| 3787 ResourceId contents_resource_id = ca_layer_overlay.contents_resource_id; | 3801 ResourceId contents_resource_id = ca_layer_overlay.contents_resource_id; |
| 3788 unsigned texture_id = 0; | 3802 unsigned texture_id = 0; |
| 3789 if (contents_resource_id) { | 3803 if (contents_resource_id) { |
| 3790 pending_overlay_resources_.push_back( | 3804 pending_overlay_resources_.push_back( |
| 3791 base::WrapUnique(new ResourceProvider::ScopedReadLockGL( | 3805 base::WrapUnique(new ResourceProvider::ScopedReadLockGL( |
| 3792 resource_provider_, contents_resource_id))); | 3806 resource_provider_, contents_resource_id))); |
| 3793 texture_id = pending_overlay_resources_.back()->texture_id(); | 3807 texture_id = pending_overlay_resources_.back()->texture_id(); |
| 3794 } | 3808 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3848 resource_provider_, overlay.resource_id))); | 3862 resource_provider_, overlay.resource_id))); |
| 3849 texture_id = pending_overlay_resources_.back()->texture_id(); | 3863 texture_id = pending_overlay_resources_.back()->texture_id(); |
| 3850 } | 3864 } |
| 3851 | 3865 |
| 3852 context_support_->ScheduleOverlayPlane( | 3866 context_support_->ScheduleOverlayPlane( |
| 3853 overlay.plane_z_order, overlay.transform, texture_id, | 3867 overlay.plane_z_order, overlay.transform, texture_id, |
| 3854 ToNearestRect(overlay.display_rect), overlay.uv_rect); | 3868 ToNearestRect(overlay.display_rect), overlay.uv_rect); |
| 3855 } | 3869 } |
| 3856 } | 3870 } |
| 3857 | 3871 |
| 3872 // This function draws the RenderPassDrawQuad into a temporary | |
| 3873 // texture/framebuffer, and then copies the result into an IOSurface. The | |
| 3874 // inefficient (but simple) way to do this would be to: | |
| 3875 // 1. Allocate a framebuffer the size of the screen. | |
| 3876 // 2. Draw using all the normal RPDQ draw logic. | |
| 3877 // | |
| 3878 // Instead, this method does the following: | |
| 3879 // 1. Configure parameters as if drawing to a framebuffer the size of the | |
| 3880 // screen. This reuses most of the RPDQ draw logic. | |
| 3881 // 2. Update parameters to draw into a framebuffer only as large as needed. | |
| 3882 // 3. Fix shader uniforms that were broken by (2). | |
| 3883 // | |
| 3884 // Then: | |
| 3885 // 4. Allocate an IOSurface as the drawing destination. | |
| 3886 // 5. Draw the RPDQ. | |
| 3887 void GLRenderer::CopyRenderPassDrawQuadToOverlayResource( | |
| 3888 const CALayerOverlay* ca_layer_overlay, | |
| 3889 Resource** resource, | |
| 3890 DrawingFrame* external_frame, | |
| 3891 gfx::RectF* new_bounds) { | |
| 3892 ScopedResource* contents_texture = | |
| 3893 render_pass_textures_[ca_layer_overlay->rpdq->render_pass_id].get(); | |
| 3894 DCHECK(contents_texture); | |
| 3895 | |
| 3896 // Configure parameters as if drawing to a framebuffer the size of the | |
| 3897 // screen. | |
| 3898 DrawRenderPassDrawQuadParams params; | |
| 3899 params.quad = ca_layer_overlay->rpdq; | |
| 3900 params.flip_texture = true; | |
| 3901 params.contents_texture = contents_texture; | |
| 3902 params.quad_to_target_transform = | |
| 3903 params.quad->shared_quad_state->quad_to_target_transform; | |
| 3904 | |
| 3905 // Calculate projection and window matrices using InitializeViewport(). This | |
| 3906 // requires creating a dummy DrawingFrame. | |
| 3907 { | |
| 3908 DrawingFrame frame; | |
| 3909 gfx::Rect frame_rect = external_frame->device_viewport_rect; | |
| 3910 force_drawing_frame_framebuffer_unflipped_ = true; | |
| 3911 InitializeViewport(&frame, frame_rect, frame_rect, frame_rect.size()); | |
| 3912 force_drawing_frame_framebuffer_unflipped_ = false; | |
| 3913 params.projection_matrix = frame.projection_matrix; | |
| 3914 params.window_matrix = frame.window_matrix; | |
| 3915 } | |
| 3916 | |
| 3917 // Perform basic initialization with the screen-sized viewport. | |
| 3918 if (!InitializeRPDQParameters(¶ms)) | |
| 3919 return; | |
| 3920 | |
| 3921 if (!UpdateRPDQWithSkiaFilters(¶ms)) | |
| 3922 return; | |
| 3923 | |
| 3924 // |params.dst_rect| now contain values that reflect a potentially increased | |
| 3925 // size quad. | |
| 3926 gfx::RectF updated_dst_rect = params.dst_rect; | |
| 3927 *new_bounds = updated_dst_rect; | |
| 3928 | |
| 3929 // Calculate new projection and window matrices for a minimally sized viewport | |
| 3930 // using InitializeViewport(). This requires creating a dummy DrawingFrame. | |
| 3931 { | |
| 3932 DrawingFrame frame; | |
| 3933 force_drawing_frame_framebuffer_unflipped_ = true; | |
| 3934 gfx::Rect frame_rect = | |
| 3935 gfx::Rect(0, 0, updated_dst_rect.width(), updated_dst_rect.height()); | |
| 3936 InitializeViewport(&frame, frame_rect, frame_rect, frame_rect.size()); | |
| 3937 force_drawing_frame_framebuffer_unflipped_ = false; | |
| 3938 params.projection_matrix = frame.projection_matrix; | |
| 3939 params.window_matrix = frame.window_matrix; | |
| 3940 } | |
| 3941 | |
| 3942 // Calculate a new quad_to_target_transform. | |
| 3943 params.quad_to_target_transform = gfx::Transform(); | |
| 3944 params.quad_to_target_transform.Translate(-updated_dst_rect.x(), | |
| 3945 -updated_dst_rect.y()); | |
| 3946 | |
| 3947 // Antialiasing works by fading out content that is close to the edge of the | |
| 3948 // viewport. All of these values need to be recalculated. | |
| 3949 if (params.use_aa) { | |
| 3950 current_window_space_viewport_ = | |
| 3951 gfx::Rect(0, 0, updated_dst_rect.width(), updated_dst_rect.height()); | |
| 3952 gfx::Transform quad_rect_matrix; | |
| 3953 QuadRectTransform(&quad_rect_matrix, params.quad_to_target_transform, | |
| 3954 updated_dst_rect); | |
| 3955 params.contents_device_transform = | |
| 3956 params.window_matrix * params.projection_matrix * quad_rect_matrix; | |
| 3957 bool clipped = false; | |
| 3958 params.contents_device_transform.FlattenTo2d(); | |
| 3959 gfx::QuadF device_layer_quad = MathUtil::MapQuad( | |
| 3960 params.contents_device_transform, SharedGeometryQuad(), &clipped); | |
| 3961 LayerQuad device_layer_edges(device_layer_quad); | |
| 3962 InflateAntiAliasingDistances(device_layer_quad, &device_layer_edges, | |
| 3963 params.edge); | |
| 3964 } | |
| 3965 | |
| 3966 // Establish destination texture. | |
| 3967 *resource = overlay_resource_pool_->AcquireResource( | |
| 3968 gfx::Size(updated_dst_rect.width(), updated_dst_rect.height()), | |
| 3969 ResourceFormat::RGBA_8888); | |
| 3970 ResourceProvider::ScopedWriteLockGL destination(resource_provider_, | |
| 3971 (*resource)->id(), false); | |
| 3972 GLuint temp_fbo; | |
| 3973 | |
| 3974 gl_->GenFramebuffers(1, &temp_fbo); | |
| 3975 ScopedFramebufferDeleter framebuffer_deleter(temp_fbo, gl_); | |
|
ccameron
2016/08/09 06:32:15
Because we don't have any early-outs here, I think
erikchen
2016/08/09 16:52:13
Done.
| |
| 3976 gl_->BindFramebuffer(GL_FRAMEBUFFER, temp_fbo); | |
| 3977 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
| 3978 destination.target(), destination.texture_id(), 0); | |
| 3979 DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) == | |
| 3980 GL_FRAMEBUFFER_COMPLETE); | |
| 3981 | |
| 3982 // Clear to 0 to ensure the background is transparent. | |
| 3983 gl_->ClearColor(0, 0, 0, 0); | |
| 3984 gl_->Clear(GL_COLOR_BUFFER_BIT); | |
| 3985 | |
| 3986 UpdateRPDQTexturesForSampling(¶ms); | |
| 3987 UpdateRPDQBlendMode(¶ms); | |
| 3988 ChooseRPDQProgram(¶ms); | |
| 3989 UpdateRPDQUniforms(¶ms); | |
| 3990 | |
| 3991 // Prior to drawing, set up the destination framebuffer and viewport. | |
| 3992 gl_->BindFramebuffer(GL_FRAMEBUFFER, temp_fbo); | |
| 3993 gl_->Viewport(0, 0, updated_dst_rect.width(), updated_dst_rect.height()); | |
| 3994 | |
| 3995 DrawRPDQ(params); | |
| 3996 } | |
| 3997 | |
| 3998 void GLRenderer::ScheduleRenderPassDrawQuad( | |
| 3999 const CALayerOverlay* ca_layer_overlay, | |
| 4000 DrawingFrame* external_frame) { | |
| 4001 DCHECK(ca_layer_overlay->rpdq); | |
| 4002 | |
| 4003 if (!overlay_resource_pool_) { | |
| 4004 overlay_resource_pool_ = ResourcePool::CreateForGpuMemoryBufferResources( | |
| 4005 resource_provider_, base::ThreadTaskRunnerHandle::Get().get(), | |
| 4006 gfx::BufferUsage::SCANOUT); | |
| 4007 } | |
| 4008 | |
| 4009 Resource* resource = nullptr; | |
| 4010 gfx::RectF new_bounds; | |
| 4011 CopyRenderPassDrawQuadToOverlayResource(ca_layer_overlay, &resource, | |
| 4012 external_frame, &new_bounds); | |
| 4013 if (!resource || !resource->id()) | |
| 4014 return; | |
| 4015 | |
| 4016 pending_overlay_resources_.push_back( | |
| 4017 base::WrapUnique(new ResourceProvider::ScopedReadLockGL( | |
| 4018 resource_provider_, resource->id()))); | |
| 4019 unsigned texture_id = pending_overlay_resources_.back()->texture_id(); | |
| 4020 | |
| 4021 // Once a resource is released, it is marked as "busy". It will be | |
| 4022 // available for reuse after the ScopedReadLockGL is destroyed. | |
| 4023 overlay_resource_pool_->ReleaseResource(resource); | |
| 4024 | |
| 4025 GLfloat contents_rect[4] = { | |
| 4026 ca_layer_overlay->contents_rect.x(), ca_layer_overlay->contents_rect.y(), | |
| 4027 ca_layer_overlay->contents_rect.width(), | |
| 4028 ca_layer_overlay->contents_rect.height(), | |
| 4029 }; | |
| 4030 GLfloat bounds_rect[4] = { | |
| 4031 0, 0, new_bounds.width(), new_bounds.height(), | |
|
ccameron
2016/08/09 06:32:15
It's vaguely easier to comprehend this if bounds_r
erikchen
2016/08/09 16:52:13
Done.
| |
| 4032 }; | |
| 4033 GLboolean is_clipped = ca_layer_overlay->shared_state->is_clipped; | |
| 4034 GLfloat clip_rect[4] = {ca_layer_overlay->shared_state->clip_rect.x(), | |
| 4035 ca_layer_overlay->shared_state->clip_rect.y(), | |
| 4036 ca_layer_overlay->shared_state->clip_rect.width(), | |
| 4037 ca_layer_overlay->shared_state->clip_rect.height()}; | |
| 4038 GLint sorting_context_id = ca_layer_overlay->shared_state->sorting_context_id; | |
| 4039 SkMatrix44 transform = ca_layer_overlay->shared_state->transform; | |
| 4040 transform.preTranslate(new_bounds.x(), new_bounds.y(), 0); | |
| 4041 GLfloat gl_transform[16]; | |
| 4042 transform.asColMajorf(gl_transform); | |
| 4043 unsigned filter = ca_layer_overlay->filter; | |
| 4044 | |
| 4045 gl_->ScheduleCALayerSharedStateCHROMIUM( | |
| 4046 ca_layer_overlay->shared_state->opacity, is_clipped, clip_rect, | |
| 4047 sorting_context_id, gl_transform); | |
| 4048 gl_->ScheduleCALayerCHROMIUM( | |
| 4049 texture_id, contents_rect, ca_layer_overlay->background_color, | |
| 4050 ca_layer_overlay->edge_aa_mask, bounds_rect, filter); | |
| 4051 } | |
| 4052 | |
| 3858 } // namespace cc | 4053 } // namespace cc |
| OLD | NEW |