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 "testing/gtest/include/gtest/gtest.h" 13 14 namespace cc { 15 16 FakeOutputSurface::FakeOutputSurface( 17 scoped_refptr<ContextProvider> context_provider, 18 bool delegated_rendering) 19 : OutputSurface(context_provider), 20 client_(NULL), 21 num_sent_frames_(0), 22 needs_begin_impl_frame_(false), 23 forced_draw_to_software_device_(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 32 FakeOutputSurface::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 forced_draw_to_software_device_(false), 39 has_external_stencil_test_(false), 40 fake_weak_ptr_factory_(this) { 41 if (delegated_rendering) { 42 capabilities_.delegated_rendering = true; 43 capabilities_.max_frames_pending = 1; 44 } 45 } 46 47 FakeOutputSurface::FakeOutputSurface( 48 scoped_refptr<ContextProvider> context_provider, 49 scoped_ptr<SoftwareOutputDevice> software_device, 50 bool delegated_rendering) 51 : OutputSurface(context_provider, software_device.Pass()), 52 client_(NULL), 53 num_sent_frames_(0), 54 forced_draw_to_software_device_(false), 55 has_external_stencil_test_(false), 56 fake_weak_ptr_factory_(this) { 57 if (delegated_rendering) { 58 capabilities_.delegated_rendering = true; 59 capabilities_.max_frames_pending = 1; 60 } 61 } 62 63 FakeOutputSurface::~FakeOutputSurface() {} 64 65 void FakeOutputSurface::SwapBuffers(CompositorFrame* frame) { 66 if (frame->software_frame_data || frame->delegated_frame_data || 67 !context_provider()) { 68 frame->AssignTo(&last_sent_frame_); 69 70 if (last_sent_frame_.delegated_frame_data) { 71 resources_held_by_parent_.insert( 72 resources_held_by_parent_.end(), 73 last_sent_frame_.delegated_frame_data->resource_list.begin(), 74 last_sent_frame_.delegated_frame_data->resource_list.end()); 75 } 76 77 ++num_sent_frames_; 78 PostSwapBuffersComplete(); 79 DidSwapBuffers(); 80 } else { 81 OutputSurface::SwapBuffers(frame); 82 frame->AssignTo(&last_sent_frame_); 83 ++num_sent_frames_; 84 } 85 } 86 87 void FakeOutputSurface::SetNeedsBeginImplFrame(bool enable) { 88 needs_begin_impl_frame_ = enable; 89 OutputSurface::SetNeedsBeginImplFrame(enable); 90 91 // If there is not BeginImplFrame emulation from the FrameRateController, 92 // then we just post a BeginImplFrame to emulate it as part of the test. 93 if (enable && !frame_rate_controller_) { 94 base::MessageLoop::current()->PostDelayedTask( 95 FROM_HERE, base::Bind(&FakeOutputSurface::OnBeginImplFrame, 96 fake_weak_ptr_factory_.GetWeakPtr()), 97 base::TimeDelta::FromMilliseconds(16)); 98 } 99 } 100 101 void FakeOutputSurface::OnBeginImplFrame() { 102 OutputSurface::BeginImplFrame(BeginFrameArgs::CreateForTesting()); 103 } 104 105 106 bool FakeOutputSurface::ForcedDrawToSoftwareDevice() const { 107 return forced_draw_to_software_device_; 108 } 109 110 bool FakeOutputSurface::BindToClient(OutputSurfaceClient* client) { 111 if (OutputSurface::BindToClient(client)) { 112 client_ = client; 113 if (memory_policy_to_set_at_bind_) { 114 client_->SetMemoryPolicy(*memory_policy_to_set_at_bind_.get()); 115 memory_policy_to_set_at_bind_.reset(); 116 } 117 return true; 118 } else { 119 return false; 120 } 121 } 122 123 void FakeOutputSurface::SetTreeActivationCallback( 124 const base::Closure& callback) { 125 DCHECK(client_); 126 client_->SetTreeActivationCallback(callback); 127 } 128 129 void FakeOutputSurface::ReturnResource(unsigned id, CompositorFrameAck* ack) { 130 TransferableResourceArray::iterator it; 131 for (it = resources_held_by_parent_.begin(); 132 it != resources_held_by_parent_.end(); 133 ++it) { 134 if (it->id == id) 135 break; 136 } 137 DCHECK(it != resources_held_by_parent_.end()); 138 ack->resources.push_back(it->ToReturnedResource()); 139 resources_held_by_parent_.erase(it); 140 } 141 142 bool FakeOutputSurface::HasExternalStencilTest() const { 143 return has_external_stencil_test_; 144 } 145 146 void FakeOutputSurface::SetMemoryPolicyToSetAtBind( 147 scoped_ptr<ManagedMemoryPolicy> memory_policy_to_set_at_bind) { 148 memory_policy_to_set_at_bind_.swap(memory_policy_to_set_at_bind); 149 } 150 151 } // namespace cc 152