14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/layers/delegated_frame_provider.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/layers/delegated_frame_resource_collection.h"
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/layers/delegated_renderer_layer.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/output/delegated_frame_data.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "cc/quads/render_pass_draw_quad.h"
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace cc {
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DelegatedFrameProvider::DelegatedFrameProvider(
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const scoped_refptr<DelegatedFrameResourceCollection>& resource_collection,
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<DelegatedFrameData> frame)
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : resource_collection_(resource_collection) {
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderPass* root_pass = frame->render_pass_list.back();
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  frame_size_ = root_pass->output_rect.size();
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!frame_size_.IsEmpty());
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetFrameData(frame.Pass());
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DelegatedFrameProvider::~DelegatedFrameProvider() {
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ReturnedResourceArray returned;
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TransferableResource::ReturnResources(frame_->resource_list, &returned);
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  resource_collection_->UnrefResources(returned);
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DelegatedFrameProvider::AddObserver(DelegatedRendererLayer* layer) {
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if DCHECK_IS_ON
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < observers_.size(); ++i)
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(observers_[i].layer != layer);
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  observers_.push_back(Observer(layer, gfx::RectF(frame_size_)));
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(frame_) << "Must have a frame when given to a DelegatedRendererLayer.";
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DelegatedFrameProvider::RemoveObserver(DelegatedRendererLayer* layer) {
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool found_observer = false;
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < observers_.size(); ++i) {
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (observers_[i].layer != layer)
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      continue;
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    observers_.erase(observers_.begin() + i);
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    found_observer = true;
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    break;
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(found_observer);
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DelegatedFrameProvider::SetFrameData(
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<DelegatedFrameData> frame) {
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(frame);
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_NE(0u, frame->render_pass_list.size());
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (frame_) {
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ReturnedResourceArray returned;
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TransferableResource::ReturnResources(frame_->resource_list, &returned);
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    resource_collection_->UnrefResources(returned);
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  frame_ = frame.Pass();
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  resource_collection_->ReceivedResources(frame_->resource_list);
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  resource_collection_->RefResources(frame_->resource_list);
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderPass* root_pass = frame_->render_pass_list.back();
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(frame_size_.ToString(), root_pass->output_rect.size().ToString())
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      << "All frames in a single DelegatedFrameProvider must have the same "
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      << "size. Use a new frame provider for frames of a different size.";
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < observers_.size(); ++i) {
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    observers_[i].damage =
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        gfx::UnionRects(observers_[i].damage, root_pass->damage_rect);
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    observers_[i].layer->ProviderHasNewFrame();
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DelegatedFrameData* DelegatedFrameProvider::GetFrameDataAndRefResources(
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DelegatedRendererLayer* observer,
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    gfx::RectF* damage) {
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool found_observer = false;
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (size_t i = 0; i < observers_.size(); ++i) {
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (observers_[i].layer != observer)
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      continue;
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    *damage = observers_[i].damage;
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // The observer is now responsible for the damage.
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    observers_[i].damage = gfx::RectF();
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    found_observer = true;
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(found_observer);
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  resource_collection_->RefResources(frame_->resource_list);
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return frame_.get();
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ReturnCallback
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)DelegatedFrameProvider::GetReturnResourcesCallbackForImplThread() {
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return resource_collection_->GetReturnResourcesCallbackForImplThread();
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DelegatedFrameProvider::UnrefResourcesOnMainThread(
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const ReturnedResourceArray& returned) {
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  resource_collection_->UnrefResources(returned);
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace cc
111