ppapi_command_buffer_proxy.cc revision 010d83a9304c5a91596085d917d248abff47903a
1// Copyright (c) 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 "ppapi/proxy/ppapi_command_buffer_proxy.h" 6 7#include "ppapi/proxy/ppapi_messages.h" 8#include "ppapi/proxy/proxy_channel.h" 9#include "ppapi/shared_impl/api_id.h" 10#include "ppapi/shared_impl/host_resource.h" 11#include "ppapi/shared_impl/proxy_lock.h" 12 13namespace ppapi { 14namespace proxy { 15 16PpapiCommandBufferProxy::PpapiCommandBufferProxy( 17 const ppapi::HostResource& resource, 18 ProxyChannel* channel) 19 : resource_(resource), 20 channel_(channel) { 21} 22 23PpapiCommandBufferProxy::~PpapiCommandBufferProxy() { 24 // gpu::Buffers are no longer referenced, allowing shared memory objects to be 25 // deleted, closing the handle in this process. 26} 27 28bool PpapiCommandBufferProxy::Initialize() { 29 return true; 30} 31 32gpu::CommandBuffer::State PpapiCommandBufferProxy::GetLastState() { 33 ppapi::ProxyLock::AssertAcquiredDebugOnly(); 34 return last_state_; 35} 36 37int32 PpapiCommandBufferProxy::GetLastToken() { 38 ppapi::ProxyLock::AssertAcquiredDebugOnly(); 39 return last_state_.token; 40} 41 42void PpapiCommandBufferProxy::Flush(int32 put_offset) { 43 if (last_state_.error != gpu::error::kNoError) 44 return; 45 46 IPC::Message* message = new PpapiHostMsg_PPBGraphics3D_AsyncFlush( 47 ppapi::API_ID_PPB_GRAPHICS_3D, resource_, put_offset); 48 49 // Do not let a synchronous flush hold up this message. If this handler is 50 // deferred until after the synchronous flush completes, it will overwrite the 51 // cached last_state_ with out-of-date data. 52 message->set_unblock(true); 53 Send(message); 54} 55 56void PpapiCommandBufferProxy::WaitForTokenInRange(int32 start, int32 end) { 57 if (last_state_.error != gpu::error::kNoError) 58 return; 59 60 bool success; 61 gpu::CommandBuffer::State state; 62 if (Send(new PpapiHostMsg_PPBGraphics3D_WaitForTokenInRange( 63 ppapi::API_ID_PPB_GRAPHICS_3D, 64 resource_, 65 start, 66 end, 67 &state, 68 &success))) 69 UpdateState(state, success); 70} 71 72void PpapiCommandBufferProxy::WaitForGetOffsetInRange(int32 start, int32 end) { 73 if (last_state_.error != gpu::error::kNoError) 74 return; 75 76 bool success; 77 gpu::CommandBuffer::State state; 78 if (Send(new PpapiHostMsg_PPBGraphics3D_WaitForGetOffsetInRange( 79 ppapi::API_ID_PPB_GRAPHICS_3D, 80 resource_, 81 start, 82 end, 83 &state, 84 &success))) 85 UpdateState(state, success); 86} 87 88void PpapiCommandBufferProxy::SetGetBuffer(int32 transfer_buffer_id) { 89 if (last_state_.error == gpu::error::kNoError) { 90 Send(new PpapiHostMsg_PPBGraphics3D_SetGetBuffer( 91 ppapi::API_ID_PPB_GRAPHICS_3D, resource_, transfer_buffer_id)); 92 } 93} 94 95scoped_refptr<gpu::Buffer> PpapiCommandBufferProxy::CreateTransferBuffer( 96 size_t size, 97 int32* id) { 98 *id = -1; 99 100 if (last_state_.error != gpu::error::kNoError) 101 return NULL; 102 103 // Assuming we are in the renderer process, the service is responsible for 104 // duplicating the handle. This might not be true for NaCl. 105 ppapi::proxy::SerializedHandle handle( 106 ppapi::proxy::SerializedHandle::SHARED_MEMORY); 107 if (!Send(new PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer( 108 ppapi::API_ID_PPB_GRAPHICS_3D, resource_, size, id, &handle))) { 109 return NULL; 110 } 111 112 if (*id <= 0 || !handle.is_shmem()) 113 return NULL; 114 115 scoped_ptr<base::SharedMemory> shared_memory( 116 new base::SharedMemory(handle.shmem(), false)); 117 118 // Map the shared memory on demand. 119 if (!shared_memory->memory()) { 120 if (!shared_memory->Map(handle.size())) { 121 *id = -1; 122 return NULL; 123 } 124 } 125 126 return gpu::MakeBufferFromSharedMemory(shared_memory.Pass(), handle.size()); 127} 128 129void PpapiCommandBufferProxy::DestroyTransferBuffer(int32 id) { 130 if (last_state_.error != gpu::error::kNoError) 131 return; 132 133 Send(new PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer( 134 ppapi::API_ID_PPB_GRAPHICS_3D, resource_, id)); 135} 136 137void PpapiCommandBufferProxy::Echo(const base::Closure& callback) { 138 NOTREACHED(); 139} 140 141uint32 PpapiCommandBufferProxy::CreateStreamTexture(uint32 texture_id) { 142 NOTREACHED(); 143 return 0; 144} 145 146uint32 PpapiCommandBufferProxy::InsertSyncPoint() { 147 uint32 sync_point = 0; 148 if (last_state_.error == gpu::error::kNoError) { 149 Send(new PpapiHostMsg_PPBGraphics3D_InsertSyncPoint( 150 ppapi::API_ID_PPB_GRAPHICS_3D, resource_, &sync_point)); 151 } 152 return sync_point; 153} 154 155void PpapiCommandBufferProxy::SignalSyncPoint(uint32 sync_point, 156 const base::Closure& callback) { 157 NOTREACHED(); 158} 159 160void PpapiCommandBufferProxy::SignalQuery(uint32 query, 161 const base::Closure& callback) { 162 NOTREACHED(); 163} 164 165void PpapiCommandBufferProxy::SetSurfaceVisible(bool visible) { 166 NOTREACHED(); 167} 168 169void PpapiCommandBufferProxy::SendManagedMemoryStats( 170 const gpu::ManagedMemoryStats& stats) { 171 NOTREACHED(); 172} 173 174gpu::Capabilities PpapiCommandBufferProxy::GetCapabilities() { 175 // TODO(boliu): Need to implement this to use cc in Pepper. Tracked in 176 // crbug.com/325391. 177 return gpu::Capabilities(); 178} 179 180gfx::GpuMemoryBuffer* PpapiCommandBufferProxy::CreateGpuMemoryBuffer( 181 size_t width, 182 size_t height, 183 unsigned internalformat, 184 unsigned usage, 185 int32* id) { 186 NOTREACHED(); 187 return NULL; 188} 189 190void PpapiCommandBufferProxy::DestroyGpuMemoryBuffer(int32 id) { 191 NOTREACHED(); 192} 193 194bool PpapiCommandBufferProxy::Send(IPC::Message* msg) { 195 DCHECK(last_state_.error == gpu::error::kNoError); 196 197 if (channel_->Send(msg)) 198 return true; 199 200 last_state_.error = gpu::error::kLostContext; 201 return false; 202} 203 204void PpapiCommandBufferProxy::UpdateState( 205 const gpu::CommandBuffer::State& state, 206 bool success) { 207 // Handle wraparound. It works as long as we don't have more than 2B state 208 // updates in flight across which reordering occurs. 209 if (success) { 210 if (state.generation - last_state_.generation < 0x80000000U) { 211 last_state_ = state; 212 } 213 } else { 214 last_state_.error = gpu::error::kLostContext; 215 ++last_state_.generation; 216 } 217} 218 219} // namespace proxy 220} // namespace ppapi 221