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