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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 1136006: Calling OpenGL from the renderer process. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 9 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "gpu/command_buffer/service/gles2_cmd_decoder.h" 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <vector> 10 #include <vector>
11 #include <string> 11 #include <string>
12 #include <map> 12 #include <map>
13 #include <build/build_config.h> // NOLINT 13 #include <build/build_config.h> // NOLINT
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/linked_ptr.h" 15 #include "base/linked_ptr.h"
16 #include "base/scoped_ptr.h" 16 #include "base/scoped_ptr.h"
17 #include "base/weak_ptr.h"
17 #define GLES2_GPU_SERVICE 1 18 #define GLES2_GPU_SERVICE 1
18 #include "gpu/command_buffer/common/gles2_cmd_format.h" 19 #include "gpu/command_buffer/common/gles2_cmd_format.h"
19 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 20 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
20 #include "gpu/command_buffer/service/buffer_manager.h" 21 #include "gpu/command_buffer/service/buffer_manager.h"
21 #include "gpu/command_buffer/service/cmd_buffer_engine.h" 22 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
22 #include "gpu/command_buffer/service/context_group.h" 23 #include "gpu/command_buffer/service/context_group.h"
23 #include "gpu/command_buffer/service/framebuffer_manager.h" 24 #include "gpu/command_buffer/service/framebuffer_manager.h"
24 #include "gpu/command_buffer/service/gl_utils.h" 25 #include "gpu/command_buffer/service/gl_utils.h"
25 #include "gpu/command_buffer/service/gles2_cmd_validation.h" 26 #include "gpu/command_buffer/service/gles2_cmd_validation.h"
26 #include "gpu/command_buffer/service/id_manager.h" 27 #include "gpu/command_buffer/service/id_manager.h"
27 #include "gpu/command_buffer/service/program_manager.h" 28 #include "gpu/command_buffer/service/program_manager.h"
28 #include "gpu/command_buffer/service/renderbuffer_manager.h" 29 #include "gpu/command_buffer/service/renderbuffer_manager.h"
29 #include "gpu/command_buffer/service/shader_manager.h" 30 #include "gpu/command_buffer/service/shader_manager.h"
30 #include "gpu/command_buffer/service/texture_manager.h" 31 #include "gpu/command_buffer/service/texture_manager.h"
31 #if defined(UNIT_TEST) 32 #if defined(UNIT_TEST)
32 #elif defined(OS_LINUX) 33 #elif defined(OS_LINUX)
33 // XWindowWrapper is stubbed out for unit-tests. 34 // XWindowWrapper is stubbed out for unit-tests.
34 #include "gpu/command_buffer/service/x_utils.h" 35 #include "gpu/command_buffer/service/x_utils.h"
35 #elif defined(OS_MACOSX) 36 #elif defined(OS_MACOSX)
36 #include "app/surface/accelerated_surface_mac.h" 37 #include "app/surface/accelerated_surface_mac.h"
37 #endif 38 #endif
38 39
40 #if !defined(GL_DEPTH24_STENCIL8)
41 #define GL_DEPTH24_STENCIL8 0x88F0
42 #endif
43
39 namespace gpu { 44 namespace gpu {
40 namespace gles2 { 45 namespace gles2 {
41 46
47 class GLES2DecoderImpl;
48
42 // Check that certain assumptions the code makes are true. There are places in 49 // Check that certain assumptions the code makes are true. There are places in
43 // the code where shared memory is passed direclty to GL. Example, glUniformiv, 50 // the code where shared memory is passed direclty to GL. Example, glUniformiv,
44 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe 51 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
45 // a few others) are 32bits. If they are not 32bits the code will have to change 52 // a few others) are 32bits. If they are not 32bits the code will have to change
46 // to call those GL functions with service side memory and then copy the results 53 // to call those GL functions with service side memory and then copy the results
47 // to shared memory, converting the sizes. 54 // to shared memory, converting the sizes.
48 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT 55 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
49 GLint_not_same_size_as_uint32); 56 GLint_not_same_size_as_uint32);
50 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT 57 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
51 GLint_not_same_size_as_uint32); 58 GLint_not_same_size_as_uint32);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 const CommandInfo g_command_info[] = { 107 const CommandInfo g_command_info[] = {
101 #define GLES2_CMD_OP(name) { \ 108 #define GLES2_CMD_OP(name) { \
102 name::kArgFlags, \ 109 name::kArgFlags, \
103 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ 110 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
104 111
105 GLES2_COMMAND_LIST(GLES2_CMD_OP) 112 GLES2_COMMAND_LIST(GLES2_CMD_OP)
106 113
107 #undef GLES2_CMD_OP 114 #undef GLES2_CMD_OP
108 }; 115 };
109 116
117 // This class prevents any GL errors that occur when it is in scope from
118 // being reported to the client.
119 class ScopedGLErrorSuppressor {
120 public:
121 explicit ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder);
122 ~ScopedGLErrorSuppressor();
123 private:
124 GLES2DecoderImpl* decoder_;
125 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
126 };
127
128 // Temporarily changes a decoder's bound 2D texture and restore it when this
129 // object goes out of scope. Also temporarily switches to using active texture
130 // unit zero in case the client has changed that to something invalid.
131 class ScopedTexture2DBinder {
132 public:
133 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
134 ~ScopedTexture2DBinder();
135
136 private:
137 GLES2DecoderImpl* decoder_;
138 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
139 };
140
141 // Temporarily changes a decoder's bound render buffer and restore it when this
142 // object goes out of scope.
143 class ScopedRenderBufferBinder {
144 public:
145 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
146 ~ScopedRenderBufferBinder();
147
148 private:
149 GLES2DecoderImpl* decoder_;
150 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
151 };
152
153 // Temporarily changes a decoder's bound frame buffer and restore it when this
154 // object goes out of scope.
155 class ScopedFrameBufferBinder {
156 public:
157 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
158 ~ScopedFrameBufferBinder();
159
160 private:
161 GLES2DecoderImpl* decoder_;
162 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
163 };
164
165 // Encapsulates an OpenGL texture.
166 class Texture {
167 public:
168 explicit Texture(GLES2DecoderImpl* decoder);
169 ~Texture();
170
171 // Create a new render texture.
172 void Create();
173
174 // Set the initial size and format of a render texture or resize it.
175 bool AllocateStorage(const gfx::Size& size);
176
177 // Copy the contents of the currently bound frame buffer.
178 void Copy(const gfx::Size& size);
179
180 // Destroy the render texture. This must be explicitly called before
181 // destroying this object.
182 void Destroy();
183
184 GLuint id() const {
185 return id_;
186 }
187
188 private:
189 GLES2DecoderImpl* decoder_;
190 GLuint id_;
191 DISALLOW_COPY_AND_ASSIGN(Texture);
192 };
193
194 // Encapsulates an OpenGL render buffer of any format.
195 class RenderBuffer {
196 public:
197 explicit RenderBuffer(GLES2DecoderImpl* decoder);
198 ~RenderBuffer();
199
200 // Create a new render buffer.
201 void Create();
202
203 // Set the initial size and format of a render buffer or resize it.
204 bool AllocateStorage(const gfx::Size& size, GLenum format);
205
206 // Destroy the render buffer. This must be explicitly called before destroying
207 // this object.
208 void Destroy();
209
210 GLuint id() const {
211 return id_;
212 }
213
214 private:
215 GLES2DecoderImpl* decoder_;
216 GLuint id_;
217 DISALLOW_COPY_AND_ASSIGN(RenderBuffer);
218 };
219
220 // Encapsulates an OpenGL frame buffer.
221 class FrameBuffer {
222 public:
223 explicit FrameBuffer(GLES2DecoderImpl* decoder);
224 ~FrameBuffer();
225
226 // Create a new frame buffer.
227 void Create();
228
229 // Attach a color render buffer to a frame buffer.
230 void AttachRenderTexture(Texture* texture);
231
232 // Attach a depth stencil render buffer to a frame buffer. Note that
233 // this unbinds any currently bound frame buffer.
234 void AttachDepthStencilRenderBuffer(RenderBuffer* render_buffer);
235
236 // Clear the given attached buffers.
237 void Clear(GLbitfield buffers);
238
239 // Destroy the frame buffer. This must be explicitly called before destroying
240 // this object.
241 void Destroy();
242
243 // See glCheckFramebufferStatusEXT.
244 GLenum CheckStatus();
245
246 GLuint id() const {
247 return id_;
248 }
249
250 private:
251 GLES2DecoderImpl* decoder_;
252 GLuint id_;
253 DISALLOW_COPY_AND_ASSIGN(FrameBuffer);
254 };
110 // } // anonymous namespace. 255 // } // anonymous namespace.
111 256
112 GLES2Decoder::GLES2Decoder(ContextGroup* group) 257 GLES2Decoder::GLES2Decoder(ContextGroup* group)
113 : group_(group), 258 : group_(group),
114 #if defined(UNIT_TEST) 259 #if defined(UNIT_TEST)
115 debug_(false) { 260 debug_(false) {
116 #elif defined(OS_LINUX) 261 #elif defined(OS_LINUX)
117 debug_(false), 262 debug_(false),
118 window_(NULL) { 263 window_(NULL) {
119 #elif defined(OS_WIN) 264 #elif defined(OS_WIN)
120 debug_(false), 265 debug_(false),
121 hwnd_(NULL) { 266 hwnd_(NULL) {
122 #else 267 #else
123 debug_(false) { 268 debug_(false) {
124 #endif 269 #endif
125 } 270 }
126 271
127 GLES2Decoder::~GLES2Decoder() { 272 GLES2Decoder::~GLES2Decoder() {
128 } 273 }
129 274
130 // This class implements GLES2Decoder so we don't have to expose all the GLES2 275 // This class implements GLES2Decoder so we don't have to expose all the GLES2
131 // cmd stuff to outside this class. 276 // cmd stuff to outside this class.
132 class GLES2DecoderImpl : public GLES2Decoder { 277 class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
278 public GLES2Decoder {
133 public: 279 public:
134 explicit GLES2DecoderImpl(ContextGroup* group); 280 explicit GLES2DecoderImpl(ContextGroup* group);
135 281
136 // Info about Vertex Attributes. This is used to track what the user currently 282 // Info about Vertex Attributes. This is used to track what the user currently
137 // has bound on each Vertex Attribute so that checking can be done at 283 // has bound on each Vertex Attribute so that checking can be done at
138 // glDrawXXX time. 284 // glDrawXXX time.
139 class VertexAttribInfo { 285 class VertexAttribInfo {
140 public: 286 public:
141 VertexAttribInfo() 287 VertexAttribInfo()
142 : enabled_(false), 288 : enabled_(false),
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 349
204 // Overridden from AsyncAPIInterface. 350 // Overridden from AsyncAPIInterface.
205 virtual Error DoCommand(unsigned int command, 351 virtual Error DoCommand(unsigned int command,
206 unsigned int arg_count, 352 unsigned int arg_count,
207 const void* args); 353 const void* args);
208 354
209 // Overridden from AsyncAPIInterface. 355 // Overridden from AsyncAPIInterface.
210 virtual const char* GetCommandName(unsigned int command_id) const; 356 virtual const char* GetCommandName(unsigned int command_id) const;
211 357
212 // Overridden from GLES2Decoder. 358 // Overridden from GLES2Decoder.
213 virtual bool Initialize(); 359 virtual bool Initialize(GLES2Decoder* parent,
360 const gfx::Size& size,
361 uint32 parent_client_texture_id);
214 virtual void Destroy(); 362 virtual void Destroy();
363 virtual void ResizeOffscreenFrameBuffer(const gfx::Size& size);
215 virtual bool MakeCurrent(); 364 virtual bool MakeCurrent();
216 virtual uint32 GetServiceIdForTesting(uint32 client_id); 365 virtual uint32 GetServiceIdForTesting(uint32 client_id);
217 virtual GLES2Util* GetGLES2Util() { return &util_; } 366 virtual GLES2Util* GetGLES2Util() { return &util_; }
218 367
219 #if defined(OS_MACOSX) 368 #if defined(OS_MACOSX)
220 // Overridden from GLES2Decoder. 369 // Overridden from GLES2Decoder.
221 370
222 // The recommended usage is to call SetWindowSizeForIOSurface() first, and if 371 // The recommended usage is to call SetWindowSizeForIOSurface() first, and if
223 // that returns 0, try calling SetWindowSizeForTransportDIB(). A return value 372 // that returns 0, try calling SetWindowSizeForTransportDIB(). A return value
224 // of 0 from SetWindowSizeForIOSurface() might mean the IOSurface API is not 373 // of 0 from SetWindowSizeForIOSurface() might mean the IOSurface API is not
225 // available, which is true if you are not running on Max OS X 10.6 or later. 374 // available, which is true if you are not running on Max OS X 10.6 or later.
226 // If SetWindowSizeForTransportDIB() also returns a NULL handle, then an 375 // If SetWindowSizeForTransportDIB() also returns a NULL handle, then an
227 // error has occured. 376 // error has occured.
228 virtual uint64 SetWindowSizeForIOSurface(int32 width, int32 height); 377 virtual uint64 SetWindowSizeForIOSurface(int32 width, int32 height);
229 virtual TransportDIB::Handle SetWindowSizeForTransportDIB(int32 width, 378 virtual TransportDIB::Handle SetWindowSizeForTransportDIB(int32 width,
230 int32 height); 379 int32 height);
231 // |allocator| sends a message to the renderer asking for a new 380 // |allocator| sends a message to the renderer asking for a new
232 // TransportDIB big enough to hold the rendered bits. The parameters to the 381 // TransportDIB big enough to hold the rendered bits. The parameters to the
233 // call back are the size of the DIB and the handle (filled in on return). 382 // call back are the size of the DIB and the handle (filled in on return).
234 virtual void SetTransportDIBAllocAndFree( 383 virtual void SetTransportDIBAllocAndFree(
235 Callback2<size_t, TransportDIB::Handle*>::Type* allocator, 384 Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
236 Callback1<TransportDIB::Id>::Type* deallocator); 385 Callback1<TransportDIB::Id>::Type* deallocator);
237 #endif 386 #endif
238 387
239 virtual void SetSwapBuffersCallback(Callback0::Type* callback); 388 virtual void SetSwapBuffersCallback(Callback0::Type* callback);
240 389
241 private: 390 private:
391 friend class ScopedGLErrorSuppressor;
392 friend class ScopedTexture2DBinder;
393 friend class ScopedFrameBufferBinder;
394 friend class ScopedRenderBufferBinder;
395 friend class RenderBuffer;
396 friend class FrameBuffer;
397
242 // State associated with each texture unit. 398 // State associated with each texture unit.
243 struct TextureUnit { 399 struct TextureUnit {
244 TextureUnit() : bind_target(GL_TEXTURE_2D) { } 400 TextureUnit() : bind_target(GL_TEXTURE_2D) { }
245 401
246 // The last target that was bound to this texture unit. 402 // The last target that was bound to this texture unit.
247 GLenum bind_target; 403 GLenum bind_target;
248 404
249 // texture currently bound to this unit's GL_TEXTURE_2D with glBindTexture 405 // texture currently bound to this unit's GL_TEXTURE_2D with glBindTexture
250 TextureManager::TextureInfo::Ref bound_texture_2d; 406 TextureManager::TextureInfo::Ref bound_texture_2d;
251 407
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 458
303 #if defined(OS_WIN) 459 #if defined(OS_WIN)
304 static bool InitializeOneOff(bool anti_aliased); 460 static bool InitializeOneOff(bool anti_aliased);
305 #endif 461 #endif
306 462
307 463
308 bool InitPlatformSpecific(); 464 bool InitPlatformSpecific();
309 static bool InitGlew(); 465 static bool InitGlew();
310 void DestroyPlatformSpecific(); 466 void DestroyPlatformSpecific();
311 467
468 bool UpdateOffscreenFrameBufferSize();
469
312 // Template to help call glGenXXX functions. 470 // Template to help call glGenXXX functions.
313 template <void gl_gen_function(GLES2DecoderImpl*, GLsizei, GLuint*)> 471 template <void gl_gen_function(GLES2DecoderImpl*, GLsizei, GLuint*)>
314 bool GenGLObjects(GLsizei n, const GLuint* client_ids) { 472 bool GenGLObjects(GLsizei n, const GLuint* client_ids) {
315 DCHECK_GE(n, 0); 473 DCHECK_GE(n, 0);
316 if (!ValidateIdsAreUnused(n, client_ids)) { 474 if (!ValidateIdsAreUnused(n, client_ids)) {
317 return false; 475 return false;
318 } 476 }
319 scoped_array<GLuint>temp(new GLuint[n]); 477 scoped_array<GLuint>temp(new GLuint[n]);
320 gl_gen_function(this, n, temp.get()); 478 gl_gen_function(this, n, temp.get());
321 return RegisterObjects(n, client_ids, temp.get()); 479 return RegisterObjects(n, client_ids, temp.get());
(...skipping 14 matching lines...) Expand all
336 494
337 // Register client ids with generated service ids. 495 // Register client ids with generated service ids.
338 bool RegisterObjects( 496 bool RegisterObjects(
339 GLsizei n, const GLuint* client_ids, const GLuint* service_ids); 497 GLsizei n, const GLuint* client_ids, const GLuint* service_ids);
340 498
341 // Unregisters client ids with service ids. 499 // Unregisters client ids with service ids.
342 void UnregisterObjects( 500 void UnregisterObjects(
343 GLsizei n, const GLuint* client_ids, GLuint* service_ids); 501 GLsizei n, const GLuint* client_ids, GLuint* service_ids);
344 502
345 // Creates a TextureInfo for the given texture. 503 // Creates a TextureInfo for the given texture.
346 void CreateTextureInfo(GLuint texture) { 504 TextureManager::TextureInfo* CreateTextureInfo(GLuint texture) {
347 texture_manager()->CreateTextureInfo(texture); 505 return texture_manager()->CreateTextureInfo(texture);
348 } 506 }
349 507
350 // Gets the texture info for the given texture. Returns NULL if none exists. 508 // Gets the texture info for the given texture. Returns NULL if none exists.
351 TextureManager::TextureInfo* GetTextureInfo(GLuint texture) { 509 TextureManager::TextureInfo* GetTextureInfo(GLuint texture) {
352 TextureManager::TextureInfo* info = 510 TextureManager::TextureInfo* info =
353 texture_manager()->GetTextureInfo(texture); 511 texture_manager()->GetTextureInfo(texture);
354 return (info && !info->IsDeleted()) ? info : NULL; 512 return (info && !info->IsDeleted()) ? info : NULL;
355 } 513 }
356 514
357 // Deletes the texture info for the given texture. 515 // Deletes the texture info for the given texture.
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 void DoGetShaderSource( 712 void DoGetShaderSource(
555 GLuint shader, GLsizei bufsize, GLsizei* length, char* dst); 713 GLuint shader, GLsizei bufsize, GLsizei* length, char* dst);
556 714
557 // Wrapper for glLinkProgram 715 // Wrapper for glLinkProgram
558 void DoLinkProgram(GLuint program); 716 void DoLinkProgram(GLuint program);
559 717
560 // Wrapper for glRenderbufferStorage. 718 // Wrapper for glRenderbufferStorage.
561 void DoRenderbufferStorage( 719 void DoRenderbufferStorage(
562 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); 720 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
563 721
564 // Swaps the buffers (copies/renders to the current window).
565 void DoSwapBuffers();
566
567 // Wrappers for glTexParameter functions. 722 // Wrappers for glTexParameter functions.
568 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param); 723 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
569 void DoTexParameteri(GLenum target, GLenum pname, GLint param); 724 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
570 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params); 725 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
571 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params); 726 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
572 727
573 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2 728 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
574 // spec only these 2 functions can be used to set sampler uniforms. 729 // spec only these 2 functions can be used to set sampler uniforms.
575 void DoUniform1i(GLint location, GLint v0); 730 void DoUniform1i(GLint location, GLint v0);
576 void DoUniform1iv(GLint location, GLsizei count, const GLint *value); 731 void DoUniform1iv(GLint location, GLsizei count, const GLint *value);
577 732
578 // Wrapper for glUseProgram 733 // Wrapper for glUseProgram
579 void DoUseProgram(GLuint program); 734 void DoUseProgram(GLuint program);
580 735
581 // Gets the GLError through our wrapper. 736 // Gets the GLError through our wrapper.
582 GLenum GetGLError(); 737 GLenum GetGLError();
583 738
584 // Sets our wrapper for the GLError. 739 // Sets our wrapper for the GLError.
585 void SetGLError(GLenum error); 740 void SetGLError(GLenum error);
586 741
587 // Copies the real GL errors to the wrapper. This is so we can 742 // Copies the real GL errors to the wrapper. This is so we can
588 // make sure there are no native GL errors before calling some GL function 743 // make sure there are no native GL errors before calling some GL function
589 // so that on return we know any error generated was for that specific 744 // so that on return we know any error generated was for that specific
590 // command. 745 // command.
591 void CopyRealGLErrorsToWrapper(); 746 void CopyRealGLErrorsToWrapper();
592 747
748 // Clear all real GL errors. This is to prevent the client from seeing any
749 // errors caused by GL calls that it was not responsible for issuing.
750 void ClearRealGLErrors();
751
593 // Checks if the current program and vertex attributes are valid for drawing. 752 // Checks if the current program and vertex attributes are valid for drawing.
594 bool IsDrawValid(GLuint max_vertex_accessed); 753 bool IsDrawValid(GLuint max_vertex_accessed);
595 754
596 void SetBlackTextureForNonRenderableTextures( 755 void SetBlackTextureForNonRenderableTextures(
597 bool* has_non_renderable_textures); 756 bool* has_non_renderable_textures);
598 void RestoreStateForNonRenderableTextures(); 757 void RestoreStateForNonRenderableTextures();
599 758
600 // Gets the buffer id for a given target. 759 // Gets the buffer id for a given target.
601 BufferManager::BufferInfo* GetBufferInfoForTarget(GLenum target) { 760 BufferManager::BufferInfo* GetBufferInfoForTarget(GLenum target) {
602 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); 761 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 // typesafe way. 806 // typesafe way.
648 #define GLES2_CMD_OP(name) \ 807 #define GLES2_CMD_OP(name) \
649 Error Handle ## name( \ 808 Error Handle ## name( \
650 uint32 immediate_data_size, \ 809 uint32 immediate_data_size, \
651 const gles2::name& args); \ 810 const gles2::name& args); \
652 811
653 GLES2_COMMAND_LIST(GLES2_CMD_OP) 812 GLES2_COMMAND_LIST(GLES2_CMD_OP)
654 813
655 #undef GLES2_CMD_OP 814 #undef GLES2_CMD_OP
656 815
816 // A parent decoder can access this decoders saved offscreen frame buffer.
817 // The parent pointer is reset if the parent is destroyed.
818 base::WeakPtr<GLES2DecoderImpl> parent_;
819
820 // Width and height to which an offscreen frame buffer should be resized on
821 // the next call to SwapBuffers.
822 gfx::Size pending_size_;
823
824 // Width and height of a decoder that renders to an offscreen frame buffer.
825 gfx::Size current_size_;
826
657 // Current GL error bits. 827 // Current GL error bits.
658 uint32 error_bits_; 828 uint32 error_bits_;
659 829
660 // Util to help with GL. 830 // Util to help with GL.
661 GLES2Util util_; 831 GLES2Util util_;
662 832
663 // pack alignment as last set by glPixelStorei 833 // pack alignment as last set by glPixelStorei
664 GLint pack_alignment_; 834 GLint pack_alignment_;
665 835
666 // unpack alignment as last set by glPixelStorei 836 // unpack alignment as last set by glPixelStorei
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 static int pixel_format_; 877 static int pixel_format_;
708 HDC gl_device_context_; 878 HDC gl_device_context_;
709 HGLRC gl_context_; 879 HGLRC gl_context_;
710 HPBUFFERARB pbuffer_; 880 HPBUFFERARB pbuffer_;
711 #elif defined(OS_MACOSX) 881 #elif defined(OS_MACOSX)
712 AcceleratedSurface surface_; 882 AcceleratedSurface surface_;
713 #endif 883 #endif
714 884
715 bool anti_aliased_; 885 bool anti_aliased_;
716 886
887 // The offscreen frame buffer that the client renders to.
888 scoped_ptr<FrameBuffer> offscreen_target_frame_buffer_;
889 scoped_ptr<Texture> offscreen_target_color_texture_;
890 scoped_ptr<RenderBuffer> offscreen_target_depth_stencil_render_buffer_;
891
892 // The copy that is saved when SwapBuffers is called.
893 scoped_ptr<Texture> offscreen_saved_color_texture_;
894
895 // A frame buffer used for rendering to render textures and render buffers
896 // without concern about any state the client might have changed on the frame
897 // buffers it has access to.
898 scoped_ptr<FrameBuffer> temporary_frame_buffer_;
899
717 scoped_ptr<Callback0::Type> swap_buffers_callback_; 900 scoped_ptr<Callback0::Type> swap_buffers_callback_;
718 901
719 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); 902 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
720 }; 903 };
721 904
905 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder)
906 : decoder_(decoder) {
907 decoder_->CopyRealGLErrorsToWrapper();
908 }
909
910 ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
911 decoder_->ClearRealGLErrors();
912 }
913
914 ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
915 GLuint id)
916 : decoder_(decoder) {
917 ScopedGLErrorSuppressor suppressor(decoder_);
918
919 // TODO(apatrick): Check if there are any other states that need to be reset
920 // before binding a new texture.
921 glActiveTexture(GL_TEXTURE0);
922 glBindTexture(GL_TEXTURE_2D, id);
923 }
924
925 ScopedTexture2DBinder::~ScopedTexture2DBinder() {
926 ScopedGLErrorSuppressor suppressor(decoder_);
927 GLES2DecoderImpl::TextureUnit& info = decoder_->texture_units_[0];
928 GLuint last_id;
929 if (info.bound_texture_2d)
930 last_id = info.bound_texture_2d->texture_id();
931 else
932 last_id = 0;
933
934 glBindTexture(GL_TEXTURE_2D, last_id);
935 glActiveTexture(GL_TEXTURE0 + decoder_->active_texture_unit_);
936 }
937
938 ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
939 GLuint id)
940 : decoder_(decoder) {
941 ScopedGLErrorSuppressor suppressor(decoder_);
942 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
943 }
944
945 ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
946 ScopedGLErrorSuppressor suppressor(decoder_);
947 glBindRenderbufferEXT(GL_RENDERBUFFER, decoder_->bound_renderbuffer_);
948 }
949
950 ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
951 GLuint id)
952 : decoder_(decoder) {
953 ScopedGLErrorSuppressor suppressor(decoder_);
954 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
955 }
956
957 ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
958 ScopedGLErrorSuppressor suppressor(decoder_);
959 if (decoder_->bound_framebuffer_ == 0 &&
960 decoder_->offscreen_target_frame_buffer_.get()) {
961 glBindFramebufferEXT(GL_FRAMEBUFFER,
962 decoder_->offscreen_target_frame_buffer_->id());
963 } else {
964 glBindFramebufferEXT(GL_FRAMEBUFFER, decoder_->bound_framebuffer_);
965 }
966 }
967
968 Texture::Texture(GLES2DecoderImpl* decoder)
969 : decoder_(decoder),
970 id_(0) {
971 }
972
973 Texture::~Texture() {
974 // This does not destroy the render texture because that would require that
975 // the associated GL context was current. Just check that it was explicitly
976 // destroyed.
977 DCHECK_EQ(id_, 0u);
978 }
979
980 void Texture::Create() {
981 ScopedGLErrorSuppressor suppressor(decoder_);
982 Destroy();
983 glGenTextures(1, &id_);
984 }
985
986 bool Texture::AllocateStorage(const gfx::Size& size) {
987 DCHECK_NE(id_, 0u);
988 ScopedGLErrorSuppressor suppressor(decoder_);
989 ScopedTexture2DBinder binder(decoder_, id_);
990 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
991 glTexParameteri(
992 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
993 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
994 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
995 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
996
997 glTexImage2D(GL_TEXTURE_2D,
998 0, // mip level
999 GL_RGBA,
1000 size.width(),
1001 size.height(),
1002 0, // border
1003 GL_RGBA,
1004 GL_UNSIGNED_BYTE,
1005 NULL);
1006
1007 return glGetError() == GL_NO_ERROR;
1008 }
1009
1010 void Texture::Copy(const gfx::Size& size) {
1011 DCHECK_NE(id_, 0u);
1012 ScopedGLErrorSuppressor suppressor(decoder_);
1013 ScopedTexture2DBinder binder(decoder_, id_);
1014 glCopyTexImage2D(GL_TEXTURE_2D,
1015 0, // level
1016 GL_RGBA,
1017 0, 0,
1018 size.width(),
1019 size.height(),
1020 0); // border
1021 }
1022
1023 void Texture::Destroy() {
1024 if (id_ != 0) {
1025 ScopedGLErrorSuppressor suppressor(decoder_);
1026 glDeleteTextures(1, &id_);
1027 id_ = 0;
1028 }
1029 }
1030
1031 RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder)
1032 : decoder_(decoder),
1033 id_(0) {
1034 }
1035
1036 RenderBuffer::~RenderBuffer() {
1037 // This does not destroy the render buffer because that would require that
1038 // the associated GL context was current. Just check that it was explicitly
1039 // destroyed.
1040 DCHECK_EQ(id_, 0u);
1041 }
1042
1043 void RenderBuffer::Create() {
1044 ScopedGLErrorSuppressor suppressor(decoder_);
1045 Destroy();
1046 glGenRenderbuffersEXT(1, &id_);
1047 }
1048
1049 bool RenderBuffer::AllocateStorage(const gfx::Size& size, GLenum format) {
1050 ScopedGLErrorSuppressor suppressor(decoder_);
1051 ScopedRenderBufferBinder binder(decoder_, id_);
1052 glRenderbufferStorageEXT(GL_RENDERBUFFER,
1053 format,
1054 size.width(),
1055 size.height());
1056 return glGetError() == GL_NO_ERROR;
1057 }
1058
1059 void RenderBuffer::Destroy() {
1060 if (id_ != 0) {
1061 ScopedGLErrorSuppressor suppressor(decoder_);
1062 glDeleteRenderbuffersEXT(1, &id_);
1063 id_ = 0;
1064 }
1065 }
1066
1067 FrameBuffer::FrameBuffer(GLES2DecoderImpl* decoder)
1068 : decoder_(decoder),
1069 id_(0) {
1070 }
1071
1072 FrameBuffer::~FrameBuffer() {
1073 // This does not destroy the frame buffer because that would require that
1074 // the associated GL context was current. Just check that it was explicitly
1075 // destroyed.
1076 DCHECK_EQ(id_, 0u);
1077 }
1078
1079 void FrameBuffer::Create() {
1080 ScopedGLErrorSuppressor suppressor(decoder_);
1081 Destroy();
1082 glGenFramebuffersEXT(1, &id_);
1083 }
1084
1085 void FrameBuffer::AttachRenderTexture(Texture* texture) {
1086 DCHECK_NE(id_, 0u);
1087 ScopedGLErrorSuppressor suppressor(decoder_);
1088 ScopedFrameBufferBinder binder(decoder_, id_);
1089 GLuint attach_id = texture ? texture->id() : 0;
1090 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
1091 GL_COLOR_ATTACHMENT0,
1092 GL_TEXTURE_2D,
1093 attach_id,
1094 0);
1095 }
1096
1097 void FrameBuffer::AttachDepthStencilRenderBuffer(RenderBuffer* render_buffer) {
1098 DCHECK_NE(id_, 0u);
1099 ScopedGLErrorSuppressor suppressor(decoder_);
1100 ScopedFrameBufferBinder binder(decoder_, id_);
1101 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
1102 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1103 GL_DEPTH_ATTACHMENT,
1104 GL_RENDERBUFFER,
1105 attach_id);
1106 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1107 GL_STENCIL_ATTACHMENT,
1108 GL_RENDERBUFFER,
1109 attach_id);
1110 }
1111
1112 void FrameBuffer::Clear(GLbitfield buffers) {
1113 ScopedGLErrorSuppressor suppressor(decoder_);
1114 ScopedFrameBufferBinder binder(decoder_, id_);
1115 glClear(buffers);
1116 }
1117
1118 void FrameBuffer::Destroy() {
1119 if (id_ != 0) {
1120 ScopedGLErrorSuppressor suppressor(decoder_);
1121 glDeleteFramebuffersEXT(1, &id_);
1122 id_ = 0;
1123 }
1124 }
1125
1126 GLenum FrameBuffer::CheckStatus() {
1127 DCHECK_NE(id_, 0u);
1128 ScopedGLErrorSuppressor suppressor(decoder_);
1129 ScopedFrameBufferBinder binder(decoder_, id_);
1130 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
1131 }
1132
722 GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) { 1133 GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
723 return new GLES2DecoderImpl(group); 1134 return new GLES2DecoderImpl(group);
724 } 1135 }
725 1136
726 #if defined(UNIT_TEST) 1137 #if defined(UNIT_TEST)
727 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) 1138 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2)
728 #elif defined(OS_WIN) 1139 #elif defined(OS_WIN)
729 int GLES2DecoderImpl::pixel_format_; 1140 int GLES2DecoderImpl::pixel_format_;
730 #endif 1141 #endif
731 1142
(...skipping 11 matching lines...) Expand all
743 #if defined(UNIT_TEST) 1154 #if defined(UNIT_TEST)
744 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) 1155 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2)
745 #elif defined(OS_WIN) 1156 #elif defined(OS_WIN)
746 gl_device_context_(NULL), 1157 gl_device_context_(NULL),
747 gl_context_(NULL), 1158 gl_context_(NULL),
748 pbuffer_(NULL), 1159 pbuffer_(NULL),
749 #endif 1160 #endif
750 anti_aliased_(false) { 1161 anti_aliased_(false) {
751 } 1162 }
752 1163
753 bool GLES2DecoderImpl::Initialize() { 1164 bool GLES2DecoderImpl::Initialize(GLES2Decoder* parent,
1165 const gfx::Size& size,
1166 uint32 parent_client_texture_id) {
1167 // Keep only a weak pointer to the parent so we don't unmap its client
1168 // frame buffer is after it has been destroyed.
1169 if (parent)
1170 parent_ = static_cast<GLES2DecoderImpl*>(parent)->AsWeakPtr();
1171
1172 pending_size_ = size;
1173
754 if (!InitPlatformSpecific()) { 1174 if (!InitPlatformSpecific()) {
755 Destroy(); 1175 Destroy();
756 return false; 1176 return false;
757 } 1177 }
1178
758 if (!MakeCurrent()) { 1179 if (!MakeCurrent()) {
759 Destroy(); 1180 Destroy();
760 return false; 1181 return false;
761 } 1182 }
762 1183
763 // This happens in InitializeOneOff in windows. TODO(apatrick): generalize to 1184 // This happens in InitializeOneOff in windows. TODO(apatrick): generalize to
764 // other platforms. 1185 // other platforms.
765 #if !defined(OS_WIN) 1186 #if !defined(OS_WIN)
766 if (!InitGlew()) { 1187 if (!InitGlew()) {
767 Destroy(); 1188 Destroy();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 1220 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
800 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 1221 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
801 }; 1222 };
802 for (size_t ii = 0; ii < arraysize(faces); ++ii) { 1223 for (size_t ii = 0; ii < arraysize(faces); ++ii) {
803 glTexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA, 1224 glTexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA,
804 GL_UNSIGNED_BYTE, black); 1225 GL_UNSIGNED_BYTE, black);
805 } 1226 }
806 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); 1227 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
807 CHECK_GL_ERROR(); 1228 CHECK_GL_ERROR();
808 1229
1230 if (size.width() > 0 && size.height() > 0) {
1231 // Create the target frame buffer. This is the one that the client renders
1232 // directly to.
1233 offscreen_target_frame_buffer_.reset(new FrameBuffer(this));
1234 offscreen_target_frame_buffer_->Create();
1235 offscreen_target_color_texture_.reset(new Texture(this));
1236 offscreen_target_color_texture_->Create();
1237 offscreen_target_depth_stencil_render_buffer_.reset(
1238 new RenderBuffer(this));
1239 offscreen_target_depth_stencil_render_buffer_->Create();
1240
1241 // Create the saved offscreen texture. The target frame buffer is copied
1242 // here when SwapBuffers is called.
1243 offscreen_saved_color_texture_.reset(new Texture(this));
1244 offscreen_saved_color_texture_->Create();
1245
1246 // Create the temporary frame buffer, used to operate on render textures
1247 // without concern for state the client might have changed on the frame
1248 // buffers it has access to, like the clear color and the color mask.
1249 temporary_frame_buffer_.reset(new FrameBuffer(this));
1250 temporary_frame_buffer_->Create();
1251
1252 // Map the ID of the saved offscreen texture into the parent so that
1253 // it can reference it.
1254 if (parent_) {
1255 GLuint service_id = offscreen_saved_color_texture_->id();
1256 parent_->id_manager()->AddMapping(parent_client_texture_id,
1257 service_id);
1258 TextureManager::TextureInfo* info =
1259 parent_->CreateTextureInfo(service_id);
1260 parent_->texture_manager()->SetInfoTarget(info, GL_TEXTURE_2D);
1261 }
1262
1263 // Allocate the render buffers at their initial size and check the status
1264 // of the frame buffers is okay.
1265 if (!UpdateOffscreenFrameBufferSize()) {
1266 DLOG(ERROR) << "Could not allocate offscreen buffer storage.";
1267 Destroy();
1268 return false;
1269 }
1270
1271 // Bind to the new default frame buffer (the offscreen target frame buffer).
1272 // This should now be associated with ID zero.
1273 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
1274 }
1275
809 return true; 1276 return true;
810 } 1277 }
811 1278
812 // TODO(kbr): the use of this anonymous namespace core dumps the 1279 // TODO(kbr): the use of this anonymous namespace core dumps the
813 // linker on Mac OS X 10.6 when the symbol ordering file is used 1280 // linker on Mac OS X 10.6 when the symbol ordering file is used
814 // namespace { 1281 // namespace {
815 1282
816 #if defined(UNIT_TEST) 1283 #if defined(UNIT_TEST)
817 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) 1284 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2)
818 #elif defined(OS_WIN) 1285 #elif defined(OS_WIN)
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 module_handle); 1379 module_handle);
913 return false; 1380 return false;
914 } 1381 }
915 1382
916 // Create a temporary GL context to query for multisampled pixel formats. 1383 // Create a temporary GL context to query for multisampled pixel formats.
917 HGLRC gl_context = ::wglCreateContext(intermediate_dc); 1384 HGLRC gl_context = ::wglCreateContext(intermediate_dc);
918 if (::wglMakeCurrent(intermediate_dc, gl_context)) { 1385 if (::wglMakeCurrent(intermediate_dc, gl_context)) {
919 // GL context was successfully created and applied to the window's DC. 1386 // GL context was successfully created and applied to the window's DC.
920 // Startup GLEW, the GL extensions wrangler. 1387 // Startup GLEW, the GL extensions wrangler.
921 if (InitGlew()) { 1388 if (InitGlew()) {
922 DLOG(INFO) << "Initialized GLEW " << ::glewGetString(GLEW_VERSION); 1389 DLOG(INFO) << "Initialized GLEW " << glewGetString(GLEW_VERSION);
923 } else { 1390 } else {
924 ::wglMakeCurrent(intermediate_dc, NULL); 1391 ::wglMakeCurrent(intermediate_dc, NULL);
925 ::wglDeleteContext(gl_context); 1392 ::wglDeleteContext(gl_context);
926 ::ReleaseDC(intermediate_window, intermediate_dc); 1393 ::ReleaseDC(intermediate_window, intermediate_dc);
927 ::DestroyWindow(intermediate_window); 1394 ::DestroyWindow(intermediate_window);
928 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), 1395 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
929 module_handle); 1396 module_handle);
930 return false; 1397 return false;
931 } 1398 }
932 1399
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 for (GLsizei ii = 0; ii < n; ++ii) { 1584 for (GLsizei ii = 0; ii < n; ++ii) {
1118 if (id_manager()->GetServiceId(client_ids[ii], &service_ids[ii])) { 1585 if (id_manager()->GetServiceId(client_ids[ii], &service_ids[ii])) {
1119 id_manager()->RemoveMapping(client_ids[ii], service_ids[ii]); 1586 id_manager()->RemoveMapping(client_ids[ii], service_ids[ii]);
1120 } else { 1587 } else {
1121 service_ids[ii] = 0; 1588 service_ids[ii] = 0;
1122 } 1589 }
1123 } 1590 }
1124 } 1591 }
1125 1592
1126 bool GLES2DecoderImpl::InitPlatformSpecific() { 1593 bool GLES2DecoderImpl::InitPlatformSpecific() {
1594 bool offscreen = pending_size_.width() > 0 && pending_size_.height() > 0;
1127 #if defined(UNIT_TEST) 1595 #if defined(UNIT_TEST)
1128 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) 1596 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2)
1129 #elif defined(OS_WIN) 1597 #elif defined(OS_WIN)
1130 // Do one-off initialization. 1598 // Do one-off initialization.
1131 static bool success = InitializeOneOff(anti_aliased_); 1599 static bool success = InitializeOneOff(anti_aliased_);
1132 if (!success) 1600 if (!success)
1133 return false; 1601 return false;
1134 1602
1135 if (hwnd()) { 1603 if (offscreen) {
1136 // The GL context will render to this window.
1137 gl_device_context_ = ::GetDC(hwnd());
1138
1139 if (!::SetPixelFormat(gl_device_context_,
1140 pixel_format_,
1141 &kPixelFormatDescriptor)) {
1142 DLOG(ERROR) << "Unable to set the pixel format for GL context.";
1143 DestroyPlatformSpecific();
1144 return false;
1145 }
1146 } else {
1147 // Create a device context compatible with the primary display. 1604 // Create a device context compatible with the primary display.
1148 HDC display_device_context = ::CreateDC(L"DISPLAY", NULL, NULL, NULL); 1605 HDC display_device_context = ::CreateDC(L"DISPLAY", NULL, NULL, NULL);
1149 1606
1150 // Create a 1 x 1 pbuffer suitable for use with the device. 1607 // Create a 1 x 1 pbuffer suitable for use with the device. This is just
1608 // a stepping stone towards creating a frame buffer object. It doesn't
1609 // matter what size it is.
1151 const int kNoAttributes[] = { 0 }; 1610 const int kNoAttributes[] = { 0 };
1152 pbuffer_ = ::wglCreatePbufferARB(display_device_context, 1611 pbuffer_ = ::wglCreatePbufferARB(display_device_context,
1153 pixel_format_, 1612 pixel_format_,
1154 1, 1, 1613 1, 1,
1155 kNoAttributes); 1614 kNoAttributes);
1156 ::DeleteDC(display_device_context); 1615 ::DeleteDC(display_device_context);
1157 if (!pbuffer_) { 1616 if (!pbuffer_) {
1158 DLOG(ERROR) << "Unable to create pbuffer."; 1617 DLOG(ERROR) << "Unable to create pbuffer.";
1159 DestroyPlatformSpecific(); 1618 DestroyPlatformSpecific();
1160 return false; 1619 return false;
1161 } 1620 }
1162 1621
1163 gl_device_context_ = ::wglGetPbufferDCARB(pbuffer_); 1622 gl_device_context_ = ::wglGetPbufferDCARB(pbuffer_);
1164 if (!gl_device_context_) { 1623 if (!gl_device_context_) {
1165 DLOG(ERROR) << "Unable to get pbuffer device context."; 1624 DLOG(ERROR) << "Unable to get pbuffer device context.";
1166 DestroyPlatformSpecific(); 1625 DestroyPlatformSpecific();
1167 return false; 1626 return false;
1168 } 1627 }
1628 } else {
1629 // The GL context will render to this window.
1630 gl_device_context_ = ::GetDC(hwnd());
1631
1632 if (!::SetPixelFormat(gl_device_context_,
1633 pixel_format_,
1634 &kPixelFormatDescriptor)) {
1635 DLOG(ERROR) << "Unable to set the pixel format for GL context.";
1636 DestroyPlatformSpecific();
1637 return false;
1638 }
1169 } 1639 }
1170 1640
1171 gl_context_ = ::wglCreateContext(gl_device_context_); 1641 gl_context_ = ::wglCreateContext(gl_device_context_);
1172 if (!gl_context_) { 1642 if (!gl_context_) {
1173 DLOG(ERROR) << "Failed to create GL context."; 1643 DLOG(ERROR) << "Failed to create GL context.";
1174 DestroyPlatformSpecific(); 1644 DestroyPlatformSpecific();
1175 return false; 1645 return false;
1176 } 1646 }
1647
1648 if (parent_) {
1649 if (!wglShareLists(parent_->gl_context_, gl_context_)) {
1650 DLOG(ERROR) << "Could not share GL contexts.";
1651 DestroyPlatformSpecific();
1652 return false;
1653 }
1654 }
1655
1177 #elif defined(OS_LINUX) 1656 #elif defined(OS_LINUX)
1657 // TODO(apatrick): offscreen rendering not yet supported on this platform.
1658 DCHECK(!offscreen);
1659
1660 // TODO(apatrick): parent contexts not yet supported on this platform.
1661 DCHECK(!parent_);
1662
1178 DCHECK(window()); 1663 DCHECK(window());
1179 if (!window()->Initialize()) 1664 if (!window()->Initialize())
1180 return false; 1665 return false;
1181 #elif defined(OS_MACOSX) 1666 #elif defined(OS_MACOSX)
1667 // TODO(apatrick): offscreen rendering not yet supported on this platform.
1668 DCHECK(!offscreen);
1669
1670 // TODO(apatrick): parent contexts not yet supported on this platform.
1671 DCHECK(!parent_);
1672
1182 return surface_.Initialize(); 1673 return surface_.Initialize();
1183 #endif 1674 #endif
1184 1675
1185 return true; 1676 return true;
1186 } 1677 }
1187 1678
1188 bool GLES2DecoderImpl::InitGlew() { 1679 bool GLES2DecoderImpl::InitGlew() {
1189 #if !defined(UNIT_TEST) && !defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) 1680 #if !defined(UNIT_TEST) && !defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2)
1190 DLOG(INFO) << "Initializing GL and GLEW for GLES2Decoder."; 1681 DLOG(INFO) << "Initializing GL and GLEW for GLES2Decoder.";
1191 1682
1192 GLenum glew_error = glewInit(); 1683 GLenum glew_error = glewInit();
1193 if (glew_error != GLEW_OK) { 1684 if (glew_error != GLEW_OK) {
1194 DLOG(ERROR) << "Unable to initialise GLEW : " 1685 DLOG(ERROR) << "Unable to initialise GLEW : "
1195 << ::glewGetErrorString(glew_error); 1686 << glewGetErrorString(glew_error);
1196 return false; 1687 return false;
1197 } 1688 }
1198 1689
1199 // Check to see that we can use the OpenGL vertex attribute APIs 1690 // Check to see that we can use the OpenGL vertex attribute APIs
1200 // TODO(petersont): Return false if this check fails, but because some 1691 // TODO(petersont): Return false if this check fails, but because some
1201 // Intel hardware does not support OpenGL 2.0, yet does support all of the 1692 // Intel hardware does not support OpenGL 2.0, yet does support all of the
1202 // extensions we require, we only log an error. A future CL should change 1693 // extensions we require, we only log an error. A future CL should change
1203 // this check to ensure that all of the extension strings we require are 1694 // this check to ensure that all of the extension strings we require are
1204 // present. 1695 // present.
1205 if (!GLEW_VERSION_2_0) { 1696 if (!GLEW_VERSION_2_0) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 gl_device_context_ = NULL; 1749 gl_device_context_ = NULL;
1259 } 1750 }
1260 1751
1261 if (pbuffer_) { 1752 if (pbuffer_) {
1262 ::wglDestroyPbufferARB(pbuffer_); 1753 ::wglDestroyPbufferARB(pbuffer_);
1263 pbuffer_ = NULL; 1754 pbuffer_ = NULL;
1264 } 1755 }
1265 #endif 1756 #endif
1266 } 1757 }
1267 1758
1759 bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() {
1760 if (current_size_ != pending_size_)
1761 return true;
1762
1763 // Reallocate the offscreen target buffers.
1764 if (!offscreen_target_color_texture_->AllocateStorage(pending_size_)) {
1765 return false;
1766 }
1767
1768 if (!offscreen_target_depth_stencil_render_buffer_->AllocateStorage(
1769 pending_size_, GL_DEPTH24_STENCIL8)) {
1770 return false;
1771 }
1772
1773 // Attach the offscreen target buffers to the temporary frame buffer
1774 // so they can be cleared using that frame buffer's clear parameters (all
1775 // zero, no color mask, etc).
1776 temporary_frame_buffer_->AttachRenderTexture(
1777 offscreen_target_color_texture_.get());
1778 temporary_frame_buffer_->AttachDepthStencilRenderBuffer(
1779 offscreen_target_depth_stencil_render_buffer_.get());
1780 if (temporary_frame_buffer_->CheckStatus() !=
1781 GL_FRAMEBUFFER_COMPLETE) {
1782 return false;
1783 }
1784
1785 // Clear the offscreen target buffers to all zero (using the saved frame
1786 // buffer they are temporarily attached to).
1787 temporary_frame_buffer_->Clear(
1788 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1789
1790 // Detach the offscreen target buffer.
1791 temporary_frame_buffer_->AttachRenderTexture(NULL);
1792 temporary_frame_buffer_->AttachDepthStencilRenderBuffer(NULL);
1793
1794 // Attach the offscreen target buffers to the proper frame buffer.
1795 offscreen_target_frame_buffer_->AttachRenderTexture(
1796 offscreen_target_color_texture_.get());
1797 offscreen_target_frame_buffer_->AttachDepthStencilRenderBuffer(
1798 offscreen_target_depth_stencil_render_buffer_.get());
1799 if (offscreen_target_frame_buffer_->CheckStatus() !=
1800 GL_FRAMEBUFFER_COMPLETE) {
1801 return false;
1802 }
1803
1804 // Create the saved offscreen color texture.
1805 offscreen_saved_color_texture_->AllocateStorage(pending_size_);
1806
1807 // Clear the offscreen saved color texture by copying the cleared target
1808 // frame buffer into it.
1809 {
1810 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
1811 offscreen_saved_color_texture_->Copy(pending_size_);
1812 }
1813
1814 // Update the info about the offscreen saved color texture in the parent.
1815 // The reference to the parent is a weak pointer and will become null if the
1816 // parent is later destroyed.
1817 if (parent_) {
1818 GLuint service_id = offscreen_saved_color_texture_->id();
1819
1820 TextureManager::TextureInfo* info =
1821 parent_->texture_manager()->GetTextureInfo(service_id);
1822 DCHECK(info);
1823
1824 info->SetLevelInfo(GL_TEXTURE_2D,
1825 0, // level
1826 GL_RGBA,
1827 pending_size_.width(), pending_size_.height(),
1828 1, // depth
1829 0, // border
1830 GL_RGBA,
1831 GL_UNSIGNED_BYTE);
1832 }
1833
1834 current_size_ = pending_size_;
1835 return true;
1836 }
1837
1268 #if defined(OS_MACOSX) 1838 #if defined(OS_MACOSX)
1269 1839
1270 uint64 GLES2DecoderImpl::SetWindowSizeForIOSurface(int32 width, int32 height) { 1840 uint64 GLES2DecoderImpl::SetWindowSizeForIOSurface(int32 width, int32 height) {
1271 #if defined(UNIT_TEST) 1841 #if defined(UNIT_TEST)
1272 return 0; 1842 return 0;
1273 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) 1843 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2)
1274 return 0; 1844 return 0;
1275 #else 1845 #else
1276 return surface_.SetSurfaceSize(width, height); 1846 return surface_.SetSurfaceSize(width, height);
1277 #endif // !defined(UNIT_TEST) 1847 #endif // !defined(UNIT_TEST)
(...skipping 15 matching lines...) Expand all
1293 Callback1<TransportDIB::Id>::Type* deallocator) { 1863 Callback1<TransportDIB::Id>::Type* deallocator) {
1294 surface_.SetTransportDIBAllocAndFree(allocator, deallocator); 1864 surface_.SetTransportDIBAllocAndFree(allocator, deallocator);
1295 } 1865 }
1296 #endif // defined(OS_MACOSX) 1866 #endif // defined(OS_MACOSX)
1297 1867
1298 void GLES2DecoderImpl::SetSwapBuffersCallback(Callback0::Type* callback) { 1868 void GLES2DecoderImpl::SetSwapBuffersCallback(Callback0::Type* callback) {
1299 swap_buffers_callback_.reset(callback); 1869 swap_buffers_callback_.reset(callback);
1300 } 1870 }
1301 1871
1302 void GLES2DecoderImpl::Destroy() { 1872 void GLES2DecoderImpl::Destroy() {
1873 MakeCurrent();
1874
1875 // Remove the saved frame buffer mapping from the parent decoder. The
1876 // parent pointer is a weak pointer so it will be null if the parent has
1877 // already been destroyed.
1878 if (parent_) {
1879 // First check the texture has been mapped into the parent. This might not
1880 // be the case if initialization failed midway through.
1881 GLuint service_id = offscreen_saved_color_texture_->id();
1882 GLuint client_id;
1883 if (parent_->id_manager()->GetClientId(service_id, &client_id)) {
1884 parent_->texture_manager()->RemoveTextureInfo(service_id);
1885 parent_->id_manager()->RemoveMapping(client_id, service_id);
1886 }
1887 }
1888
1889 if (offscreen_target_frame_buffer_.get())
1890 offscreen_target_frame_buffer_->Destroy();
1891
1892 if (offscreen_target_color_texture_.get())
1893 offscreen_target_color_texture_->Destroy();
1894
1895 if (offscreen_target_depth_stencil_render_buffer_.get())
1896 offscreen_target_depth_stencil_render_buffer_->Destroy();
1897
1898 if (temporary_frame_buffer_.get())
1899 temporary_frame_buffer_->Destroy();
1900
1901 if (offscreen_saved_color_texture_.get())
1902 offscreen_saved_color_texture_->Destroy();
1903
1303 #if defined(UNIT_TEST) 1904 #if defined(UNIT_TEST)
1304 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) 1905 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2)
1305 #elif defined(OS_LINUX) 1906 #elif defined(OS_LINUX)
1306 DCHECK(window()); 1907 DCHECK(window());
1307 window()->Destroy(); 1908 window()->Destroy();
1308 #elif defined(OS_MACOSX) 1909 #elif defined(OS_MACOSX)
1309 surface_.Destroy(); 1910 surface_.Destroy();
1310 #endif 1911 #endif
1311 1912
1312 DestroyPlatformSpecific(); 1913 DestroyPlatformSpecific();
1313 } 1914 }
1314 1915
1916 void GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
1917 // We can't resize the render buffers immediately because there might be a
1918 // partial frame rendered into them and we don't want the tail end of that
1919 // rendered into the reallocated storage. Defer until the next SwapBuffers.
1920 pending_size_ = size;
1921 }
1922
1315 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const { 1923 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
1316 if (command_id > kStartPoint && command_id < kNumCommands) { 1924 if (command_id > kStartPoint && command_id < kNumCommands) {
1317 return gles2::GetCommandName(static_cast<CommandId>(command_id)); 1925 return gles2::GetCommandName(static_cast<CommandId>(command_id));
1318 } 1926 }
1319 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); 1927 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
1320 } 1928 }
1321 1929
1322 // Decode command with its arguments, and call the corresponding GL function. 1930 // Decode command with its arguments, and call the corresponding GL function.
1323 // Note: args is a pointer to the command buffer. As such, it could be changed 1931 // Note: args is a pointer to the command buffer. As such, it could be changed
1324 // by a (malicious) client at any time, so if validation has to happen, it 1932 // by a (malicious) client at any time, so if validation has to happen, it
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 break; 2053 break;
1446 default: 2054 default:
1447 NOTREACHED(); // Validation should prevent us getting here. 2055 NOTREACHED(); // Validation should prevent us getting here.
1448 break; 2056 break;
1449 } 2057 }
1450 glBindBuffer(target, buffer); 2058 glBindBuffer(target, buffer);
1451 } 2059 }
1452 2060
1453 void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint framebuffer) { 2061 void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint framebuffer) {
1454 bound_framebuffer_ = framebuffer; 2062 bound_framebuffer_ = framebuffer;
2063
2064 // When rendering to an offscreen frame buffer, instead of unbinding from
2065 // the current frame buffer, bind to the offscreen target frame buffer.
2066 if (framebuffer == 0 && offscreen_target_frame_buffer_.get())
2067 framebuffer = offscreen_target_frame_buffer_->id();
2068
1455 glBindFramebufferEXT(target, framebuffer); 2069 glBindFramebufferEXT(target, framebuffer);
1456 } 2070 }
1457 2071
1458 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint renderbuffer) { 2072 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint renderbuffer) {
1459 bound_renderbuffer_ = renderbuffer; 2073 bound_renderbuffer_ = renderbuffer;
1460 glBindRenderbufferEXT(target, renderbuffer); 2074 glBindRenderbufferEXT(target, renderbuffer);
1461 } 2075 }
1462 2076
1463 void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint texture) { 2077 void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint texture) {
1464 TextureManager::TextureInfo* info = NULL; 2078 TextureManager::TextureInfo* info = NULL;
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 glLinkProgram(program); 2292 glLinkProgram(program);
1679 GLenum error = glGetError(); 2293 GLenum error = glGetError();
1680 if (error != GL_NO_ERROR) { 2294 if (error != GL_NO_ERROR) {
1681 RemoveProgramInfo(program); 2295 RemoveProgramInfo(program);
1682 SetGLError(error); 2296 SetGLError(error);
1683 } else { 2297 } else {
1684 info->Update(); 2298 info->Update();
1685 } 2299 }
1686 }; 2300 };
1687 2301
1688 void GLES2DecoderImpl::DoSwapBuffers() {
1689 #if defined(UNIT_TEST)
1690 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2)
1691 #elif defined(OS_WIN)
1692 ::SwapBuffers(gl_device_context_);
1693 #elif defined(OS_LINUX)
1694 DCHECK(window());
1695 window()->SwapBuffers();
1696 #elif defined(OS_MACOSX)
1697 // TODO(kbr): Need to property hook up and track the OpenGL state and hook
1698 // up the notion of the currently bound FBO.
1699 surface_.SwapBuffers();
1700 #endif
1701 if (swap_buffers_callback_.get()) {
1702 swap_buffers_callback_->Run();
1703 }
1704 }
1705
1706 void GLES2DecoderImpl::DoTexParameterf( 2302 void GLES2DecoderImpl::DoTexParameterf(
1707 GLenum target, GLenum pname, GLfloat param) { 2303 GLenum target, GLenum pname, GLfloat param) {
1708 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 2304 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
1709 if (!info) { 2305 if (!info) {
1710 SetGLError(GL_INVALID_VALUE); 2306 SetGLError(GL_INVALID_VALUE);
1711 } else { 2307 } else {
1712 info->SetParameter(pname, static_cast<GLint>(param)); 2308 info->SetParameter(pname, static_cast<GLint>(param));
1713 glTexParameterf(target, pname, param); 2309 glTexParameterf(target, pname, param);
1714 } 2310 }
1715 } 2311 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1805 error_bits_ |= GLES2Util::GLErrorToErrorBit(error); 2401 error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
1806 } 2402 }
1807 2403
1808 void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() { 2404 void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() {
1809 GLenum error; 2405 GLenum error;
1810 while ((error = glGetError()) != GL_NO_ERROR) { 2406 while ((error = glGetError()) != GL_NO_ERROR) {
1811 SetGLError(error); 2407 SetGLError(error);
1812 } 2408 }
1813 } 2409 }
1814 2410
2411 void GLES2DecoderImpl::ClearRealGLErrors() {
2412 GLenum error;
2413 while ((error = glGetError()) != GL_NO_ERROR) {
2414 NOTREACHED() << "GL error " << error << " was unhandled.";
2415 }
2416 }
2417
1815 bool GLES2DecoderImpl::VertexAttribInfo::CanAccess(GLuint index) { 2418 bool GLES2DecoderImpl::VertexAttribInfo::CanAccess(GLuint index) {
1816 if (!enabled_) { 2419 if (!enabled_) {
1817 return true; 2420 return true;
1818 } 2421 }
1819 2422
1820 if (!buffer_ || buffer_->IsDeleted()) { 2423 if (!buffer_ || buffer_->IsDeleted()) {
1821 return false; 2424 return false;
1822 } 2425 }
1823 2426
1824 // The number of elements that can be accessed. 2427 // The number of elements that can be accessed.
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2974 return error::kNoError; 3577 return error::kNoError;
2975 } 3578 }
2976 result->success = 1; // true. 3579 result->success = 1; // true.
2977 result->size = attrib_info->size; 3580 result->size = attrib_info->size;
2978 result->type = attrib_info->type; 3581 result->type = attrib_info->type;
2979 Bucket* bucket = CreateBucket(name_bucket_id); 3582 Bucket* bucket = CreateBucket(name_bucket_id);
2980 bucket->SetFromString(attrib_info->name); 3583 bucket->SetFromString(attrib_info->name);
2981 return error::kNoError; 3584 return error::kNoError;
2982 } 3585 }
2983 3586
3587 error::Error GLES2DecoderImpl::HandleSwapBuffers(
3588 uint32 immediate_data_size, const gles2::SwapBuffers& c) {
3589 // Check a client created frame buffer is not bound. TODO(apatrick):
3590 // this error is overkill. It will require that the client recreate the
3591 // context to continue.
3592 if (bound_framebuffer_ != 0)
3593 return error::kLostContext;
3594
3595 // If offscreen then don't actually SwapBuffers to the display. Just copy
3596 // the rendered frame to another frame buffer.
3597 if (offscreen_target_frame_buffer_.get()) {
3598 ScopedGLErrorSuppressor suppressor(this);
3599
3600 // First check to see if a deferred offscreen render buffer resize is
3601 // pending.
3602 if (!UpdateOffscreenFrameBufferSize())
3603 return error::kLostContext;
3604
3605 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3606 offscreen_saved_color_texture_->Copy(current_size_);
3607 } else {
3608 #if defined(UNIT_TEST)
3609 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2)
3610 #elif defined(OS_WIN)
3611 ::SwapBuffers(gl_device_context_);
3612 #elif defined(OS_LINUX)
3613 DCHECK(window());
3614 window()->SwapBuffers();
3615 #elif defined(OS_MACOSX)
3616 // TODO(kbr): Need to property hook up and track the OpenGL state and hook
3617 // up the notion of the currently bound FBO.
3618 surface_.SwapBuffers();
3619 #endif
3620 }
3621
3622 if (swap_buffers_callback_.get()) {
3623 swap_buffers_callback_->Run();
3624 }
3625
3626 return error::kNoError;
3627 }
3628
2984 // Include the auto-generated part of this file. We split this because it means 3629 // Include the auto-generated part of this file. We split this because it means
2985 // we can easily edit the non-auto generated parts right here in this file 3630 // we can easily edit the non-auto generated parts right here in this file
2986 // instead of having to edit some template or the code generator. 3631 // instead of having to edit some template or the code generator.
2987 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 3632 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
2988 3633
2989 } // namespace gles2 3634 } // namespace gles2
2990 } // namespace gpu 3635 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/gles2_cmd_decoder.h ('k') | gpu/command_buffer/service/gles2_cmd_decoder_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698