delegated_renderer_layer.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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.h" 6 7#include "cc/layers/delegated_renderer_layer_impl.h" 8#include "cc/output/delegated_frame_data.h" 9#include "cc/quads/render_pass_draw_quad.h" 10#include "cc/trees/blocking_task_runner.h" 11#include "cc/trees/layer_tree_host.h" 12 13namespace cc { 14 15scoped_refptr<DelegatedRendererLayer> DelegatedRendererLayer::Create( 16 const scoped_refptr<DelegatedFrameProvider>& frame_provider) { 17 return scoped_refptr<DelegatedRendererLayer>( 18 new DelegatedRendererLayer(frame_provider)); 19} 20 21DelegatedRendererLayer::DelegatedRendererLayer( 22 const scoped_refptr<DelegatedFrameProvider>& frame_provider) 23 : Layer(), 24 frame_provider_(frame_provider), 25 should_collect_new_frame_(true), 26 frame_data_(NULL), 27 main_thread_runner_(BlockingTaskRunner::current()), 28 weak_ptrs_(this) { 29 frame_provider_->AddObserver(this); 30} 31 32DelegatedRendererLayer::~DelegatedRendererLayer() { 33 frame_provider_->RemoveObserver(this); 34} 35 36scoped_ptr<LayerImpl> DelegatedRendererLayer::CreateLayerImpl( 37 LayerTreeImpl* tree_impl) { 38 return DelegatedRendererLayerImpl::Create( 39 tree_impl, layer_id_).PassAs<LayerImpl>(); 40} 41 42void DelegatedRendererLayer::SetLayerTreeHost(LayerTreeHost* host) { 43 if (layer_tree_host() == host) { 44 Layer::SetLayerTreeHost(host); 45 return; 46 } 47 48 if (!host) { 49 // The active frame needs to be removed from the active tree and resources 50 // returned before the commit is called complete. 51 // TODO(danakj): Don't need to do this if the last frame commited was empty 52 // or we never commited a frame with resources. 53 SetNextCommitWaitsForActivation(); 54 } else { 55 // There is no active frame in the new layer tree host to wait for so no 56 // need to call SetNextCommitWaitsForActivation(). 57 should_collect_new_frame_ = true; 58 SetNeedsUpdate(); 59 } 60 61 Layer::SetLayerTreeHost(host); 62} 63 64void DelegatedRendererLayer::PushPropertiesTo(LayerImpl* impl) { 65 Layer::PushPropertiesTo(impl); 66 67 DelegatedRendererLayerImpl* delegated_impl = 68 static_cast<DelegatedRendererLayerImpl*>(impl); 69 70 delegated_impl->SetDisplaySize(display_size_); 71 72 delegated_impl->CreateChildIdIfNeeded( 73 frame_provider_->GetReturnResourcesCallbackForImplThread()); 74 75 if (frame_data_) 76 delegated_impl->SetFrameData(frame_data_, frame_damage_); 77 frame_data_ = NULL; 78 frame_damage_ = gfx::RectF(); 79} 80 81void DelegatedRendererLayer::ProviderHasNewFrame() { 82 should_collect_new_frame_ = true; 83 SetNeedsUpdate(); 84 // The active frame needs to be replaced and resources returned before the 85 // commit is called complete. 86 SetNextCommitWaitsForActivation(); 87} 88 89void DelegatedRendererLayer::SetDisplaySize(const gfx::Size& size) { 90 if (display_size_ == size) 91 return; 92 display_size_ = size; 93 SetNeedsCommit(); 94} 95 96static bool FrameDataRequiresFilterContext(const DelegatedFrameData* frame) { 97 for (size_t i = 0; i < frame->render_pass_list.size(); ++i) { 98 const QuadList& quad_list = frame->render_pass_list[i]->quad_list; 99 for (size_t j = 0; j < quad_list.size(); ++j) { 100 if (quad_list[j]->shared_quad_state->blend_mode != 101 SkXfermode::kSrcOver_Mode) 102 return true; 103 if (quad_list[j]->material != DrawQuad::RENDER_PASS) 104 continue; 105 const RenderPassDrawQuad* render_pass_quad = 106 RenderPassDrawQuad::MaterialCast(quad_list[j]); 107 if (!render_pass_quad->filters.IsEmpty() || 108 !render_pass_quad->background_filters.IsEmpty()) 109 return true; 110 } 111 } 112 return false; 113} 114 115bool DelegatedRendererLayer::Update(ResourceUpdateQueue* queue, 116 const OcclusionTracker* occlusion) { 117 bool updated = Layer::Update(queue, occlusion); 118 if (!should_collect_new_frame_) 119 return updated; 120 121 frame_data_ = 122 frame_provider_->GetFrameDataAndRefResources(this, &frame_damage_); 123 should_collect_new_frame_ = false; 124 125 // If any quad has a filter operation or a blend mode other than normal, 126 // then we need an offscreen context to draw this layer's content. 127 if (FrameDataRequiresFilterContext(frame_data_)) 128 layer_tree_host()->set_needs_filter_context(); 129 130 SetNeedsPushProperties(); 131 return true; 132} 133 134} // namespace cc 135