Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: gpu/pgl/pgl.cc

Issue 566021: [GPU] GLES2 lost context recovery (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gpu/pgl/pgl.h ('k') | third_party/npapi/bindings/npapi_extensions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <build/build_config.h> 5 #include <build/build_config.h>
6 6
7 #include "gpu/command_buffer/client/gles2_cmd_helper.h" 7 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
8 #include "gpu/command_buffer/client/gles2_implementation.h" 8 #include "gpu/command_buffer/client/gles2_implementation.h"
9 #include "gpu/command_buffer/client/gles2_lib.h" 9 #include "gpu/command_buffer/client/gles2_lib.h"
10 #include "gpu/command_buffer/common/constants.h"
10 #include "gpu/command_buffer/common/thread_local.h" 11 #include "gpu/command_buffer/common/thread_local.h"
11 #include "gpu/pgl/command_buffer_pepper.h" 12 #include "gpu/pgl/command_buffer_pepper.h"
12 #include "gpu/pgl/pgl.h" 13 #include "gpu/pgl/pgl.h"
13 14
14 namespace { 15 namespace {
15 const int32 kTransferBufferSize = 512 * 1024; 16 const int32 kTransferBufferSize = 512 * 1024;
16 17
17 class PGLContextImpl { 18 class PGLContextImpl {
18 public: 19 public:
19 PGLContextImpl(NPP npp, 20 PGLContextImpl(NPP npp,
20 NPDevice* device, 21 NPDevice* device,
21 NPDeviceContext3D* device_context); 22 NPDeviceContext3D* device_context);
22 ~PGLContextImpl(); 23 ~PGLContextImpl();
23 24
24 // Initlaize a PGL context with a transfer buffer of a particular size. 25 // Initlaize a PGL context with a transfer buffer of a particular size.
25 bool Initialize(int32 transfer_buffer_size); 26 PGLBoolean Initialize(int32 transfer_buffer_size);
26 27
27 // Destroy all resources associated with the PGL context. 28 // Destroy all resources associated with the PGL context.
28 void Destroy(); 29 void Destroy();
29 30
30 // Make a PGL context current for the calling thread. 31 // Make a PGL context current for the calling thread.
31 static bool MakeCurrent(PGLContextImpl* pgl_context); 32 static PGLBoolean MakeCurrent(PGLContextImpl* pgl_context);
32 33
33 // Display all content rendered since last call to SwapBuffers. 34 // Display all content rendered since last call to SwapBuffers.
34 bool SwapBuffers(); 35 PGLBoolean SwapBuffers();
36
37 // Get the current error code.
38 PGLInt GetError();
35 39
36 private: 40 private:
37 PGLContextImpl(const PGLContextImpl&); 41 PGLContextImpl(const PGLContextImpl&);
38 void operator=(const PGLContextImpl&); 42 void operator=(const PGLContextImpl&);
39 43
40 NPP npp_; 44 NPP npp_;
41 NPDevice* device_; 45 NPDevice* device_;
42 NPDeviceContext3D* device_context_; 46 NPDeviceContext3D* device_context_;
43 CommandBufferPepper* command_buffer_; 47 CommandBufferPepper* command_buffer_;
44 gpu::gles2::GLES2CmdHelper* gles2_helper_; 48 gpu::gles2::GLES2CmdHelper* gles2_helper_;
(...skipping 12 matching lines...) Expand all
57 command_buffer_(NULL), 61 command_buffer_(NULL),
58 gles2_helper_(NULL), 62 gles2_helper_(NULL),
59 transfer_buffer_id_(0), 63 transfer_buffer_id_(0),
60 gles2_implementation_(NULL) { 64 gles2_implementation_(NULL) {
61 } 65 }
62 66
63 PGLContextImpl::~PGLContextImpl() { 67 PGLContextImpl::~PGLContextImpl() {
64 Destroy(); 68 Destroy();
65 } 69 }
66 70
67 bool PGLContextImpl::Initialize(int32 transfer_buffer_size) { 71 PGLBoolean PGLContextImpl::Initialize(int32 transfer_buffer_size) {
68 // Create and initialize the objects required to issue GLES2 calls. 72 // Create and initialize the objects required to issue GLES2 calls.
69 command_buffer_ = new CommandBufferPepper( 73 command_buffer_ = new CommandBufferPepper(
70 npp_, device_, device_context_); 74 npp_, device_, device_context_);
71 gles2_helper_ = new gpu::gles2::GLES2CmdHelper(command_buffer_); 75 gles2_helper_ = new gpu::gles2::GLES2CmdHelper(command_buffer_);
72 if (gles2_helper_->Initialize()) { 76 if (gles2_helper_->Initialize()) {
73 transfer_buffer_id_ = 77 transfer_buffer_id_ =
74 command_buffer_->CreateTransferBuffer(kTransferBufferSize); 78 command_buffer_->CreateTransferBuffer(kTransferBufferSize);
75 gpu::Buffer transfer_buffer = 79 gpu::Buffer transfer_buffer =
76 command_buffer_->GetTransferBuffer(transfer_buffer_id_); 80 command_buffer_->GetTransferBuffer(transfer_buffer_id_);
77 if (transfer_buffer.ptr) { 81 if (transfer_buffer.ptr) {
78 gles2_implementation_ = new gpu::gles2::GLES2Implementation( 82 gles2_implementation_ = new gpu::gles2::GLES2Implementation(
79 gles2_helper_, 83 gles2_helper_,
80 transfer_buffer.size, 84 transfer_buffer.size,
81 transfer_buffer.ptr, 85 transfer_buffer.ptr,
82 transfer_buffer_id_); 86 transfer_buffer_id_);
83 return true; 87 return PGL_TRUE;
84 } 88 }
85 } 89 }
86 90
87 // Tear everything down if initialization failed. 91 // Tear everything down if initialization failed.
88 Destroy(); 92 Destroy();
89 return false; 93 return PGL_FALSE;
90 } 94 }
91 95
92 void PGLContextImpl::Destroy() { 96 void PGLContextImpl::Destroy() {
93 delete gles2_implementation_; 97 delete gles2_implementation_;
94 gles2_implementation_ = NULL; 98 gles2_implementation_ = NULL;
95 99
96 if (command_buffer_ && transfer_buffer_id_ != 0) { 100 if (command_buffer_ && transfer_buffer_id_ != 0) {
97 command_buffer_->DestroyTransferBuffer(transfer_buffer_id_); 101 command_buffer_->DestroyTransferBuffer(transfer_buffer_id_);
98 transfer_buffer_id_ = 0; 102 transfer_buffer_id_ = 0;
99 } 103 }
100 104
101 delete gles2_helper_; 105 delete gles2_helper_;
102 gles2_helper_ = NULL; 106 gles2_helper_ = NULL;
103 107
104 delete command_buffer_; 108 delete command_buffer_;
105 command_buffer_ = NULL; 109 command_buffer_ = NULL;
106 } 110 }
107 111
108 bool PGLContextImpl::MakeCurrent(PGLContextImpl* pgl_context) { 112 PGLBoolean PGLContextImpl::MakeCurrent(PGLContextImpl* pgl_context) {
109 if (!g_pgl_context_key) 113 if (!g_pgl_context_key)
110 return false; 114 return PGL_FALSE;
111 115
112 gpu::ThreadLocalSetValue(g_pgl_context_key, pgl_context); 116 gpu::ThreadLocalSetValue(g_pgl_context_key, pgl_context);
113 if (pgl_context) 117 if (pgl_context) {
114 gles2::SetGLContext(pgl_context->gles2_implementation_); 118 gles2::SetGLContext(pgl_context->gles2_implementation_);
115 else 119
120 // Don't request latest error status from service. Just use the locally
121 // cached information from the last flush.
122 // TODO(apatrick): I'm not sure if this should actually change the
123 // current context if it fails. For now it gets changed even if it fails
124 // becuase making GL calls with a NULL context crashes.
125 if (pgl_context->device_context_->error != NPDeviceContext3DError_NoError)
126 return PGL_FALSE;
127 }
128 else {
116 gles2::SetGLContext(NULL); 129 gles2::SetGLContext(NULL);
130 }
117 131
118 return true; 132 return PGL_TRUE;
119 } 133 }
120 134
121 bool PGLContextImpl::SwapBuffers() { 135 PGLBoolean PGLContextImpl::SwapBuffers() {
136 // Don't request latest error status from service. Just use the locally cached
137 // information from the last flush.
138 if (device_context_->error != NPDeviceContext3DError_NoError)
139 return PGL_FALSE;
140
122 gles2_implementation_->SwapBuffers(); 141 gles2_implementation_->SwapBuffers();
123 return true; 142 return PGL_TRUE;
143 }
144
145 PGLInt PGLContextImpl::GetError() {
146 gpu::CommandBuffer::State state = command_buffer_->GetState();
147 if (state.error == gpu::error::kNoError) {
148 return PGL_SUCCESS;
149 } else {
150 // All command buffer errors are unrecoverable. The error is treated as a
151 // lost context: destroy the context and create another one.
152 return PGL_CONTEXT_LOST;
153 }
124 } 154 }
125 } // namespace anonymous 155 } // namespace anonymous
126 156
127 extern "C" { 157 extern "C" {
128 158
129 PGLBoolean pglInitialize() { 159 PGLBoolean pglInitialize() {
130 if (g_pgl_context_key) 160 if (g_pgl_context_key)
131 return true; 161 return PGL_TRUE;
132 162
133 gles2::Initialize(); 163 gles2::Initialize();
134 g_pgl_context_key = gpu::ThreadLocalAlloc(); 164 g_pgl_context_key = gpu::ThreadLocalAlloc();
135 return true; 165 return PGL_TRUE;
136 } 166 }
137 167
138 PGLBoolean pglTerminate() { 168 PGLBoolean pglTerminate() {
139 if (!g_pgl_context_key) 169 if (!g_pgl_context_key)
140 return true; 170 return PGL_TRUE;
141 171
142 gpu::ThreadLocalFree(g_pgl_context_key); 172 gpu::ThreadLocalFree(g_pgl_context_key);
173 g_pgl_context_key = 0;
174
143 gles2::Terminate(); 175 gles2::Terminate();
144 return true; 176 return PGL_TRUE;
145 } 177 }
146 178
147 PGLContext pglCreateContext(NPP npp, 179 PGLContext pglCreateContext(NPP npp,
148 NPDevice* device, 180 NPDevice* device,
149 NPDeviceContext3D* device_context) { 181 NPDeviceContext3D* device_context) {
150 if (!g_pgl_context_key) 182 if (!g_pgl_context_key)
151 return NULL; 183 return NULL;
152 184
153 PGLContextImpl* pgl_context = new PGLContextImpl( 185 PGLContextImpl* pgl_context = new PGLContextImpl(
154 npp, device, device_context); 186 npp, device, device_context);
(...skipping 13 matching lines...) Expand all
168 if (!g_pgl_context_key) 200 if (!g_pgl_context_key)
169 return NULL; 201 return NULL;
170 202
171 return static_cast<PGLContext>(gpu::ThreadLocalGetValue(g_pgl_context_key)); 203 return static_cast<PGLContext>(gpu::ThreadLocalGetValue(g_pgl_context_key));
172 } 204 }
173 205
174 PGLBoolean pglSwapBuffers(void) { 206 PGLBoolean pglSwapBuffers(void) {
175 PGLContextImpl* context = static_cast<PGLContextImpl*>( 207 PGLContextImpl* context = static_cast<PGLContextImpl*>(
176 pglGetCurrentContext()); 208 pglGetCurrentContext());
177 if (!context) 209 if (!context)
178 return false; 210 return PGL_FALSE;
179 211
180 return context->SwapBuffers(); 212 return context->SwapBuffers();
181 } 213 }
182 214
183 PGLBoolean pglDestroyContext(PGLContext pgl_context) { 215 PGLBoolean pglDestroyContext(PGLContext pgl_context) {
184 if (!g_pgl_context_key) 216 if (!g_pgl_context_key)
185 return NULL; 217 return PGL_FALSE;
186 218
187 if (!pgl_context) 219 if (!pgl_context)
188 return false; 220 return PGL_FALSE;
189 221
190 if (pgl_context == pglGetCurrentContext()) 222 if (pgl_context == pglGetCurrentContext())
191 pglMakeCurrent(NULL); 223 pglMakeCurrent(NULL);
192 224
193 delete static_cast<PGLContextImpl*>(pgl_context); 225 delete static_cast<PGLContextImpl*>(pgl_context);
194 return true; 226 return PGL_TRUE;
195 } 227 }
196 228
229 PGLInt pglGetError() {
230 if (!g_pgl_context_key)
231 return PGL_NOT_INITIALIZED;
232
233 PGLContextImpl* context = static_cast<PGLContextImpl*>(
234 pglGetCurrentContext());
235 if (!context)
236 return PGL_BAD_CONTEXT;
237
238 return context->GetError();
239 }
197 } // extern "C" 240 } // extern "C"
OLDNEW
« no previous file with comments | « gpu/pgl/pgl.h ('k') | third_party/npapi/bindings/npapi_extensions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698