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