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 |