| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 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 "cc/layers/delegated_renderer_layer_impl.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <utility> | |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/containers/hash_tables.h" | |
| 12 #include "cc/base/math_util.h" | |
| 13 #include "cc/layers/append_quads_data.h" | |
| 14 #include "cc/layers/render_pass_sink.h" | |
| 15 #include "cc/output/delegated_frame_data.h" | |
| 16 #include "cc/quads/render_pass_draw_quad.h" | |
| 17 #include "cc/quads/solid_color_draw_quad.h" | |
| 18 #include "cc/trees/layer_tree_impl.h" | |
| 19 #include "cc/trees/occlusion.h" | |
| 20 #include "ui/gfx/geometry/rect_conversions.h" | |
| 21 | |
| 22 namespace cc { | |
| 23 | |
| 24 DelegatedRendererLayerImpl::DelegatedRendererLayerImpl(LayerTreeImpl* tree_impl, | |
| 25 int id) | |
| 26 : LayerImpl(tree_impl, id), | |
| 27 have_render_passes_to_push_(false), | |
| 28 inverse_device_scale_factor_(1.0f), | |
| 29 child_id_(0), | |
| 30 own_child_id_(false) { | |
| 31 } | |
| 32 | |
| 33 DelegatedRendererLayerImpl::~DelegatedRendererLayerImpl() { | |
| 34 ClearRenderPasses(); | |
| 35 ClearChildId(); | |
| 36 } | |
| 37 | |
| 38 bool DelegatedRendererLayerImpl::HasDelegatedContent() const { return true; } | |
| 39 | |
| 40 bool DelegatedRendererLayerImpl::HasContributingDelegatedRenderPasses() const { | |
| 41 // The root RenderPass for the layer is merged with its target | |
| 42 // RenderPass in each frame. So we only have extra RenderPasses | |
| 43 // to merge when we have a non-root RenderPass present. | |
| 44 return render_passes_in_draw_order_.size() > 1; | |
| 45 } | |
| 46 | |
| 47 static ResourceProvider::ResourceId ResourceRemapHelper( | |
| 48 bool* invalid_frame, | |
| 49 const ResourceProvider::ResourceIdMap& child_to_parent_map, | |
| 50 ResourceProvider::ResourceIdArray* resources_in_frame, | |
| 51 ResourceProvider::ResourceId id) { | |
| 52 | |
| 53 ResourceProvider::ResourceIdMap::const_iterator it = | |
| 54 child_to_parent_map.find(id); | |
| 55 if (it == child_to_parent_map.end()) { | |
| 56 *invalid_frame = true; | |
| 57 return 0; | |
| 58 } | |
| 59 | |
| 60 DCHECK_EQ(it->first, id); | |
| 61 ResourceProvider::ResourceId remapped_id = it->second; | |
| 62 resources_in_frame->push_back(id); | |
| 63 return remapped_id; | |
| 64 } | |
| 65 | |
| 66 void DelegatedRendererLayerImpl::PushPropertiesTo(LayerImpl* layer) { | |
| 67 LayerImpl::PushPropertiesTo(layer); | |
| 68 | |
| 69 DelegatedRendererLayerImpl* delegated_layer = | |
| 70 static_cast<DelegatedRendererLayerImpl*>(layer); | |
| 71 | |
| 72 // If we have a new child_id to give to the active layer, it should | |
| 73 // have already deleted its old child_id. | |
| 74 DCHECK(delegated_layer->child_id_ == 0 || | |
| 75 delegated_layer->child_id_ == child_id_); | |
| 76 delegated_layer->inverse_device_scale_factor_ = inverse_device_scale_factor_; | |
| 77 delegated_layer->child_id_ = child_id_; | |
| 78 delegated_layer->own_child_id_ = true; | |
| 79 own_child_id_ = false; | |
| 80 | |
| 81 if (have_render_passes_to_push_) { | |
| 82 // This passes ownership of the render passes to the active tree. | |
| 83 delegated_layer->SetRenderPasses(&render_passes_in_draw_order_); | |
| 84 DCHECK(render_passes_in_draw_order_.empty()); | |
| 85 have_render_passes_to_push_ = false; | |
| 86 } | |
| 87 | |
| 88 // This is just a copy for testing, since resources are added to the | |
| 89 // ResourceProvider in the pending tree. | |
| 90 delegated_layer->resources_ = resources_; | |
| 91 } | |
| 92 | |
| 93 void DelegatedRendererLayerImpl::CreateChildIdIfNeeded( | |
| 94 const ReturnCallback& return_callback) { | |
| 95 if (child_id_) | |
| 96 return; | |
| 97 | |
| 98 ResourceProvider* resource_provider = layer_tree_impl()->resource_provider(); | |
| 99 child_id_ = resource_provider->CreateChild(return_callback); | |
| 100 own_child_id_ = true; | |
| 101 } | |
| 102 | |
| 103 void DelegatedRendererLayerImpl::SetFrameData( | |
| 104 const DelegatedFrameData* frame_data, | |
| 105 const gfx::RectF& damage_in_frame) { | |
| 106 DCHECK(child_id_) << "CreateChildIdIfNeeded must be called first."; | |
| 107 DCHECK(frame_data); | |
| 108 DCHECK(!frame_data->render_pass_list.empty()); | |
| 109 // A frame with an empty root render pass is invalid. | |
| 110 DCHECK(!frame_data->render_pass_list.back()->output_rect.IsEmpty()); | |
| 111 | |
| 112 ResourceProvider* resource_provider = layer_tree_impl()->resource_provider(); | |
| 113 const ResourceProvider::ResourceIdMap& resource_map = | |
| 114 resource_provider->GetChildToParentMap(child_id_); | |
| 115 | |
| 116 resource_provider->ReceiveFromChild(child_id_, frame_data->resource_list); | |
| 117 | |
| 118 RenderPassList render_pass_list; | |
| 119 RenderPass::CopyAll(frame_data->render_pass_list, &render_pass_list); | |
| 120 | |
| 121 bool invalid_frame = false; | |
| 122 ResourceProvider::ResourceIdArray resources_in_frame; | |
| 123 DrawQuad::ResourceIteratorCallback remap_resources_to_parent_callback = | |
| 124 base::Bind(&ResourceRemapHelper, | |
| 125 &invalid_frame, | |
| 126 resource_map, | |
| 127 &resources_in_frame); | |
| 128 for (const auto& pass : render_pass_list) { | |
| 129 for (const auto& quad : pass->quad_list) | |
| 130 quad->IterateResources(remap_resources_to_parent_callback); | |
| 131 } | |
| 132 | |
| 133 if (invalid_frame) { | |
| 134 // Declare we are still using the last frame's resources. | |
| 135 resource_provider->DeclareUsedResourcesFromChild(child_id_, resources_); | |
| 136 return; | |
| 137 } | |
| 138 | |
| 139 // Declare we are using the new frame's resources. | |
| 140 resources_.swap(resources_in_frame); | |
| 141 resource_provider->DeclareUsedResourcesFromChild(child_id_, resources_); | |
| 142 | |
| 143 inverse_device_scale_factor_ = 1.0f / frame_data->device_scale_factor; | |
| 144 // Display size is already set so we can compute what the damage rect | |
| 145 // will be in layer space. The damage may exceed the visible portion of | |
| 146 // the frame, so intersect the damage to the layer's bounds. | |
| 147 RenderPass* new_root_pass = render_pass_list.back(); | |
| 148 gfx::Size frame_size = new_root_pass->output_rect.size(); | |
| 149 gfx::RectF damage_in_layer = damage_in_frame; | |
| 150 damage_in_layer.Scale(inverse_device_scale_factor_); | |
| 151 SetUpdateRect(gfx::IntersectRects( | |
| 152 gfx::UnionRects(update_rect(), gfx::ToEnclosingRect(damage_in_layer)), | |
| 153 gfx::Rect(bounds()))); | |
| 154 | |
| 155 SetRenderPasses(&render_pass_list); | |
| 156 have_render_passes_to_push_ = true; | |
| 157 } | |
| 158 | |
| 159 void DelegatedRendererLayerImpl::SetRenderPasses( | |
| 160 RenderPassList* render_passes_in_draw_order) { | |
| 161 ClearRenderPasses(); | |
| 162 | |
| 163 for (size_t i = 0; i < render_passes_in_draw_order->size(); ++i) { | |
| 164 RenderPassList::iterator to_take = | |
| 165 render_passes_in_draw_order->begin() + i; | |
| 166 render_passes_index_by_id_.insert( | |
| 167 std::pair<RenderPassId, int>((*to_take)->id, i)); | |
| 168 scoped_ptr<RenderPass> taken_render_pass = | |
| 169 render_passes_in_draw_order->take(to_take); | |
| 170 render_passes_in_draw_order_.push_back(taken_render_pass.Pass()); | |
| 171 } | |
| 172 | |
| 173 // Give back an empty array instead of nulls. | |
| 174 render_passes_in_draw_order->clear(); | |
| 175 | |
| 176 // The render passes given here become part of the RenderSurfaceLayerList, so | |
| 177 // changing them requires recomputing the RenderSurfaceLayerList. | |
| 178 layer_tree_impl()->set_needs_update_draw_properties(); | |
| 179 } | |
| 180 | |
| 181 void DelegatedRendererLayerImpl::ClearRenderPasses() { | |
| 182 render_passes_index_by_id_.clear(); | |
| 183 render_passes_in_draw_order_.clear(); | |
| 184 } | |
| 185 | |
| 186 scoped_ptr<LayerImpl> DelegatedRendererLayerImpl::CreateLayerImpl( | |
| 187 LayerTreeImpl* tree_impl) { | |
| 188 return DelegatedRendererLayerImpl::Create(tree_impl, id()); | |
| 189 } | |
| 190 | |
| 191 void DelegatedRendererLayerImpl::ReleaseResources() { | |
| 192 ClearRenderPasses(); | |
| 193 ClearChildId(); | |
| 194 } | |
| 195 | |
| 196 static inline int IndexToId(int index) { return index + 1; } | |
| 197 static inline int IdToIndex(int id) { return id - 1; } | |
| 198 | |
| 199 RenderPassId DelegatedRendererLayerImpl::FirstContributingRenderPassId() const { | |
| 200 return RenderPassId(id(), IndexToId(0)); | |
| 201 } | |
| 202 | |
| 203 RenderPassId DelegatedRendererLayerImpl::NextContributingRenderPassId( | |
| 204 RenderPassId previous) const { | |
| 205 return RenderPassId(previous.layer_id, previous.index + 1); | |
| 206 } | |
| 207 | |
| 208 bool DelegatedRendererLayerImpl::ConvertDelegatedRenderPassId( | |
| 209 RenderPassId delegated_render_pass_id, | |
| 210 RenderPassId* output_render_pass_id) const { | |
| 211 base::hash_map<RenderPassId, int>::const_iterator found = | |
| 212 render_passes_index_by_id_.find(delegated_render_pass_id); | |
| 213 if (found == render_passes_index_by_id_.end()) { | |
| 214 // Be robust against a RenderPass id that isn't part of the frame. | |
| 215 return false; | |
| 216 } | |
| 217 unsigned delegated_render_pass_index = found->second; | |
| 218 *output_render_pass_id = | |
| 219 RenderPassId(id(), IndexToId(delegated_render_pass_index)); | |
| 220 return true; | |
| 221 } | |
| 222 | |
| 223 void DelegatedRendererLayerImpl::AppendContributingRenderPasses( | |
| 224 RenderPassSink* render_pass_sink) { | |
| 225 DCHECK(HasContributingDelegatedRenderPasses()); | |
| 226 | |
| 227 const RenderPass* root_delegated_render_pass = | |
| 228 render_passes_in_draw_order_.back(); | |
| 229 gfx::Size frame_size = root_delegated_render_pass->output_rect.size(); | |
| 230 gfx::Transform delegated_frame_to_root_transform = screen_space_transform(); | |
| 231 delegated_frame_to_root_transform.Scale(inverse_device_scale_factor_, | |
| 232 inverse_device_scale_factor_); | |
| 233 | |
| 234 for (size_t i = 0; i < render_passes_in_draw_order_.size() - 1; ++i) { | |
| 235 RenderPassId output_render_pass_id(-1, -1); | |
| 236 bool present = | |
| 237 ConvertDelegatedRenderPassId(render_passes_in_draw_order_[i]->id, | |
| 238 &output_render_pass_id); | |
| 239 | |
| 240 // Don't clash with the RenderPass we generate if we own a RenderSurface. | |
| 241 DCHECK(present) << render_passes_in_draw_order_[i]->id.layer_id << ", " | |
| 242 << render_passes_in_draw_order_[i]->id.index; | |
| 243 DCHECK_GT(output_render_pass_id.index, 0); | |
| 244 | |
| 245 scoped_ptr<RenderPass> copy_pass = | |
| 246 render_passes_in_draw_order_[i]->Copy(output_render_pass_id); | |
| 247 copy_pass->transform_to_root_target.ConcatTransform( | |
| 248 delegated_frame_to_root_transform); | |
| 249 render_pass_sink->AppendRenderPass(copy_pass.Pass()); | |
| 250 } | |
| 251 } | |
| 252 | |
| 253 bool DelegatedRendererLayerImpl::WillDraw(DrawMode draw_mode, | |
| 254 ResourceProvider* resource_provider) { | |
| 255 if (draw_mode == DRAW_MODE_RESOURCELESS_SOFTWARE) | |
| 256 return false; | |
| 257 return LayerImpl::WillDraw(draw_mode, resource_provider); | |
| 258 } | |
| 259 | |
| 260 void DelegatedRendererLayerImpl::AppendQuads( | |
| 261 RenderPass* render_pass, | |
| 262 AppendQuadsData* append_quads_data) { | |
| 263 AppendRainbowDebugBorder(render_pass); | |
| 264 | |
| 265 // This list will be empty after a lost context until a new frame arrives. | |
| 266 if (render_passes_in_draw_order_.empty()) | |
| 267 return; | |
| 268 | |
| 269 RenderPassId target_render_pass_id = render_pass->id; | |
| 270 | |
| 271 const RenderPass* root_delegated_render_pass = | |
| 272 render_passes_in_draw_order_.back(); | |
| 273 | |
| 274 DCHECK(root_delegated_render_pass->output_rect.origin().IsOrigin()); | |
| 275 gfx::Size frame_size = root_delegated_render_pass->output_rect.size(); | |
| 276 | |
| 277 // If the index of the RenderPassId is 0, then it is a RenderPass generated | |
| 278 // for a layer in this compositor, not the delegating renderer. Then we want | |
| 279 // to merge our root RenderPass with the target RenderPass. Otherwise, it is | |
| 280 // some RenderPass which we added from the delegating renderer. | |
| 281 bool should_merge_root_render_pass_with_target = !target_render_pass_id.index; | |
| 282 if (should_merge_root_render_pass_with_target) { | |
| 283 // Verify that the RenderPass we are appending to is created by our | |
| 284 // render_target. | |
| 285 DCHECK(target_render_pass_id.layer_id == render_target()->id()); | |
| 286 | |
| 287 AppendRenderPassQuads(render_pass, | |
| 288 root_delegated_render_pass, | |
| 289 frame_size); | |
| 290 } else { | |
| 291 // Verify that the RenderPass we are appending to was created by us. | |
| 292 DCHECK(target_render_pass_id.layer_id == id()); | |
| 293 | |
| 294 int render_pass_index = IdToIndex(target_render_pass_id.index); | |
| 295 const RenderPass* delegated_render_pass = | |
| 296 render_passes_in_draw_order_[render_pass_index]; | |
| 297 AppendRenderPassQuads(render_pass, | |
| 298 delegated_render_pass, | |
| 299 frame_size); | |
| 300 } | |
| 301 } | |
| 302 | |
| 303 void DelegatedRendererLayerImpl::AppendRainbowDebugBorder( | |
| 304 RenderPass* render_pass) { | |
| 305 if (!ShowDebugBorders()) | |
| 306 return; | |
| 307 | |
| 308 SharedQuadState* shared_quad_state = | |
| 309 render_pass->CreateAndAppendSharedQuadState(); | |
| 310 PopulateSharedQuadState(shared_quad_state); | |
| 311 | |
| 312 SkColor color; | |
| 313 float border_width; | |
| 314 GetDebugBorderProperties(&color, &border_width); | |
| 315 | |
| 316 SkColor colors[] = { | |
| 317 0x80ff0000, // Red. | |
| 318 0x80ffa500, // Orange. | |
| 319 0x80ffff00, // Yellow. | |
| 320 0x80008000, // Green. | |
| 321 0x800000ff, // Blue. | |
| 322 0x80ee82ee, // Violet. | |
| 323 }; | |
| 324 const int kNumColors = arraysize(colors); | |
| 325 | |
| 326 const int kStripeWidth = 300; | |
| 327 const int kStripeHeight = 300; | |
| 328 | |
| 329 for (size_t i = 0; ; ++i) { | |
| 330 // For horizontal lines. | |
| 331 int x = kStripeWidth * i; | |
| 332 int width = std::min(kStripeWidth, content_bounds().width() - x - 1); | |
| 333 | |
| 334 // For vertical lines. | |
| 335 int y = kStripeHeight * i; | |
| 336 int height = std::min(kStripeHeight, content_bounds().height() - y - 1); | |
| 337 | |
| 338 gfx::Rect top(x, 0, width, border_width); | |
| 339 gfx::Rect bottom(x, | |
| 340 content_bounds().height() - border_width, | |
| 341 width, | |
| 342 border_width); | |
| 343 gfx::Rect left(0, y, border_width, height); | |
| 344 gfx::Rect right(content_bounds().width() - border_width, | |
| 345 y, | |
| 346 border_width, | |
| 347 height); | |
| 348 | |
| 349 if (top.IsEmpty() && left.IsEmpty()) | |
| 350 break; | |
| 351 | |
| 352 if (!top.IsEmpty()) { | |
| 353 bool force_anti_aliasing_off = false; | |
| 354 SolidColorDrawQuad* top_quad = | |
| 355 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
| 356 top_quad->SetNew(shared_quad_state, top, top, colors[i % kNumColors], | |
| 357 force_anti_aliasing_off); | |
| 358 | |
| 359 SolidColorDrawQuad* bottom_quad = | |
| 360 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
| 361 bottom_quad->SetNew(shared_quad_state, bottom, bottom, | |
| 362 colors[kNumColors - 1 - (i % kNumColors)], | |
| 363 force_anti_aliasing_off); | |
| 364 | |
| 365 if (contents_opaque()) { | |
| 366 // Draws a stripe filling the layer vertically with the same color and | |
| 367 // width as the horizontal stipes along the layer's top border. | |
| 368 SolidColorDrawQuad* solid_quad = | |
| 369 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
| 370 // The inner fill is more transparent then the border. | |
| 371 static const float kFillOpacity = 0.1f; | |
| 372 SkColor fill_color = SkColorSetA( | |
| 373 colors[i % kNumColors], | |
| 374 static_cast<uint8_t>(SkColorGetA(colors[i % kNumColors]) * | |
| 375 kFillOpacity)); | |
| 376 gfx::Rect fill_rect(x, 0, width, content_bounds().height()); | |
| 377 solid_quad->SetNew(shared_quad_state, fill_rect, fill_rect, fill_color, | |
| 378 force_anti_aliasing_off); | |
| 379 } | |
| 380 } | |
| 381 if (!left.IsEmpty()) { | |
| 382 bool force_anti_aliasing_off = false; | |
| 383 SolidColorDrawQuad* left_quad = | |
| 384 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
| 385 left_quad->SetNew(shared_quad_state, left, left, | |
| 386 colors[kNumColors - 1 - (i % kNumColors)], | |
| 387 force_anti_aliasing_off); | |
| 388 | |
| 389 SolidColorDrawQuad* right_quad = | |
| 390 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
| 391 right_quad->SetNew(shared_quad_state, right, right, | |
| 392 colors[i % kNumColors], force_anti_aliasing_off); | |
| 393 } | |
| 394 } | |
| 395 } | |
| 396 | |
| 397 void DelegatedRendererLayerImpl::AppendRenderPassQuads( | |
| 398 RenderPass* render_pass, | |
| 399 const RenderPass* delegated_render_pass, | |
| 400 const gfx::Size& frame_size) const { | |
| 401 const SharedQuadState* delegated_shared_quad_state = nullptr; | |
| 402 SharedQuadState* output_shared_quad_state = nullptr; | |
| 403 | |
| 404 for (const auto& delegated_quad : delegated_render_pass->quad_list) { | |
| 405 bool is_root_delegated_render_pass = | |
| 406 delegated_render_pass == render_passes_in_draw_order_.back(); | |
| 407 | |
| 408 if (delegated_quad->shared_quad_state != delegated_shared_quad_state) { | |
| 409 delegated_shared_quad_state = delegated_quad->shared_quad_state; | |
| 410 output_shared_quad_state = render_pass->CreateAndAppendSharedQuadState(); | |
| 411 output_shared_quad_state->CopyFrom(delegated_shared_quad_state); | |
| 412 | |
| 413 if (is_root_delegated_render_pass) { | |
| 414 gfx::Transform delegated_frame_to_target_transform = draw_transform(); | |
| 415 delegated_frame_to_target_transform.Scale(inverse_device_scale_factor_, | |
| 416 inverse_device_scale_factor_); | |
| 417 | |
| 418 output_shared_quad_state->content_to_target_transform.ConcatTransform( | |
| 419 delegated_frame_to_target_transform); | |
| 420 | |
| 421 if (render_target() == this) { | |
| 422 DCHECK(!is_clipped()); | |
| 423 DCHECK(render_surface()); | |
| 424 DCHECK_EQ(0, num_unclipped_descendants()); | |
| 425 output_shared_quad_state->clip_rect = | |
| 426 MathUtil::MapEnclosingClippedRect( | |
| 427 delegated_frame_to_target_transform, | |
| 428 output_shared_quad_state->clip_rect); | |
| 429 } else { | |
| 430 gfx::Rect clip_rect = drawable_content_rect(); | |
| 431 if (output_shared_quad_state->is_clipped) { | |
| 432 clip_rect.Intersect(MathUtil::MapEnclosingClippedRect( | |
| 433 delegated_frame_to_target_transform, | |
| 434 output_shared_quad_state->clip_rect)); | |
| 435 } | |
| 436 output_shared_quad_state->clip_rect = clip_rect; | |
| 437 output_shared_quad_state->is_clipped = true; | |
| 438 } | |
| 439 | |
| 440 output_shared_quad_state->opacity *= draw_opacity(); | |
| 441 } | |
| 442 } | |
| 443 DCHECK(output_shared_quad_state); | |
| 444 | |
| 445 gfx::Transform quad_content_to_delegated_target_space = | |
| 446 output_shared_quad_state->content_to_target_transform; | |
| 447 if (!is_root_delegated_render_pass) { | |
| 448 quad_content_to_delegated_target_space.ConcatTransform( | |
| 449 delegated_render_pass->transform_to_root_target); | |
| 450 quad_content_to_delegated_target_space.ConcatTransform(draw_transform()); | |
| 451 } | |
| 452 | |
| 453 Occlusion occlusion_in_quad_space = | |
| 454 draw_properties() | |
| 455 .occlusion_in_content_space.GetOcclusionWithGivenDrawTransform( | |
| 456 quad_content_to_delegated_target_space); | |
| 457 | |
| 458 gfx::Rect quad_visible_rect = | |
| 459 occlusion_in_quad_space.GetUnoccludedContentRect( | |
| 460 delegated_quad->visible_rect); | |
| 461 | |
| 462 if (quad_visible_rect.IsEmpty()) | |
| 463 continue; | |
| 464 | |
| 465 if (delegated_quad->material != DrawQuad::RENDER_PASS) { | |
| 466 DrawQuad* output_quad = render_pass->CopyFromAndAppendDrawQuad( | |
| 467 delegated_quad, output_shared_quad_state); | |
| 468 output_quad->visible_rect = quad_visible_rect; | |
| 469 } else { | |
| 470 RenderPassId delegated_contributing_render_pass_id = | |
| 471 RenderPassDrawQuad::MaterialCast(delegated_quad)->render_pass_id; | |
| 472 RenderPassId output_contributing_render_pass_id(-1, -1); | |
| 473 | |
| 474 bool present = | |
| 475 ConvertDelegatedRenderPassId(delegated_contributing_render_pass_id, | |
| 476 &output_contributing_render_pass_id); | |
| 477 | |
| 478 // The frame may have a RenderPassDrawQuad that points to a RenderPass not | |
| 479 // part of the frame. Just ignore these quads. | |
| 480 if (present) { | |
| 481 DCHECK(output_contributing_render_pass_id != render_pass->id); | |
| 482 | |
| 483 RenderPassDrawQuad* output_quad = | |
| 484 render_pass->CopyFromAndAppendRenderPassDrawQuad( | |
| 485 RenderPassDrawQuad::MaterialCast(delegated_quad), | |
| 486 output_shared_quad_state, | |
| 487 output_contributing_render_pass_id); | |
| 488 output_quad->visible_rect = quad_visible_rect; | |
| 489 } | |
| 490 } | |
| 491 } | |
| 492 } | |
| 493 | |
| 494 const char* DelegatedRendererLayerImpl::LayerTypeAsString() const { | |
| 495 return "cc::DelegatedRendererLayerImpl"; | |
| 496 } | |
| 497 | |
| 498 void DelegatedRendererLayerImpl::ClearChildId() { | |
| 499 if (!child_id_) | |
| 500 return; | |
| 501 | |
| 502 if (own_child_id_) { | |
| 503 ResourceProvider* provider = layer_tree_impl()->resource_provider(); | |
| 504 provider->DestroyChild(child_id_); | |
| 505 } | |
| 506 | |
| 507 resources_.clear(); | |
| 508 child_id_ = 0; | |
| 509 } | |
| 510 | |
| 511 } // namespace cc | |
| OLD | NEW |