OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ui/android/delegated_frame_host_android.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "cc/layers/solid_color_layer.h" | |
9 #include "cc/layers/surface_layer.h" | |
10 #include "cc/output/compositor_frame.h" | |
11 #include "cc/output/copy_output_request.h" | |
12 #include "cc/surfaces/surface.h" | |
13 #include "cc/surfaces/surface_id.h" | |
14 #include "cc/surfaces/surface_id_allocator.h" | |
15 #include "cc/surfaces/surface_manager.h" | |
16 #include "ui/android/context_provider_factory.h" | |
17 #include "ui/android/view_android.h" | |
18 | |
19 namespace ui { | |
20 | |
21 namespace { | |
22 | |
23 void SatisfyCallback(cc::SurfaceManager* manager, | |
24 const cc::SurfaceSequence& sequence) { | |
25 std::vector<uint32_t> sequences; | |
26 sequences.push_back(sequence.sequence); | |
27 manager->DidSatisfySequences(sequence.client_id, &sequences); | |
28 } | |
29 | |
30 void RequireCallback(cc::SurfaceManager* manager, | |
31 const cc::SurfaceId& id, | |
32 const cc::SurfaceSequence& sequence) { | |
33 cc::Surface* surface = manager->GetSurfaceForId(id); | |
34 if (!surface) { | |
35 LOG(ERROR) << "Attempting to require callback on nonexistent surface"; | |
36 return; | |
37 } | |
38 surface->AddDestructionDependency(sequence); | |
39 } | |
40 | |
41 } // namespace | |
42 | |
43 DelegatedFrameHostAndroid::DelegatedFrameHostAndroid( | |
44 ui::ViewAndroid* view, | |
45 SkColor background_color, | |
46 ReturnResourcesCallback return_resources_callback) | |
47 : view_(view), | |
48 return_resources_callback_(return_resources_callback), | |
49 background_layer_(cc::SolidColorLayer::Create()) { | |
50 DCHECK(view_); | |
51 DCHECK(!return_resources_callback_.is_null()); | |
52 | |
53 surface_manager_ = | |
54 ui::ContextProviderFactory::GetInstance()->GetSurfaceManager(); | |
55 surface_id_allocator_.reset(new cc::SurfaceIdAllocator( | |
56 ui::ContextProviderFactory::GetInstance()->AllocateSurfaceClientId())); | |
57 surface_manager_->RegisterSurfaceClientId(surface_id_allocator_->client_id()); | |
58 | |
59 background_layer_->SetBackgroundColor(background_color); | |
60 view_->GetLayer()->AddChild(background_layer_); | |
61 UpdateBackgroundLayer(); | |
62 } | |
63 | |
64 DelegatedFrameHostAndroid::~DelegatedFrameHostAndroid() { | |
65 DestroyDelegatedContent(); | |
66 surface_factory_.reset(); | |
67 surface_manager_->InvalidateSurfaceClientId( | |
68 surface_id_allocator_->client_id()); | |
69 background_layer_->RemoveFromParent(); | |
70 } | |
71 | |
72 void DelegatedFrameHostAndroid::SubmitCompositorFrame( | |
73 cc::CompositorFrame frame, | |
74 cc::SurfaceFactory::DrawCallback draw_callback) { | |
75 if (!surface_factory_) { | |
76 surface_factory_ = | |
77 base::WrapUnique(new cc::SurfaceFactory(surface_manager_, this)); | |
78 } | |
79 | |
80 cc::RenderPass* root_pass = | |
81 frame.delegated_frame_data->render_pass_list.back().get(); | |
82 gfx::Size texture_size_in_layer = root_pass->output_rect.size(); | |
no sievers
2016/08/12 19:33:04
nit: This name is a bit of an artifact. You can pr
Khushal
2016/08/16 01:34:23
Done.
| |
83 | |
84 if (surface_id_.is_null() || texture_size_in_layer != current_surface_size_ || | |
85 location_bar_content_translation_ != | |
86 frame.metadata.location_bar_content_translation || | |
87 current_viewport_selection_ != frame.metadata.selection) { | |
88 DestroyDelegatedContent(); | |
89 DCHECK(!content_layer_); | |
90 DCHECK(surface_id_.is_null()); | |
91 | |
92 surface_id_ = surface_id_allocator_->GenerateId(); | |
93 surface_factory_->Create(surface_id_); | |
94 | |
95 current_surface_size_ = texture_size_in_layer; | |
96 location_bar_content_translation_ = | |
97 frame.metadata.location_bar_content_translation; | |
98 current_viewport_selection_ = frame.metadata.selection; | |
99 CreateContentLayer(); | |
100 } | |
101 | |
102 surface_factory_->SubmitCompositorFrame(surface_id_, std::move(frame), | |
103 draw_callback); | |
104 } | |
105 | |
106 uint32_t DelegatedFrameHostAndroid::GetSurfaceClientId() const { | |
107 return surface_id_allocator_->client_id(); | |
108 } | |
109 | |
110 void DelegatedFrameHostAndroid::RequestCopyOfSurface( | |
111 std::unique_ptr<cc::CopyOutputRequest> copy_output_request) { | |
112 DCHECK(!surface_id_.is_null()); | |
113 surface_factory_->RequestCopyOfSurface(surface_id_, | |
114 std::move(copy_output_request)); | |
115 } | |
116 | |
117 void DelegatedFrameHostAndroid::DestroyDelegatedContent() { | |
118 if (surface_id_.is_null()) | |
119 return; | |
120 | |
121 DCHECK(surface_factory_.get()); | |
122 DCHECK(content_layer_); | |
123 | |
124 content_layer_->RemoveFromParent(); | |
125 content_layer_ = nullptr; | |
126 surface_factory_->Destroy(surface_id_); | |
127 surface_id_ = cc::SurfaceId(); | |
128 | |
129 UpdateBackgroundLayer(); | |
130 } | |
131 | |
132 void DelegatedFrameHostAndroid::OutputSurfaceChanged() { | |
133 DestroyDelegatedContent(); | |
134 surface_factory_.reset(); | |
135 } | |
136 | |
137 void DelegatedFrameHostAndroid::UpdateBackgroundColor(SkColor color) { | |
138 background_layer_->SetBackgroundColor(color); | |
139 } | |
140 | |
141 void DelegatedFrameHostAndroid::UpdateSize( | |
142 const gfx::Size& desired_content_size) { | |
143 desired_content_size_ = desired_content_size; | |
144 background_layer_->SetBounds(desired_content_size); | |
145 UpdateBackgroundLayer(); | |
146 } | |
147 | |
148 cc::Layer* DelegatedFrameHostAndroid::GetContentLayer() const { | |
149 return content_layer_.get(); | |
150 } | |
151 | |
152 void DelegatedFrameHostAndroid::ReturnResources( | |
153 const cc::ReturnedResourceArray& resources) { | |
154 return_resources_callback_.Run(resources); | |
155 } | |
156 | |
157 void DelegatedFrameHostAndroid::SetBeginFrameSource( | |
158 cc::BeginFrameSource* begin_frame_source) { | |
159 // TODO(tansell): Hook this up. | |
160 } | |
161 | |
162 void DelegatedFrameHostAndroid::CreateContentLayer() { | |
163 DCHECK(!content_layer_); | |
164 | |
165 // manager must outlive compositors using it. | |
166 content_layer_ = cc::SurfaceLayer::Create( | |
167 base::Bind(&SatisfyCallback, base::Unretained(surface_manager_)), | |
168 base::Bind(&RequireCallback, base::Unretained(surface_manager_))); | |
169 content_layer_->SetSurfaceId(surface_id_, 1.f, current_surface_size_); | |
170 content_layer_->SetBounds(current_surface_size_); | |
171 content_layer_->SetIsDrawable(true); | |
172 content_layer_->SetContentsOpaque(true); | |
173 | |
174 view_->GetLayer()->AddChild(content_layer_); | |
175 | |
176 UpdateBackgroundLayer(); | |
177 } | |
178 | |
179 void DelegatedFrameHostAndroid::UpdateBackgroundLayer() { | |
180 // The background layer draws in 2 cases: | |
181 // 1) When we don't have any content from the renderer. | |
182 // 2) When the bounds of the content received from the renderer does not match | |
183 // the desired content bounds. | |
184 bool background_is_drawable = | |
185 content_layer_.get() == nullptr || | |
186 content_layer_->bounds() != desired_content_size_; | |
no sievers
2016/08/12 19:33:04
See other comment about dip vs. pix.
Also, this w
Khushal
2016/08/16 01:34:23
Thanks for pointing that out.
| |
187 background_layer_->SetIsDrawable(background_is_drawable); | |
188 } | |
189 | |
190 } // namespace ui | |
OLD | NEW |