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/shared_impl/ppb_graphics_3d_shared.h" 6 7 #include "base/logging.h" 8 #include "gpu/command_buffer/client/gles2_cmd_helper.h" 9 #include "gpu/command_buffer/client/gles2_implementation.h" 10 #include "gpu/command_buffer/client/transfer_buffer.h" 11 #include "ppapi/c/pp_errors.h" 12 13 namespace ppapi { 14 15 PPB_Graphics3D_Shared::PPB_Graphics3D_Shared(PP_Instance instance) 16 : Resource(OBJECT_IS_IMPL, instance) { 17 } 18 19 PPB_Graphics3D_Shared::PPB_Graphics3D_Shared(const HostResource& host_resource) 20 : Resource(OBJECT_IS_PROXY, host_resource) { 21 } 22 23 PPB_Graphics3D_Shared::~PPB_Graphics3D_Shared() { 24 // Make sure that GLES2 implementation has already been destroyed. 25 DCHECK(!gles2_helper_.get()); 26 DCHECK(!transfer_buffer_.get()); 27 DCHECK(!gles2_impl_.get()); 28 } 29 30 thunk::PPB_Graphics3D_API* PPB_Graphics3D_Shared::AsPPB_Graphics3D_API() { 31 return this; 32 } 33 34 int32_t PPB_Graphics3D_Shared::GetAttribs(int32_t attrib_list[]) { 35 // TODO(alokp): Implement me. 36 return PP_ERROR_FAILED; 37 } 38 39 int32_t PPB_Graphics3D_Shared::SetAttribs(const int32_t attrib_list[]) { 40 // TODO(alokp): Implement me. 41 return PP_ERROR_FAILED; 42 } 43 44 int32_t PPB_Graphics3D_Shared::GetError() { 45 // TODO(alokp): Implement me. 46 return PP_ERROR_FAILED; 47 } 48 49 int32_t PPB_Graphics3D_Shared::ResizeBuffers(int32_t width, int32_t height) { 50 if ((width < 0) || (height < 0)) 51 return PP_ERROR_BADARGUMENT; 52 53 ScopedNoLocking already_locked(this); 54 gles2_impl()->ResizeCHROMIUM(width, height, 1.f); 55 // TODO(alokp): Check if resize succeeded and return appropriate error code. 56 return PP_OK; 57 } 58 59 int32_t PPB_Graphics3D_Shared::SwapBuffers( 60 scoped_refptr<TrackedCallback> callback) { 61 ScopedNoLocking already_locked(this); 62 if (HasPendingSwap()) { 63 Log(PP_LOGLEVEL_ERROR, "PPB_Graphics3D.SwapBuffers: Plugin attempted swap " 64 "with previous swap still pending."); 65 // Already a pending SwapBuffers that hasn't returned yet. 66 return PP_ERROR_INPROGRESS; 67 } 68 69 swap_callback_ = callback; 70 return DoSwapBuffers(); 71 } 72 73 int32_t PPB_Graphics3D_Shared::GetAttribMaxValue(int32_t attribute, 74 int32_t* value) { 75 // TODO(alokp): Implement me. 76 return PP_ERROR_FAILED; 77 } 78 79 void* PPB_Graphics3D_Shared::MapTexSubImage2DCHROMIUM(GLenum target, 80 GLint level, 81 GLint xoffset, 82 GLint yoffset, 83 GLsizei width, 84 GLsizei height, 85 GLenum format, 86 GLenum type, 87 GLenum access) { 88 ScopedNoLocking already_locked(this); 89 return gles2_impl_->MapTexSubImage2DCHROMIUM( 90 target, level, xoffset, yoffset, width, height, format, type, access); 91 } 92 93 void PPB_Graphics3D_Shared::UnmapTexSubImage2DCHROMIUM(const void* mem) { 94 ScopedNoLocking already_locked(this); 95 gles2_impl_->UnmapTexSubImage2DCHROMIUM(mem); 96 } 97 98 void PPB_Graphics3D_Shared::SwapBuffersACK(int32_t pp_error) { 99 DCHECK(HasPendingSwap()); 100 swap_callback_->Run(pp_error); 101 } 102 103 bool PPB_Graphics3D_Shared::HasPendingSwap() const { 104 return TrackedCallback::IsPending(swap_callback_); 105 } 106 107 bool PPB_Graphics3D_Shared::CreateGLES2Impl( 108 int32 command_buffer_size, 109 int32 transfer_buffer_size, 110 gpu::gles2::GLES2Implementation* share_gles2) { 111 ScopedNoLocking already_locked(this); 112 gpu::CommandBuffer* command_buffer = GetCommandBuffer(); 113 DCHECK(command_buffer); 114 115 // Create the GLES2 helper, which writes the command buffer protocol. 116 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer)); 117 if (!gles2_helper_->Initialize(command_buffer_size)) 118 return false; 119 120 // Create a transfer buffer used to copy resources between the renderer 121 // process and the GPU process. 122 const int32 kMinTransferBufferSize = 256 * 1024; 123 const int32 kMaxTransferBufferSize = 16 * 1024 * 1024; 124 transfer_buffer_.reset(new gpu::TransferBuffer(gles2_helper_.get())); 125 126 // Create the object exposing the OpenGL API. 127 gles2_impl_.reset(new gpu::gles2::GLES2Implementation( 128 gles2_helper_.get(), 129 share_gles2 ? share_gles2->share_group() : NULL, 130 transfer_buffer_.get(), 131 true, 132 NULL // Do not use GpuMemoryBuffers. 133 )); 134 135 if (!gles2_impl_->Initialize( 136 transfer_buffer_size, 137 kMinTransferBufferSize, 138 std::max(kMaxTransferBufferSize, transfer_buffer_size))) { 139 return false; 140 } 141 142 gles2_impl_->PushGroupMarkerEXT(0, "PPAPIContext"); 143 144 return true; 145 } 146 147 void PPB_Graphics3D_Shared::DestroyGLES2Impl() { 148 ScopedNoLocking already_locked(this); 149 gles2_impl_.reset(); 150 transfer_buffer_.reset(); 151 gles2_helper_.reset(); 152 } 153 154 void PPB_Graphics3D_Shared::PushAlreadyLocked() { 155 // Do nothing. This should be overridden in the plugin side. 156 } 157 158 void PPB_Graphics3D_Shared::PopAlreadyLocked() { 159 // Do nothing. This should be overridden in the plugin side. 160 } 161 162 } // namespace ppapi 163 164