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