Home | History | Annotate | Download | only in surfaces
      1 // Copyright 2014 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/surfaces/surface.h"
      6 
      7 #include "cc/output/compositor_frame.h"
      8 #include "cc/output/copy_output_request.h"
      9 #include "cc/surfaces/surface_factory.h"
     10 
     11 namespace cc {
     12 
     13 // The frame index starts at 2 so that empty frames will be treated as
     14 // completely damaged the first time they're drawn from.
     15 static const int kFrameIndexStart = 2;
     16 
     17 Surface::Surface(SurfaceId id, const gfx::Size& size, SurfaceFactory* factory)
     18     : surface_id_(id),
     19       size_(size),
     20       factory_(factory),
     21       frame_index_(kFrameIndexStart) {
     22 }
     23 
     24 Surface::~Surface() {
     25   for (ScopedPtrVector<CopyOutputRequest>::iterator it = copy_requests_.begin();
     26        it != copy_requests_.end();
     27        ++it) {
     28     (*it)->SendEmptyResult();
     29   }
     30   copy_requests_.clear();
     31   if (current_frame_) {
     32     ReturnedResourceArray current_resources;
     33     TransferableResource::ReturnResources(
     34         current_frame_->delegated_frame_data->resource_list,
     35         &current_resources);
     36     factory_->UnrefResources(current_resources);
     37   }
     38 }
     39 
     40 void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame,
     41                          const base::Closure& callback) {
     42   for (ScopedPtrVector<CopyOutputRequest>::iterator it = copy_requests_.begin();
     43        it != copy_requests_.end();
     44        ++it) {
     45     (*it)->SendEmptyResult();
     46   }
     47   copy_requests_.clear();
     48 
     49   TakeLatencyInfo(&frame->metadata.latency_info);
     50   scoped_ptr<CompositorFrame> previous_frame = current_frame_.Pass();
     51   current_frame_ = frame.Pass();
     52   factory_->ReceiveFromChild(
     53       current_frame_->delegated_frame_data->resource_list);
     54   ++frame_index_;
     55 
     56   if (previous_frame) {
     57     ReturnedResourceArray previous_resources;
     58     TransferableResource::ReturnResources(
     59         previous_frame->delegated_frame_data->resource_list,
     60         &previous_resources);
     61     factory_->UnrefResources(previous_resources);
     62   }
     63   if (!draw_callback_.is_null())
     64     draw_callback_.Run();
     65   draw_callback_ = callback;
     66 }
     67 
     68 void Surface::RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request) {
     69   copy_requests_.push_back(copy_request.Pass());
     70 }
     71 
     72 void Surface::TakeCopyOutputRequests(
     73     ScopedPtrVector<CopyOutputRequest>* copy_requests) {
     74   DCHECK(copy_requests->empty());
     75   copy_requests->swap(copy_requests_);
     76 }
     77 
     78 const CompositorFrame* Surface::GetEligibleFrame() {
     79   return current_frame_.get();
     80 }
     81 
     82 void Surface::TakeLatencyInfo(std::vector<ui::LatencyInfo>* latency_info) {
     83   if (!current_frame_)
     84     return;
     85   if (latency_info->empty()) {
     86     current_frame_->metadata.latency_info.swap(*latency_info);
     87     return;
     88   }
     89   std::copy(current_frame_->metadata.latency_info.begin(),
     90             current_frame_->metadata.latency_info.end(),
     91             std::back_inserter(*latency_info));
     92   current_frame_->metadata.latency_info.clear();
     93 }
     94 
     95 void Surface::RunDrawCallbacks() {
     96   if (!draw_callback_.is_null()) {
     97     base::Closure callback = draw_callback_;
     98     draw_callback_ = base::Closure();
     99     callback.Run();
    100   }
    101 }
    102 
    103 }  // namespace cc
    104