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 ScopedTextureDeleter { |
| 71 public: |
| 72 ScopedTextureDeleter(GLuint texture, gpu::gles2::GLES2Interface* gl) |
| 73 : texture_(texture), gl_(gl) {} |
| 74 ~ScopedTextureDeleter() { gl_->DeleteTextures(1, &texture_); } |
| 75 |
| 76 private: |
| 77 GLuint texture_; |
| 78 gpu::gles2::GLES2Interface* gl_; |
| 79 }; |
| 80 |
| 81 class ScopedFramebufferDeleter { |
| 82 public: |
| 83 ScopedFramebufferDeleter(GLuint fbo, gpu::gles2::GLES2Interface* gl) |
| 84 : fbo_(fbo), gl_(gl) {} |
| 85 ~ScopedFramebufferDeleter() { gl_->DeleteFramebuffers(1, &fbo_); } |
| 86 |
| 87 private: |
| 88 GLuint fbo_; |
| 89 gpu::gles2::GLES2Interface* gl_; |
| 90 }; |
| 91 |
70 Float4 UVTransform(const TextureDrawQuad* quad) { | 92 Float4 UVTransform(const TextureDrawQuad* quad) { |
71 gfx::PointF uv0 = quad->uv_top_left; | 93 gfx::PointF uv0 = quad->uv_top_left; |
72 gfx::PointF uv1 = quad->uv_bottom_right; | 94 gfx::PointF uv1 = quad->uv_bottom_right; |
73 Float4 xform = {{uv0.x(), uv0.y(), uv1.x() - uv0.x(), uv1.y() - uv0.y()}}; | 95 Float4 xform = {{uv0.x(), uv0.y(), uv1.x() - uv0.x(), uv1.y() - uv0.y()}}; |
74 if (quad->y_flipped) { | 96 if (quad->y_flipped) { |
75 xform.data[1] = 1.0f - xform.data[1]; | 97 xform.data[1] = 1.0f - xform.data[1]; |
76 xform.data[3] = -xform.data[3]; | 98 xform.data[3] = -xform.data[3]; |
77 } | 99 } |
78 return xform; | 100 return xform; |
79 } | 101 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 // Parameters needed to draw a RenderPassDrawQuad. | 176 // Parameters needed to draw a RenderPassDrawQuad. |
155 struct DrawRenderPassDrawQuadParams { | 177 struct DrawRenderPassDrawQuadParams { |
156 DrawRenderPassDrawQuadParams() {} | 178 DrawRenderPassDrawQuadParams() {} |
157 ~DrawRenderPassDrawQuadParams() {} | 179 ~DrawRenderPassDrawQuadParams() {} |
158 | 180 |
159 // Required Inputs. | 181 // Required Inputs. |
160 const RenderPassDrawQuad* quad = nullptr; | 182 const RenderPassDrawQuad* quad = nullptr; |
161 const Resource* contents_texture = nullptr; | 183 const Resource* contents_texture = nullptr; |
162 const gfx::QuadF* clip_region = nullptr; | 184 const gfx::QuadF* clip_region = nullptr; |
163 bool flip_texture = false; | 185 bool flip_texture = false; |
164 | |
165 gfx::Transform window_matrix; | 186 gfx::Transform window_matrix; |
166 gfx::Transform projection_matrix; | 187 gfx::Transform projection_matrix; |
| 188 gfx::Transform quad_to_target_transform; |
167 | 189 |
168 // |frame| is needed for background effects. | 190 // |frame| is only used for background effects. |
169 DirectRenderer::DrawingFrame* frame = nullptr; | 191 DirectRenderer::DrawingFrame* frame = nullptr; |
170 | 192 |
171 // Whether the texture to be sampled from needs to be flipped. | 193 // Whether the texture to be sampled from needs to be flipped. |
172 bool source_needs_flip = false; | 194 bool source_needs_flip = false; |
173 | 195 |
174 float edge[24]; | 196 float edge[24]; |
175 SkScalar color_matrix[20]; | 197 SkScalar color_matrix[20]; |
176 | 198 |
177 // Blending refers to modifications to the backdrop. | 199 // Blending refers to modifications to the backdrop. |
178 bool use_shaders_for_blending = false; | 200 bool use_shaders_for_blending = false; |
(...skipping 30 matching lines...) Expand all Loading... |
209 GLuint background_image_id = 0; | 231 GLuint background_image_id = 0; |
210 | 232 |
211 // Whether the original background texture is needed for the mask. | 233 // Whether the original background texture is needed for the mask. |
212 bool mask_for_background = false; | 234 bool mask_for_background = false; |
213 | 235 |
214 // Whether a color matrix needs to be applied by the shaders when drawing | 236 // Whether a color matrix needs to be applied by the shaders when drawing |
215 // the RPDQ. | 237 // the RPDQ. |
216 bool use_color_matrix = false; | 238 bool use_color_matrix = false; |
217 | 239 |
218 gfx::QuadF surface_quad; | 240 gfx::QuadF surface_quad; |
| 241 |
219 gfx::Transform contents_device_transform; | 242 gfx::Transform contents_device_transform; |
220 }; | 243 }; |
221 | 244 |
222 static GLint GetActiveTextureUnit(GLES2Interface* gl) { | 245 static GLint GetActiveTextureUnit(GLES2Interface* gl) { |
223 GLint active_unit = 0; | 246 GLint active_unit = 0; |
224 gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit); | 247 gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit); |
225 return active_unit; | 248 return active_unit; |
226 } | 249 } |
227 | 250 |
228 class GLRenderer::ScopedUseGrContext { | 251 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 | 1085 // See above comments about texture flipping. When the input is a |
1063 // render pass, it needs to an extra flip to be oriented correctly. | 1086 // render pass, it needs to an extra flip to be oriented correctly. |
1064 params.flip_texture = true; | 1087 params.flip_texture = true; |
1065 params.contents_texture = contents_texture; | 1088 params.contents_texture = contents_texture; |
1066 DrawRenderPassQuadInternal(¶ms); | 1089 DrawRenderPassQuadInternal(¶ms); |
1067 } | 1090 } |
1068 } | 1091 } |
1069 | 1092 |
1070 void GLRenderer::DrawRenderPassQuadInternal( | 1093 void GLRenderer::DrawRenderPassQuadInternal( |
1071 DrawRenderPassDrawQuadParams* params) { | 1094 DrawRenderPassDrawQuadParams* params) { |
| 1095 params->quad_to_target_transform = |
| 1096 params->quad->shared_quad_state->quad_to_target_transform; |
1072 if (!InitializeRPDQParameters(params)) | 1097 if (!InitializeRPDQParameters(params)) |
1073 return; | 1098 return; |
1074 UpdateRPDQShadersForBlending(params); | 1099 UpdateRPDQShadersForBlending(params); |
1075 if (!UpdateRPDQWithSkiaFilters(params)) | 1100 if (!UpdateRPDQWithSkiaFilters(params)) |
1076 return; | 1101 return; |
1077 UseRenderPass(params->frame, params->frame->current_render_pass); | 1102 UseRenderPass(params->frame, params->frame->current_render_pass); |
1078 SetViewport(); | 1103 SetViewport(); |
1079 UpdateRPDQTexturesForSampling(params); | 1104 UpdateRPDQTexturesForSampling(params); |
1080 UpdateRPDQBlendMode(params); | 1105 UpdateRPDQBlendMode(params); |
1081 ChooseRPDQProgram(params); | 1106 ChooseRPDQProgram(params); |
1082 UpdateRPDQUniforms(params); | 1107 UpdateRPDQUniforms(params); |
1083 DrawRPDQ(*params); | 1108 DrawRPDQ(*params); |
1084 } | 1109 } |
1085 | 1110 |
1086 bool GLRenderer::InitializeRPDQParameters( | 1111 bool GLRenderer::InitializeRPDQParameters( |
1087 DrawRenderPassDrawQuadParams* params) { | 1112 DrawRenderPassDrawQuadParams* params) { |
1088 const RenderPassDrawQuad* quad = params->quad; | 1113 const RenderPassDrawQuad* quad = params->quad; |
1089 SkMatrix scale_matrix; | 1114 SkMatrix scale_matrix; |
1090 scale_matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); | 1115 scale_matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y()); |
1091 gfx::Rect dst_rect = quad->filters.MapRect(quad->rect, scale_matrix); | 1116 gfx::Rect dst_rect = quad->filters.MapRect(quad->rect, scale_matrix); |
1092 params->dst_rect.SetRect(static_cast<float>(dst_rect.x()), | 1117 params->dst_rect.SetRect(static_cast<float>(dst_rect.x()), |
1093 static_cast<float>(dst_rect.y()), | 1118 static_cast<float>(dst_rect.y()), |
1094 static_cast<float>(dst_rect.width()), | 1119 static_cast<float>(dst_rect.width()), |
1095 static_cast<float>(dst_rect.height())); | 1120 static_cast<float>(dst_rect.height())); |
1096 gfx::Transform quad_rect_matrix; | 1121 gfx::Transform quad_rect_matrix; |
1097 QuadRectTransform(&quad_rect_matrix, | 1122 QuadRectTransform(&quad_rect_matrix, params->quad_to_target_transform, |
1098 quad->shared_quad_state->quad_to_target_transform, | |
1099 params->dst_rect); | 1123 params->dst_rect); |
1100 params->contents_device_transform = | 1124 params->contents_device_transform = |
1101 params->window_matrix * params->projection_matrix * quad_rect_matrix; | 1125 params->window_matrix * params->projection_matrix * quad_rect_matrix; |
1102 params->contents_device_transform.FlattenTo2d(); | 1126 params->contents_device_transform.FlattenTo2d(); |
1103 | 1127 |
1104 // Can only draw surface if device matrix is invertible. | 1128 // Can only draw surface if device matrix is invertible. |
1105 if (!params->contents_device_transform.IsInvertible()) | 1129 if (!params->contents_device_transform.IsInvertible()) |
1106 return false; | 1130 return false; |
1107 | 1131 |
1108 params->surface_quad = SharedGeometryQuad(); | 1132 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) | 1235 // locally in the compositor and process the rest of the DAG (if any) |
1212 // in Skia. | 1236 // in Skia. |
1213 params->use_color_matrix = true; | 1237 params->use_color_matrix = true; |
1214 filter = sk_ref_sp(filter->getInput(0)); | 1238 filter = sk_ref_sp(filter->getInput(0)); |
1215 } | 1239 } |
1216 if (filter) { | 1240 if (filter) { |
1217 gfx::Rect clip_rect = quad->shared_quad_state->clip_rect; | 1241 gfx::Rect clip_rect = quad->shared_quad_state->clip_rect; |
1218 if (clip_rect.IsEmpty()) { | 1242 if (clip_rect.IsEmpty()) { |
1219 clip_rect = current_draw_rect_; | 1243 clip_rect = current_draw_rect_; |
1220 } | 1244 } |
1221 gfx::Transform transform = | 1245 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)); | 1246 gfx::QuadF clip_quad = gfx::QuadF(gfx::RectF(clip_rect)); |
1224 gfx::QuadF local_clip = MapQuadToLocalSpace(transform, clip_quad); | 1247 gfx::QuadF local_clip = MapQuadToLocalSpace(transform, clip_quad); |
1225 params->dst_rect.Intersect(local_clip.BoundingBox()); | 1248 params->dst_rect.Intersect(local_clip.BoundingBox()); |
1226 // If we've been fully clipped out (by crop rect or clipping), there's | 1249 // If we've been fully clipped out (by crop rect or clipping), there's |
1227 // nothing to draw. | 1250 // nothing to draw. |
1228 if (params->dst_rect.IsEmpty()) { | 1251 if (params->dst_rect.IsEmpty()) { |
1229 return false; | 1252 return false; |
1230 } | 1253 } |
1231 SkIPoint offset; | 1254 SkIPoint offset; |
1232 SkIRect subset; | 1255 SkIRect subset; |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1493 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), | 1516 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), |
1494 params->shader_background_sampler_lock->target()); | 1517 params->shader_background_sampler_lock->target()); |
1495 } | 1518 } |
1496 } | 1519 } |
1497 | 1520 |
1498 SetShaderOpacity(params->quad->shared_quad_state->opacity, locations.alpha); | 1521 SetShaderOpacity(params->quad->shared_quad_state->opacity, locations.alpha); |
1499 SetShaderQuadF(params->surface_quad, locations.quad); | 1522 SetShaderQuadF(params->surface_quad, locations.quad); |
1500 } | 1523 } |
1501 | 1524 |
1502 void GLRenderer::DrawRPDQ(const DrawRenderPassDrawQuadParams& params) { | 1525 void GLRenderer::DrawRPDQ(const DrawRenderPassDrawQuadParams& params) { |
1503 DrawQuadGeometry(params.projection_matrix, | 1526 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); | 1527 params.dst_rect, params.locations.matrix); |
1506 | 1528 |
1507 // Flush the compositor context before the filter bitmap goes out of | 1529 // Flush the compositor context before the filter bitmap goes out of |
1508 // scope, so the draw gets processed before the filter texture gets deleted. | 1530 // scope, so the draw gets processed before the filter texture gets deleted. |
1509 if (params.filter_image) | 1531 if (params.filter_image) |
1510 gl_->Flush(); | 1532 gl_->Flush(); |
1511 | 1533 |
1512 if (!params.use_shaders_for_blending) | 1534 if (!params.use_shaders_for_blending) |
1513 RestoreBlendFuncToDefault(params.quad->shared_quad_state->blend_mode); | 1535 RestoreBlendFuncToDefault(params.quad->shared_quad_state->blend_mode); |
1514 } | 1536 } |
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2722 | 2744 |
2723 ScheduleCALayers(frame); | 2745 ScheduleCALayers(frame); |
2724 ScheduleOverlays(frame); | 2746 ScheduleOverlays(frame); |
2725 } | 2747 } |
2726 | 2748 |
2727 void GLRenderer::FinishDrawingQuadList() { | 2749 void GLRenderer::FinishDrawingQuadList() { |
2728 FlushTextureQuadCache(SHARED_BINDING); | 2750 FlushTextureQuadCache(SHARED_BINDING); |
2729 } | 2751 } |
2730 | 2752 |
2731 bool GLRenderer::FlippedFramebuffer(const DrawingFrame* frame) const { | 2753 bool GLRenderer::FlippedFramebuffer(const DrawingFrame* frame) const { |
| 2754 if (frame == force_drawing_frame_framebuffer_flipped_) |
| 2755 return true; |
2732 if (frame->current_render_pass != frame->root_render_pass) | 2756 if (frame->current_render_pass != frame->root_render_pass) |
2733 return true; | 2757 return true; |
2734 return FlippedRootFramebuffer(); | 2758 return FlippedRootFramebuffer(); |
2735 } | 2759 } |
2736 | 2760 |
2737 bool GLRenderer::FlippedRootFramebuffer() const { | 2761 bool GLRenderer::FlippedRootFramebuffer() const { |
2738 // GL is normally flipped, so a flipped output results in an unflipping. | 2762 // GL is normally flipped, so a flipped output results in an unflipping. |
2739 return !output_surface_->capabilities().flipped_output_surface; | 2763 return !output_surface_->capabilities().flipped_output_surface; |
2740 } | 2764 } |
2741 | 2765 |
(...skipping 1029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3771 } | 3795 } |
3772 | 3796 |
3773 bool GLRenderer::IsContextLost() { | 3797 bool GLRenderer::IsContextLost() { |
3774 return gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR; | 3798 return gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR; |
3775 } | 3799 } |
3776 | 3800 |
3777 void GLRenderer::ScheduleCALayers(DrawingFrame* frame) { | 3801 void GLRenderer::ScheduleCALayers(DrawingFrame* frame) { |
3778 scoped_refptr<CALayerOverlaySharedState> shared_state; | 3802 scoped_refptr<CALayerOverlaySharedState> shared_state; |
3779 size_t copied_render_pass_count = 0; | 3803 size_t copied_render_pass_count = 0; |
3780 for (const CALayerOverlay& ca_layer_overlay : frame->ca_layer_overlay_list) { | 3804 for (const CALayerOverlay& ca_layer_overlay : frame->ca_layer_overlay_list) { |
3781 if (!overlay_resource_pool_) { | 3805 if (ca_layer_overlay.rpdq) { |
3782 overlay_resource_pool_ = ResourcePool::CreateForGpuMemoryBufferResources( | 3806 ScheduleRenderPassDrawQuad(&ca_layer_overlay, frame); |
3783 resource_provider_, base::ThreadTaskRunnerHandle::Get().get(), | 3807 shared_state = nullptr; |
3784 gfx::BufferUsage::SCANOUT); | 3808 ++copied_render_pass_count; |
| 3809 continue; |
3785 } | 3810 } |
3786 | 3811 |
3787 ResourceId contents_resource_id = ca_layer_overlay.contents_resource_id; | 3812 ResourceId contents_resource_id = ca_layer_overlay.contents_resource_id; |
3788 unsigned texture_id = 0; | 3813 unsigned texture_id = 0; |
3789 if (contents_resource_id) { | 3814 if (contents_resource_id) { |
3790 pending_overlay_resources_.push_back( | 3815 pending_overlay_resources_.push_back( |
3791 base::WrapUnique(new ResourceProvider::ScopedReadLockGL( | 3816 base::WrapUnique(new ResourceProvider::ScopedReadLockGL( |
3792 resource_provider_, contents_resource_id))); | 3817 resource_provider_, contents_resource_id))); |
3793 texture_id = pending_overlay_resources_.back()->texture_id(); | 3818 texture_id = pending_overlay_resources_.back()->texture_id(); |
3794 } | 3819 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3848 resource_provider_, overlay.resource_id))); | 3873 resource_provider_, overlay.resource_id))); |
3849 texture_id = pending_overlay_resources_.back()->texture_id(); | 3874 texture_id = pending_overlay_resources_.back()->texture_id(); |
3850 } | 3875 } |
3851 | 3876 |
3852 context_support_->ScheduleOverlayPlane( | 3877 context_support_->ScheduleOverlayPlane( |
3853 overlay.plane_z_order, overlay.transform, texture_id, | 3878 overlay.plane_z_order, overlay.transform, texture_id, |
3854 ToNearestRect(overlay.display_rect), overlay.uv_rect); | 3879 ToNearestRect(overlay.display_rect), overlay.uv_rect); |
3855 } | 3880 } |
3856 } | 3881 } |
3857 | 3882 |
| 3883 // This function draws the RenderPassDrawQuad into a temporary |
| 3884 // texture/framebuffer, and then copies the result into an IOSurface. The |
| 3885 // inefficient (but simple) way to do this would be to: |
| 3886 // 1. Allocate a framebuffer the size of the screen. |
| 3887 // 2. Draw using all the normal RPDQ draw logic. |
| 3888 // Instead, this method does the following: |
| 3889 // 1. Configure parameters as if drawing to a framebuffer the size of the |
| 3890 // screen. This reuses most of the RPDQ draw logic. |
| 3891 // 2. Update parameters to draw into a framebuffer only as large as needed. |
| 3892 // 3. Fix shader uniforms that were broken by (2). |
| 3893 // |
| 3894 // Then: |
| 3895 // 4. Allocate a temporary TEXTURE_2D as the drawing destination. |
| 3896 // 5. Draw the RPDQ. |
| 3897 // 6. Copy from the temporary texture into an IOSurface. |
| 3898 void GLRenderer::CopyRenderPassDrawQuadToOverlayResource( |
| 3899 const CALayerOverlay* ca_layer_overlay, |
| 3900 Resource** resource, |
| 3901 DrawingFrame* external_frame, |
| 3902 gfx::RectF* new_bounds) { |
| 3903 ScopedResource* contents_texture = |
| 3904 render_pass_textures_[ca_layer_overlay->rpdq->render_pass_id].get(); |
| 3905 DCHECK(contents_texture); |
| 3906 |
| 3907 // Configure parameters as if drawing to a framebuffer the size of the |
| 3908 // screen. |
| 3909 DrawRenderPassDrawQuadParams params; |
| 3910 params.quad = ca_layer_overlay->rpdq; |
| 3911 params.flip_texture = true; |
| 3912 params.contents_texture = contents_texture; |
| 3913 params.quad_to_target_transform = |
| 3914 params.quad->shared_quad_state->quad_to_target_transform; |
| 3915 |
| 3916 // Calculate projection and window matrices using InitializeViewport(). This |
| 3917 // requires creating a dummy DrawingFrame. |
| 3918 { |
| 3919 DrawingFrame frame; |
| 3920 gfx::Rect frame_rect = external_frame->device_viewport_rect; |
| 3921 force_drawing_frame_framebuffer_flipped_ = &frame; |
| 3922 InitializeViewport(&frame, frame_rect, frame_rect, frame_rect.size()); |
| 3923 force_drawing_frame_framebuffer_flipped_ = nullptr; |
| 3924 params.projection_matrix = frame.projection_matrix; |
| 3925 params.window_matrix = frame.window_matrix; |
| 3926 } |
| 3927 |
| 3928 // Perform basic initialization with the screen-sized viewport. |
| 3929 if (!InitializeRPDQParameters(¶ms)) |
| 3930 return; |
| 3931 |
| 3932 if (!UpdateRPDQWithSkiaFilters(¶ms)) |
| 3933 return; |
| 3934 |
| 3935 // |params.dst_rect| now contain values that reflect a potentially increased |
| 3936 // size quad. |
| 3937 gfx::RectF updated_dst_rect = params.dst_rect; |
| 3938 *new_bounds = updated_dst_rect; |
| 3939 |
| 3940 // Calculate new projection and window matrices for a minimally sized viewport |
| 3941 // using InitializeViewport(). This requires creating a dummy DrawingFrame. |
| 3942 { |
| 3943 DrawingFrame frame; |
| 3944 force_drawing_frame_framebuffer_flipped_ = &frame; |
| 3945 gfx::Rect frame_rect = |
| 3946 gfx::Rect(0, 0, updated_dst_rect.width(), updated_dst_rect.height()); |
| 3947 InitializeViewport(&frame, frame_rect, frame_rect, frame_rect.size()); |
| 3948 force_drawing_frame_framebuffer_flipped_ = nullptr; |
| 3949 params.projection_matrix = frame.projection_matrix; |
| 3950 params.window_matrix = frame.window_matrix; |
| 3951 } |
| 3952 |
| 3953 // Calculate a new quad_to_target_transform. |
| 3954 params.quad_to_target_transform = gfx::Transform(); |
| 3955 params.quad_to_target_transform.Translate(-updated_dst_rect.x(), |
| 3956 -updated_dst_rect.y()); |
| 3957 |
| 3958 // Antialiasing works by fading out content that is close to the edge of the |
| 3959 // viewport. All of these values need to be recalculated. |
| 3960 if (params.use_aa) { |
| 3961 current_window_space_viewport_ = |
| 3962 gfx::Rect(0, 0, updated_dst_rect.width(), updated_dst_rect.height()); |
| 3963 gfx::Transform quad_rect_matrix; |
| 3964 QuadRectTransform(&quad_rect_matrix, params.quad_to_target_transform, |
| 3965 updated_dst_rect); |
| 3966 params.contents_device_transform = |
| 3967 params.window_matrix * params.projection_matrix * quad_rect_matrix; |
| 3968 bool clipped = false; |
| 3969 params.contents_device_transform.FlattenTo2d(); |
| 3970 gfx::QuadF device_layer_quad = MathUtil::MapQuad( |
| 3971 params.contents_device_transform, SharedGeometryQuad(), &clipped); |
| 3972 LayerQuad device_layer_edges(device_layer_quad); |
| 3973 InflateAntiAliasingDistances(device_layer_quad, &device_layer_edges, |
| 3974 params.edge); |
| 3975 } |
| 3976 |
| 3977 // Establish temp texture and fbo. |
| 3978 GLuint temp_texture; |
| 3979 GLuint temp_fbo; |
| 3980 |
| 3981 gl_->GenTextures(1, &temp_texture); |
| 3982 ScopedTextureDeleter texture_deleter(temp_texture, gl_); |
| 3983 gl_->BindTexture(GL_TEXTURE_2D, temp_texture); |
| 3984 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 3985 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 3986 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 3987 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 3988 gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, updated_dst_rect.width(), |
| 3989 updated_dst_rect.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| 3990 nullptr); |
| 3991 |
| 3992 gl_->GenFramebuffers(1, &temp_fbo); |
| 3993 ScopedFramebufferDeleter framebuffer_deleter(temp_fbo, gl_); |
| 3994 gl_->BindFramebuffer(GL_FRAMEBUFFER, temp_fbo); |
| 3995 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, |
| 3996 temp_texture, 0); |
| 3997 DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) == |
| 3998 GL_FRAMEBUFFER_COMPLETE); |
| 3999 |
| 4000 // Clear to 0 to ensure the background is transparent. |
| 4001 gl_->ClearColor(0, 0, 0, 0); |
| 4002 gl_->Clear(GL_COLOR_BUFFER_BIT); |
| 4003 |
| 4004 UpdateRPDQTexturesForSampling(¶ms); |
| 4005 UpdateRPDQBlendMode(¶ms); |
| 4006 ChooseRPDQProgram(¶ms); |
| 4007 UpdateRPDQUniforms(¶ms); |
| 4008 |
| 4009 // Prior to drawing, set up the destination framebuffer and viewport. |
| 4010 gl_->BindFramebuffer(GL_FRAMEBUFFER, temp_fbo); |
| 4011 gl_->Viewport(0, 0, updated_dst_rect.width(), updated_dst_rect.height()); |
| 4012 |
| 4013 DrawRPDQ(params); |
| 4014 |
| 4015 // Copy from the temporary framebuffer into an overlay. |
| 4016 *resource = overlay_resource_pool_->AcquireResource( |
| 4017 gfx::Size(updated_dst_rect.width(), updated_dst_rect.height()), |
| 4018 ResourceFormat::RGBA_8888); |
| 4019 ResourceProvider::ScopedWriteLockGL destination(resource_provider_, |
| 4020 (*resource)->id(), false); |
| 4021 gl_->CopySubTextureCHROMIUM(temp_texture, destination.texture_id(), 0, 0, 0, |
| 4022 0, updated_dst_rect.width(), |
| 4023 updated_dst_rect.height(), GL_TRUE, GL_FALSE, |
| 4024 GL_FALSE); |
| 4025 } |
| 4026 |
| 4027 void GLRenderer::ScheduleRenderPassDrawQuad( |
| 4028 const CALayerOverlay* ca_layer_overlay, |
| 4029 DrawingFrame* external_frame) { |
| 4030 DCHECK(ca_layer_overlay->rpdq); |
| 4031 |
| 4032 if (!overlay_resource_pool_) { |
| 4033 overlay_resource_pool_ = ResourcePool::CreateForGpuMemoryBufferResources( |
| 4034 resource_provider_, base::ThreadTaskRunnerHandle::Get().get(), |
| 4035 gfx::BufferUsage::SCANOUT); |
| 4036 } |
| 4037 |
| 4038 Resource* resource = nullptr; |
| 4039 gfx::RectF new_bounds; |
| 4040 CopyRenderPassDrawQuadToOverlayResource(ca_layer_overlay, &resource, |
| 4041 external_frame, &new_bounds); |
| 4042 if (!resource || !resource->id()) |
| 4043 return; |
| 4044 |
| 4045 pending_overlay_resources_.push_back( |
| 4046 base::WrapUnique(new ResourceProvider::ScopedReadLockGL( |
| 4047 resource_provider_, resource->id()))); |
| 4048 unsigned texture_id = pending_overlay_resources_.back()->texture_id(); |
| 4049 |
| 4050 // Once a resource is released, it is marked as "busy". It will be |
| 4051 // available for reuse after the ScopedReadLockGL is destroyed. |
| 4052 overlay_resource_pool_->ReleaseResource(resource); |
| 4053 |
| 4054 GLfloat contents_rect[4] = { |
| 4055 ca_layer_overlay->contents_rect.x(), ca_layer_overlay->contents_rect.y(), |
| 4056 ca_layer_overlay->contents_rect.width(), |
| 4057 ca_layer_overlay->contents_rect.height(), |
| 4058 }; |
| 4059 GLfloat bounds_rect[4] = { |
| 4060 0, 0, new_bounds.width(), new_bounds.height(), |
| 4061 }; |
| 4062 GLboolean is_clipped = ca_layer_overlay->shared_state->is_clipped; |
| 4063 GLfloat clip_rect[4] = {ca_layer_overlay->shared_state->clip_rect.x(), |
| 4064 ca_layer_overlay->shared_state->clip_rect.y(), |
| 4065 ca_layer_overlay->shared_state->clip_rect.width(), |
| 4066 ca_layer_overlay->shared_state->clip_rect.height()}; |
| 4067 GLint sorting_context_id = ca_layer_overlay->shared_state->sorting_context_id; |
| 4068 SkMatrix44 transform = ca_layer_overlay->shared_state->transform; |
| 4069 transform.preTranslate(new_bounds.x(), new_bounds.y(), 0); |
| 4070 GLfloat gl_transform[16]; |
| 4071 transform.asColMajorf(gl_transform); |
| 4072 unsigned filter = ca_layer_overlay->filter; |
| 4073 |
| 4074 gl_->ScheduleCALayerSharedStateCHROMIUM( |
| 4075 ca_layer_overlay->shared_state->opacity, is_clipped, clip_rect, |
| 4076 sorting_context_id, gl_transform); |
| 4077 gl_->ScheduleCALayerCHROMIUM( |
| 4078 texture_id, contents_rect, ca_layer_overlay->background_color, |
| 4079 ca_layer_overlay->edge_aa_mask, bounds_rect, filter); |
| 4080 } |
| 4081 |
3858 } // namespace cc | 4082 } // namespace cc |
OLD | NEW |