1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
7 #include "base/logging.h"
8 #include "gpu/GLES2/gl2extchromium.h"
9 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
10 #include "gpu/command_buffer/client/gles2_implementation.h"
11 #include "gpu/command_buffer/client/shared_memory_limits.h"
12 #include "gpu/command_buffer/client/transfer_buffer.h"
13 #include "gpu/command_buffer/common/sync_token.h"
14 #include "ppapi/c/pp_errors.h"
18 PPB_Graphics3D_Shared::PPB_Graphics3D_Shared(PP_Instance instance)
19 : Resource(OBJECT_IS_IMPL, instance) {}
21 PPB_Graphics3D_Shared::PPB_Graphics3D_Shared(const HostResource& host_resource,
22 const gfx::Size& size)
23 : Resource(OBJECT_IS_PROXY, host_resource), size_(size) {}
25 PPB_Graphics3D_Shared::~PPB_Graphics3D_Shared() {
26 // Make sure that GLES2 implementation has already been destroyed.
27 DCHECK(!gles2_helper_.get());
28 DCHECK(!transfer_buffer_.get());
29 DCHECK(!gles2_impl_.get());
32 thunk::PPB_Graphics3D_API* PPB_Graphics3D_Shared::AsPPB_Graphics3D_API() {
36 int32_t PPB_Graphics3D_Shared::GetAttribs(int32_t attrib_list[]) {
37 // TODO(alokp): Implement me.
38 LOG(ERROR) << "Method not implemented";
39 return PP_ERROR_FAILED;
42 int32_t PPB_Graphics3D_Shared::SetAttribs(const int32_t attrib_list[]) {
43 // TODO(alokp): Implement me.
44 LOG(ERROR) << "Method not implemented";
45 return PP_ERROR_FAILED;
48 int32_t PPB_Graphics3D_Shared::GetError() {
49 // TODO(alokp): Implement me.
50 LOG(ERROR) << "Method not implemented";
51 return PP_ERROR_FAILED;
54 int32_t PPB_Graphics3D_Shared::ResizeBuffers(int32_t width, int32_t height) {
55 if ((width < 0) || (height < 0))
56 return PP_ERROR_BADARGUMENT;
58 gles2_impl()->ResizeCHROMIUM(width, height, 1.f, nullptr, true);
59 size_ = gfx::Size(width, height);
60 // TODO(alokp): Check if resize succeeded and return appropriate error code.
64 int32_t PPB_Graphics3D_Shared::SwapBuffers(
65 scoped_refptr<TrackedCallback> callback) {
66 return SwapBuffersWithSyncToken(callback, gpu::SyncToken(), size_);
69 int32_t PPB_Graphics3D_Shared::SwapBuffersWithSyncToken(
70 scoped_refptr<TrackedCallback> callback,
71 const gpu::SyncToken& sync_token,
72 const gfx::Size& size) {
73 if (HasPendingSwap()) {
74 Log(PP_LOGLEVEL_ERROR,
75 "PPB_Graphics3D.SwapBuffers: Plugin attempted swap "
76 "with previous swap still pending.");
77 // Already a pending SwapBuffers that hasn't returned yet.
78 return PP_ERROR_INPROGRESS;
81 swap_callback_ = callback;
82 return DoSwapBuffers(sync_token, size);
85 int32_t PPB_Graphics3D_Shared::GetAttribMaxValue(int32_t attribute,
87 // TODO(alokp): Implement me.
88 LOG(ERROR) << "Method not implemented";
89 return PP_ERROR_FAILED;
92 void* PPB_Graphics3D_Shared::MapTexSubImage2DCHROMIUM(GLenum target,
101 return gles2_impl_->MapTexSubImage2DCHROMIUM(
102 target, level, xoffset, yoffset, width, height, format, type, access);
105 void PPB_Graphics3D_Shared::UnmapTexSubImage2DCHROMIUM(const void* mem) {
106 gles2_impl_->UnmapTexSubImage2DCHROMIUM(mem);
109 gpu::gles2::GLES2Interface* PPB_Graphics3D_Shared::gles2_interface() {
110 return gles2_impl_.get();
113 void PPB_Graphics3D_Shared::SwapBuffersACK(int32_t pp_error) {
114 DCHECK(HasPendingSwap());
115 swap_callback_->Run(pp_error);
118 bool PPB_Graphics3D_Shared::HasPendingSwap() const {
119 return TrackedCallback::IsPending(swap_callback_);
122 bool PPB_Graphics3D_Shared::CreateGLES2Impl(
123 gpu::gles2::GLES2Implementation* share_gles2) {
124 gpu::SharedMemoryLimits limits;
125 gpu::CommandBuffer* command_buffer = GetCommandBuffer();
126 DCHECK(command_buffer);
128 // Create the GLES2 helper, which writes the command buffer protocol.
129 gles2_helper_ = std::make_unique<gpu::gles2::GLES2CmdHelper>(command_buffer);
130 if (gles2_helper_->Initialize(limits.command_buffer_size) !=
131 gpu::ContextResult::kSuccess)
134 // Create a transfer buffer used to copy resources between the renderer
135 // process and the GPU process.
136 transfer_buffer_ = std::make_unique<gpu::TransferBuffer>(gles2_helper_.get());
138 const bool bind_creates_resources = true;
139 const bool lose_context_when_out_of_memory = false;
140 const bool support_client_side_arrays = true;
142 // Create the object exposing the OpenGL API.
143 gles2_impl_ = std::make_unique<gpu::gles2::GLES2Implementation>(
144 gles2_helper_.get(), share_gles2 ? share_gles2->share_group() : nullptr,
145 transfer_buffer_.get(), bind_creates_resources,
146 lose_context_when_out_of_memory, support_client_side_arrays,
149 if (gles2_impl_->Initialize(limits) != gpu::ContextResult::kSuccess)
152 gles2_impl_->TraceBeginCHROMIUM("gpu_toplevel", "PPAPIContext");
157 void PPB_Graphics3D_Shared::DestroyGLES2Impl() {
159 transfer_buffer_.reset();
160 gles2_helper_.reset();