Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: cc/output/gl_renderer.cc

Issue 2205133003: Implement new RPDQ copy logic for CALayer promotion. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@temp60_more_refactor
Patch Set: Fix vertical flip. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 186
165 gfx::Transform window_matrix; 187 gfx::Transform window_matrix;
166 gfx::Transform projection_matrix; 188 gfx::Transform projection_matrix;
167 189
168 // |frame| is needed for background effects. 190 // |frame| is used to restore the current render pass. |frame| is also needed
191 // for background effects. If |frame| is not present, nothing happens.
169 DirectRenderer::DrawingFrame* frame = nullptr; 192 DirectRenderer::DrawingFrame* frame = nullptr;
170 193
171 // Whether the texture to be sampled from needs to be flipped. 194 // Whether the texture to be sampled from needs to be flipped.
172 bool source_needs_flip = false; 195 bool source_needs_flip = false;
173 196
174 float edge[24]; 197 float edge[24];
175 SkScalar color_matrix[20]; 198 SkScalar color_matrix[20];
176 199
177 // Blending refers to modifications to the backdrop. 200 // Blending refers to modifications to the backdrop.
178 bool use_shaders_for_blending = false; 201 bool use_shaders_for_blending = false;
(...skipping 2511 matching lines...) Expand 10 before | Expand all | Expand 10 after
2690 2713
2691 ScheduleCALayers(frame); 2714 ScheduleCALayers(frame);
2692 ScheduleOverlays(frame); 2715 ScheduleOverlays(frame);
2693 } 2716 }
2694 2717
2695 void GLRenderer::FinishDrawingQuadList() { 2718 void GLRenderer::FinishDrawingQuadList() {
2696 FlushTextureQuadCache(SHARED_BINDING); 2719 FlushTextureQuadCache(SHARED_BINDING);
2697 } 2720 }
2698 2721
2699 bool GLRenderer::FlippedFramebuffer(const DrawingFrame* frame) const { 2722 bool GLRenderer::FlippedFramebuffer(const DrawingFrame* frame) const {
2723 if (frame == force_drawing_frame_framebuffer_flipped_)
2724 return true;
2700 if (frame->current_render_pass != frame->root_render_pass) 2725 if (frame->current_render_pass != frame->root_render_pass)
2701 return true; 2726 return true;
2702 return FlippedRootFramebuffer(); 2727 return FlippedRootFramebuffer();
2703 } 2728 }
2704 2729
2705 bool GLRenderer::FlippedRootFramebuffer() const { 2730 bool GLRenderer::FlippedRootFramebuffer() const {
2706 // GL is normally flipped, so a flipped output results in an unflipping. 2731 // GL is normally flipped, so a flipped output results in an unflipping.
2707 return !output_surface_->capabilities().flipped_output_surface; 2732 return !output_surface_->capabilities().flipped_output_surface;
2708 } 2733 }
2709 2734
(...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after
3738 } 3763 }
3739 } 3764 }
3740 3765
3741 bool GLRenderer::IsContextLost() { 3766 bool GLRenderer::IsContextLost() {
3742 return gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR; 3767 return gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
3743 } 3768 }
3744 3769
3745 void GLRenderer::ScheduleCALayers(DrawingFrame* frame) { 3770 void GLRenderer::ScheduleCALayers(DrawingFrame* frame) {
3746 scoped_refptr<CALayerOverlaySharedState> shared_state; 3771 scoped_refptr<CALayerOverlaySharedState> shared_state;
3747 size_t copied_render_pass_count = 0; 3772 size_t copied_render_pass_count = 0;
3748 for (const CALayerOverlay& ca_layer_overlay : frame->ca_layer_overlay_list) { 3773 for (CALayerOverlay& ca_layer_overlay : frame->ca_layer_overlay_list) {
3749 if (!overlay_resource_pool_) { 3774 if (!overlay_resource_pool_) {
3750 overlay_resource_pool_ = ResourcePool::CreateForGpuMemoryBufferResources( 3775 overlay_resource_pool_ = ResourcePool::CreateForGpuMemoryBufferResources(
3751 resource_provider_, base::ThreadTaskRunnerHandle::Get().get(), 3776 resource_provider_, base::ThreadTaskRunnerHandle::Get().get(),
3752 gfx::BufferUsage::SCANOUT); 3777 gfx::BufferUsage::SCANOUT);
3753 } 3778 }
3754 3779
3755 ResourceId contents_resource_id = ca_layer_overlay.contents_resource_id; 3780 ResourceId contents_resource_id = ca_layer_overlay.contents_resource_id;
3756 Resource* resource = nullptr; 3781 Resource* resource = nullptr;
3757 // Some CALayers require a final round of processing. 3782 // Some CALayers require a final round of processing.
3758 if (ca_layer_overlay.render_pass_id.IsValid()) { 3783 if (ca_layer_overlay.rpdq.get()) {
3759 CopyRenderPassToOverlayResource(ca_layer_overlay.render_pass_id, 3784 CopyRenderPassDrawQuadToOverlayResource(&ca_layer_overlay, &resource,
3760 &resource); 3785 frame);
ccameron 2016/08/04 01:46:01 Rather than updating the CALayerOverlay parameters
erikchen 2016/08/05 17:15:06 Done.
3761 contents_resource_id = resource->id(); 3786 if (resource) {
3762 ++copied_render_pass_count; 3787 contents_resource_id = resource->id();
3788 ++copied_render_pass_count;
3789 }
3763 } 3790 }
3764 3791
3765 unsigned texture_id = 0; 3792 unsigned texture_id = 0;
3766 if (contents_resource_id) { 3793 if (contents_resource_id) {
3767 pending_overlay_resources_.push_back( 3794 pending_overlay_resources_.push_back(
3768 base::WrapUnique(new ResourceProvider::ScopedReadLockGL( 3795 base::WrapUnique(new ResourceProvider::ScopedReadLockGL(
3769 resource_provider_, contents_resource_id))); 3796 resource_provider_, contents_resource_id)));
3770 texture_id = pending_overlay_resources_.back()->texture_id(); 3797 texture_id = pending_overlay_resources_.back()->texture_id();
3771 3798
3772 if (resource) { 3799 if (resource) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3813 effect.amount = filter_effect.amount; 3840 effect.amount = filter_effect.amount;
3814 effect.drop_shadow_offset_x = filter_effect.drop_shadow_offset.x(); 3841 effect.drop_shadow_offset_x = filter_effect.drop_shadow_offset.x();
3815 effect.drop_shadow_offset_y = filter_effect.drop_shadow_offset.y(); 3842 effect.drop_shadow_offset_y = filter_effect.drop_shadow_offset.y();
3816 3843
3817 static_assert(sizeof(GLuint) == sizeof(SkColor), 3844 static_assert(sizeof(GLuint) == sizeof(SkColor),
3818 "GLuint and SkColor must have the same size."); 3845 "GLuint and SkColor must have the same size.");
3819 effect.drop_shadow_color = 3846 effect.drop_shadow_color =
3820 static_cast<GLuint>(filter_effect.drop_shadow_color); 3847 static_cast<GLuint>(filter_effect.drop_shadow_color);
3821 } 3848 }
3822 3849
3823 gl_->ScheduleCALayerFilterEffectsCHROMIUM(effects.size(), effects.data()); 3850 // TODO(erikchen): Remove all logic associated with
3851 // ScheduleCALayerFilterEffectsCHROMIUM once the implementation of filter
3852 // effects for CA is fully functional. https://crbug.com/581526.
3853 // gl_->ScheduleCALayerFilterEffectsCHROMIUM(effects.size(),
3854 // effects.data());
3824 } 3855 }
3825 gl_->ScheduleCALayerCHROMIUM( 3856 gl_->ScheduleCALayerCHROMIUM(
3826 texture_id, contents_rect, ca_layer_overlay.background_color, 3857 texture_id, contents_rect, ca_layer_overlay.background_color,
3827 ca_layer_overlay.edge_aa_mask, bounds_rect, filter); 3858 ca_layer_overlay.edge_aa_mask, bounds_rect, filter);
3828 } 3859 }
3829 3860
3830 // Take the number of copied render passes in this frame, and use 3 times that 3861 // Take the number of copied render passes in this frame, and use 3 times that
3831 // amount as the cache limit. 3862 // amount as the cache limit.
3832 if (overlay_resource_pool_) { 3863 if (overlay_resource_pool_) {
3833 overlay_resource_pool_->SetResourceUsageLimits( 3864 overlay_resource_pool_->SetResourceUsageLimits(
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3879 source.reset(new ResourceProvider::ScopedReadLockGL( 3910 source.reset(new ResourceProvider::ScopedReadLockGL(
3880 resource_provider_, contents_texture->id())); 3911 resource_provider_, contents_texture->id()));
3881 source_texture = source->texture_id(); 3912 source_texture = source->texture_id();
3882 } 3913 }
3883 gl_->CopySubTextureCHROMIUM(source_texture, destination.texture_id(), 0, 0, 0, 3914 gl_->CopySubTextureCHROMIUM(source_texture, destination.texture_id(), 0, 0, 0,
3884 0, contents_texture->size().width(), 3915 0, contents_texture->size().width(),
3885 contents_texture->size().height(), GL_TRUE, 3916 contents_texture->size().height(), GL_TRUE,
3886 GL_FALSE, GL_FALSE); 3917 GL_FALSE, GL_FALSE);
3887 } 3918 }
3888 3919
3920 // This function draws the RenderPassDrawQuad into a temporary
3921 // texture/framebuffer, and then copies the result into an IOSurface.
3922 void GLRenderer::CopyRenderPassDrawQuadToOverlayResource(
3923 CALayerOverlay* ca_layer_overlay,
3924 Resource** resource,
3925 DrawingFrame* external_frame) {
3926 ScopedResource* contents_texture =
3927 render_pass_textures_[ca_layer_overlay->rpdq->render_pass_id].get();
3928 DCHECK(contents_texture);
3929
3930 // The intermediary texture may need to be larger than the original content,
3931 // since the BLUR and DROP_SHADOW filter effects affect pixels outside the
3932 // original content. The exact size is computed within Skia, along with the
3933 // creation of |filter_image|. That computation requires that the |dst_rect|
3934 // parameter be configured.
3935 DrawRenderPassDrawQuadParams params;
3936 params.quad = ca_layer_overlay->rpdq.get();
3937 params.flip_texture = true;
3938 params.contents_texture = contents_texture;
3939
3940 SkMatrix scale_matrix;
3941 scale_matrix.setScale(params.quad->filters_scale.x(),
3942 params.quad->filters_scale.y());
3943 gfx::Rect dst_rect =
3944 params.quad->filters.MapRect(params.quad->rect, scale_matrix);
3945 params.dst_rect.SetRect(static_cast<float>(dst_rect.x()),
3946 static_cast<float>(dst_rect.y()),
3947 static_cast<float>(dst_rect.width()),
3948 static_cast<float>(dst_rect.height()));
3949
3950 if (!UpdateRPDQWithSkiaFilters(&params)) {
3951 return;
3952 }
3953
3954 // |params.dst_rect| and |params.src_offset| now contain values that reflect a
3955 // potentially increased-size content area.
3956 gfx::RectF updated_dst_rect = params.dst_rect;
3957 gfx::Point updated_src_offset = params.src_offset;
3958
3959 // Establish temp texture and fbo.
3960 GLuint temp_texture;
3961 GLuint temp_fbo;
3962
3963 gl_->GenTextures(1, &temp_texture);
3964 ScopedTextureDeleter texture_deleter(temp_texture, gl_);
3965 gl_->BindTexture(GL_TEXTURE_2D, temp_texture);
3966 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3967 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3968 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3969 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3970 gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, updated_dst_rect.width(),
3971 updated_dst_rect.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
3972 nullptr);
3973
3974 gl_->GenFramebuffers(1, &temp_fbo);
3975 ScopedFramebufferDeleter framebuffer_deleter(temp_fbo, gl_);
3976 gl_->BindFramebuffer(GL_FRAMEBUFFER, temp_fbo);
3977 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
3978 temp_texture, 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 // Set up a new drawing context. The viewport should be the same size as
3987 // |temp_fbo|. Update the viewport using InitializeViewport(). This requires
3988 // creating a dummy DrawingFrame. This also calculates the projection and
3989 // window matrices.
3990 DrawingFrame frame;
3991 force_drawing_frame_framebuffer_flipped_ = &frame;
3992 gfx::Rect frame_rect =
3993 gfx::Rect(0, 0, updated_dst_rect.width(), updated_dst_rect.height());
3994 InitializeViewport(&frame, frame_rect, frame_rect, frame_rect.size());
3995 force_drawing_frame_framebuffer_flipped_ = nullptr;
3996 SetViewport();
3997 params.projection_matrix = frame.projection_matrix;
3998 params.window_matrix = frame.window_matrix;
3999
4000 // The SharedQuadState for the RenderPassDrawQuad needs to be updated to
4001 // reflect the new viewport.
4002 SharedQuadState sqs = *(ca_layer_overlay->rpdq->shared_quad_state);
4003 ca_layer_overlay->rpdq->shared_quad_state = &sqs;
4004 sqs.quad_to_target_transform = gfx::Transform();
4005 sqs.quad_to_target_transform.Translate(-updated_dst_rect.x(),
4006 -updated_dst_rect.y());
4007
4008 // Perform basic initialization in the new viewport.
4009 if (!InitializeRPDQParameters(&params))
4010 return;
4011
4012 // Update |dst_rect| and |src_offset| with the values originally calculated
4013 // from Skia.
4014 params.dst_rect = updated_dst_rect;
4015 params.src_offset = updated_src_offset;
4016
4017 UpdateRPDQTexturesForSampling(&params);
4018 UpdateRPDQBlendMode(&params);
4019 ChooseRPDQProgram(&params);
4020 UpdateRPDQUniforms(&params);
4021
4022 // Prior to drawing, set up the destination framebuffer.
4023 gl_->BindFramebuffer(GL_FRAMEBUFFER, temp_fbo);
4024 DrawRPDQ(params);
ccameron 2016/08/04 01:46:01 I'll need to understand this a bit better, but, my
erikchen 2016/08/05 17:15:06 Your suggestion is sound. The new PS implements yo
4025
4026 // Copy from the temporary framebuffer into an overlay.
4027 *resource = overlay_resource_pool_->AcquireResource(
4028 gfx::Size(updated_dst_rect.width(), updated_dst_rect.height()),
4029 ResourceFormat::RGBA_8888);
4030 ResourceProvider::ScopedWriteLockGL destination(resource_provider_,
4031 (*resource)->id(), false);
4032 gl_->CopySubTextureCHROMIUM(temp_texture, destination.texture_id(), 0, 0, 0,
4033 0, updated_dst_rect.width(),
4034 updated_dst_rect.height(), GL_TRUE, GL_FALSE,
4035 GL_FALSE);
4036
4037 // Update the CALayerOverlaySharedState to reflect the new size and translate
4038 // of the overlay.
4039 ca_layer_overlay->bounds_rect =
4040 gfx::RectF(0, 0, updated_dst_rect.width(), updated_dst_rect.height());
4041 scoped_refptr<CALayerOverlaySharedState> shared_state =
4042 (new CALayerOverlaySharedState);
4043 *shared_state = *ca_layer_overlay->shared_state;
4044 ca_layer_overlay->shared_state = shared_state;
ccameron 2016/08/04 01:46:01 This doesn't strike me as correct. What if shared_
erikchen 2016/08/05 17:15:06 Right. This should have been preTranslate.
4045 float x_translate = shared_state->transform.getFloat(0, 3);
4046 float y_translate = shared_state->transform.getFloat(1, 3);
4047 float z_translate = shared_state->transform.getFloat(2, 3);
4048 shared_state->transform.setTranslate(x_translate + updated_dst_rect.x(),
4049 y_translate + updated_dst_rect.y(),
4050 z_translate);
4051 }
4052
3889 } // namespace cc 4053 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698