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 gles2_impl()->ResizeCHROMIUM(width, height, 1.f); 54 // TODO(alokp): Check if resize succeeded and return appropriate error code. 55 return PP_OK; 56 } 57 58 int32_t PPB_Graphics3D_Shared::SwapBuffers( 59 scoped_refptr<TrackedCallback> callback) { 60 if (HasPendingSwap()) { 61 Log(PP_LOGLEVEL_ERROR, "PPB_Graphics3D.SwapBuffers: Plugin attempted swap " 62 "with previous swap still pending."); 63 // Already a pending SwapBuffers that hasn't returned yet. 64 return PP_ERROR_INPROGRESS; 65 } 66 67 swap_callback_ = callback; 68 return DoSwapBuffers(); 69 } 70 71 int32_t PPB_Graphics3D_Shared::GetAttribMaxValue(int32_t attribute, 72 int32_t* value) { 73 // TODO(alokp): Implement me. 74 return PP_ERROR_FAILED; 75 } 76 77 void* PPB_Graphics3D_Shared::MapTexSubImage2DCHROMIUM(GLenum target, 78 GLint level, 79 GLint xoffset, 80 GLint yoffset, 81 GLsizei width, 82 GLsizei height, 83 GLenum format, 84 GLenum type, 85 GLenum access) { 86 return gles2_impl_->MapTexSubImage2DCHROMIUM( 87 target, level, xoffset, yoffset, width, height, format, type, access); 88 } 89 90 void PPB_Graphics3D_Shared::UnmapTexSubImage2DCHROMIUM(const void* mem) { 91 gles2_impl_->UnmapTexSubImage2DCHROMIUM(mem); 92 } 93 94 void PPB_Graphics3D_Shared::SwapBuffersACK(int32_t pp_error) { 95 DCHECK(HasPendingSwap()); 96 swap_callback_->Run(pp_error); 97 } 98 99 bool PPB_Graphics3D_Shared::HasPendingSwap() const { 100 return TrackedCallback::IsPending(swap_callback_); 101 } 102 103 bool PPB_Graphics3D_Shared::CreateGLES2Impl( 104 int32 command_buffer_size, 105 int32 transfer_buffer_size, 106 gpu::gles2::GLES2Implementation* share_gles2) { 107 gpu::CommandBuffer* command_buffer = GetCommandBuffer(); 108 DCHECK(command_buffer); 109 110 // Create the GLES2 helper, which writes the command buffer protocol. 111 gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer)); 112 if (!gles2_helper_->Initialize(command_buffer_size)) 113 return false; 114 115 // Create a transfer buffer used to copy resources between the renderer 116 // process and the GPU process. 117 const int32 kMinTransferBufferSize = 256 * 1024; 118 const int32 kMaxTransferBufferSize = 16 * 1024 * 1024; 119 transfer_buffer_.reset(new gpu::TransferBuffer(gles2_helper_.get())); 120 121 const bool bind_creates_resources = true; 122 const bool free_everything_when_invisible = false; 123 124 // Create the object exposing the OpenGL API. 125 gles2_impl_.reset(new gpu::gles2::GLES2Implementation( 126 gles2_helper_.get(), 127 share_gles2 ? share_gles2->share_group() : NULL, 128 transfer_buffer_.get(), 129 bind_creates_resources, 130 free_everything_when_invisible, 131 GetGpuControl())); 132 133 if (!gles2_impl_->Initialize( 134 transfer_buffer_size, 135 kMinTransferBufferSize, 136 std::max(kMaxTransferBufferSize, transfer_buffer_size), 137 gpu::gles2::GLES2Implementation::kNoLimit)) { 138 return false; 139 } 140 141 gles2_impl_->PushGroupMarkerEXT(0, "PPAPIContext"); 142 143 return true; 144 } 145 146 void PPB_Graphics3D_Shared::DestroyGLES2Impl() { 147 gles2_impl_.reset(); 148 transfer_buffer_.reset(); 149 gles2_helper_.reset(); 150 } 151 152 } // namespace ppapi 153 154