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/test/fake_output_surface.h"
6
7#include "base/bind.h"
8#include "base/message_loop/message_loop.h"
9#include "cc/output/compositor_frame_ack.h"
10#include "cc/output/output_surface_client.h"
11#include "cc/resources/returned_resource.h"
12#include "cc/test/begin_frame_args_test.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace cc {
16
17FakeOutputSurface::FakeOutputSurface(
18    scoped_refptr<ContextProvider> context_provider,
19    bool delegated_rendering)
20    : OutputSurface(context_provider),
21      client_(NULL),
22      num_sent_frames_(0),
23      needs_begin_frame_(false),
24      has_external_stencil_test_(false),
25      fake_weak_ptr_factory_(this) {
26  if (delegated_rendering) {
27    capabilities_.delegated_rendering = true;
28    capabilities_.max_frames_pending = 1;
29  }
30}
31
32FakeOutputSurface::FakeOutputSurface(
33    scoped_ptr<SoftwareOutputDevice> software_device,
34    bool delegated_rendering)
35    : OutputSurface(software_device.Pass()),
36      client_(NULL),
37      num_sent_frames_(0),
38      has_external_stencil_test_(false),
39      fake_weak_ptr_factory_(this) {
40  if (delegated_rendering) {
41    capabilities_.delegated_rendering = true;
42    capabilities_.max_frames_pending = 1;
43  }
44}
45
46FakeOutputSurface::FakeOutputSurface(
47    scoped_refptr<ContextProvider> context_provider,
48    scoped_ptr<SoftwareOutputDevice> software_device,
49    bool delegated_rendering)
50    : OutputSurface(context_provider, software_device.Pass()),
51      client_(NULL),
52      num_sent_frames_(0),
53      has_external_stencil_test_(false),
54      fake_weak_ptr_factory_(this) {
55  if (delegated_rendering) {
56    capabilities_.delegated_rendering = true;
57    capabilities_.max_frames_pending = 1;
58  }
59}
60
61FakeOutputSurface::~FakeOutputSurface() {}
62
63void FakeOutputSurface::SwapBuffers(CompositorFrame* frame) {
64  if (frame->software_frame_data || frame->delegated_frame_data ||
65      !context_provider()) {
66    frame->AssignTo(&last_sent_frame_);
67
68    if (last_sent_frame_.delegated_frame_data) {
69      resources_held_by_parent_.insert(
70          resources_held_by_parent_.end(),
71          last_sent_frame_.delegated_frame_data->resource_list.begin(),
72          last_sent_frame_.delegated_frame_data->resource_list.end());
73    }
74
75    ++num_sent_frames_;
76    PostSwapBuffersComplete();
77    client_->DidSwapBuffers();
78  } else {
79    OutputSurface::SwapBuffers(frame);
80    frame->AssignTo(&last_sent_frame_);
81    ++num_sent_frames_;
82  }
83}
84
85void FakeOutputSurface::SetNeedsBeginFrame(bool enable) {
86  needs_begin_frame_ = enable;
87  OutputSurface::SetNeedsBeginFrame(enable);
88
89  if (enable) {
90    base::MessageLoop::current()->PostDelayedTask(
91        FROM_HERE,
92        base::Bind(&FakeOutputSurface::OnBeginFrame,
93                   fake_weak_ptr_factory_.GetWeakPtr()),
94        base::TimeDelta::FromMilliseconds(16));
95  }
96}
97
98void FakeOutputSurface::OnBeginFrame() {
99  client_->BeginFrame(CreateBeginFrameArgsForTesting());
100}
101
102
103bool FakeOutputSurface::BindToClient(OutputSurfaceClient* client) {
104  if (OutputSurface::BindToClient(client)) {
105    client_ = client;
106    if (memory_policy_to_set_at_bind_) {
107      client_->SetMemoryPolicy(*memory_policy_to_set_at_bind_.get());
108      memory_policy_to_set_at_bind_.reset();
109    }
110    return true;
111  } else {
112    return false;
113  }
114}
115
116void FakeOutputSurface::SetTreeActivationCallback(
117    const base::Closure& callback) {
118  DCHECK(client_);
119  client_->SetTreeActivationCallback(callback);
120}
121
122void FakeOutputSurface::ReturnResource(unsigned id, CompositorFrameAck* ack) {
123  TransferableResourceArray::iterator it;
124  for (it = resources_held_by_parent_.begin();
125       it != resources_held_by_parent_.end();
126       ++it) {
127    if (it->id == id)
128      break;
129  }
130  DCHECK(it != resources_held_by_parent_.end());
131  ack->resources.push_back(it->ToReturnedResource());
132  resources_held_by_parent_.erase(it);
133}
134
135bool FakeOutputSurface::HasExternalStencilTest() const {
136  return has_external_stencil_test_;
137}
138
139void FakeOutputSurface::SetMemoryPolicyToSetAtBind(
140    scoped_ptr<ManagedMemoryPolicy> memory_policy_to_set_at_bind) {
141  memory_policy_to_set_at_bind_.swap(memory_policy_to_set_at_bind);
142}
143
144}  // namespace cc
145