| OLD | NEW | 
|    1 // Copyright 2012 The Chromium Authors. All rights reserved. |    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 |    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/layers/delegated_renderer_layer.h" |    5 #include "cc/layers/delegated_renderer_layer.h" | 
|    6  |    6  | 
|    7 #include "cc/layers/delegated_renderer_layer_client.h" |    7 #include "cc/layers/delegated_renderer_layer_client.h" | 
|    8 #include "cc/layers/delegated_renderer_layer_impl.h" |    8 #include "cc/layers/delegated_renderer_layer_impl.h" | 
|    9 #include "cc/output/delegated_frame_data.h" |    9 #include "cc/output/delegated_frame_data.h" | 
|   10 #include "cc/quads/render_pass_draw_quad.h" |   10 #include "cc/quads/render_pass_draw_quad.h" | 
|   11 #include "cc/trees/blocking_task_runner.h" |   11 #include "cc/trees/blocking_task_runner.h" | 
|   12 #include "cc/trees/layer_tree_host.h" |   12 #include "cc/trees/layer_tree_host.h" | 
|   13  |   13  | 
|   14 namespace cc { |   14 namespace cc { | 
|   15  |   15  | 
|   16 scoped_refptr<DelegatedRendererLayer> DelegatedRendererLayer::Create( |   16 scoped_refptr<DelegatedRendererLayer> DelegatedRendererLayer::Create( | 
|   17     DelegatedRendererLayerClient* client) { |   17     DelegatedRendererLayerClient* client, | 
 |   18     const scoped_refptr<DelegatedFrameProvider>& frame_provider) { | 
|   18   return scoped_refptr<DelegatedRendererLayer>( |   19   return scoped_refptr<DelegatedRendererLayer>( | 
|   19       new DelegatedRendererLayer(client)); |   20       new DelegatedRendererLayer(client, frame_provider)); | 
|   20 } |   21 } | 
|   21  |   22  | 
|   22 DelegatedRendererLayer::DelegatedRendererLayer( |   23 DelegatedRendererLayer::DelegatedRendererLayer( | 
|   23     DelegatedRendererLayerClient* client) |   24     DelegatedRendererLayerClient* client, | 
 |   25     const scoped_refptr<DelegatedFrameProvider>& frame_provider) | 
|   24     : Layer(), |   26     : Layer(), | 
|   25       client_(client), |   27       client_(client), | 
|   26       needs_filter_context_(false), |   28       frame_provider_(frame_provider), | 
 |   29       should_collect_new_frame_(true), | 
 |   30       frame_data_(NULL), | 
|   27       main_thread_runner_(BlockingTaskRunner::current()), |   31       main_thread_runner_(BlockingTaskRunner::current()), | 
|   28       weak_ptrs_(this) {} |   32       weak_ptrs_(this) { | 
 |   33   frame_provider_->AddObserver(this); | 
 |   34 } | 
|   29  |   35  | 
|   30 DelegatedRendererLayer::~DelegatedRendererLayer() {} |   36 DelegatedRendererLayer::~DelegatedRendererLayer() { | 
 |   37   frame_provider_->RemoveObserver(this); | 
 |   38 } | 
|   31  |   39  | 
|   32 scoped_ptr<LayerImpl> DelegatedRendererLayer::CreateLayerImpl( |   40 scoped_ptr<LayerImpl> DelegatedRendererLayer::CreateLayerImpl( | 
|   33     LayerTreeImpl* tree_impl) { |   41     LayerTreeImpl* tree_impl) { | 
|   34   return DelegatedRendererLayerImpl::Create( |   42   return DelegatedRendererLayerImpl::Create( | 
|   35       tree_impl, layer_id_).PassAs<LayerImpl>(); |   43       tree_impl, layer_id_).PassAs<LayerImpl>(); | 
|   36 } |   44 } | 
|   37  |   45  | 
|   38 void DelegatedRendererLayer::SetLayerTreeHost(LayerTreeHost* host) { |   46 void DelegatedRendererLayer::SetLayerTreeHost(LayerTreeHost* host) { | 
|   39   if (layer_tree_host() == host) { |   47   if (layer_tree_host() == host) { | 
|   40     Layer::SetLayerTreeHost(host); |   48     Layer::SetLayerTreeHost(host); | 
|   41     return; |   49     return; | 
|   42   } |   50   } | 
|   43  |   51  | 
|   44   if (!host) { |   52   if (!host) { | 
|   45     // The active frame needs to be removed from the active tree and resources |   53     // The active frame needs to be removed from the active tree and resources | 
|   46     // returned before the commit is called complete. |   54     // returned before the commit is called complete. | 
|   47     // TODO(danakj): Don't need to do this if the last frame commited was empty |   55     // TODO(danakj): Don't need to do this if the last frame commited was empty | 
|   48     // or we never commited a frame with resources. |   56     // or we never commited a frame with resources. | 
|   49     SetNextCommitWaitsForActivation(); |   57     SetNextCommitWaitsForActivation(); | 
|   50   } else { |   58   } else { | 
|   51     if (needs_filter_context_) |   59     // There is no active frame in the new layer tree host to wait for so no | 
|   52       host->set_needs_filter_context(); |   60     // need to call SetNextCommitWaitsForActivation(). | 
 |   61     should_collect_new_frame_ = true; | 
 |   62     SetNeedsUpdate(); | 
|   53   } |   63   } | 
|   54  |   64  | 
|   55   Layer::SetLayerTreeHost(host); |   65   Layer::SetLayerTreeHost(host); | 
|   56 } |   66 } | 
|   57  |   67  | 
|   58 bool DelegatedRendererLayer::DrawsContent() const { |  | 
|   59   return Layer::DrawsContent() && !frame_size_.IsEmpty(); |  | 
|   60 } |  | 
|   61  |  | 
|   62 void DelegatedRendererLayer::PushPropertiesTo(LayerImpl* impl) { |   68 void DelegatedRendererLayer::PushPropertiesTo(LayerImpl* impl) { | 
|   63   Layer::PushPropertiesTo(impl); |   69   Layer::PushPropertiesTo(impl); | 
|   64  |   70  | 
|   65   DelegatedRendererLayerImpl* delegated_impl = |   71   DelegatedRendererLayerImpl* delegated_impl = | 
|   66       static_cast<DelegatedRendererLayerImpl*>(impl); |   72       static_cast<DelegatedRendererLayerImpl*>(impl); | 
|   67  |   73  | 
|   68   delegated_impl->SetDisplaySize(display_size_); |   74   delegated_impl->SetDisplaySize(display_size_); | 
|   69  |   75  | 
|   70   delegated_impl->CreateChildIdIfNeeded( |   76   delegated_impl->CreateChildIdIfNeeded( | 
|   71       base::Bind(&DelegatedRendererLayer::ReceiveUnusedResourcesOnImplThread, |   77       frame_provider_->GetReturnResourcesCallbackForImplThread()); | 
|   72                  main_thread_runner_, |  | 
|   73                  weak_ptrs_.GetWeakPtr())); |  | 
|   74  |   78  | 
|   75   if (frame_data_) |   79   if (frame_data_) | 
|   76     delegated_impl->SetFrameData(frame_data_.Pass(), damage_in_frame_); |   80     delegated_impl->SetFrameData(frame_data_, frame_damage_); | 
|   77   frame_data_.reset(); |   81   frame_data_ = NULL; | 
|   78   damage_in_frame_ = gfx::RectF(); |   82   frame_damage_ = gfx::RectF(); | 
|   79  |   83  | 
|   80   // The ResourceProvider will have the new frame as soon as we push it to the |   84   // The ResourceProvider will have the new frame as soon as we push it to the | 
|   81   // pending tree. So unused resources will be returned as well. |   85   // pending tree. So resources no longer in use will be returned as well. | 
|   82   if (client_) |   86   if (client_) | 
|   83     client_->DidCommitFrameData(); |   87     client_->DidCommitFrameData(); | 
|   84  |   88  | 
|   85   // TODO(danakj): The DidCommitFrameData() notification requires a push |   89   // TODO(danakj): The DidCommitFrameData() notification requires a push | 
|   86   // properties to happen in order to notify about unused resources returned |   90   // properties to happen in order to notify about resources returned | 
|   87   // from the parent compositor. crbug.com/259090 |   91   // from the parent compositor that are no longer in use. crbug.com/259090 | 
|   88   needs_push_properties_ = true; |   92   needs_push_properties_ = true; | 
|   89 } |   93 } | 
|   90  |   94  | 
 |   95 void 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  | 
|   91 void DelegatedRendererLayer::SetDisplaySize(gfx::Size size) { |  103 void DelegatedRendererLayer::SetDisplaySize(gfx::Size size) { | 
|   92   if (display_size_ == size) |  104   if (display_size_ == size) | 
|   93     return; |  105     return; | 
|   94   display_size_ = size; |  106   display_size_ = size; | 
|   95   SetNeedsCommit(); |  107   SetNeedsCommit(); | 
|   96 } |  108 } | 
|   97  |  109  | 
|   98 void DelegatedRendererLayer::SetFrameData( |  110 static bool FrameDataHasFilter(DelegatedFrameData* frame) { | 
|   99     scoped_ptr<DelegatedFrameData> new_frame_data) { |  111   for (size_t i = 0; i < frame->render_pass_list.size(); ++i) { | 
|  100   DCHECK(new_frame_data); |  112     const QuadList& quad_list = frame->render_pass_list[i]->quad_list; | 
|  101  |  113     for (size_t j = 0; j < quad_list.size(); ++j) { | 
|  102   if (frame_data_) { |  | 
|  103     // Copy the resources from the last provided frame into the unused resources |  | 
|  104     // list, as the new frame will provide its own resources. |  | 
|  105     TransferableResource::ReturnResources( |  | 
|  106         frame_data_->resource_list, |  | 
|  107         &unused_resources_for_child_compositor_); |  | 
|  108     if (client_) |  | 
|  109       client_->UnusedResourcesAreAvailable(); |  | 
|  110   } |  | 
|  111   frame_data_ = new_frame_data.Pass(); |  | 
|  112   if (!frame_data_->render_pass_list.empty()) { |  | 
|  113     RenderPass* root_pass = frame_data_->render_pass_list.back(); |  | 
|  114     damage_in_frame_.Union(root_pass->damage_rect); |  | 
|  115     frame_size_ = root_pass->output_rect.size(); |  | 
|  116   } else { |  | 
|  117     frame_size_ = gfx::Size(); |  | 
|  118   } |  | 
|  119  |  | 
|  120   // If any RenderPassDrawQuad has a filter operation, then we need a filter |  | 
|  121   // context to draw this layer's content. |  | 
|  122   for (size_t i = 0; |  | 
|  123        !needs_filter_context_ && i < frame_data_->render_pass_list.size(); |  | 
|  124        ++i) { |  | 
|  125     const QuadList& quad_list = frame_data_->render_pass_list[i]->quad_list; |  | 
|  126     for (size_t j = 0; !needs_filter_context_ && j < quad_list.size(); ++j) { |  | 
|  127       if (quad_list[j]->material != DrawQuad::RENDER_PASS) |  114       if (quad_list[j]->material != DrawQuad::RENDER_PASS) | 
|  128         continue; |  115         continue; | 
|  129       const RenderPassDrawQuad* render_pass_quad = |  116       const RenderPassDrawQuad* render_pass_quad = | 
|  130           RenderPassDrawQuad::MaterialCast(quad_list[j]); |  117           RenderPassDrawQuad::MaterialCast(quad_list[j]); | 
|  131       if (!render_pass_quad->filters.IsEmpty() || |  118       if (!render_pass_quad->filters.IsEmpty() || | 
|  132           !render_pass_quad->background_filters.IsEmpty()) |  119           !render_pass_quad->background_filters.IsEmpty()) | 
|  133         needs_filter_context_ = true; |  120         return true; | 
|  134     } |  121     } | 
|  135   } |  122   } | 
|  136   if (needs_filter_context_ && layer_tree_host()) |  123   return false; | 
 |  124 } | 
 |  125  | 
 |  126 bool 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()) | 
|  137     layer_tree_host()->set_needs_filter_context(); |  139     layer_tree_host()->set_needs_filter_context(); | 
|  138  |  140  | 
|  139   SetNeedsCommit(); |  141   return true; | 
|  140   // The active frame needs to be replaced and resources returned before the |  | 
|  141   // commit is called complete. |  | 
|  142   SetNextCommitWaitsForActivation(); |  | 
|  143 } |  | 
|  144  |  | 
|  145 void DelegatedRendererLayer::TakeUnusedResourcesForChildCompositor( |  | 
|  146     ReturnedResourceArray* array) { |  | 
|  147   DCHECK(array->empty()); |  | 
|  148   array->clear(); |  | 
|  149  |  | 
|  150   array->swap(unused_resources_for_child_compositor_); |  | 
|  151 } |  | 
|  152  |  | 
|  153 void DelegatedRendererLayer::ReceiveUnusedResources( |  | 
|  154     const ReturnedResourceArray& unused) { |  | 
|  155   unused_resources_for_child_compositor_.insert( |  | 
|  156       unused_resources_for_child_compositor_.end(), |  | 
|  157       unused.begin(), |  | 
|  158       unused.end()); |  | 
|  159   if (client_) |  | 
|  160     client_->UnusedResourcesAreAvailable(); |  | 
|  161 } |  | 
|  162  |  | 
|  163 // static |  | 
|  164 void DelegatedRendererLayer::ReceiveUnusedResourcesOnImplThread( |  | 
|  165     scoped_refptr<BlockingTaskRunner> task_runner, |  | 
|  166     base::WeakPtr<DelegatedRendererLayer> self, |  | 
|  167     const ReturnedResourceArray& unused) { |  | 
|  168   task_runner->PostTask( |  | 
|  169       FROM_HERE, |  | 
|  170       base::Bind( |  | 
|  171           &DelegatedRendererLayer::ReceiveUnusedResources, self, unused)); |  | 
|  172 } |  142 } | 
|  173  |  143  | 
|  174 }  // namespace cc |  144 }  // namespace cc | 
| OLD | NEW |