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 "gpu/command_buffer/service/gles2_cmd_decoder.h"
6
7 #include <stdio.h>
8
9 #include <algorithm>
10 #include <list>
11 #include <map>
12 #include <stack>
13 #include <string>
14 #include <vector>
15
16 #include "base/at_exit.h"
17 #include "base/bind.h"
18 #include "base/callback_helpers.h"
19 #include "base/command_line.h"
20 #include "base/debug/trace_event.h"
21 #include "base/debug/trace_event_synthetic_delay.h"
22 #include "base/memory/scoped_ptr.h"
23 #include "base/numerics/safe_math.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/string_split.h"
26 #include "build/build_config.h"
27 #define GLES2_GPU_SERVICE 1
28 #include "gpu/command_buffer/common/debug_marker_manager.h"
29 #include "gpu/command_buffer/common/gles2_cmd_format.h"
30 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
31 #include "gpu/command_buffer/common/id_allocator.h"
32 #include "gpu/command_buffer/common/mailbox.h"
33 #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
34 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
35 #include "gpu/command_buffer/service/buffer_manager.h"
36 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
37 #include "gpu/command_buffer/service/context_group.h"
38 #include "gpu/command_buffer/service/context_state.h"
39 #include "gpu/command_buffer/service/error_state.h"
40 #include "gpu/command_buffer/service/feature_info.h"
41 #include "gpu/command_buffer/service/framebuffer_manager.h"
42 #include "gpu/command_buffer/service/gl_utils.h"
43 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
44 #include "gpu/command_buffer/service/gles2_cmd_validation.h"
45 #include "gpu/command_buffer/service/gpu_state_tracer.h"
46 #include "gpu/command_buffer/service/gpu_switches.h"
47 #include "gpu/command_buffer/service/gpu_tracer.h"
48 #include "gpu/command_buffer/service/image_manager.h"
49 #include "gpu/command_buffer/service/mailbox_manager.h"
50 #include "gpu/command_buffer/service/memory_tracking.h"
51 #include "gpu/command_buffer/service/program_manager.h"
52 #include "gpu/command_buffer/service/query_manager.h"
53 #include "gpu/command_buffer/service/renderbuffer_manager.h"
54 #include "gpu/command_buffer/service/shader_manager.h"
55 #include "gpu/command_buffer/service/shader_translator.h"
56 #include "gpu/command_buffer/service/shader_translator_cache.h"
57 #include "gpu/command_buffer/service/texture_manager.h"
58 #include "gpu/command_buffer/service/vertex_array_manager.h"
59 #include "gpu/command_buffer/service/vertex_attrib_manager.h"
60 #include "third_party/smhasher/src/City.h"
61 #include "ui/gl/gl_bindings.h"
62 #include "ui/gl/gl_fence.h"
63 #include "ui/gl/gl_image.h"
64 #include "ui/gl/gl_implementation.h"
65 #include "ui/gl/gl_surface.h"
66
67 #if defined(OS_MACOSX)
68 #include <IOSurface/IOSurfaceAPI.h>
69 // Note that this must be included after gl_bindings.h to avoid conflicts.
70 #include <OpenGL/CGLIOSurface.h>
71 #endif
72
73 #if defined(OS_WIN)
74 #include "base/win/win_util.h"
75 #endif
76
77 namespace gpu {
78 namespace gles2 {
79
80 namespace {
81
82 static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
83 static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
84 static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
85 static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
86
87 #if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
CityHashForAngle(const char * name,unsigned int len)88 khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
89 return static_cast<khronos_uint64_t>(
90 CityHash64(name, static_cast<size_t>(len)));
91 }
92 #endif
93
PrecisionMeetsSpecForHighpFloat(GLint rangeMin,GLint rangeMax,GLint precision)94 static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
95 GLint rangeMax,
96 GLint precision) {
97 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
98 }
99
GetShaderPrecisionFormatImpl(GLenum shader_type,GLenum precision_type,GLint * range,GLint * precision)100 static void GetShaderPrecisionFormatImpl(GLenum shader_type,
101 GLenum precision_type,
102 GLint *range, GLint *precision) {
103 switch (precision_type) {
104 case GL_LOW_INT:
105 case GL_MEDIUM_INT:
106 case GL_HIGH_INT:
107 // These values are for a 32-bit twos-complement integer format.
108 range[0] = 31;
109 range[1] = 30;
110 *precision = 0;
111 break;
112 case GL_LOW_FLOAT:
113 case GL_MEDIUM_FLOAT:
114 case GL_HIGH_FLOAT:
115 // These values are for an IEEE single-precision floating-point format.
116 range[0] = 127;
117 range[1] = 127;
118 *precision = 23;
119 break;
120 default:
121 NOTREACHED();
122 break;
123 }
124
125 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
126 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
127 // This function is sometimes defined even though it's really just
128 // a stub, so we need to set range and precision as if it weren't
129 // defined before calling it.
130 // On Mac OS with some GPUs, calling this generates a
131 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
132 // platforms.
133 glGetShaderPrecisionFormat(shader_type, precision_type,
134 range, precision);
135
136 // TODO(brianderson): Make the following official workarounds.
137
138 // Some drivers have bugs where they report the ranges as a negative number.
139 // Taking the absolute value here shouldn't hurt because negative numbers
140 // aren't expected anyway.
141 range[0] = abs(range[0]);
142 range[1] = abs(range[1]);
143
144 // If the driver reports a precision for highp float that isn't actually
145 // highp, don't pretend like it's supported because shader compilation will
146 // fail anyway.
147 if (precision_type == GL_HIGH_FLOAT &&
148 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
149 range[0] = 0;
150 range[1] = 0;
151 *precision = 0;
152 }
153 }
154 }
155
156 } // namespace
157
158 class GLES2DecoderImpl;
159
160 // Local versions of the SET_GL_ERROR macros
161 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \
162 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
163 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
164 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
165 function_name, value, label)
166 #define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
167 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
168 function_name, pname)
169 #define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
170 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
171 function_name)
172 #define LOCAL_PEEK_GL_ERROR(function_name) \
173 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
174 #define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
175 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
176 #define LOCAL_PERFORMANCE_WARNING(msg) \
177 PerformanceWarning(__FILE__, __LINE__, msg)
178 #define LOCAL_RENDER_WARNING(msg) \
179 RenderWarning(__FILE__, __LINE__, msg)
180
181 // Check that certain assumptions the code makes are true. There are places in
182 // the code where shared memory is passed direclty to GL. Example, glUniformiv,
183 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
184 // a few others) are 32bits. If they are not 32bits the code will have to change
185 // to call those GL functions with service side memory and then copy the results
186 // to shared memory, converting the sizes.
187 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
188 GLint_not_same_size_as_uint32);
189 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
190 GLint_not_same_size_as_uint32);
191 COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
192 GLfloat_not_same_size_as_float);
193
194 // TODO(kbr): the use of this anonymous namespace core dumps the
195 // linker on Mac OS X 10.6 when the symbol ordering file is used
196 // namespace {
197
198 // Returns the address of the first byte after a struct.
199 template <typename T>
AddressAfterStruct(const T & pod)200 const void* AddressAfterStruct(const T& pod) {
201 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
202 }
203
204 // Returns the address of the frst byte after the struct or NULL if size >
205 // immediate_data_size.
206 template <typename RETURN_TYPE, typename COMMAND_TYPE>
GetImmediateDataAs(const COMMAND_TYPE & pod,uint32 size,uint32 immediate_data_size)207 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
208 uint32 size,
209 uint32 immediate_data_size) {
210 return (size <= immediate_data_size) ?
211 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
212 NULL;
213 }
214
215 // Computes the data size for certain gl commands like glUniform.
ComputeDataSize(GLuint count,size_t size,unsigned int elements_per_unit,uint32 * dst)216 bool ComputeDataSize(
217 GLuint count,
218 size_t size,
219 unsigned int elements_per_unit,
220 uint32* dst) {
221 uint32 value;
222 if (!SafeMultiplyUint32(count, size, &value)) {
223 return false;
224 }
225 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
226 return false;
227 }
228 *dst = value;
229 return true;
230 }
231
232 // A struct to hold info about each command.
233 struct CommandInfo {
234 uint8 arg_flags; // How to handle the arguments for this command
235 uint8 cmd_flags; // How to handle this command
236 uint16 arg_count; // How many arguments are expected for this command.
237 };
238
239 // cmds::name::cmd_flags,
240 // A table of CommandInfo for all the commands.
241 const CommandInfo g_command_info[] = {
242 #define GLES2_CMD_OP(name) { \
243 cmds::name::kArgFlags, \
244 cmds::name::cmd_flags, \
245 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */
246
247 GLES2_COMMAND_LIST(GLES2_CMD_OP)
248
249 #undef GLES2_CMD_OP
250 };
251
252 // Return true if a character belongs to the ASCII subset as defined in
253 // GLSL ES 1.0 spec section 3.1.
CharacterIsValidForGLES(unsigned char c)254 static bool CharacterIsValidForGLES(unsigned char c) {
255 // Printing characters are valid except " $ ` @ \ ' DEL.
256 if (c >= 32 && c <= 126 &&
257 c != '"' &&
258 c != '$' &&
259 c != '`' &&
260 c != '@' &&
261 c != '\\' &&
262 c != '\'') {
263 return true;
264 }
265 // Horizontal tab, line feed, vertical tab, form feed, carriage return
266 // are also valid.
267 if (c >= 9 && c <= 13) {
268 return true;
269 }
270
271 return false;
272 }
273
StringIsValidForGLES(const char * str)274 static bool StringIsValidForGLES(const char* str) {
275 for (; *str; ++str) {
276 if (!CharacterIsValidForGLES(*str)) {
277 return false;
278 }
279 }
280 return true;
281 }
282
283 // This class prevents any GL errors that occur when it is in scope from
284 // being reported to the client.
285 class ScopedGLErrorSuppressor {
286 public:
287 explicit ScopedGLErrorSuppressor(
288 const char* function_name, ErrorState* error_state);
289 ~ScopedGLErrorSuppressor();
290 private:
291 const char* function_name_;
292 ErrorState* error_state_;
293 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
294 };
295
296 // Temporarily changes a decoder's bound texture and restore it when this
297 // object goes out of scope. Also temporarily switches to using active texture
298 // unit zero in case the client has changed that to something invalid.
299 class ScopedTextureBinder {
300 public:
301 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
302 ~ScopedTextureBinder();
303
304 private:
305 ContextState* state_;
306 GLenum target_;
307 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
308 };
309
310 // Temporarily changes a decoder's bound render buffer and restore it when this
311 // object goes out of scope.
312 class ScopedRenderBufferBinder {
313 public:
314 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
315 ~ScopedRenderBufferBinder();
316
317 private:
318 ContextState* state_;
319 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
320 };
321
322 // Temporarily changes a decoder's bound frame buffer and restore it when this
323 // object goes out of scope.
324 class ScopedFrameBufferBinder {
325 public:
326 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
327 ~ScopedFrameBufferBinder();
328
329 private:
330 GLES2DecoderImpl* decoder_;
331 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
332 };
333
334 // Temporarily changes a decoder's bound frame buffer to a resolved version of
335 // the multisampled offscreen render buffer if that buffer is multisampled, and,
336 // if it is bound or enforce_internal_framebuffer is true. If internal is
337 // true, the resolved framebuffer is not visible to the parent.
338 class ScopedResolvedFrameBufferBinder {
339 public:
340 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
341 bool enforce_internal_framebuffer,
342 bool internal);
343 ~ScopedResolvedFrameBufferBinder();
344
345 private:
346 GLES2DecoderImpl* decoder_;
347 bool resolve_and_bind_;
348 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
349 };
350
351 class ScopedModifyPixels {
352 public:
353 explicit ScopedModifyPixels(TextureRef* ref);
354 ~ScopedModifyPixels();
355
356 private:
357 TextureRef* ref_;
358 };
359
ScopedModifyPixels(TextureRef * ref)360 ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
361 if (ref_)
362 ref_->texture()->OnWillModifyPixels();
363 }
364
~ScopedModifyPixels()365 ScopedModifyPixels::~ScopedModifyPixels() {
366 if (ref_)
367 ref_->texture()->OnDidModifyPixels();
368 }
369
370 class ScopedRenderTo {
371 public:
372 explicit ScopedRenderTo(Framebuffer* framebuffer);
373 ~ScopedRenderTo();
374
375 private:
376 const Framebuffer* framebuffer_;
377 };
378
ScopedRenderTo(Framebuffer * framebuffer)379 ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
380 : framebuffer_(framebuffer) {
381 if (framebuffer)
382 framebuffer_->OnWillRenderTo();
383 }
384
~ScopedRenderTo()385 ScopedRenderTo::~ScopedRenderTo() {
386 if (framebuffer_)
387 framebuffer_->OnDidRenderTo();
388 }
389
390 // Encapsulates an OpenGL texture.
391 class BackTexture {
392 public:
393 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
394 ~BackTexture();
395
396 // Create a new render texture.
397 void Create();
398
399 // Set the initial size and format of a render texture or resize it.
400 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
401
402 // Copy the contents of the currently bound frame buffer.
403 void Copy(const gfx::Size& size, GLenum format);
404
405 // Destroy the render texture. This must be explicitly called before
406 // destroying this object.
407 void Destroy();
408
409 // Invalidate the texture. This can be used when a context is lost and it is
410 // not possible to make it current in order to free the resource.
411 void Invalidate();
412
id() const413 GLuint id() const {
414 return id_;
415 }
416
size() const417 gfx::Size size() const {
418 return size_;
419 }
420
421 private:
422 MemoryTypeTracker memory_tracker_;
423 ContextState* state_;
424 size_t bytes_allocated_;
425 GLuint id_;
426 gfx::Size size_;
427 DISALLOW_COPY_AND_ASSIGN(BackTexture);
428 };
429
430 // Encapsulates an OpenGL render buffer of any format.
431 class BackRenderbuffer {
432 public:
433 explicit BackRenderbuffer(
434 RenderbufferManager* renderbuffer_manager,
435 MemoryTracker* memory_tracker,
436 ContextState* state);
437 ~BackRenderbuffer();
438
439 // Create a new render buffer.
440 void Create();
441
442 // Set the initial size and format of a render buffer or resize it.
443 bool AllocateStorage(const FeatureInfo* feature_info,
444 const gfx::Size& size,
445 GLenum format,
446 GLsizei samples);
447
448 // Destroy the render buffer. This must be explicitly called before destroying
449 // this object.
450 void Destroy();
451
452 // Invalidate the render buffer. This can be used when a context is lost and
453 // it is not possible to make it current in order to free the resource.
454 void Invalidate();
455
id() const456 GLuint id() const {
457 return id_;
458 }
459
460 private:
461 RenderbufferManager* renderbuffer_manager_;
462 MemoryTypeTracker memory_tracker_;
463 ContextState* state_;
464 size_t bytes_allocated_;
465 GLuint id_;
466 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
467 };
468
469 // Encapsulates an OpenGL frame buffer.
470 class BackFramebuffer {
471 public:
472 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
473 ~BackFramebuffer();
474
475 // Create a new frame buffer.
476 void Create();
477
478 // Attach a color render buffer to a frame buffer.
479 void AttachRenderTexture(BackTexture* texture);
480
481 // Attach a render buffer to a frame buffer. Note that this unbinds any
482 // currently bound frame buffer.
483 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
484
485 // Destroy the frame buffer. This must be explicitly called before destroying
486 // this object.
487 void Destroy();
488
489 // Invalidate the frame buffer. This can be used when a context is lost and it
490 // is not possible to make it current in order to free the resource.
491 void Invalidate();
492
493 // See glCheckFramebufferStatusEXT.
494 GLenum CheckStatus();
495
id() const496 GLuint id() const {
497 return id_;
498 }
499
500 private:
501 GLES2DecoderImpl* decoder_;
502 GLuint id_;
503 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
504 };
505
506 struct FenceCallback {
FenceCallbackgpu::gles2::FenceCallback507 explicit FenceCallback()
508 : fence(gfx::GLFence::Create()) {
509 DCHECK(fence);
510 }
511 std::vector<base::Closure> callbacks;
512 scoped_ptr<gfx::GLFence> fence;
513 };
514
515 class AsyncUploadTokenCompletionObserver
516 : public AsyncPixelTransferCompletionObserver {
517 public:
AsyncUploadTokenCompletionObserver(uint32 async_upload_token)518 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
519 : async_upload_token_(async_upload_token) {
520 }
521
DidComplete(const AsyncMemoryParams & mem_params)522 virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE {
523 DCHECK(mem_params.buffer());
524 void* data = mem_params.GetDataAddress();
525 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
526 sync->SetAsyncUploadToken(async_upload_token_);
527 }
528
529 private:
~AsyncUploadTokenCompletionObserver()530 virtual ~AsyncUploadTokenCompletionObserver() {
531 }
532
533 uint32 async_upload_token_;
534
535 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
536 };
537
538 // } // anonymous namespace.
539
GetServiceTextureId(uint32 client_texture_id,uint32 * service_texture_id)540 bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
541 uint32* service_texture_id) {
542 return false;
543 }
544
GLES2Decoder()545 GLES2Decoder::GLES2Decoder()
546 : initialized_(false),
547 debug_(false),
548 log_commands_(false) {
549 }
550
~GLES2Decoder()551 GLES2Decoder::~GLES2Decoder() {
552 }
553
BeginDecoding()554 void GLES2Decoder::BeginDecoding() {}
555
EndDecoding()556 void GLES2Decoder::EndDecoding() {}
557
558 // This class implements GLES2Decoder so we don't have to expose all the GLES2
559 // cmd stuff to outside this class.
560 class GLES2DecoderImpl : public GLES2Decoder,
561 public FramebufferManager::TextureDetachObserver,
562 public ErrorStateClient {
563 public:
564 explicit GLES2DecoderImpl(ContextGroup* group);
565 virtual ~GLES2DecoderImpl();
566
567 // Overridden from AsyncAPIInterface.
568 virtual Error DoCommand(unsigned int command,
569 unsigned int arg_count,
570 const void* args) OVERRIDE;
571
572 // Overridden from AsyncAPIInterface.
573 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
574
575 // Overridden from GLES2Decoder.
576 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
577 const scoped_refptr<gfx::GLContext>& context,
578 bool offscreen,
579 const gfx::Size& size,
580 const DisallowedFeatures& disallowed_features,
581 const std::vector<int32>& attribs) OVERRIDE;
582 virtual void Destroy(bool have_context) OVERRIDE;
583 virtual void SetSurface(
584 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
585 virtual void ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
586 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
587 void UpdateParentTextureInfo();
588 virtual bool MakeCurrent() OVERRIDE;
GetGLES2Util()589 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
GetGLContext()590 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
GetContextGroup()591 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
592 virtual Capabilities GetCapabilities() OVERRIDE;
593 virtual void RestoreState(const ContextState* prev_state) const OVERRIDE;
594
RestoreActiveTexture() const595 virtual void RestoreActiveTexture() const OVERRIDE {
596 state_.RestoreActiveTexture();
597 }
RestoreAllTextureUnitBindings(const ContextState * prev_state) const598 virtual void RestoreAllTextureUnitBindings(
599 const ContextState* prev_state) const OVERRIDE {
600 state_.RestoreAllTextureUnitBindings(prev_state);
601 }
RestoreActiveTextureUnitBinding(unsigned int target) const602 virtual void RestoreActiveTextureUnitBinding(
603 unsigned int target) const OVERRIDE {
604 state_.RestoreActiveTextureUnitBinding(target);
605 }
RestoreBufferBindings() const606 virtual void RestoreBufferBindings() const OVERRIDE {
607 state_.RestoreBufferBindings();
608 }
RestoreGlobalState() const609 virtual void RestoreGlobalState() const OVERRIDE {
610 state_.RestoreGlobalState(NULL);
611 }
RestoreProgramBindings() const612 virtual void RestoreProgramBindings() const OVERRIDE {
613 state_.RestoreProgramBindings();
614 }
RestoreTextureUnitBindings(unsigned unit) const615 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
616 state_.RestoreTextureUnitBindings(unit, NULL);
617 }
618 virtual void RestoreFramebufferBindings() const OVERRIDE;
619 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
620
621 virtual void ClearAllAttributes() const OVERRIDE;
622 virtual void RestoreAllAttributes() const OVERRIDE;
623
GetQueryManager()624 virtual QueryManager* GetQueryManager() OVERRIDE {
625 return query_manager_.get();
626 }
GetVertexArrayManager()627 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
628 return vertex_array_manager_.get();
629 }
630 virtual bool ProcessPendingQueries() OVERRIDE;
631 virtual bool HasMoreIdleWork() OVERRIDE;
632 virtual void PerformIdleWork() OVERRIDE;
633
634 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
635
636 virtual void SetResizeCallback(
637 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
638
639 virtual Logger* GetLogger() OVERRIDE;
640
641 virtual void BeginDecoding() OVERRIDE;
642 virtual void EndDecoding() OVERRIDE;
643
644 virtual ErrorState* GetErrorState() OVERRIDE;
GetContextState()645 virtual const ContextState* GetContextState() OVERRIDE { return &state_; }
646
647 virtual void SetShaderCacheCallback(
648 const ShaderCacheCallback& callback) OVERRIDE;
649 virtual void SetWaitSyncPointCallback(
650 const WaitSyncPointCallback& callback) OVERRIDE;
651
652 virtual AsyncPixelTransferManager*
653 GetAsyncPixelTransferManager() OVERRIDE;
654 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
655 virtual void SetAsyncPixelTransferManagerForTest(
656 AsyncPixelTransferManager* manager) OVERRIDE;
657 virtual void SetIgnoreCachedStateForTest(bool ignore) OVERRIDE;
658 void ProcessFinishedAsyncTransfers();
659
660 virtual bool GetServiceTextureId(uint32 client_texture_id,
661 uint32* service_texture_id) OVERRIDE;
662
663 virtual uint32 GetTextureUploadCount() OVERRIDE;
664 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
665 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
666 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
667
668 // Restores the current state to the user's settings.
669 void RestoreCurrentFramebufferBindings();
670
671 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
672 void ApplyDirtyState();
673
674 // These check the state of the currently bound framebuffer or the
675 // backbuffer if no framebuffer is bound.
676 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
677 // check with all attached and enabled color attachments.
678 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
679 bool BoundFramebufferHasDepthAttachment();
680 bool BoundFramebufferHasStencilAttachment();
681
682 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
683
684 // Overridden from FramebufferManager::TextureDetachObserver:
685 virtual void OnTextureRefDetachedFromFramebuffer(
686 TextureRef* texture) OVERRIDE;
687
688 // Overriden from ErrorStateClient.
689 virtual void OnOutOfMemoryError() OVERRIDE;
690
691 // Helpers to facilitate calling into compatible extensions.
692 static void RenderbufferStorageMultisampleHelper(
693 const FeatureInfo* feature_info,
694 GLenum target,
695 GLsizei samples,
696 GLenum internal_format,
697 GLsizei width,
698 GLsizei height);
699
700 void BlitFramebufferHelper(GLint srcX0,
701 GLint srcY0,
702 GLint srcX1,
703 GLint srcY1,
704 GLint dstX0,
705 GLint dstY0,
706 GLint dstX1,
707 GLint dstY1,
708 GLbitfield mask,
709 GLenum filter);
710
711 private:
712 friend class ScopedFrameBufferBinder;
713 friend class ScopedResolvedFrameBufferBinder;
714 friend class BackFramebuffer;
715
716 // Initialize or re-initialize the shader translator.
717 bool InitializeShaderTranslator();
718
719 void UpdateCapabilities();
720
721 // Helpers for the glGen and glDelete functions.
722 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
723 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
724 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
725 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
726 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
727 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
728 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
729 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
730 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
731 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
732 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
733 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
734
735 // Helper for async upload token completion notification callback.
736 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
737 uint32 sync_data_shm_id,
738 uint32 sync_data_shm_offset);
739
740
741
742 // Workarounds
743 void OnFboChanged() const;
744 void OnUseFramebuffer() const;
745
746 // TODO(gman): Cache these pointers?
buffer_manager()747 BufferManager* buffer_manager() {
748 return group_->buffer_manager();
749 }
750
renderbuffer_manager()751 RenderbufferManager* renderbuffer_manager() {
752 return group_->renderbuffer_manager();
753 }
754
framebuffer_manager()755 FramebufferManager* framebuffer_manager() {
756 return group_->framebuffer_manager();
757 }
758
program_manager()759 ProgramManager* program_manager() {
760 return group_->program_manager();
761 }
762
shader_manager()763 ShaderManager* shader_manager() {
764 return group_->shader_manager();
765 }
766
shader_translator_cache()767 ShaderTranslatorCache* shader_translator_cache() {
768 return group_->shader_translator_cache();
769 }
770
texture_manager() const771 const TextureManager* texture_manager() const {
772 return group_->texture_manager();
773 }
774
texture_manager()775 TextureManager* texture_manager() {
776 return group_->texture_manager();
777 }
778
mailbox_manager()779 MailboxManager* mailbox_manager() {
780 return group_->mailbox_manager();
781 }
782
image_manager()783 ImageManager* image_manager() {
784 return group_->image_manager();
785 }
786
vertex_array_manager()787 VertexArrayManager* vertex_array_manager() {
788 return vertex_array_manager_.get();
789 }
790
memory_tracker()791 MemoryTracker* memory_tracker() {
792 return group_->memory_tracker();
793 }
794
EnsureGPUMemoryAvailable(size_t estimated_size)795 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
796 MemoryTracker* tracker = memory_tracker();
797 if (tracker) {
798 return tracker->EnsureGPUMemoryAvailable(estimated_size);
799 }
800 return true;
801 }
802
IsOffscreenBufferMultisampled() const803 bool IsOffscreenBufferMultisampled() const {
804 return offscreen_target_samples_ > 1;
805 }
806
807 // Creates a Texture for the given texture.
CreateTexture(GLuint client_id,GLuint service_id)808 TextureRef* CreateTexture(
809 GLuint client_id, GLuint service_id) {
810 return texture_manager()->CreateTexture(client_id, service_id);
811 }
812
813 // Gets the texture info for the given texture. Returns NULL if none exists.
GetTexture(GLuint client_id) const814 TextureRef* GetTexture(GLuint client_id) const {
815 return texture_manager()->GetTexture(client_id);
816 }
817
818 // Deletes the texture info for the given texture.
RemoveTexture(GLuint client_id)819 void RemoveTexture(GLuint client_id) {
820 texture_manager()->RemoveTexture(client_id);
821 }
822
823 // Get the size (in pixels) of the currently bound frame buffer (either FBO
824 // or regular back buffer).
825 gfx::Size GetBoundReadFrameBufferSize();
826
827 // Get the format of the currently bound frame buffer (either FBO or regular
828 // back buffer)
829 GLenum GetBoundReadFrameBufferTextureType();
830 GLenum GetBoundReadFrameBufferInternalFormat();
831 GLenum GetBoundDrawFrameBufferInternalFormat();
832
833 // Wrapper for CompressedTexImage2D commands.
834 error::Error DoCompressedTexImage2D(
835 GLenum target,
836 GLint level,
837 GLenum internal_format,
838 GLsizei width,
839 GLsizei height,
840 GLint border,
841 GLsizei image_size,
842 const void* data);
843
844 // Wrapper for CompressedTexSubImage2D.
845 void DoCompressedTexSubImage2D(
846 GLenum target,
847 GLint level,
848 GLint xoffset,
849 GLint yoffset,
850 GLsizei width,
851 GLsizei height,
852 GLenum format,
853 GLsizei imageSize,
854 const void * data);
855
856 // Wrapper for CopyTexImage2D.
857 void DoCopyTexImage2D(
858 GLenum target,
859 GLint level,
860 GLenum internal_format,
861 GLint x,
862 GLint y,
863 GLsizei width,
864 GLsizei height,
865 GLint border);
866
867 // Wrapper for SwapBuffers.
868 void DoSwapBuffers();
869
870 // Wrapper for CopyTexSubImage2D.
871 void DoCopyTexSubImage2D(
872 GLenum target,
873 GLint level,
874 GLint xoffset,
875 GLint yoffset,
876 GLint x,
877 GLint y,
878 GLsizei width,
879 GLsizei height);
880
881 // Validation for TexSubImage2D.
882 bool ValidateTexSubImage2D(
883 error::Error* error,
884 const char* function_name,
885 GLenum target,
886 GLint level,
887 GLint xoffset,
888 GLint yoffset,
889 GLsizei width,
890 GLsizei height,
891 GLenum format,
892 GLenum type,
893 const void * data);
894
895 // Wrapper for TexSubImage2D.
896 error::Error DoTexSubImage2D(
897 GLenum target,
898 GLint level,
899 GLint xoffset,
900 GLint yoffset,
901 GLsizei width,
902 GLsizei height,
903 GLenum format,
904 GLenum type,
905 const void * data);
906
907 // Extra validation for async tex(Sub)Image2D.
908 bool ValidateAsyncTransfer(
909 const char* function_name,
910 TextureRef* texture_ref,
911 GLenum target,
912 GLint level,
913 const void * data);
914
915 // Wrapper for TexImageIOSurface2DCHROMIUM.
916 void DoTexImageIOSurface2DCHROMIUM(
917 GLenum target,
918 GLsizei width,
919 GLsizei height,
920 GLuint io_surface_id,
921 GLuint plane);
922
923 void DoCopyTextureCHROMIUM(
924 GLenum target,
925 GLuint source_id,
926 GLuint target_id,
927 GLint level,
928 GLenum internal_format,
929 GLenum dest_type);
930
931 // Wrapper for TexStorage2DEXT.
932 void DoTexStorage2DEXT(
933 GLenum target,
934 GLint levels,
935 GLenum internal_format,
936 GLsizei width,
937 GLsizei height);
938
939 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
940 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
941 const GLbyte* key);
942 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
943 GLenum target, const GLbyte* data);
944
945 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
946 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
947 GLuint client_id);
948
949 void DoBindTexImage2DCHROMIUM(
950 GLenum target,
951 GLint image_id);
952 void DoReleaseTexImage2DCHROMIUM(
953 GLenum target,
954 GLint image_id);
955
956 void DoTraceEndCHROMIUM(void);
957
958 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
959
960 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
961
962 // Creates a Program for the given program.
CreateProgram(GLuint client_id,GLuint service_id)963 Program* CreateProgram(
964 GLuint client_id, GLuint service_id) {
965 return program_manager()->CreateProgram(client_id, service_id);
966 }
967
968 // Gets the program info for the given program. Returns NULL if none exists.
GetProgram(GLuint client_id)969 Program* GetProgram(GLuint client_id) {
970 return program_manager()->GetProgram(client_id);
971 }
972
973 #if defined(NDEBUG)
LogClientServiceMapping(const char *,GLuint,GLuint)974 void LogClientServiceMapping(
975 const char* /* function_name */,
976 GLuint /* client_id */,
977 GLuint /* service_id */) {
978 }
979 template<typename T>
LogClientServiceForInfo(T *,GLuint,const char *)980 void LogClientServiceForInfo(
981 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
982 }
983 #else
LogClientServiceMapping(const char * function_name,GLuint client_id,GLuint service_id)984 void LogClientServiceMapping(
985 const char* function_name, GLuint client_id, GLuint service_id) {
986 if (service_logging_) {
987 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
988 << ": client_id = " << client_id
989 << ", service_id = " << service_id;
990 }
991 }
992 template<typename T>
LogClientServiceForInfo(T * info,GLuint client_id,const char * function_name)993 void LogClientServiceForInfo(
994 T* info, GLuint client_id, const char* function_name) {
995 if (info) {
996 LogClientServiceMapping(function_name, client_id, info->service_id());
997 }
998 }
999 #endif
1000
1001 // Gets the program info for the given program. If it's not a program
1002 // generates a GL error. Returns NULL if not program.
GetProgramInfoNotShader(GLuint client_id,const char * function_name)1003 Program* GetProgramInfoNotShader(
1004 GLuint client_id, const char* function_name) {
1005 Program* program = GetProgram(client_id);
1006 if (!program) {
1007 if (GetShader(client_id)) {
1008 LOCAL_SET_GL_ERROR(
1009 GL_INVALID_OPERATION, function_name, "shader passed for program");
1010 } else {
1011 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
1012 }
1013 }
1014 LogClientServiceForInfo(program, client_id, function_name);
1015 return program;
1016 }
1017
1018
1019 // Creates a Shader for the given shader.
CreateShader(GLuint client_id,GLuint service_id,GLenum shader_type)1020 Shader* CreateShader(
1021 GLuint client_id,
1022 GLuint service_id,
1023 GLenum shader_type) {
1024 return shader_manager()->CreateShader(
1025 client_id, service_id, shader_type);
1026 }
1027
1028 // Gets the shader info for the given shader. Returns NULL if none exists.
GetShader(GLuint client_id)1029 Shader* GetShader(GLuint client_id) {
1030 return shader_manager()->GetShader(client_id);
1031 }
1032
1033 // Gets the shader info for the given shader. If it's not a shader generates a
1034 // GL error. Returns NULL if not shader.
GetShaderInfoNotProgram(GLuint client_id,const char * function_name)1035 Shader* GetShaderInfoNotProgram(
1036 GLuint client_id, const char* function_name) {
1037 Shader* shader = GetShader(client_id);
1038 if (!shader) {
1039 if (GetProgram(client_id)) {
1040 LOCAL_SET_GL_ERROR(
1041 GL_INVALID_OPERATION, function_name, "program passed for shader");
1042 } else {
1043 LOCAL_SET_GL_ERROR(
1044 GL_INVALID_VALUE, function_name, "unknown shader");
1045 }
1046 }
1047 LogClientServiceForInfo(shader, client_id, function_name);
1048 return shader;
1049 }
1050
1051 // Creates a buffer info for the given buffer.
CreateBuffer(GLuint client_id,GLuint service_id)1052 void CreateBuffer(GLuint client_id, GLuint service_id) {
1053 return buffer_manager()->CreateBuffer(client_id, service_id);
1054 }
1055
1056 // Gets the buffer info for the given buffer.
GetBuffer(GLuint client_id)1057 Buffer* GetBuffer(GLuint client_id) {
1058 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1059 return buffer;
1060 }
1061
1062 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1063 // on glDeleteBuffers so we can make sure the user does not try to render
1064 // with deleted buffers.
1065 void RemoveBuffer(GLuint client_id);
1066
1067 // Creates a framebuffer info for the given framebuffer.
CreateFramebuffer(GLuint client_id,GLuint service_id)1068 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1069 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
1070 }
1071
1072 // Gets the framebuffer info for the given framebuffer.
GetFramebuffer(GLuint client_id)1073 Framebuffer* GetFramebuffer(GLuint client_id) {
1074 return framebuffer_manager()->GetFramebuffer(client_id);
1075 }
1076
1077 // Removes the framebuffer info for the given framebuffer.
RemoveFramebuffer(GLuint client_id)1078 void RemoveFramebuffer(GLuint client_id) {
1079 framebuffer_manager()->RemoveFramebuffer(client_id);
1080 }
1081
1082 // Creates a renderbuffer info for the given renderbuffer.
CreateRenderbuffer(GLuint client_id,GLuint service_id)1083 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1084 return renderbuffer_manager()->CreateRenderbuffer(
1085 client_id, service_id);
1086 }
1087
1088 // Gets the renderbuffer info for the given renderbuffer.
GetRenderbuffer(GLuint client_id)1089 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1090 return renderbuffer_manager()->GetRenderbuffer(client_id);
1091 }
1092
1093 // Removes the renderbuffer info for the given renderbuffer.
RemoveRenderbuffer(GLuint client_id)1094 void RemoveRenderbuffer(GLuint client_id) {
1095 renderbuffer_manager()->RemoveRenderbuffer(client_id);
1096 }
1097
1098 // Gets the vertex attrib manager for the given vertex array.
GetVertexAttribManager(GLuint client_id)1099 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1100 VertexAttribManager* info =
1101 vertex_array_manager()->GetVertexAttribManager(client_id);
1102 return info;
1103 }
1104
1105 // Removes the vertex attrib manager for the given vertex array.
RemoveVertexAttribManager(GLuint client_id)1106 void RemoveVertexAttribManager(GLuint client_id) {
1107 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1108 }
1109
1110 // Creates a vertex attrib manager for the given vertex array.
CreateVertexAttribManager(GLuint client_id,GLuint service_id,bool client_visible)1111 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1112 GLuint client_id,
1113 GLuint service_id,
1114 bool client_visible) {
1115 return vertex_array_manager()->CreateVertexAttribManager(
1116 client_id, service_id, group_->max_vertex_attribs(), client_visible);
1117 }
1118
1119 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
1120 void DoBindUniformLocationCHROMIUM(
1121 GLuint client_id, GLint location, const char* name);
1122
1123 error::Error GetAttribLocationHelper(
1124 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1125 const std::string& name_str);
1126
1127 error::Error GetUniformLocationHelper(
1128 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1129 const std::string& name_str);
1130
1131 // Helper for glShaderSource.
1132 error::Error ShaderSourceHelper(
1133 GLuint client_id, const char* data, uint32 data_size);
1134
1135 // Clear any textures used by the current program.
1136 bool ClearUnclearedTextures();
1137
1138 // Clears any uncleared attachments attached to the given frame buffer.
1139 // Returns false if there was a generated GL error.
1140 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
1141
1142 // overridden from GLES2Decoder
1143 virtual bool ClearLevel(unsigned service_id,
1144 unsigned bind_target,
1145 unsigned target,
1146 int level,
1147 unsigned internal_format,
1148 unsigned format,
1149 unsigned type,
1150 int width,
1151 int height,
1152 bool is_texture_immutable) OVERRIDE;
1153
1154 // Restore all GL state that affects clearing.
1155 void RestoreClearState();
1156
1157 // Remembers the state of some capabilities.
1158 // Returns: true if glEnable/glDisable should actually be called.
1159 bool SetCapabilityState(GLenum cap, bool enabled);
1160
1161 // Check that the currently bound framebuffers are valid.
1162 // Generates GL error if not.
1163 bool CheckBoundFramebuffersValid(const char* func_name);
1164
1165 // Check if a framebuffer meets our requirements.
1166 bool CheckFramebufferValid(
1167 Framebuffer* framebuffer,
1168 GLenum target,
1169 const char* func_name);
1170
1171 // Checks if the current program exists and is valid. If not generates the
1172 // appropriate GL error. Returns true if the current program is in a usable
1173 // state.
1174 bool CheckCurrentProgram(const char* function_name);
1175
1176 // Checks if the current program exists and is valid and that location is not
1177 // -1. If the current program is not valid generates the appropriate GL
1178 // error. Returns true if the current program is in a usable state and
1179 // location is not -1.
1180 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1181
1182 // Gets the type of a uniform for a location in the current program. Sets GL
1183 // errors if the current program is not valid. Returns true if the current
1184 // program is valid and the location exists. Adjusts count so it
1185 // does not overflow the uniform.
1186 bool PrepForSetUniformByLocation(GLint fake_location,
1187 const char* function_name,
1188 Program::UniformApiType api_type,
1189 GLint* real_location,
1190 GLenum* type,
1191 GLsizei* count);
1192
1193 // Gets the service id for any simulated backbuffer fbo.
1194 GLuint GetBackbufferServiceId() const;
1195
1196 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1197 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1198
1199 // Helper for glGetVertexAttrib
1200 void GetVertexAttribHelper(
1201 const VertexAttrib* attrib, GLenum pname, GLint* param);
1202
1203 // Wrapper for glCreateProgram
1204 bool CreateProgramHelper(GLuint client_id);
1205
1206 // Wrapper for glCreateShader
1207 bool CreateShaderHelper(GLenum type, GLuint client_id);
1208
1209 // Wrapper for glActiveTexture
1210 void DoActiveTexture(GLenum texture_unit);
1211
1212 // Wrapper for glAttachShader
1213 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1214
1215 // Wrapper for glBindBuffer since we need to track the current targets.
1216 void DoBindBuffer(GLenum target, GLuint buffer);
1217
1218 // Wrapper for glBindFramebuffer since we need to track the current targets.
1219 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1220
1221 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1222 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1223
1224 // Wrapper for glBindTexture since we need to track the current targets.
1225 void DoBindTexture(GLenum target, GLuint texture);
1226
1227 // Wrapper for glBindVertexArrayOES
1228 void DoBindVertexArrayOES(GLuint array);
1229 void EmulateVertexArrayState();
1230
1231 // Wrapper for glBlitFramebufferCHROMIUM.
1232 void DoBlitFramebufferCHROMIUM(
1233 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1234 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1235 GLbitfield mask, GLenum filter);
1236
1237 // Wrapper for glBufferSubData.
1238 void DoBufferSubData(
1239 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1240
1241 // Wrapper for glCheckFramebufferStatus
1242 GLenum DoCheckFramebufferStatus(GLenum target);
1243
1244 // Wrapper for glClear
1245 error::Error DoClear(GLbitfield mask);
1246
1247 // Wrappers for various state.
1248 void DoDepthRangef(GLclampf znear, GLclampf zfar);
1249 void DoSampleCoverage(GLclampf value, GLboolean invert);
1250
1251 // Wrapper for glCompileShader.
1252 void DoCompileShader(GLuint shader);
1253
1254 // Helper for DeleteSharedIdsCHROMIUM commands.
1255 void DoDeleteSharedIdsCHROMIUM(
1256 GLuint namespace_id, GLsizei n, const GLuint* ids);
1257
1258 // Wrapper for glDetachShader
1259 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1260
1261 // Wrapper for glDisable
1262 void DoDisable(GLenum cap);
1263
1264 // Wrapper for glDisableVertexAttribArray.
1265 void DoDisableVertexAttribArray(GLuint index);
1266
1267 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1268 // attachments.
1269 void DoDiscardFramebufferEXT(GLenum target,
1270 GLsizei numAttachments,
1271 const GLenum* attachments);
1272
1273 // Wrapper for glEnable
1274 void DoEnable(GLenum cap);
1275
1276 // Wrapper for glEnableVertexAttribArray.
1277 void DoEnableVertexAttribArray(GLuint index);
1278
1279 // Wrapper for glFinish.
1280 void DoFinish();
1281
1282 // Wrapper for glFlush.
1283 void DoFlush();
1284
1285 // Wrapper for glFramebufferRenderbufffer.
1286 void DoFramebufferRenderbuffer(
1287 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1288 GLuint renderbuffer);
1289
1290 // Wrapper for glFramebufferTexture2D.
1291 void DoFramebufferTexture2D(
1292 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1293 GLint level);
1294
1295 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1296 void DoFramebufferTexture2DMultisample(
1297 GLenum target, GLenum attachment, GLenum textarget,
1298 GLuint texture, GLint level, GLsizei samples);
1299
1300 // Common implementation for both DoFramebufferTexture2D wrappers.
1301 void DoFramebufferTexture2DCommon(const char* name,
1302 GLenum target, GLenum attachment, GLenum textarget,
1303 GLuint texture, GLint level, GLsizei samples);
1304
1305 // Wrapper for glGenerateMipmap
1306 void DoGenerateMipmap(GLenum target);
1307
1308 // Helper for GenSharedIdsCHROMIUM commands.
1309 void DoGenSharedIdsCHROMIUM(
1310 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1311
1312 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1313 // to account for different pname values defined in different extension
1314 // variants.
1315 GLenum AdjustGetPname(GLenum pname);
1316
1317 // Wrapper for DoGetBooleanv.
1318 void DoGetBooleanv(GLenum pname, GLboolean* params);
1319
1320 // Wrapper for DoGetFloatv.
1321 void DoGetFloatv(GLenum pname, GLfloat* params);
1322
1323 // Wrapper for glGetFramebufferAttachmentParameteriv.
1324 void DoGetFramebufferAttachmentParameteriv(
1325 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1326
1327 // Wrapper for glGetIntegerv.
1328 void DoGetIntegerv(GLenum pname, GLint* params);
1329
1330 // Gets the max value in a range in a buffer.
1331 GLuint DoGetMaxValueInBufferCHROMIUM(
1332 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1333
1334 // Wrapper for glGetBufferParameteriv.
1335 void DoGetBufferParameteriv(
1336 GLenum target, GLenum pname, GLint* params);
1337
1338 // Wrapper for glGetProgramiv.
1339 void DoGetProgramiv(
1340 GLuint program_id, GLenum pname, GLint* params);
1341
1342 // Wrapper for glRenderbufferParameteriv.
1343 void DoGetRenderbufferParameteriv(
1344 GLenum target, GLenum pname, GLint* params);
1345
1346 // Wrapper for glGetShaderiv
1347 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1348
1349 // Wrappers for glGetTexParameter.
1350 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1351 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1352 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1353
1354 // Wrappers for glGetVertexAttrib.
1355 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1356 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1357
1358 // Wrappers for glIsXXX functions.
1359 bool DoIsEnabled(GLenum cap);
1360 bool DoIsBuffer(GLuint client_id);
1361 bool DoIsFramebuffer(GLuint client_id);
1362 bool DoIsProgram(GLuint client_id);
1363 bool DoIsRenderbuffer(GLuint client_id);
1364 bool DoIsShader(GLuint client_id);
1365 bool DoIsTexture(GLuint client_id);
1366 bool DoIsVertexArrayOES(GLuint client_id);
1367
1368 // Wrapper for glLinkProgram
1369 void DoLinkProgram(GLuint program);
1370
1371 // Helper for RegisterSharedIdsCHROMIUM.
1372 void DoRegisterSharedIdsCHROMIUM(
1373 GLuint namespace_id, GLsizei n, const GLuint* ids);
1374
1375 // Wrapper for glRenderbufferStorage.
1376 void DoRenderbufferStorage(
1377 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
1378
1379 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1380 void DoRenderbufferStorageMultisampleCHROMIUM(
1381 GLenum target, GLsizei samples, GLenum internalformat,
1382 GLsizei width, GLsizei height);
1383
1384 // Handler for glRenderbufferStorageMultisampleEXT
1385 // (multisampled_render_to_texture).
1386 void DoRenderbufferStorageMultisampleEXT(
1387 GLenum target, GLsizei samples, GLenum internalformat,
1388 GLsizei width, GLsizei height);
1389
1390 // Common validation for multisample extensions.
1391 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1392 GLenum internalformat,
1393 GLsizei width,
1394 GLsizei height);
1395
1396 // Verifies that the currently bound multisample renderbuffer is valid
1397 // Very slow! Only done on platforms with driver bugs that return invalid
1398 // buffers under memory pressure
1399 bool VerifyMultisampleRenderbufferIntegrity(
1400 GLuint renderbuffer, GLenum format);
1401
1402 // Wrapper for glReleaseShaderCompiler.
DoReleaseShaderCompiler()1403 void DoReleaseShaderCompiler() { }
1404
1405 // Wrappers for glTexParameter functions.
1406 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1407 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1408 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1409 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1410
1411 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1412 // spec only these 2 functions can be used to set sampler uniforms.
1413 void DoUniform1i(GLint fake_location, GLint v0);
1414 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1415 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1416 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1417 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
1418
1419 // Wrappers for glUniformfv because some drivers don't correctly accept
1420 // bool uniforms.
1421 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1422 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1423 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1424 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
1425
1426 void DoUniformMatrix2fv(
1427 GLint fake_location, GLsizei count, GLboolean transpose,
1428 const GLfloat* value);
1429 void DoUniformMatrix3fv(
1430 GLint fake_location, GLsizei count, GLboolean transpose,
1431 const GLfloat* value);
1432 void DoUniformMatrix4fv(
1433 GLint fake_location, GLsizei count, GLboolean transpose,
1434 const GLfloat* value);
1435
1436 bool SetVertexAttribValue(
1437 const char* function_name, GLuint index, const GLfloat* value);
1438
1439 // Wrappers for glVertexAttrib??
1440 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1441 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1442 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1443 void DoVertexAttrib4f(
1444 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1445 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1446 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1447 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1448 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1449
1450 // Wrapper for glViewport
1451 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1452
1453 // Wrapper for glUseProgram
1454 void DoUseProgram(GLuint program);
1455
1456 // Wrapper for glValidateProgram.
1457 void DoValidateProgram(GLuint program_client_id);
1458
1459 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1460 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1461 void DoPopGroupMarkerEXT(void);
1462
1463 // Gets the number of values that will be returned by glGetXXX. Returns
1464 // false if pname is unknown.
1465 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1466
1467 // Checks if the current program and vertex attributes are valid for drawing.
1468 bool IsDrawValid(
1469 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
1470
1471 // Returns true if successful, simulated will be true if attrib0 was
1472 // simulated.
1473 bool SimulateAttrib0(
1474 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
1475 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
1476
1477 // If an image is bound to texture, this will call Will/DidUseTexImage
1478 // if needed.
1479 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1480 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1481
1482 // Returns false if textures were replaced.
1483 bool PrepareTexturesForRender();
1484 void RestoreStateForTextures();
1485
1486 // Returns true if GL_FIXED attribs were simulated.
1487 bool SimulateFixedAttribs(
1488 const char* function_name,
1489 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
1490 void RestoreStateForSimulatedFixedAttribs();
1491
1492 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1493 // cases (primcount is 0 for non-instanced).
1494 error::Error DoDrawArrays(
1495 const char* function_name,
1496 bool instanced, GLenum mode, GLint first, GLsizei count,
1497 GLsizei primcount);
1498 error::Error DoDrawElements(
1499 const char* function_name,
1500 bool instanced, GLenum mode, GLsizei count, GLenum type,
1501 int32 offset, GLsizei primcount);
1502
GetBindTargetForSamplerType(GLenum type)1503 GLenum GetBindTargetForSamplerType(GLenum type) {
1504 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
1505 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1506 switch (type) {
1507 case GL_SAMPLER_2D:
1508 return GL_TEXTURE_2D;
1509 case GL_SAMPLER_CUBE:
1510 return GL_TEXTURE_CUBE_MAP;
1511 case GL_SAMPLER_EXTERNAL_OES:
1512 return GL_TEXTURE_EXTERNAL_OES;
1513 case GL_SAMPLER_2D_RECT_ARB:
1514 return GL_TEXTURE_RECTANGLE_ARB;
1515 }
1516
1517 NOTREACHED();
1518 return 0;
1519 }
1520
1521 // Gets the framebuffer info for a particular target.
GetFramebufferInfoForTarget(GLenum target)1522 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1523 Framebuffer* framebuffer = NULL;
1524 switch (target) {
1525 case GL_FRAMEBUFFER:
1526 case GL_DRAW_FRAMEBUFFER_EXT:
1527 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
1528 break;
1529 case GL_READ_FRAMEBUFFER_EXT:
1530 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
1531 break;
1532 default:
1533 NOTREACHED();
1534 break;
1535 }
1536 return framebuffer;
1537 }
1538
GetRenderbufferInfoForTarget(GLenum target)1539 Renderbuffer* GetRenderbufferInfoForTarget(
1540 GLenum target) {
1541 Renderbuffer* renderbuffer = NULL;
1542 switch (target) {
1543 case GL_RENDERBUFFER:
1544 renderbuffer = state_.bound_renderbuffer.get();
1545 break;
1546 default:
1547 NOTREACHED();
1548 break;
1549 }
1550 return renderbuffer;
1551 }
1552
1553 // Validates the program and location for a glGetUniform call and returns
1554 // a SizeResult setup to receive the result. Returns true if glGetUniform
1555 // should be called.
1556 bool GetUniformSetup(
1557 GLuint program, GLint fake_location,
1558 uint32 shm_id, uint32 shm_offset,
1559 error::Error* error, GLint* real_location, GLuint* service_id,
1560 void** result, GLenum* result_type);
1561
1562 virtual bool WasContextLost() OVERRIDE;
1563 virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
1564 virtual void LoseContext(uint32 reset_status) OVERRIDE;
1565
1566 #if defined(OS_MACOSX)
1567 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1568 #endif
1569
1570 bool ValidateCompressedTexDimensions(
1571 const char* function_name,
1572 GLint level, GLsizei width, GLsizei height, GLenum format);
1573 bool ValidateCompressedTexFuncData(
1574 const char* function_name,
1575 GLsizei width, GLsizei height, GLenum format, size_t size);
1576 bool ValidateCompressedTexSubDimensions(
1577 const char* function_name,
1578 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1579 GLsizei width, GLsizei height, GLenum format,
1580 Texture* texture);
1581
1582 void RenderWarning(const char* filename, int line, const std::string& msg);
1583 void PerformanceWarning(
1584 const char* filename, int line, const std::string& msg);
1585
features() const1586 const FeatureInfo::FeatureFlags& features() const {
1587 return feature_info_->feature_flags();
1588 }
1589
workarounds() const1590 const FeatureInfo::Workarounds& workarounds() const {
1591 return feature_info_->workarounds();
1592 }
1593
ShouldDeferDraws()1594 bool ShouldDeferDraws() {
1595 return !offscreen_target_frame_buffer_.get() &&
1596 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
1597 surface_->DeferDraws();
1598 }
1599
ShouldDeferReads()1600 bool ShouldDeferReads() {
1601 return !offscreen_target_frame_buffer_.get() &&
1602 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
1603 surface_->DeferDraws();
1604 }
1605
WillAccessBoundFramebufferForDraw()1606 error::Error WillAccessBoundFramebufferForDraw() {
1607 if (ShouldDeferDraws())
1608 return error::kDeferCommandUntilLater;
1609 if (!offscreen_target_frame_buffer_.get() &&
1610 !framebuffer_state_.bound_draw_framebuffer.get() &&
1611 !surface_->SetBackbufferAllocation(true))
1612 return error::kLostContext;
1613 return error::kNoError;
1614 }
1615
WillAccessBoundFramebufferForRead()1616 error::Error WillAccessBoundFramebufferForRead() {
1617 if (ShouldDeferReads())
1618 return error::kDeferCommandUntilLater;
1619 if (!offscreen_target_frame_buffer_.get() &&
1620 !framebuffer_state_.bound_read_framebuffer.get() &&
1621 !surface_->SetBackbufferAllocation(true))
1622 return error::kLostContext;
1623 return error::kNoError;
1624 }
1625
1626 void ProcessPendingReadPixels();
1627 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1628
1629 // Generate a member function prototype for each command in an automated and
1630 // typesafe way.
1631 #define GLES2_CMD_OP(name) \
1632 Error Handle ## name( \
1633 uint32 immediate_data_size, \
1634 const cmds::name& args); \
1635
1636 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1637
1638 #undef GLES2_CMD_OP
1639
1640 // The GL context this decoder renders to on behalf of the client.
1641 scoped_refptr<gfx::GLSurface> surface_;
1642 scoped_refptr<gfx::GLContext> context_;
1643
1644 // The ContextGroup for this decoder uses to track resources.
1645 scoped_refptr<ContextGroup> group_;
1646
1647 DebugMarkerManager debug_marker_manager_;
1648 Logger logger_;
1649
1650 // All the state for this context.
1651 ContextState state_;
1652
1653 // Current width and height of the offscreen frame buffer.
1654 gfx::Size offscreen_size_;
1655
1656 // Util to help with GL.
1657 GLES2Util util_;
1658
1659 // unpack flip y as last set by glPixelStorei
1660 bool unpack_flip_y_;
1661
1662 // unpack (un)premultiply alpha as last set by glPixelStorei
1663 bool unpack_premultiply_alpha_;
1664 bool unpack_unpremultiply_alpha_;
1665
1666 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1667 GLuint attrib_0_buffer_id_;
1668
1669 // The value currently in attrib_0.
1670 Vec4 attrib_0_value_;
1671
1672 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1673 bool attrib_0_buffer_matches_value_;
1674
1675 // The size of attrib 0.
1676 GLsizei attrib_0_size_;
1677
1678 // The buffer used to simulate GL_FIXED attribs.
1679 GLuint fixed_attrib_buffer_id_;
1680
1681 // The size of fiixed attrib buffer.
1682 GLsizei fixed_attrib_buffer_size_;
1683
1684 // The offscreen frame buffer that the client renders to. With EGL, the
1685 // depth and stencil buffers are separate. With regular GL there is a single
1686 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1687 // offscreen_target_stencil_render_buffer_ is unused.
1688 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1689 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1690 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1691 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1692 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
1693 GLenum offscreen_target_color_format_;
1694 GLenum offscreen_target_depth_format_;
1695 GLenum offscreen_target_stencil_format_;
1696 GLsizei offscreen_target_samples_;
1697 GLboolean offscreen_target_buffer_preserved_;
1698
1699 // The copy that is saved when SwapBuffers is called.
1700 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1701 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
1702 scoped_refptr<TextureRef>
1703 offscreen_saved_color_texture_info_;
1704
1705 // The copy that is used as the destination for multi-sample resolves.
1706 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1707 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
1708 GLenum offscreen_saved_color_format_;
1709
1710 scoped_ptr<QueryManager> query_manager_;
1711
1712 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1713
1714 base::Callback<void(gfx::Size, float)> resize_callback_;
1715
1716 WaitSyncPointCallback wait_sync_point_callback_;
1717
1718 ShaderCacheCallback shader_cache_callback_;
1719
1720 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
1721
1722 // The format of the back buffer_
1723 GLenum back_buffer_color_format_;
1724 bool back_buffer_has_depth_;
1725 bool back_buffer_has_stencil_;
1726
1727 // Backbuffer attachments that are currently undefined.
1728 uint32 backbuffer_needs_clear_bits_;
1729
1730 // The current decoder error communicates the decoder error through command
1731 // processing functions that do not return the error value. Should be set only
1732 // if not returning an error.
1733 error::Error current_decoder_error_;
1734
1735 bool use_shader_translator_;
1736 scoped_refptr<ShaderTranslator> vertex_translator_;
1737 scoped_refptr<ShaderTranslator> fragment_translator_;
1738
1739 DisallowedFeatures disallowed_features_;
1740
1741 // Cached from ContextGroup
1742 const Validators* validators_;
1743 scoped_refptr<FeatureInfo> feature_info_;
1744
1745 int frame_number_;
1746
1747 bool has_robustness_extension_;
1748 GLenum reset_status_;
1749 bool reset_by_robustness_extension_;
1750 bool supports_post_sub_buffer_;
1751
1752 // These flags are used to override the state of the shared feature_info_
1753 // member. Because the same FeatureInfo instance may be shared among many
1754 // contexts, the assumptions on the availablity of extensions in WebGL
1755 // contexts may be broken. These flags override the shared state to preserve
1756 // WebGL semantics.
1757 bool force_webgl_glsl_validation_;
1758 bool derivatives_explicitly_enabled_;
1759 bool frag_depth_explicitly_enabled_;
1760 bool draw_buffers_explicitly_enabled_;
1761 bool shader_texture_lod_explicitly_enabled_;
1762
1763 bool compile_shader_always_succeeds_;
1764
1765 // An optional behaviour to lose the context and group when OOM.
1766 bool lose_context_when_out_of_memory_;
1767
1768 // Log extra info.
1769 bool service_logging_;
1770
1771 #if defined(OS_MACOSX)
1772 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
1773 TextureToIOSurfaceMap texture_to_io_surface_map_;
1774 #endif
1775
1776 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1777
1778 // Cached values of the currently assigned viewport dimensions.
1779 GLsizei viewport_max_width_;
1780 GLsizei viewport_max_height_;
1781
1782 // Command buffer stats.
1783 base::TimeDelta total_processing_commands_time_;
1784
1785 // States related to each manager.
1786 DecoderTextureState texture_state_;
1787 DecoderFramebufferState framebuffer_state_;
1788
1789 scoped_ptr<GPUTracer> gpu_tracer_;
1790 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
1791 int gpu_trace_level_;
1792 bool gpu_trace_commands_;
1793
1794 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1795
1796 // Used to validate multisample renderbuffers if needed
1797 GLuint validation_texture_;
1798 GLuint validation_fbo_multisample_;
1799 GLuint validation_fbo_;
1800
1801 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1802 };
1803
ScopedGLErrorSuppressor(const char * function_name,ErrorState * error_state)1804 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
1805 const char* function_name, ErrorState* error_state)
1806 : function_name_(function_name),
1807 error_state_(error_state) {
1808 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
1809 }
1810
~ScopedGLErrorSuppressor()1811 ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
1812 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
1813 }
1814
RestoreCurrentTextureBindings(ContextState * state,GLenum target)1815 static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
1816 TextureUnit& info = state->texture_units[0];
1817 GLuint last_id;
1818 scoped_refptr<TextureRef> texture_ref;
1819 switch (target) {
1820 case GL_TEXTURE_2D:
1821 texture_ref = info.bound_texture_2d;
1822 break;
1823 case GL_TEXTURE_CUBE_MAP:
1824 texture_ref = info.bound_texture_cube_map;
1825 break;
1826 case GL_TEXTURE_EXTERNAL_OES:
1827 texture_ref = info.bound_texture_external_oes;
1828 break;
1829 case GL_TEXTURE_RECTANGLE_ARB:
1830 texture_ref = info.bound_texture_rectangle_arb;
1831 break;
1832 default:
1833 NOTREACHED();
1834 break;
1835 }
1836 if (texture_ref.get()) {
1837 last_id = texture_ref->service_id();
1838 } else {
1839 last_id = 0;
1840 }
1841
1842 glBindTexture(target, last_id);
1843 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1844 }
1845
ScopedTextureBinder(ContextState * state,GLuint id,GLenum target)1846 ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1847 GLuint id,
1848 GLenum target)
1849 : state_(state),
1850 target_(target) {
1851 ScopedGLErrorSuppressor suppressor(
1852 "ScopedTextureBinder::ctor", state_->GetErrorState());
1853
1854 // TODO(apatrick): Check if there are any other states that need to be reset
1855 // before binding a new texture.
1856 glActiveTexture(GL_TEXTURE0);
1857 glBindTexture(target, id);
1858 }
1859
~ScopedTextureBinder()1860 ScopedTextureBinder::~ScopedTextureBinder() {
1861 ScopedGLErrorSuppressor suppressor(
1862 "ScopedTextureBinder::dtor", state_->GetErrorState());
1863 RestoreCurrentTextureBindings(state_, target_);
1864 }
1865
ScopedRenderBufferBinder(ContextState * state,GLuint id)1866 ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
1867 GLuint id)
1868 : state_(state) {
1869 ScopedGLErrorSuppressor suppressor(
1870 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
1871 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1872 }
1873
~ScopedRenderBufferBinder()1874 ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
1875 ScopedGLErrorSuppressor suppressor(
1876 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1877 state_->RestoreRenderbufferBindings();
1878 }
1879
ScopedFrameBufferBinder(GLES2DecoderImpl * decoder,GLuint id)1880 ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1881 GLuint id)
1882 : decoder_(decoder) {
1883 ScopedGLErrorSuppressor suppressor(
1884 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
1885 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
1886 decoder->OnFboChanged();
1887 }
1888
~ScopedFrameBufferBinder()1889 ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
1890 ScopedGLErrorSuppressor suppressor(
1891 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
1892 decoder_->RestoreCurrentFramebufferBindings();
1893 }
1894
ScopedResolvedFrameBufferBinder(GLES2DecoderImpl * decoder,bool enforce_internal_framebuffer,bool internal)1895 ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
1896 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
1897 : decoder_(decoder) {
1898 resolve_and_bind_ = (
1899 decoder_->offscreen_target_frame_buffer_.get() &&
1900 decoder_->IsOffscreenBufferMultisampled() &&
1901 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1902 enforce_internal_framebuffer));
1903 if (!resolve_and_bind_)
1904 return;
1905
1906 ScopedGLErrorSuppressor suppressor(
1907 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
1908 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1909 decoder_->offscreen_target_frame_buffer_->id());
1910 GLuint targetid;
1911 if (internal) {
1912 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1913 decoder_->offscreen_resolved_frame_buffer_.reset(
1914 new BackFramebuffer(decoder_));
1915 decoder_->offscreen_resolved_frame_buffer_->Create();
1916 decoder_->offscreen_resolved_color_texture_.reset(
1917 new BackTexture(decoder->memory_tracker(), &decoder->state_));
1918 decoder_->offscreen_resolved_color_texture_->Create();
1919
1920 DCHECK(decoder_->offscreen_saved_color_format_);
1921 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
1922 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1923 false);
1924 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1925 decoder_->offscreen_resolved_color_texture_.get());
1926 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1927 GL_FRAMEBUFFER_COMPLETE) {
1928 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1929 << "because offscreen resolved FBO was incomplete.";
1930 return;
1931 }
1932 }
1933 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1934 } else {
1935 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1936 }
1937 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
1938 const int width = decoder_->offscreen_size_.width();
1939 const int height = decoder_->offscreen_size_.height();
1940 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
1941 decoder->BlitFramebufferHelper(0,
1942 0,
1943 width,
1944 height,
1945 0,
1946 0,
1947 width,
1948 height,
1949 GL_COLOR_BUFFER_BIT,
1950 GL_NEAREST);
1951 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
1952 }
1953
~ScopedResolvedFrameBufferBinder()1954 ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1955 if (!resolve_and_bind_)
1956 return;
1957
1958 ScopedGLErrorSuppressor suppressor(
1959 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
1960 decoder_->RestoreCurrentFramebufferBindings();
1961 if (decoder_->state_.enable_flags.scissor_test) {
1962 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
1963 }
1964 }
1965
BackTexture(MemoryTracker * memory_tracker,ContextState * state)1966 BackTexture::BackTexture(
1967 MemoryTracker* memory_tracker,
1968 ContextState* state)
1969 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
1970 state_(state),
1971 bytes_allocated_(0),
1972 id_(0) {
1973 }
1974
~BackTexture()1975 BackTexture::~BackTexture() {
1976 // This does not destroy the render texture because that would require that
1977 // the associated GL context was current. Just check that it was explicitly
1978 // destroyed.
1979 DCHECK_EQ(id_, 0u);
1980 }
1981
Create()1982 void BackTexture::Create() {
1983 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
1984 state_->GetErrorState());
1985 Destroy();
1986 glGenTextures(1, &id_);
1987 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
1988 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1989 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1990 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1991 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1992
1993 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1994 // never called on an offscreen context, no data will ever be uploaded to the
1995 // saved offscreen color texture (it is deferred until to when SwapBuffers
1996 // is called). My idea is that some nvidia drivers might have a bug where
1997 // deleting a texture that has never been populated might cause a
1998 // crash.
1999 glTexImage2D(
2000 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2001
2002 bytes_allocated_ = 16u * 16u * 4u;
2003 memory_tracker_.TrackMemAlloc(bytes_allocated_);
2004 }
2005
AllocateStorage(const gfx::Size & size,GLenum format,bool zero)2006 bool BackTexture::AllocateStorage(
2007 const gfx::Size& size, GLenum format, bool zero) {
2008 DCHECK_NE(id_, 0u);
2009 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
2010 state_->GetErrorState());
2011 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
2012 uint32 image_size = 0;
2013 GLES2Util::ComputeImageDataSizes(
2014 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
2015 NULL, NULL);
2016
2017 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2018 return false;
2019 }
2020
2021 scoped_ptr<char[]> zero_data;
2022 if (zero) {
2023 zero_data.reset(new char[image_size]);
2024 memset(zero_data.get(), 0, image_size);
2025 }
2026
2027 glTexImage2D(GL_TEXTURE_2D,
2028 0, // mip level
2029 format,
2030 size.width(),
2031 size.height(),
2032 0, // border
2033 format,
2034 GL_UNSIGNED_BYTE,
2035 zero_data.get());
2036
2037 size_ = size;
2038
2039 bool success = glGetError() == GL_NO_ERROR;
2040 if (success) {
2041 memory_tracker_.TrackMemFree(bytes_allocated_);
2042 bytes_allocated_ = image_size;
2043 memory_tracker_.TrackMemAlloc(bytes_allocated_);
2044 }
2045 return success;
2046 }
2047
Copy(const gfx::Size & size,GLenum format)2048 void BackTexture::Copy(const gfx::Size& size, GLenum format) {
2049 DCHECK_NE(id_, 0u);
2050 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
2051 state_->GetErrorState());
2052 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
2053 glCopyTexImage2D(GL_TEXTURE_2D,
2054 0, // level
2055 format,
2056 0, 0,
2057 size.width(),
2058 size.height(),
2059 0); // border
2060 }
2061
Destroy()2062 void BackTexture::Destroy() {
2063 if (id_ != 0) {
2064 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
2065 state_->GetErrorState());
2066 glDeleteTextures(1, &id_);
2067 id_ = 0;
2068 }
2069 memory_tracker_.TrackMemFree(bytes_allocated_);
2070 bytes_allocated_ = 0;
2071 }
2072
Invalidate()2073 void BackTexture::Invalidate() {
2074 id_ = 0;
2075 }
2076
BackRenderbuffer(RenderbufferManager * renderbuffer_manager,MemoryTracker * memory_tracker,ContextState * state)2077 BackRenderbuffer::BackRenderbuffer(
2078 RenderbufferManager* renderbuffer_manager,
2079 MemoryTracker* memory_tracker,
2080 ContextState* state)
2081 : renderbuffer_manager_(renderbuffer_manager),
2082 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2083 state_(state),
2084 bytes_allocated_(0),
2085 id_(0) {
2086 }
2087
~BackRenderbuffer()2088 BackRenderbuffer::~BackRenderbuffer() {
2089 // This does not destroy the render buffer because that would require that
2090 // the associated GL context was current. Just check that it was explicitly
2091 // destroyed.
2092 DCHECK_EQ(id_, 0u);
2093 }
2094
Create()2095 void BackRenderbuffer::Create() {
2096 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
2097 state_->GetErrorState());
2098 Destroy();
2099 glGenRenderbuffersEXT(1, &id_);
2100 }
2101
AllocateStorage(const FeatureInfo * feature_info,const gfx::Size & size,GLenum format,GLsizei samples)2102 bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2103 const gfx::Size& size,
2104 GLenum format,
2105 GLsizei samples) {
2106 ScopedGLErrorSuppressor suppressor(
2107 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2108 ScopedRenderBufferBinder binder(state_, id_);
2109
2110 uint32 estimated_size = 0;
2111 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
2112 size.width(), size.height(), samples, format, &estimated_size)) {
2113 return false;
2114 }
2115
2116 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2117 return false;
2118 }
2119
2120 if (samples <= 1) {
2121 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2122 format,
2123 size.width(),
2124 size.height());
2125 } else {
2126 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2127 GL_RENDERBUFFER,
2128 samples,
2129 format,
2130 size.width(),
2131 size.height());
2132 }
2133 bool success = glGetError() == GL_NO_ERROR;
2134 if (success) {
2135 // Mark the previously allocated bytes as free.
2136 memory_tracker_.TrackMemFree(bytes_allocated_);
2137 bytes_allocated_ = estimated_size;
2138 // Track the newly allocated bytes.
2139 memory_tracker_.TrackMemAlloc(bytes_allocated_);
2140 }
2141 return success;
2142 }
2143
Destroy()2144 void BackRenderbuffer::Destroy() {
2145 if (id_ != 0) {
2146 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
2147 state_->GetErrorState());
2148 glDeleteRenderbuffersEXT(1, &id_);
2149 id_ = 0;
2150 }
2151 memory_tracker_.TrackMemFree(bytes_allocated_);
2152 bytes_allocated_ = 0;
2153 }
2154
Invalidate()2155 void BackRenderbuffer::Invalidate() {
2156 id_ = 0;
2157 }
2158
BackFramebuffer(GLES2DecoderImpl * decoder)2159 BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
2160 : decoder_(decoder),
2161 id_(0) {
2162 }
2163
~BackFramebuffer()2164 BackFramebuffer::~BackFramebuffer() {
2165 // This does not destroy the frame buffer because that would require that
2166 // the associated GL context was current. Just check that it was explicitly
2167 // destroyed.
2168 DCHECK_EQ(id_, 0u);
2169 }
2170
Create()2171 void BackFramebuffer::Create() {
2172 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2173 decoder_->GetErrorState());
2174 Destroy();
2175 glGenFramebuffersEXT(1, &id_);
2176 }
2177
AttachRenderTexture(BackTexture * texture)2178 void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
2179 DCHECK_NE(id_, 0u);
2180 ScopedGLErrorSuppressor suppressor(
2181 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
2182 ScopedFrameBufferBinder binder(decoder_, id_);
2183 GLuint attach_id = texture ? texture->id() : 0;
2184 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2185 GL_COLOR_ATTACHMENT0,
2186 GL_TEXTURE_2D,
2187 attach_id,
2188 0);
2189 }
2190
AttachRenderBuffer(GLenum target,BackRenderbuffer * render_buffer)2191 void BackFramebuffer::AttachRenderBuffer(GLenum target,
2192 BackRenderbuffer* render_buffer) {
2193 DCHECK_NE(id_, 0u);
2194 ScopedGLErrorSuppressor suppressor(
2195 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
2196 ScopedFrameBufferBinder binder(decoder_, id_);
2197 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2198 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
2199 target,
2200 GL_RENDERBUFFER,
2201 attach_id);
2202 }
2203
Destroy()2204 void BackFramebuffer::Destroy() {
2205 if (id_ != 0) {
2206 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2207 decoder_->GetErrorState());
2208 glDeleteFramebuffersEXT(1, &id_);
2209 id_ = 0;
2210 }
2211 }
2212
Invalidate()2213 void BackFramebuffer::Invalidate() {
2214 id_ = 0;
2215 }
2216
CheckStatus()2217 GLenum BackFramebuffer::CheckStatus() {
2218 DCHECK_NE(id_, 0u);
2219 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2220 decoder_->GetErrorState());
2221 ScopedFrameBufferBinder binder(decoder_, id_);
2222 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2223 }
2224
Create(ContextGroup * group)2225 GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2226 return new GLES2DecoderImpl(group);
2227 }
2228
GLES2DecoderImpl(ContextGroup * group)2229 GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
2230 : GLES2Decoder(),
2231 group_(group),
2232 logger_(&debug_marker_manager_),
2233 state_(group_->feature_info(), this, &logger_),
2234 unpack_flip_y_(false),
2235 unpack_premultiply_alpha_(false),
2236 unpack_unpremultiply_alpha_(false),
2237 attrib_0_buffer_id_(0),
2238 attrib_0_buffer_matches_value_(true),
2239 attrib_0_size_(0),
2240 fixed_attrib_buffer_id_(0),
2241 fixed_attrib_buffer_size_(0),
2242 offscreen_target_color_format_(0),
2243 offscreen_target_depth_format_(0),
2244 offscreen_target_stencil_format_(0),
2245 offscreen_target_samples_(0),
2246 offscreen_target_buffer_preserved_(true),
2247 offscreen_saved_color_format_(0),
2248 back_buffer_color_format_(0),
2249 back_buffer_has_depth_(false),
2250 back_buffer_has_stencil_(false),
2251 backbuffer_needs_clear_bits_(0),
2252 current_decoder_error_(error::kNoError),
2253 use_shader_translator_(true),
2254 validators_(group_->feature_info()->validators()),
2255 feature_info_(group_->feature_info()),
2256 frame_number_(0),
2257 has_robustness_extension_(false),
2258 reset_status_(GL_NO_ERROR),
2259 reset_by_robustness_extension_(false),
2260 supports_post_sub_buffer_(false),
2261 force_webgl_glsl_validation_(false),
2262 derivatives_explicitly_enabled_(false),
2263 frag_depth_explicitly_enabled_(false),
2264 draw_buffers_explicitly_enabled_(false),
2265 shader_texture_lod_explicitly_enabled_(false),
2266 compile_shader_always_succeeds_(false),
2267 lose_context_when_out_of_memory_(false),
2268 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2269 switches::kEnableGPUServiceLoggingGPU)),
2270 viewport_max_width_(0),
2271 viewport_max_height_(0),
2272 texture_state_(group_->feature_info()
2273 ->workarounds()
2274 .texsubimage2d_faster_than_teximage2d),
2275 validation_texture_(0),
2276 validation_fbo_multisample_(0),
2277 validation_fbo_(0) {
2278 DCHECK(group);
2279
2280 attrib_0_value_.v[0] = 0.0f;
2281 attrib_0_value_.v[1] = 0.0f;
2282 attrib_0_value_.v[2] = 0.0f;
2283 attrib_0_value_.v[3] = 1.0f;
2284
2285 // The shader translator is used for WebGL even when running on EGL
2286 // because additional restrictions are needed (like only enabling
2287 // GL_OES_standard_derivatives on demand). It is used for the unit
2288 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2289 // the empty string to CompileShader and this is not a valid shader.
2290 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
2291 CommandLine::ForCurrentProcess()->HasSwitch(
2292 switches::kDisableGLSLTranslator)) {
2293 use_shader_translator_ = false;
2294 }
2295 }
2296
~GLES2DecoderImpl()2297 GLES2DecoderImpl::~GLES2DecoderImpl() {
2298 }
2299
Initialize(const scoped_refptr<gfx::GLSurface> & surface,const scoped_refptr<gfx::GLContext> & context,bool offscreen,const gfx::Size & size,const DisallowedFeatures & disallowed_features,const std::vector<int32> & attribs)2300 bool GLES2DecoderImpl::Initialize(
2301 const scoped_refptr<gfx::GLSurface>& surface,
2302 const scoped_refptr<gfx::GLContext>& context,
2303 bool offscreen,
2304 const gfx::Size& size,
2305 const DisallowedFeatures& disallowed_features,
2306 const std::vector<int32>& attribs) {
2307 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
2308 DCHECK(context->IsCurrent(surface.get()));
2309 DCHECK(!context_.get());
2310
2311 set_initialized();
2312 gpu_tracer_ = GPUTracer::Create(this);
2313 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
2314 // TODO(vmiura): Enable changing gpu_trace_level_ at runtime
2315 gpu_trace_level_ = 2;
2316 gpu_trace_commands_ = false;
2317
2318 if (CommandLine::ForCurrentProcess()->HasSwitch(
2319 switches::kEnableGPUDebugging)) {
2320 set_debug(true);
2321 }
2322
2323 if (CommandLine::ForCurrentProcess()->HasSwitch(
2324 switches::kEnableGPUCommandLogging)) {
2325 set_log_commands(true);
2326 }
2327
2328 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2329 switches::kCompileShaderAlwaysSucceeds);
2330
2331
2332 // Take ownership of the context and surface. The surface can be replaced with
2333 // SetSurface.
2334 context_ = context;
2335 surface_ = surface;
2336
2337 ContextCreationAttribHelper attrib_parser;
2338 if (!attrib_parser.Parse(attribs))
2339 return false;
2340
2341 // Save the loseContextWhenOutOfMemory context creation attribute.
2342 lose_context_when_out_of_memory_ =
2343 attrib_parser.lose_context_when_out_of_memory_;
2344
2345 // If the failIfMajorPerformanceCaveat context creation attribute was true
2346 // and we are using a software renderer, fail.
2347 if (attrib_parser.fail_if_major_perf_caveat_ &&
2348 feature_info_->feature_flags().is_swiftshader) {
2349 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2350 Destroy(true);
2351 return false;
2352 }
2353
2354 if (!group_->Initialize(this, disallowed_features)) {
2355 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
2356 << "failed to initialize.";
2357 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2358 Destroy(true);
2359 return false;
2360 }
2361 CHECK_GL_ERROR();
2362
2363 disallowed_features_ = disallowed_features;
2364
2365 state_.attrib_values.resize(group_->max_vertex_attribs());
2366 vertex_array_manager_.reset(new VertexArrayManager());
2367
2368 GLuint default_vertex_attrib_service_id = 0;
2369 if (features().native_vertex_array_object) {
2370 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2371 glBindVertexArrayOES(default_vertex_attrib_service_id);
2372 }
2373
2374 state_.default_vertex_attrib_manager =
2375 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2376
2377 state_.default_vertex_attrib_manager->Initialize(
2378 group_->max_vertex_attribs(),
2379 feature_info_->workarounds().init_vertex_attributes);
2380
2381 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
2382 DoBindVertexArrayOES(0);
2383
2384 query_manager_.reset(new QueryManager(this, feature_info_.get()));
2385
2386 util_.set_num_compressed_texture_formats(
2387 validators_->compressed_texture_format.GetValues().size());
2388
2389 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2390 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2391 // OpenGL ES 2.0 does not have this issue.
2392 glEnableVertexAttribArray(0);
2393 }
2394 glGenBuffersARB(1, &attrib_0_buffer_id_);
2395 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2396 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2397 glBindBuffer(GL_ARRAY_BUFFER, 0);
2398 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
2399
2400 state_.texture_units.resize(group_->max_texture_units());
2401 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
2402 glActiveTexture(GL_TEXTURE0 + tt);
2403 // We want the last bind to be 2D.
2404 TextureRef* ref;
2405 if (features().oes_egl_image_external) {
2406 ref = texture_manager()->GetDefaultTextureInfo(
2407 GL_TEXTURE_EXTERNAL_OES);
2408 state_.texture_units[tt].bound_texture_external_oes = ref;
2409 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
2410 }
2411 if (features().arb_texture_rectangle) {
2412 ref = texture_manager()->GetDefaultTextureInfo(
2413 GL_TEXTURE_RECTANGLE_ARB);
2414 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2415 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
2416 }
2417 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2418 state_.texture_units[tt].bound_texture_cube_map = ref;
2419 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
2420 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2421 state_.texture_units[tt].bound_texture_2d = ref;
2422 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
2423 }
2424 glActiveTexture(GL_TEXTURE0);
2425 CHECK_GL_ERROR();
2426
2427 if (offscreen) {
2428 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
2429 features().chromium_framebuffer_multisample) {
2430 // Per ext_framebuffer_multisample spec, need max bound on sample count.
2431 // max_sample_count must be initialized to a sane value. If
2432 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2433 GLint max_sample_count = 1;
2434 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2435 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2436 max_sample_count);
2437 } else {
2438 offscreen_target_samples_ = 1;
2439 }
2440 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
2441
2442 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2443 const bool rgb8_supported =
2444 context_->HasExtension("GL_OES_rgb8_rgba8");
2445 // The only available default render buffer formats in GLES2 have very
2446 // little precision. Don't enable multisampling unless 8-bit render
2447 // buffer formats are available--instead fall back to 8-bit textures.
2448 if (rgb8_supported && offscreen_target_samples_ > 1) {
2449 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2450 GL_RGBA8 : GL_RGB8;
2451 } else {
2452 offscreen_target_samples_ = 1;
2453 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2454 GL_RGBA : GL_RGB;
2455 }
2456
2457 // ANGLE only supports packed depth/stencil formats, so use it if it is
2458 // available.
2459 const bool depth24_stencil8_supported =
2460 feature_info_->feature_flags().packed_depth24_stencil8;
2461 VLOG(1) << "GL_OES_packed_depth_stencil "
2462 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
2463 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2464 depth24_stencil8_supported) {
2465 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2466 offscreen_target_stencil_format_ = 0;
2467 } else {
2468 // It may be the case that this depth/stencil combination is not
2469 // supported, but this will be checked later by CheckFramebufferStatus.
2470 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2471 GL_DEPTH_COMPONENT16 : 0;
2472 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2473 GL_STENCIL_INDEX8 : 0;
2474 }
2475 } else {
2476 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2477 GL_RGBA : GL_RGB;
2478
2479 // If depth is requested at all, use the packed depth stencil format if
2480 // it's available, as some desktop GL drivers don't support any non-packed
2481 // formats for depth attachments.
2482 const bool depth24_stencil8_supported =
2483 feature_info_->feature_flags().packed_depth24_stencil8;
2484 VLOG(1) << "GL_EXT_packed_depth_stencil "
2485 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
2486
2487 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2488 depth24_stencil8_supported) {
2489 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2490 offscreen_target_stencil_format_ = 0;
2491 } else {
2492 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2493 GL_DEPTH_COMPONENT : 0;
2494 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2495 GL_STENCIL_INDEX : 0;
2496 }
2497 }
2498
2499 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2500 GL_RGBA : GL_RGB;
2501
2502 // Create the target frame buffer. This is the one that the client renders
2503 // directly to.
2504 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
2505 offscreen_target_frame_buffer_->Create();
2506 // Due to GLES2 format limitations, either the color texture (for
2507 // non-multisampling) or the color render buffer (for multisampling) will be
2508 // attached to the offscreen frame buffer. The render buffer has more
2509 // limited formats available to it, but the texture can't do multisampling.
2510 if (IsOffscreenBufferMultisampled()) {
2511 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2512 renderbuffer_manager(), memory_tracker(), &state_));
2513 offscreen_target_color_render_buffer_->Create();
2514 } else {
2515 offscreen_target_color_texture_.reset(new BackTexture(
2516 memory_tracker(), &state_));
2517 offscreen_target_color_texture_->Create();
2518 }
2519 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2520 renderbuffer_manager(), memory_tracker(), &state_));
2521 offscreen_target_depth_render_buffer_->Create();
2522 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2523 renderbuffer_manager(), memory_tracker(), &state_));
2524 offscreen_target_stencil_render_buffer_->Create();
2525
2526 // Create the saved offscreen texture. The target frame buffer is copied
2527 // here when SwapBuffers is called.
2528 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
2529 offscreen_saved_frame_buffer_->Create();
2530 //
2531 offscreen_saved_color_texture_.reset(new BackTexture(
2532 memory_tracker(), &state_));
2533 offscreen_saved_color_texture_->Create();
2534
2535 // Allocate the render buffers at their initial size and check the status
2536 // of the frame buffers is okay.
2537 if (!ResizeOffscreenFrameBuffer(size)) {
2538 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
2539 Destroy(true);
2540 return false;
2541 }
2542
2543 // Allocate the offscreen saved color texture.
2544 DCHECK(offscreen_saved_color_format_);
2545 offscreen_saved_color_texture_->AllocateStorage(
2546 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2547
2548 offscreen_saved_frame_buffer_->AttachRenderTexture(
2549 offscreen_saved_color_texture_.get());
2550 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2551 GL_FRAMEBUFFER_COMPLETE) {
2552 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2553 Destroy(true);
2554 return false;
2555 }
2556
2557 // Bind to the new default frame buffer (the offscreen target frame buffer).
2558 // This should now be associated with ID zero.
2559 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2560 } else {
2561 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2562 // These are NOT if the back buffer has these proprorties. They are
2563 // if we want the command buffer to enforce them regardless of what
2564 // the real backbuffer is assuming the real back buffer gives us more than
2565 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2566 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2567 // can't do anything about that.
2568
2569 GLint v = 0;
2570 glGetIntegerv(GL_ALPHA_BITS, &v);
2571 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2572 // user requested RGB then RGB. If the user did not specify a preference
2573 // than use whatever we were given. Same for DEPTH and STENCIL.
2574 back_buffer_color_format_ =
2575 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2576 glGetIntegerv(GL_DEPTH_BITS, &v);
2577 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2578 glGetIntegerv(GL_STENCIL_BITS, &v);
2579 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
2580 }
2581
2582 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2583 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2584 // isn't well documented; it was discovered in the Khronos OpenGL ES
2585 // mailing list archives. It also implicitly enables the desktop GL
2586 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2587 // variable in fragment shaders.
2588 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2589 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
2590 glEnable(GL_POINT_SPRITE);
2591 }
2592
2593 has_robustness_extension_ =
2594 context->HasExtension("GL_ARB_robustness") ||
2595 context->HasExtension("GL_EXT_robustness");
2596
2597 if (!InitializeShaderTranslator()) {
2598 return false;
2599 }
2600
2601 state_.viewport_width = size.width();
2602 state_.viewport_height = size.height();
2603
2604 GLint viewport_params[4] = { 0 };
2605 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
2606 viewport_max_width_ = viewport_params[0];
2607 viewport_max_height_ = viewport_params[1];
2608
2609 state_.scissor_width = state_.viewport_width;
2610 state_.scissor_height = state_.viewport_height;
2611
2612 // Set all the default state because some GL drivers get it wrong.
2613 state_.InitCapabilities(NULL);
2614 state_.InitState(NULL);
2615 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
2616
2617 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2618 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2619 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2620 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2621
2622 bool call_gl_clear = true;
2623 #if defined(OS_ANDROID)
2624 // Temporary workaround for Android WebView because this clear ignores the
2625 // clip and corrupts that external UI of the App. Not calling glClear is ok
2626 // because the system already clears the buffer before each draw. Proper
2627 // fix might be setting the scissor clip properly before initialize. See
2628 // crbug.com/259023 for details.
2629 call_gl_clear = surface_->GetHandle();
2630 #endif
2631 if (call_gl_clear) {
2632 // Clear the backbuffer.
2633 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2634 }
2635
2636 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2637 if (feature_info_->workarounds()
2638 .disable_post_sub_buffers_for_onscreen_surfaces &&
2639 !surface->IsOffscreen())
2640 supports_post_sub_buffer_ = false;
2641
2642 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
2643 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2644 }
2645
2646 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2647 context_->SetUnbindFboOnMakeCurrent();
2648 }
2649
2650 if (feature_info_->workarounds().release_image_after_use) {
2651 image_manager()->SetReleaseAfterUse();
2652 }
2653
2654 // Only compositor contexts are known to use only the subset of GL
2655 // that can be safely migrated between the iGPU and the dGPU. Mark
2656 // those contexts as safe to forcibly transition between the GPUs.
2657 // http://crbug.com/180876, http://crbug.com/227228
2658 if (!offscreen)
2659 context_->SetSafeToForceGpuSwitch();
2660
2661 async_pixel_transfer_manager_.reset(
2662 AsyncPixelTransferManager::Create(context.get()));
2663 async_pixel_transfer_manager_->Initialize(texture_manager());
2664
2665 framebuffer_manager()->AddObserver(this);
2666
2667 return true;
2668 }
2669
GetCapabilities()2670 Capabilities GLES2DecoderImpl::GetCapabilities() {
2671 DCHECK(initialized());
2672
2673 Capabilities caps;
2674
2675 caps.fast_npot_mo8_textures =
2676 feature_info_->workarounds().enable_chromium_fast_npot_mo8_textures;
2677 caps.egl_image_external =
2678 feature_info_->feature_flags().oes_egl_image_external;
2679 caps.texture_format_bgra8888 =
2680 feature_info_->feature_flags().ext_texture_format_bgra8888;
2681 caps.texture_format_etc1 =
2682 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
2683 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2684 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2685 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2686 caps.discard_framebuffer =
2687 feature_info_->feature_flags().ext_discard_framebuffer;
2688 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
2689
2690 #if defined(OS_MACOSX)
2691 // This is unconditionally true on mac, no need to test for it at runtime.
2692 caps.iosurface = true;
2693 #endif
2694
2695 caps.post_sub_buffer = supports_post_sub_buffer_;
2696 caps.map_image = !!image_manager();
2697
2698 return caps;
2699 }
2700
UpdateCapabilities()2701 void GLES2DecoderImpl::UpdateCapabilities() {
2702 util_.set_num_compressed_texture_formats(
2703 validators_->compressed_texture_format.GetValues().size());
2704 util_.set_num_shader_binary_formats(
2705 validators_->shader_binary_format.GetValues().size());
2706 }
2707
InitializeShaderTranslator()2708 bool GLES2DecoderImpl::InitializeShaderTranslator() {
2709 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2710
2711 if (!use_shader_translator_) {
2712 return true;
2713 }
2714 ShBuiltInResources resources;
2715 ShInitBuiltInResources(&resources);
2716 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2717 resources.MaxVertexUniformVectors =
2718 group_->max_vertex_uniform_vectors();
2719 resources.MaxVaryingVectors = group_->max_varying_vectors();
2720 resources.MaxVertexTextureImageUnits =
2721 group_->max_vertex_texture_image_units();
2722 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2723 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2724 resources.MaxFragmentUniformVectors =
2725 group_->max_fragment_uniform_vectors();
2726 resources.MaxDrawBuffers = group_->max_draw_buffers();
2727 resources.MaxExpressionComplexity = 256;
2728 resources.MaxCallStackDepth = 256;
2729
2730 #if (ANGLE_SH_VERSION >= 110)
2731 GLint range[2] = { 0, 0 };
2732 GLint precision = 0;
2733 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2734 range, &precision);
2735 resources.FragmentPrecisionHigh =
2736 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
2737 #endif
2738
2739 if (force_webgl_glsl_validation_) {
2740 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
2741 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
2742 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
2743 if (!draw_buffers_explicitly_enabled_)
2744 resources.MaxDrawBuffers = 1;
2745 #if (ANGLE_SH_VERSION >= 123)
2746 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
2747 #endif
2748 } else {
2749 resources.OES_standard_derivatives =
2750 features().oes_standard_derivatives ? 1 : 0;
2751 resources.ARB_texture_rectangle =
2752 features().arb_texture_rectangle ? 1 : 0;
2753 resources.OES_EGL_image_external =
2754 features().oes_egl_image_external ? 1 : 0;
2755 resources.EXT_draw_buffers =
2756 features().ext_draw_buffers ? 1 : 0;
2757 resources.EXT_frag_depth =
2758 features().ext_frag_depth ? 1 : 0;
2759 #if (ANGLE_SH_VERSION >= 123)
2760 resources.EXT_shader_texture_lod =
2761 features().ext_shader_texture_lod ? 1 : 0;
2762 #endif
2763 }
2764
2765 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2766 : SH_GLES2_SPEC;
2767 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
2768 #if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
2769 resources.HashFunction = &CityHashForAngle;
2770 #else
2771 resources.HashFunction = &CityHash64;
2772 #endif
2773 else
2774 resources.HashFunction = NULL;
2775 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2776 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2777 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2778 int driver_bug_workarounds = 0;
2779 if (workarounds().needs_glsl_built_in_function_emulation)
2780 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
2781 if (workarounds().init_gl_position_in_vertex_shader)
2782 driver_bug_workarounds |= SH_INIT_GL_POSITION;
2783 if (workarounds().unfold_short_circuit_as_ternary_operation)
2784 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
2785 if (workarounds().init_varyings_without_static_use)
2786 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
2787 if (workarounds().unroll_for_loop_with_sampler_array_index)
2788 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
2789
2790 vertex_translator_ = shader_translator_cache()->GetTranslator(
2791 SH_VERTEX_SHADER,
2792 shader_spec,
2793 &resources,
2794 implementation_type,
2795 static_cast<ShCompileOptions>(driver_bug_workarounds));
2796 if (!vertex_translator_.get()) {
2797 LOG(ERROR) << "Could not initialize vertex shader translator.";
2798 Destroy(true);
2799 return false;
2800 }
2801
2802 fragment_translator_ = shader_translator_cache()->GetTranslator(
2803 SH_FRAGMENT_SHADER,
2804 shader_spec,
2805 &resources,
2806 implementation_type,
2807 static_cast<ShCompileOptions>(driver_bug_workarounds));
2808 if (!fragment_translator_.get()) {
2809 LOG(ERROR) << "Could not initialize fragment shader translator.";
2810 Destroy(true);
2811 return false;
2812 }
2813 return true;
2814 }
2815
GenBuffersHelper(GLsizei n,const GLuint * client_ids)2816 bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
2817 for (GLsizei ii = 0; ii < n; ++ii) {
2818 if (GetBuffer(client_ids[ii])) {
2819 return false;
2820 }
2821 }
2822 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
2823 glGenBuffersARB(n, service_ids.get());
2824 for (GLsizei ii = 0; ii < n; ++ii) {
2825 CreateBuffer(client_ids[ii], service_ids[ii]);
2826 }
2827 return true;
2828 }
2829
GenFramebuffersHelper(GLsizei n,const GLuint * client_ids)2830 bool GLES2DecoderImpl::GenFramebuffersHelper(
2831 GLsizei n, const GLuint* client_ids) {
2832 for (GLsizei ii = 0; ii < n; ++ii) {
2833 if (GetFramebuffer(client_ids[ii])) {
2834 return false;
2835 }
2836 }
2837 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
2838 glGenFramebuffersEXT(n, service_ids.get());
2839 for (GLsizei ii = 0; ii < n; ++ii) {
2840 CreateFramebuffer(client_ids[ii], service_ids[ii]);
2841 }
2842 return true;
2843 }
2844
GenRenderbuffersHelper(GLsizei n,const GLuint * client_ids)2845 bool GLES2DecoderImpl::GenRenderbuffersHelper(
2846 GLsizei n, const GLuint* client_ids) {
2847 for (GLsizei ii = 0; ii < n; ++ii) {
2848 if (GetRenderbuffer(client_ids[ii])) {
2849 return false;
2850 }
2851 }
2852 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
2853 glGenRenderbuffersEXT(n, service_ids.get());
2854 for (GLsizei ii = 0; ii < n; ++ii) {
2855 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
2856 }
2857 return true;
2858 }
2859
GenTexturesHelper(GLsizei n,const GLuint * client_ids)2860 bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2861 for (GLsizei ii = 0; ii < n; ++ii) {
2862 if (GetTexture(client_ids[ii])) {
2863 return false;
2864 }
2865 }
2866 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
2867 glGenTextures(n, service_ids.get());
2868 for (GLsizei ii = 0; ii < n; ++ii) {
2869 CreateTexture(client_ids[ii], service_ids[ii]);
2870 }
2871 return true;
2872 }
2873
DeleteBuffersHelper(GLsizei n,const GLuint * client_ids)2874 void GLES2DecoderImpl::DeleteBuffersHelper(
2875 GLsizei n, const GLuint* client_ids) {
2876 for (GLsizei ii = 0; ii < n; ++ii) {
2877 Buffer* buffer = GetBuffer(client_ids[ii]);
2878 if (buffer && !buffer->IsDeleted()) {
2879 state_.vertex_attrib_manager->Unbind(buffer);
2880 if (state_.bound_array_buffer.get() == buffer) {
2881 state_.bound_array_buffer = NULL;
2882 }
2883 RemoveBuffer(client_ids[ii]);
2884 }
2885 }
2886 }
2887
DeleteFramebuffersHelper(GLsizei n,const GLuint * client_ids)2888 void GLES2DecoderImpl::DeleteFramebuffersHelper(
2889 GLsizei n, const GLuint* client_ids) {
2890 bool supports_separate_framebuffer_binds =
2891 features().chromium_framebuffer_multisample;
2892
2893 for (GLsizei ii = 0; ii < n; ++ii) {
2894 Framebuffer* framebuffer =
2895 GetFramebuffer(client_ids[ii]);
2896 if (framebuffer && !framebuffer->IsDeleted()) {
2897 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2898 framebuffer_state_.bound_draw_framebuffer = NULL;
2899 framebuffer_state_.clear_state_dirty = true;
2900 GLenum target = supports_separate_framebuffer_binds ?
2901 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
2902 glBindFramebufferEXT(target, GetBackbufferServiceId());
2903 }
2904 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2905 framebuffer_state_.bound_read_framebuffer = NULL;
2906 GLenum target = supports_separate_framebuffer_binds ?
2907 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
2908 glBindFramebufferEXT(target, GetBackbufferServiceId());
2909 }
2910 OnFboChanged();
2911 RemoveFramebuffer(client_ids[ii]);
2912 }
2913 }
2914 }
2915
DeleteRenderbuffersHelper(GLsizei n,const GLuint * client_ids)2916 void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2917 GLsizei n, const GLuint* client_ids) {
2918 bool supports_separate_framebuffer_binds =
2919 features().chromium_framebuffer_multisample;
2920 for (GLsizei ii = 0; ii < n; ++ii) {
2921 Renderbuffer* renderbuffer =
2922 GetRenderbuffer(client_ids[ii]);
2923 if (renderbuffer && !renderbuffer->IsDeleted()) {
2924 if (state_.bound_renderbuffer.get() == renderbuffer) {
2925 state_.bound_renderbuffer = NULL;
2926 }
2927 // Unbind from current framebuffers.
2928 if (supports_separate_framebuffer_binds) {
2929 if (framebuffer_state_.bound_read_framebuffer.get()) {
2930 framebuffer_state_.bound_read_framebuffer
2931 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
2932 }
2933 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2934 framebuffer_state_.bound_draw_framebuffer
2935 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
2936 }
2937 } else {
2938 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2939 framebuffer_state_.bound_draw_framebuffer
2940 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
2941 }
2942 }
2943 framebuffer_state_.clear_state_dirty = true;
2944 RemoveRenderbuffer(client_ids[ii]);
2945 }
2946 }
2947 }
2948
DeleteTexturesHelper(GLsizei n,const GLuint * client_ids)2949 void GLES2DecoderImpl::DeleteTexturesHelper(
2950 GLsizei n, const GLuint* client_ids) {
2951 bool supports_separate_framebuffer_binds =
2952 features().chromium_framebuffer_multisample;
2953 for (GLsizei ii = 0; ii < n; ++ii) {
2954 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2955 if (texture_ref) {
2956 Texture* texture = texture_ref->texture();
2957 if (texture->IsAttachedToFramebuffer()) {
2958 framebuffer_state_.clear_state_dirty = true;
2959 }
2960 // Unbind texture_ref from texture_ref units.
2961 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
2962 state_.texture_units[jj].Unbind(texture_ref);
2963 }
2964 // Unbind from current framebuffers.
2965 if (supports_separate_framebuffer_binds) {
2966 if (framebuffer_state_.bound_read_framebuffer.get()) {
2967 framebuffer_state_.bound_read_framebuffer
2968 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
2969 }
2970 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2971 framebuffer_state_.bound_draw_framebuffer
2972 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
2973 }
2974 } else {
2975 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2976 framebuffer_state_.bound_draw_framebuffer
2977 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
2978 }
2979 }
2980 #if defined(OS_MACOSX)
2981 GLuint service_id = texture->service_id();
2982 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2983 ReleaseIOSurfaceForTexture(service_id);
2984 }
2985 #endif
2986 RemoveTexture(client_ids[ii]);
2987 }
2988 }
2989 }
2990
2991 // } // anonymous namespace
2992
MakeCurrent()2993 bool GLES2DecoderImpl::MakeCurrent() {
2994 if (!context_.get())
2995 return false;
2996
2997 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
2998 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
2999
3000 // Some D3D drivers cannot recover from device lost in the GPU process
3001 // sandbox. Allow a new GPU process to launch.
3002 if (workarounds().exit_on_context_lost) {
3003 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
3004 << " a D3D device in the Chrome GPU process sandbox.";
3005 #if defined(OS_WIN)
3006 base::win::SetShouldCrashOnProcessDetach(false);
3007 #endif
3008 exit(0);
3009 }
3010
3011 return false;
3012 }
3013
3014 ProcessFinishedAsyncTransfers();
3015
3016 // Rebind the FBO if it was unbound by the context.
3017 if (workarounds().unbind_fbo_on_context_switch)
3018 RestoreFramebufferBindings();
3019
3020 framebuffer_state_.clear_state_dirty = true;
3021
3022 return true;
3023 }
3024
ProcessFinishedAsyncTransfers()3025 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
3026 ProcessPendingReadPixels();
3027 if (engine() && query_manager_.get())
3028 query_manager_->ProcessPendingTransferQueries();
3029
3030 // TODO(epenner): Is there a better place to do this?
3031 // This needs to occur before we execute any batch of commands
3032 // from the client, as the client may have recieved an async
3033 // completion while issuing those commands.
3034 // "DidFlushStart" would be ideal if we had such a callback.
3035 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
3036 }
3037
RebindCurrentFramebuffer(GLenum target,Framebuffer * framebuffer,GLuint back_buffer_service_id)3038 static void RebindCurrentFramebuffer(
3039 GLenum target,
3040 Framebuffer* framebuffer,
3041 GLuint back_buffer_service_id) {
3042 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
3043
3044 if (framebuffer_id == 0) {
3045 framebuffer_id = back_buffer_service_id;
3046 }
3047
3048 glBindFramebufferEXT(target, framebuffer_id);
3049 }
3050
RestoreCurrentFramebufferBindings()3051 void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
3052 framebuffer_state_.clear_state_dirty = true;
3053
3054 if (!features().chromium_framebuffer_multisample) {
3055 RebindCurrentFramebuffer(
3056 GL_FRAMEBUFFER,
3057 framebuffer_state_.bound_draw_framebuffer.get(),
3058 GetBackbufferServiceId());
3059 } else {
3060 RebindCurrentFramebuffer(
3061 GL_READ_FRAMEBUFFER_EXT,
3062 framebuffer_state_.bound_read_framebuffer.get(),
3063 GetBackbufferServiceId());
3064 RebindCurrentFramebuffer(
3065 GL_DRAW_FRAMEBUFFER_EXT,
3066 framebuffer_state_.bound_draw_framebuffer.get(),
3067 GetBackbufferServiceId());
3068 }
3069 OnFboChanged();
3070 }
3071
CheckFramebufferValid(Framebuffer * framebuffer,GLenum target,const char * func_name)3072 bool GLES2DecoderImpl::CheckFramebufferValid(
3073 Framebuffer* framebuffer,
3074 GLenum target, const char* func_name) {
3075 if (!framebuffer) {
3076 if (backbuffer_needs_clear_bits_) {
3077 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3078 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3079 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3080 glClearStencil(0);
3081 state_.SetDeviceStencilMaskSeparate(GL_FRONT, -1);
3082 state_.SetDeviceStencilMaskSeparate(GL_BACK, -1);
3083 glClearDepth(1.0f);
3084 state_.SetDeviceDepthMask(GL_TRUE);
3085 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
3086 bool reset_draw_buffer = false;
3087 if ((backbuffer_needs_clear_bits_ | GL_COLOR_BUFFER_BIT) != 0 &&
3088 group_->draw_buffer() == GL_NONE) {
3089 reset_draw_buffer = true;
3090 GLenum buf = GL_BACK;
3091 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3092 buf = GL_COLOR_ATTACHMENT0;
3093 glDrawBuffersARB(1, &buf);
3094 }
3095 glClear(backbuffer_needs_clear_bits_);
3096 if (reset_draw_buffer) {
3097 GLenum buf = GL_NONE;
3098 glDrawBuffersARB(1, &buf);
3099 }
3100 backbuffer_needs_clear_bits_ = 0;
3101 RestoreClearState();
3102 }
3103 return true;
3104 }
3105
3106 if (framebuffer_manager()->IsComplete(framebuffer)) {
3107 return true;
3108 }
3109
3110 GLenum completeness = framebuffer->IsPossiblyComplete();
3111 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
3112 LOCAL_SET_GL_ERROR(
3113 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
3114 return false;
3115 }
3116
3117 // Are all the attachments cleared?
3118 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3119 texture_manager()->HaveUnclearedMips()) {
3120 if (!framebuffer->IsCleared()) {
3121 // Can we clear them?
3122 if (framebuffer->GetStatus(texture_manager(), target) !=
3123 GL_FRAMEBUFFER_COMPLETE) {
3124 LOCAL_SET_GL_ERROR(
3125 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3126 "framebuffer incomplete (clear)");
3127 return false;
3128 }
3129 ClearUnclearedAttachments(target, framebuffer);
3130 }
3131 }
3132
3133 if (!framebuffer_manager()->IsComplete(framebuffer)) {
3134 if (framebuffer->GetStatus(texture_manager(), target) !=
3135 GL_FRAMEBUFFER_COMPLETE) {
3136 LOCAL_SET_GL_ERROR(
3137 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3138 "framebuffer incomplete (check)");
3139 return false;
3140 }
3141 framebuffer_manager()->MarkAsComplete(framebuffer);
3142 }
3143
3144 // NOTE: At this point we don't know if the framebuffer is complete but
3145 // we DO know that everything that needs to be cleared has been cleared.
3146 return true;
3147 }
3148
CheckBoundFramebuffersValid(const char * func_name)3149 bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
3150 if (!features().chromium_framebuffer_multisample) {
3151 bool valid = CheckFramebufferValid(
3152 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3153 func_name);
3154
3155 if (valid)
3156 OnUseFramebuffer();
3157
3158 return valid;
3159 }
3160 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
3161 GL_DRAW_FRAMEBUFFER_EXT,
3162 func_name) &&
3163 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
3164 GL_READ_FRAMEBUFFER_EXT,
3165 func_name);
3166 }
3167
GetBoundReadFrameBufferSize()3168 gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
3169 Framebuffer* framebuffer =
3170 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3171 if (framebuffer != NULL) {
3172 const Framebuffer::Attachment* attachment =
3173 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
3174 if (attachment) {
3175 return gfx::Size(attachment->width(), attachment->height());
3176 }
3177 return gfx::Size(0, 0);
3178 } else if (offscreen_target_frame_buffer_.get()) {
3179 return offscreen_size_;
3180 } else {
3181 return surface_->GetSize();
3182 }
3183 }
3184
GetBoundReadFrameBufferTextureType()3185 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3186 Framebuffer* framebuffer =
3187 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3188 if (framebuffer != NULL) {
3189 return framebuffer->GetColorAttachmentTextureType();
3190 } else {
3191 return GL_UNSIGNED_BYTE;
3192 }
3193 }
3194
GetBoundReadFrameBufferInternalFormat()3195 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
3196 Framebuffer* framebuffer =
3197 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3198 if (framebuffer != NULL) {
3199 return framebuffer->GetColorAttachmentFormat();
3200 } else if (offscreen_target_frame_buffer_.get()) {
3201 return offscreen_target_color_format_;
3202 } else {
3203 return back_buffer_color_format_;
3204 }
3205 }
3206
GetBoundDrawFrameBufferInternalFormat()3207 GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
3208 Framebuffer* framebuffer =
3209 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3210 if (framebuffer != NULL) {
3211 return framebuffer->GetColorAttachmentFormat();
3212 } else if (offscreen_target_frame_buffer_.get()) {
3213 return offscreen_target_color_format_;
3214 } else {
3215 return back_buffer_color_format_;
3216 }
3217 }
3218
UpdateParentTextureInfo()3219 void GLES2DecoderImpl::UpdateParentTextureInfo() {
3220 if (!offscreen_saved_color_texture_info_.get())
3221 return;
3222 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3223 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3224 texture_manager()->SetLevelInfo(
3225 offscreen_saved_color_texture_info_.get(),
3226 GL_TEXTURE_2D,
3227 0, // level
3228 GL_RGBA,
3229 offscreen_size_.width(),
3230 offscreen_size_.height(),
3231 1, // depth
3232 0, // border
3233 GL_RGBA,
3234 GL_UNSIGNED_BYTE,
3235 true);
3236 texture_manager()->SetParameteri(
3237 "UpdateParentTextureInfo",
3238 GetErrorState(),
3239 offscreen_saved_color_texture_info_.get(),
3240 GL_TEXTURE_MAG_FILTER,
3241 GL_NEAREST);
3242 texture_manager()->SetParameteri(
3243 "UpdateParentTextureInfo",
3244 GetErrorState(),
3245 offscreen_saved_color_texture_info_.get(),
3246 GL_TEXTURE_MIN_FILTER,
3247 GL_NEAREST);
3248 texture_manager()->SetParameteri(
3249 "UpdateParentTextureInfo",
3250 GetErrorState(),
3251 offscreen_saved_color_texture_info_.get(),
3252 GL_TEXTURE_WRAP_S,
3253 GL_CLAMP_TO_EDGE);
3254 texture_manager()->SetParameteri(
3255 "UpdateParentTextureInfo",
3256 GetErrorState(),
3257 offscreen_saved_color_texture_info_.get(),
3258 GL_TEXTURE_WRAP_T,
3259 GL_CLAMP_TO_EDGE);
3260 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3261 &state_, target);
3262 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
3263 }
3264
SetResizeCallback(const base::Callback<void (gfx::Size,float)> & callback)3265 void GLES2DecoderImpl::SetResizeCallback(
3266 const base::Callback<void(gfx::Size, float)>& callback) {
3267 resize_callback_ = callback;
3268 }
3269
GetLogger()3270 Logger* GLES2DecoderImpl::GetLogger() {
3271 return &logger_;
3272 }
3273
BeginDecoding()3274 void GLES2DecoderImpl::BeginDecoding() {
3275 gpu_tracer_->BeginDecoding();
3276 gpu_trace_commands_ = gpu_tracer_->IsTracing();
3277 }
3278
EndDecoding()3279 void GLES2DecoderImpl::EndDecoding() {
3280 gpu_tracer_->EndDecoding();
3281 }
3282
GetErrorState()3283 ErrorState* GLES2DecoderImpl::GetErrorState() {
3284 return state_.GetErrorState();
3285 }
3286
SetShaderCacheCallback(const ShaderCacheCallback & callback)3287 void GLES2DecoderImpl::SetShaderCacheCallback(
3288 const ShaderCacheCallback& callback) {
3289 shader_cache_callback_ = callback;
3290 }
3291
SetWaitSyncPointCallback(const WaitSyncPointCallback & callback)3292 void GLES2DecoderImpl::SetWaitSyncPointCallback(
3293 const WaitSyncPointCallback& callback) {
3294 wait_sync_point_callback_ = callback;
3295 }
3296
3297 AsyncPixelTransferManager*
GetAsyncPixelTransferManager()3298 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3299 return async_pixel_transfer_manager_.get();
3300 }
3301
ResetAsyncPixelTransferManagerForTest()3302 void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3303 async_pixel_transfer_manager_.reset();
3304 }
3305
SetAsyncPixelTransferManagerForTest(AsyncPixelTransferManager * manager)3306 void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3307 AsyncPixelTransferManager* manager) {
3308 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3309 }
3310
GetServiceTextureId(uint32 client_texture_id,uint32 * service_texture_id)3311 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3312 uint32* service_texture_id) {
3313 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3314 if (texture_ref) {
3315 *service_texture_id = texture_ref->service_id();
3316 return true;
3317 }
3318 return false;
3319 }
3320
GetTextureUploadCount()3321 uint32 GLES2DecoderImpl::GetTextureUploadCount() {
3322 return texture_state_.texture_upload_count +
3323 async_pixel_transfer_manager_->GetTextureUploadCount();
3324 }
3325
GetTotalTextureUploadTime()3326 base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
3327 return texture_state_.total_texture_upload_time +
3328 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
3329 }
3330
GetTotalProcessingCommandsTime()3331 base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3332 return total_processing_commands_time_;
3333 }
3334
AddProcessingCommandsTime(base::TimeDelta time)3335 void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3336 total_processing_commands_time_ += time;
3337 }
3338
Destroy(bool have_context)3339 void GLES2DecoderImpl::Destroy(bool have_context) {
3340 if (!initialized())
3341 return;
3342
3343 DCHECK(!have_context || context_->IsCurrent(NULL));
3344
3345 // Unbind everything.
3346 state_.vertex_attrib_manager = NULL;
3347 state_.default_vertex_attrib_manager = NULL;
3348 state_.texture_units.clear();
3349 state_.bound_array_buffer = NULL;
3350 state_.current_queries.clear();
3351 framebuffer_state_.bound_read_framebuffer = NULL;
3352 framebuffer_state_.bound_draw_framebuffer = NULL;
3353 state_.bound_renderbuffer = NULL;
3354
3355 if (offscreen_saved_color_texture_info_.get()) {
3356 DCHECK(offscreen_target_color_texture_);
3357 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3358 offscreen_saved_color_texture_->id());
3359 offscreen_saved_color_texture_->Invalidate();
3360 offscreen_saved_color_texture_info_ = NULL;
3361 }
3362 if (have_context) {
3363 if (copy_texture_CHROMIUM_.get()) {
3364 copy_texture_CHROMIUM_->Destroy();
3365 copy_texture_CHROMIUM_.reset();
3366 }
3367
3368 if (state_.current_program.get()) {
3369 program_manager()->UnuseProgram(shader_manager(),
3370 state_.current_program.get());
3371 }
3372
3373 if (attrib_0_buffer_id_) {
3374 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3375 }
3376 if (fixed_attrib_buffer_id_) {
3377 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3378 }
3379
3380 if (validation_texture_) {
3381 glDeleteTextures(1, &validation_texture_);
3382 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3383 glDeleteFramebuffersEXT(1, &validation_fbo_);
3384 }
3385
3386 if (offscreen_target_frame_buffer_.get())
3387 offscreen_target_frame_buffer_->Destroy();
3388 if (offscreen_target_color_texture_.get())
3389 offscreen_target_color_texture_->Destroy();
3390 if (offscreen_target_color_render_buffer_.get())
3391 offscreen_target_color_render_buffer_->Destroy();
3392 if (offscreen_target_depth_render_buffer_.get())
3393 offscreen_target_depth_render_buffer_->Destroy();
3394 if (offscreen_target_stencil_render_buffer_.get())
3395 offscreen_target_stencil_render_buffer_->Destroy();
3396 if (offscreen_saved_frame_buffer_.get())
3397 offscreen_saved_frame_buffer_->Destroy();
3398 if (offscreen_saved_color_texture_.get())
3399 offscreen_saved_color_texture_->Destroy();
3400 if (offscreen_resolved_frame_buffer_.get())
3401 offscreen_resolved_frame_buffer_->Destroy();
3402 if (offscreen_resolved_color_texture_.get())
3403 offscreen_resolved_color_texture_->Destroy();
3404 } else {
3405 if (offscreen_target_frame_buffer_.get())
3406 offscreen_target_frame_buffer_->Invalidate();
3407 if (offscreen_target_color_texture_.get())
3408 offscreen_target_color_texture_->Invalidate();
3409 if (offscreen_target_color_render_buffer_.get())
3410 offscreen_target_color_render_buffer_->Invalidate();
3411 if (offscreen_target_depth_render_buffer_.get())
3412 offscreen_target_depth_render_buffer_->Invalidate();
3413 if (offscreen_target_stencil_render_buffer_.get())
3414 offscreen_target_stencil_render_buffer_->Invalidate();
3415 if (offscreen_saved_frame_buffer_.get())
3416 offscreen_saved_frame_buffer_->Invalidate();
3417 if (offscreen_saved_color_texture_.get())
3418 offscreen_saved_color_texture_->Invalidate();
3419 if (offscreen_resolved_frame_buffer_.get())
3420 offscreen_resolved_frame_buffer_->Invalidate();
3421 if (offscreen_resolved_color_texture_.get())
3422 offscreen_resolved_color_texture_->Invalidate();
3423 }
3424
3425 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3426 // Otherwise, we can leak objects. http://crbug.com/258772.
3427 // state_.current_program must be reset before group_ is reset because
3428 // the later deletes the ProgramManager object that referred by
3429 // state_.current_program object.
3430 state_.current_program = NULL;
3431
3432 copy_texture_CHROMIUM_.reset();
3433
3434 if (query_manager_.get()) {
3435 query_manager_->Destroy(have_context);
3436 query_manager_.reset();
3437 }
3438
3439 if (vertex_array_manager_ .get()) {
3440 vertex_array_manager_->Destroy(have_context);
3441 vertex_array_manager_.reset();
3442 }
3443
3444 offscreen_target_frame_buffer_.reset();
3445 offscreen_target_color_texture_.reset();
3446 offscreen_target_color_render_buffer_.reset();
3447 offscreen_target_depth_render_buffer_.reset();
3448 offscreen_target_stencil_render_buffer_.reset();
3449 offscreen_saved_frame_buffer_.reset();
3450 offscreen_saved_color_texture_.reset();
3451 offscreen_resolved_frame_buffer_.reset();
3452 offscreen_resolved_color_texture_.reset();
3453
3454 // Need to release these before releasing |group_| which may own the
3455 // ShaderTranslatorCache.
3456 fragment_translator_ = NULL;
3457 vertex_translator_ = NULL;
3458
3459 // Should destroy the transfer manager before the texture manager held
3460 // by the context group.
3461 async_pixel_transfer_manager_.reset();
3462
3463 if (group_.get()) {
3464 framebuffer_manager()->RemoveObserver(this);
3465 group_->Destroy(this, have_context);
3466 group_ = NULL;
3467 }
3468
3469 if (context_.get()) {
3470 context_->ReleaseCurrent(NULL);
3471 context_ = NULL;
3472 }
3473
3474 #if defined(OS_MACOSX)
3475 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3476 it != texture_to_io_surface_map_.end(); ++it) {
3477 CFRelease(it->second);
3478 }
3479 texture_to_io_surface_map_.clear();
3480 #endif
3481 }
3482
SetSurface(const scoped_refptr<gfx::GLSurface> & surface)3483 void GLES2DecoderImpl::SetSurface(
3484 const scoped_refptr<gfx::GLSurface>& surface) {
3485 DCHECK(context_->IsCurrent(NULL));
3486 DCHECK(surface_.get());
3487 surface_ = surface;
3488 RestoreCurrentFramebufferBindings();
3489 }
3490
ProduceFrontBuffer(const Mailbox & mailbox)3491 void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3492 if (!offscreen_saved_color_texture_.get()) {
3493 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3494 return;
3495 }
3496 if (!offscreen_saved_color_texture_info_.get()) {
3497 GLuint service_id = offscreen_saved_color_texture_->id();
3498 offscreen_saved_color_texture_info_ = TextureRef::Create(
3499 texture_manager(), 0, service_id);
3500 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3501 GL_TEXTURE_2D);
3502 UpdateParentTextureInfo();
3503 }
3504 mailbox_manager()->ProduceTexture(
3505 GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture());
3506 }
3507
ResizeOffscreenFrameBuffer(const gfx::Size & size)3508 bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3509 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3510 if (!is_offscreen) {
3511 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3512 << " with an onscreen framebuffer.";
3513 return false;
3514 }
3515
3516 if (offscreen_size_ == size)
3517 return true;
3518
3519 offscreen_size_ = size;
3520 int w = offscreen_size_.width();
3521 int h = offscreen_size_.height();
3522 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3523 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3524 << "to allocate storage due to excessive dimensions.";
3525 return false;
3526 }
3527
3528 // Reallocate the offscreen target buffers.
3529 DCHECK(offscreen_target_color_format_);
3530 if (IsOffscreenBufferMultisampled()) {
3531 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3532 feature_info_, offscreen_size_, offscreen_target_color_format_,
3533 offscreen_target_samples_)) {
3534 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3535 << "to allocate storage for offscreen target color buffer.";
3536 return false;
3537 }
3538 } else {
3539 if (!offscreen_target_color_texture_->AllocateStorage(
3540 offscreen_size_, offscreen_target_color_format_, false)) {
3541 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3542 << "to allocate storage for offscreen target color texture.";
3543 return false;
3544 }
3545 }
3546 if (offscreen_target_depth_format_ &&
3547 !offscreen_target_depth_render_buffer_->AllocateStorage(
3548 feature_info_, offscreen_size_, offscreen_target_depth_format_,
3549 offscreen_target_samples_)) {
3550 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3551 << "to allocate storage for offscreen target depth buffer.";
3552 return false;
3553 }
3554 if (offscreen_target_stencil_format_ &&
3555 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3556 feature_info_, offscreen_size_, offscreen_target_stencil_format_,
3557 offscreen_target_samples_)) {
3558 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3559 << "to allocate storage for offscreen target stencil buffer.";
3560 return false;
3561 }
3562
3563 // Attach the offscreen target buffers to the target frame buffer.
3564 if (IsOffscreenBufferMultisampled()) {
3565 offscreen_target_frame_buffer_->AttachRenderBuffer(
3566 GL_COLOR_ATTACHMENT0,
3567 offscreen_target_color_render_buffer_.get());
3568 } else {
3569 offscreen_target_frame_buffer_->AttachRenderTexture(
3570 offscreen_target_color_texture_.get());
3571 }
3572 if (offscreen_target_depth_format_) {
3573 offscreen_target_frame_buffer_->AttachRenderBuffer(
3574 GL_DEPTH_ATTACHMENT,
3575 offscreen_target_depth_render_buffer_.get());
3576 }
3577 const bool packed_depth_stencil =
3578 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3579 if (packed_depth_stencil) {
3580 offscreen_target_frame_buffer_->AttachRenderBuffer(
3581 GL_STENCIL_ATTACHMENT,
3582 offscreen_target_depth_render_buffer_.get());
3583 } else if (offscreen_target_stencil_format_) {
3584 offscreen_target_frame_buffer_->AttachRenderBuffer(
3585 GL_STENCIL_ATTACHMENT,
3586 offscreen_target_stencil_render_buffer_.get());
3587 }
3588
3589 if (offscreen_target_frame_buffer_->CheckStatus() !=
3590 GL_FRAMEBUFFER_COMPLETE) {
3591 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3592 << "because offscreen FBO was incomplete.";
3593 return false;
3594 }
3595
3596 // Clear the target frame buffer.
3597 {
3598 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3599 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3600 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3601 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3602 glClearStencil(0);
3603 state_.SetDeviceStencilMaskSeparate(GL_FRONT, -1);
3604 state_.SetDeviceStencilMaskSeparate(GL_BACK, -1);
3605 glClearDepth(0);
3606 state_.SetDeviceDepthMask(GL_TRUE);
3607 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
3608 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3609 RestoreClearState();
3610 }
3611
3612 // Destroy the offscreen resolved framebuffers.
3613 if (offscreen_resolved_frame_buffer_.get())
3614 offscreen_resolved_frame_buffer_->Destroy();
3615 if (offscreen_resolved_color_texture_.get())
3616 offscreen_resolved_color_texture_->Destroy();
3617 offscreen_resolved_color_texture_.reset();
3618 offscreen_resolved_frame_buffer_.reset();
3619
3620 return true;
3621 }
3622
HandleResizeCHROMIUM(uint32 immediate_data_size,const cmds::ResizeCHROMIUM & c)3623 error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
3624 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
3625 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
3626 return error::kDeferCommandUntilLater;
3627
3628 GLuint width = static_cast<GLuint>(c.width);
3629 GLuint height = static_cast<GLuint>(c.height);
3630 GLfloat scale_factor = c.scale_factor;
3631 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
3632
3633 width = std::max(1U, width);
3634 height = std::max(1U, height);
3635
3636 #if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3637 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
3638 // Make sure that we are done drawing to the back buffer before resizing.
3639 glFinish();
3640 #endif
3641 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3642 if (is_offscreen) {
3643 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3644 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3645 << "ResizeOffscreenFrameBuffer failed.";
3646 return error::kLostContext;
3647 }
3648 }
3649
3650 if (!resize_callback_.is_null()) {
3651 resize_callback_.Run(gfx::Size(width, height), scale_factor);
3652 DCHECK(context_->IsCurrent(surface_.get()));
3653 if (!context_->IsCurrent(surface_.get())) {
3654 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3655 << "current after resize callback.";
3656 return error::kLostContext;
3657 }
3658 }
3659
3660 return error::kNoError;
3661 }
3662
GetCommandName(unsigned int command_id) const3663 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3664 if (command_id > kStartPoint && command_id < kNumCommands) {
3665 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3666 }
3667 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3668 }
3669
3670 // Decode command with its arguments, and call the corresponding GL function.
3671 // Note: args is a pointer to the command buffer. As such, it could be changed
3672 // by a (malicious) client at any time, so if validation has to happen, it
3673 // should operate on a copy of them.
DoCommand(unsigned int command,unsigned int arg_count,const void * cmd_data)3674 error::Error GLES2DecoderImpl::DoCommand(
3675 unsigned int command,
3676 unsigned int arg_count,
3677 const void* cmd_data) {
3678 error::Error result = error::kNoError;
3679 if (log_commands()) {
3680 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3681 // VLOG(1), no luck.
3682 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
3683 << GetCommandName(command);
3684 }
3685 unsigned int command_index = command - kStartPoint - 1;
3686 if (command_index < arraysize(g_command_info)) {
3687 const CommandInfo& info = g_command_info[command_index];
3688 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3689 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3690 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3691 bool doing_gpu_trace = false;
3692 if (gpu_trace_commands_) {
3693 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3694 doing_gpu_trace = true;
3695 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3696 }
3697 }
3698
3699 uint32 immediate_data_size =
3700 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
3701 switch (command) {
3702 #define GLES2_CMD_OP(name) \
3703 case cmds::name::kCmdId: \
3704 result = Handle ## name( \
3705 immediate_data_size, \
3706 *static_cast<const gles2::cmds::name*>(cmd_data)); \
3707 break; \
3708
3709 GLES2_COMMAND_LIST(GLES2_CMD_OP)
3710 #undef GLES2_CMD_OP
3711 }
3712
3713 if (doing_gpu_trace)
3714 gpu_tracer_->End(kTraceDecoder);
3715
3716 if (debug()) {
3717 GLenum error;
3718 while ((error = glGetError()) != GL_NO_ERROR) {
3719 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
3720 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3721 << GetCommandName(command);
3722 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
3723 }
3724 }
3725 } else {
3726 result = error::kInvalidArguments;
3727 }
3728 } else {
3729 result = DoCommonCommand(command, arg_count, cmd_data);
3730 }
3731 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3732 result = current_decoder_error_;
3733 current_decoder_error_ = error::kNoError;
3734 }
3735 return result;
3736 }
3737
RemoveBuffer(GLuint client_id)3738 void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3739 buffer_manager()->RemoveBuffer(client_id);
3740 }
3741
CreateProgramHelper(GLuint client_id)3742 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
3743 if (GetProgram(client_id)) {
3744 return false;
3745 }
3746 GLuint service_id = glCreateProgram();
3747 if (service_id != 0) {
3748 CreateProgram(client_id, service_id);
3749 }
3750 return true;
3751 }
3752
CreateShaderHelper(GLenum type,GLuint client_id)3753 bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
3754 if (GetShader(client_id)) {
3755 return false;
3756 }
3757 GLuint service_id = glCreateShader(type);
3758 if (service_id != 0) {
3759 CreateShader(client_id, service_id, type);
3760 }
3761 return true;
3762 }
3763
DoFinish()3764 void GLES2DecoderImpl::DoFinish() {
3765 glFinish();
3766 ProcessPendingReadPixels();
3767 ProcessPendingQueries();
3768 }
3769
DoFlush()3770 void GLES2DecoderImpl::DoFlush() {
3771 glFlush();
3772 ProcessPendingQueries();
3773 }
3774
DoActiveTexture(GLenum texture_unit)3775 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
3776 GLuint texture_index = texture_unit - GL_TEXTURE0;
3777 if (texture_index >= state_.texture_units.size()) {
3778 LOCAL_SET_GL_ERROR_INVALID_ENUM(
3779 "glActiveTexture", texture_unit, "texture_unit");
3780 return;
3781 }
3782 state_.active_texture_unit = texture_index;
3783 glActiveTexture(texture_unit);
3784 }
3785
DoBindBuffer(GLenum target,GLuint client_id)3786 void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
3787 Buffer* buffer = NULL;
3788 GLuint service_id = 0;
3789 if (client_id != 0) {
3790 buffer = GetBuffer(client_id);
3791 if (!buffer) {
3792 if (!group_->bind_generates_resource()) {
3793 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3794 "glBindBuffer",
3795 "id not generated by glGenBuffers");
3796 return;
3797 }
3798
3799 // It's a new id so make a buffer buffer for it.
3800 glGenBuffersARB(1, &service_id);
3801 CreateBuffer(client_id, service_id);
3802 buffer = GetBuffer(client_id);
3803 IdAllocatorInterface* id_allocator =
3804 group_->GetIdAllocator(id_namespaces::kBuffers);
3805 id_allocator->MarkAsUsed(client_id);
3806 }
3807 }
3808 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3809 if (buffer) {
3810 if (!buffer_manager()->SetTarget(buffer, target)) {
3811 LOCAL_SET_GL_ERROR(
3812 GL_INVALID_OPERATION,
3813 "glBindBuffer", "buffer bound to more than 1 target");
3814 return;
3815 }
3816 service_id = buffer->service_id();
3817 }
3818 switch (target) {
3819 case GL_ARRAY_BUFFER:
3820 state_.bound_array_buffer = buffer;
3821 break;
3822 case GL_ELEMENT_ARRAY_BUFFER:
3823 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
3824 break;
3825 default:
3826 NOTREACHED(); // Validation should prevent us getting here.
3827 break;
3828 }
3829 glBindBuffer(target, service_id);
3830 }
3831
BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers)3832 bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3833 bool all_draw_buffers) {
3834 Framebuffer* framebuffer =
3835 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3836 if (!all_draw_buffers || !framebuffer) {
3837 return (GLES2Util::GetChannelsForFormat(
3838 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3839 }
3840 return framebuffer->HasAlphaMRT();
3841 }
3842
BoundFramebufferHasDepthAttachment()3843 bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
3844 Framebuffer* framebuffer =
3845 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3846 if (framebuffer) {
3847 return framebuffer->HasDepthAttachment();
3848 }
3849 if (offscreen_target_frame_buffer_.get()) {
3850 return offscreen_target_depth_format_ != 0;
3851 }
3852 return back_buffer_has_depth_;
3853 }
3854
BoundFramebufferHasStencilAttachment()3855 bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
3856 Framebuffer* framebuffer =
3857 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3858 if (framebuffer) {
3859 return framebuffer->HasStencilAttachment();
3860 }
3861 if (offscreen_target_frame_buffer_.get()) {
3862 return offscreen_target_stencil_format_ != 0 ||
3863 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3864 }
3865 return back_buffer_has_stencil_;
3866 }
3867
ApplyDirtyState()3868 void GLES2DecoderImpl::ApplyDirtyState() {
3869 if (framebuffer_state_.clear_state_dirty) {
3870 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
3871 state_.SetDeviceColorMask(state_.color_mask_red,
3872 state_.color_mask_green,
3873 state_.color_mask_blue,
3874 state_.color_mask_alpha && have_alpha);
3875
3876 bool have_depth = BoundFramebufferHasDepthAttachment();
3877 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
3878
3879 bool have_stencil = BoundFramebufferHasStencilAttachment();
3880 state_.SetDeviceStencilMaskSeparate(
3881 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
3882 state_.SetDeviceStencilMaskSeparate(
3883 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
3884
3885 state_.SetDeviceCapabilityState(
3886 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
3887 state_.SetDeviceCapabilityState(
3888 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3889 framebuffer_state_.clear_state_dirty = false;
3890 }
3891 }
3892
GetBackbufferServiceId() const3893 GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
3894 return (offscreen_target_frame_buffer_.get())
3895 ? offscreen_target_frame_buffer_->id()
3896 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
3897 }
3898
RestoreState(const ContextState * prev_state) const3899 void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) const {
3900 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3901 "context", logger_.GetLogPrefix());
3902 // Restore the Framebuffer first because of bugs in Intel drivers.
3903 // Intel drivers incorrectly clip the viewport settings to
3904 // the size of the current framebuffer object.
3905 RestoreFramebufferBindings();
3906 state_.RestoreState(prev_state);
3907 }
3908
RestoreFramebufferBindings() const3909 void GLES2DecoderImpl::RestoreFramebufferBindings() const {
3910 GLuint service_id =
3911 framebuffer_state_.bound_draw_framebuffer.get()
3912 ? framebuffer_state_.bound_draw_framebuffer->service_id()
3913 : GetBackbufferServiceId();
3914 if (!features().chromium_framebuffer_multisample) {
3915 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3916 } else {
3917 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
3918 service_id = framebuffer_state_.bound_read_framebuffer.get()
3919 ? framebuffer_state_.bound_read_framebuffer->service_id()
3920 : GetBackbufferServiceId();
3921 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3922 }
3923 OnFboChanged();
3924 }
3925
RestoreTextureState(unsigned service_id) const3926 void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
3927 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3928 if (texture) {
3929 GLenum target = texture->target();
3930 glBindTexture(target, service_id);
3931 glTexParameteri(
3932 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
3933 glTexParameteri(
3934 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
3935 glTexParameteri(
3936 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
3937 glTexParameteri(
3938 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
3939 RestoreTextureUnitBindings(state_.active_texture_unit);
3940 }
3941 }
3942
ClearAllAttributes() const3943 void GLES2DecoderImpl::ClearAllAttributes() const {
3944 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
3945 // other VAOs.
3946 if (feature_info_->feature_flags().native_vertex_array_object)
3947 glBindVertexArrayOES(0);
3948
3949 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
3950 if (i != 0) // Never disable attribute 0
3951 glDisableVertexAttribArray(i);
3952 if(features().angle_instanced_arrays)
3953 glVertexAttribDivisorANGLE(i, 0);
3954 }
3955 }
3956
RestoreAllAttributes() const3957 void GLES2DecoderImpl::RestoreAllAttributes() const {
3958 state_.RestoreVertexAttribs();
3959 }
3960
SetIgnoreCachedStateForTest(bool ignore)3961 void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
3962 state_.SetIgnoreCachedStateForTest(ignore);
3963 }
3964
OnFboChanged() const3965 void GLES2DecoderImpl::OnFboChanged() const {
3966 if (workarounds().restore_scissor_on_fbo_change)
3967 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3968 }
3969
3970 // Called after the FBO is checked for completeness.
OnUseFramebuffer() const3971 void GLES2DecoderImpl::OnUseFramebuffer() const {
3972 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3973 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
3974 // The driver forgets the correct scissor when modifying the FBO binding.
3975 glScissor(state_.scissor_x,
3976 state_.scissor_y,
3977 state_.scissor_width,
3978 state_.scissor_height);
3979
3980 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3981 // it's unclear how this bug works.
3982 glFlush();
3983 }
3984 }
3985
DoBindFramebuffer(GLenum target,GLuint client_id)3986 void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
3987 Framebuffer* framebuffer = NULL;
3988 GLuint service_id = 0;
3989 if (client_id != 0) {
3990 framebuffer = GetFramebuffer(client_id);
3991 if (!framebuffer) {
3992 if (!group_->bind_generates_resource()) {
3993 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3994 "glBindFramebuffer",
3995 "id not generated by glGenFramebuffers");
3996 return;
3997 }
3998
3999 // It's a new id so make a framebuffer framebuffer for it.
4000 glGenFramebuffersEXT(1, &service_id);
4001 CreateFramebuffer(client_id, service_id);
4002 framebuffer = GetFramebuffer(client_id);
4003 IdAllocatorInterface* id_allocator =
4004 group_->GetIdAllocator(id_namespaces::kFramebuffers);
4005 id_allocator->MarkAsUsed(client_id);
4006 } else {
4007 service_id = framebuffer->service_id();
4008 }
4009 framebuffer->MarkAsValid();
4010 }
4011 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
4012
4013 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
4014 framebuffer_state_.bound_draw_framebuffer = framebuffer;
4015 }
4016
4017 // vmiura: This looks like dup code
4018 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
4019 framebuffer_state_.bound_read_framebuffer = framebuffer;
4020 }
4021
4022 framebuffer_state_.clear_state_dirty = true;
4023
4024 // If we are rendering to the backbuffer get the FBO id for any simulated
4025 // backbuffer.
4026 if (framebuffer == NULL) {
4027 service_id = GetBackbufferServiceId();
4028 }
4029
4030 glBindFramebufferEXT(target, service_id);
4031 OnFboChanged();
4032 }
4033
DoBindRenderbuffer(GLenum target,GLuint client_id)4034 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
4035 Renderbuffer* renderbuffer = NULL;
4036 GLuint service_id = 0;
4037 if (client_id != 0) {
4038 renderbuffer = GetRenderbuffer(client_id);
4039 if (!renderbuffer) {
4040 if (!group_->bind_generates_resource()) {
4041 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4042 "glBindRenderbuffer",
4043 "id not generated by glGenRenderbuffers");
4044 return;
4045 }
4046
4047 // It's a new id so make a renderbuffer renderbuffer for it.
4048 glGenRenderbuffersEXT(1, &service_id);
4049 CreateRenderbuffer(client_id, service_id);
4050 renderbuffer = GetRenderbuffer(client_id);
4051 IdAllocatorInterface* id_allocator =
4052 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
4053 id_allocator->MarkAsUsed(client_id);
4054 } else {
4055 service_id = renderbuffer->service_id();
4056 }
4057 renderbuffer->MarkAsValid();
4058 }
4059 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
4060 state_.bound_renderbuffer = renderbuffer;
4061 glBindRenderbufferEXT(target, service_id);
4062 }
4063
DoBindTexture(GLenum target,GLuint client_id)4064 void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
4065 TextureRef* texture_ref = NULL;
4066 GLuint service_id = 0;
4067 if (client_id != 0) {
4068 texture_ref = GetTexture(client_id);
4069 if (!texture_ref) {
4070 if (!group_->bind_generates_resource()) {
4071 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4072 "glBindTexture",
4073 "id not generated by glGenTextures");
4074 return;
4075 }
4076
4077 // It's a new id so make a texture texture for it.
4078 glGenTextures(1, &service_id);
4079 DCHECK_NE(0u, service_id);
4080 CreateTexture(client_id, service_id);
4081 texture_ref = GetTexture(client_id);
4082 IdAllocatorInterface* id_allocator =
4083 group_->GetIdAllocator(id_namespaces::kTextures);
4084 id_allocator->MarkAsUsed(client_id);
4085 }
4086 } else {
4087 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
4088 }
4089
4090 // Check the texture exists
4091 if (texture_ref) {
4092 Texture* texture = texture_ref->texture();
4093 // Check that we are not trying to bind it to a different target.
4094 if (texture->target() != 0 && texture->target() != target) {
4095 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4096 "glBindTexture",
4097 "texture bound to more than 1 target.");
4098 return;
4099 }
4100 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4101 if (texture->target() == 0) {
4102 texture_manager()->SetTarget(texture_ref, target);
4103 }
4104 glBindTexture(target, texture->service_id());
4105 } else {
4106 glBindTexture(target, 0);
4107 }
4108
4109 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
4110 unit.bind_target = target;
4111 switch (target) {
4112 case GL_TEXTURE_2D:
4113 unit.bound_texture_2d = texture_ref;
4114 break;
4115 case GL_TEXTURE_CUBE_MAP:
4116 unit.bound_texture_cube_map = texture_ref;
4117 break;
4118 case GL_TEXTURE_EXTERNAL_OES:
4119 unit.bound_texture_external_oes = texture_ref;
4120 break;
4121 case GL_TEXTURE_RECTANGLE_ARB:
4122 unit.bound_texture_rectangle_arb = texture_ref;
4123 break;
4124 default:
4125 NOTREACHED(); // Validation should prevent us getting here.
4126 break;
4127 }
4128 }
4129
DoDisableVertexAttribArray(GLuint index)4130 void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
4131 if (state_.vertex_attrib_manager->Enable(index, false)) {
4132 if (index != 0 ||
4133 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
4134 glDisableVertexAttribArray(index);
4135 }
4136 } else {
4137 LOCAL_SET_GL_ERROR(
4138 GL_INVALID_VALUE,
4139 "glDisableVertexAttribArray", "index out of range");
4140 }
4141 }
4142
DoDiscardFramebufferEXT(GLenum target,GLsizei numAttachments,const GLenum * attachments)4143 void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4144 GLsizei numAttachments,
4145 const GLenum* attachments) {
4146 Framebuffer* framebuffer =
4147 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4148
4149 // Validates the attachments. If one of them fails
4150 // the whole command fails.
4151 for (GLsizei i = 0; i < numAttachments; ++i) {
4152 if ((framebuffer &&
4153 !validators_->attachment.IsValid(attachments[i])) ||
4154 (!framebuffer &&
4155 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
4156 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4157 "glDiscardFramebufferEXT", attachments[i], "attachments");
4158 return;
4159 }
4160 }
4161
4162 // Marks each one of them as not cleared
4163 for (GLsizei i = 0; i < numAttachments; ++i) {
4164 if (framebuffer) {
4165 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4166 texture_manager(),
4167 attachments[i],
4168 false);
4169 } else {
4170 switch (attachments[i]) {
4171 case GL_COLOR_EXT:
4172 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4173 break;
4174 case GL_DEPTH_EXT:
4175 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4176 case GL_STENCIL_EXT:
4177 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4178 break;
4179 default:
4180 NOTREACHED();
4181 break;
4182 }
4183 }
4184 }
4185
4186 // If the default framebuffer is bound but we are still rendering to an
4187 // FBO, translate attachment names that refer to default framebuffer
4188 // channels to corresponding framebuffer attachments.
4189 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4190 for (GLsizei i = 0; i < numAttachments; ++i) {
4191 GLenum attachment = attachments[i];
4192 if (!framebuffer && GetBackbufferServiceId()) {
4193 switch (attachment) {
4194 case GL_COLOR_EXT:
4195 attachment = GL_COLOR_ATTACHMENT0;
4196 break;
4197 case GL_DEPTH_EXT:
4198 attachment = GL_DEPTH_ATTACHMENT;
4199 break;
4200 case GL_STENCIL_EXT:
4201 attachment = GL_STENCIL_ATTACHMENT;
4202 break;
4203 default:
4204 NOTREACHED();
4205 return;
4206 }
4207 }
4208 translated_attachments[i] = attachment;
4209 }
4210
4211 ScopedRenderTo do_render(framebuffer);
4212 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
4213 }
4214
DoEnableVertexAttribArray(GLuint index)4215 void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
4216 if (state_.vertex_attrib_manager->Enable(index, true)) {
4217 glEnableVertexAttribArray(index);
4218 } else {
4219 LOCAL_SET_GL_ERROR(
4220 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
4221 }
4222 }
4223
DoGenerateMipmap(GLenum target)4224 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
4225 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4226 &state_, target);
4227 if (!texture_ref ||
4228 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
4229 LOCAL_SET_GL_ERROR(
4230 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
4231 return;
4232 }
4233
4234 if (target == GL_TEXTURE_CUBE_MAP) {
4235 for (int i = 0; i < 6; ++i) {
4236 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
4237 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
4238 LOCAL_SET_GL_ERROR(
4239 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
4240 return;
4241 }
4242 }
4243 } else {
4244 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
4245 LOCAL_SET_GL_ERROR(
4246 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
4247 return;
4248 }
4249 }
4250
4251 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
4252 // Workaround for Mac driver bug. In the large scheme of things setting
4253 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
4254 // hit so there's probably no need to make this conditional. The bug appears
4255 // to be that if the filtering mode is set to something that doesn't require
4256 // mipmaps for rendering, or is never set to something other than the default,
4257 // then glGenerateMipmap misbehaves.
4258 if (workarounds().set_texture_filter_before_generating_mipmap) {
4259 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4260 }
4261 glGenerateMipmapEXT(target);
4262 if (workarounds().set_texture_filter_before_generating_mipmap) {
4263 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4264 texture_ref->texture()->min_filter());
4265 }
4266 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
4267 if (error == GL_NO_ERROR) {
4268 texture_manager()->MarkMipmapsGenerated(texture_ref);
4269 }
4270 }
4271
GetHelper(GLenum pname,GLint * params,GLsizei * num_written)4272 bool GLES2DecoderImpl::GetHelper(
4273 GLenum pname, GLint* params, GLsizei* num_written) {
4274 DCHECK(num_written);
4275 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4276 switch (pname) {
4277 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4278 *num_written = 1;
4279 // Return the GL implementation's preferred format and (see below type)
4280 // if we have the GL extension that exposes this. This allows the GPU
4281 // client to use the implementation's preferred format for glReadPixels
4282 // for optimisation.
4283 //
4284 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4285 // case when requested on integer/floating point buffers but which is
4286 // acceptable on GLES2 and with the GL_OES_read_format extension.
4287 //
4288 // Therefore if an error occurs we swallow the error and use the
4289 // internal implementation.
4290 if (params) {
4291 if (context_->HasExtension("GL_OES_read_format")) {
4292 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4293 GetErrorState());
4294 glGetIntegerv(pname, params);
4295 if (glGetError() == GL_NO_ERROR)
4296 return true;
4297 }
4298 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4299 GetBoundReadFrameBufferInternalFormat());
4300 }
4301 return true;
4302 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4303 *num_written = 1;
4304 if (params) {
4305 if (context_->HasExtension("GL_OES_read_format")) {
4306 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4307 GetErrorState());
4308 glGetIntegerv(pname, params);
4309 if (glGetError() == GL_NO_ERROR)
4310 return true;
4311 }
4312 *params = GLES2Util::GetPreferredGLReadPixelsType(
4313 GetBoundReadFrameBufferInternalFormat(),
4314 GetBoundReadFrameBufferTextureType());
4315 }
4316 return true;
4317 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4318 *num_written = 1;
4319 if (params) {
4320 *params = group_->max_fragment_uniform_vectors();
4321 }
4322 return true;
4323 case GL_MAX_VARYING_VECTORS:
4324 *num_written = 1;
4325 if (params) {
4326 *params = group_->max_varying_vectors();
4327 }
4328 return true;
4329 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4330 *num_written = 1;
4331 if (params) {
4332 *params = group_->max_vertex_uniform_vectors();
4333 }
4334 return true;
4335 }
4336 }
4337 switch (pname) {
4338 case GL_MAX_VIEWPORT_DIMS:
4339 if (offscreen_target_frame_buffer_.get()) {
4340 *num_written = 2;
4341 if (params) {
4342 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4343 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4344 }
4345 return true;
4346 }
4347 return false;
4348 case GL_MAX_SAMPLES:
4349 *num_written = 1;
4350 if (params) {
4351 params[0] = renderbuffer_manager()->max_samples();
4352 }
4353 return true;
4354 case GL_MAX_RENDERBUFFER_SIZE:
4355 *num_written = 1;
4356 if (params) {
4357 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4358 }
4359 return true;
4360 case GL_MAX_TEXTURE_SIZE:
4361 *num_written = 1;
4362 if (params) {
4363 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4364 }
4365 return true;
4366 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4367 *num_written = 1;
4368 if (params) {
4369 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4370 }
4371 return true;
4372 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4373 *num_written = 1;
4374 if (params) {
4375 params[0] = group_->max_color_attachments();
4376 }
4377 return true;
4378 case GL_MAX_DRAW_BUFFERS_ARB:
4379 *num_written = 1;
4380 if (params) {
4381 params[0] = group_->max_draw_buffers();
4382 }
4383 return true;
4384 case GL_ALPHA_BITS:
4385 *num_written = 1;
4386 if (params) {
4387 GLint v = 0;
4388 glGetIntegerv(GL_ALPHA_BITS, &v);
4389 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
4390 }
4391 return true;
4392 case GL_DEPTH_BITS:
4393 *num_written = 1;
4394 if (params) {
4395 GLint v = 0;
4396 glGetIntegerv(GL_DEPTH_BITS, &v);
4397 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4398 }
4399 return true;
4400 case GL_STENCIL_BITS:
4401 *num_written = 1;
4402 if (params) {
4403 GLint v = 0;
4404 glGetIntegerv(GL_STENCIL_BITS, &v);
4405 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4406 }
4407 return true;
4408 case GL_COMPRESSED_TEXTURE_FORMATS:
4409 *num_written = validators_->compressed_texture_format.GetValues().size();
4410 if (params) {
4411 for (GLint ii = 0; ii < *num_written; ++ii) {
4412 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4413 }
4414 }
4415 return true;
4416 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4417 *num_written = 1;
4418 if (params) {
4419 *params = validators_->compressed_texture_format.GetValues().size();
4420 }
4421 return true;
4422 case GL_NUM_SHADER_BINARY_FORMATS:
4423 *num_written = 1;
4424 if (params) {
4425 *params = validators_->shader_binary_format.GetValues().size();
4426 }
4427 return true;
4428 case GL_SHADER_BINARY_FORMATS:
4429 *num_written = validators_->shader_binary_format.GetValues().size();
4430 if (params) {
4431 for (GLint ii = 0; ii < *num_written; ++ii) {
4432 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4433 }
4434 }
4435 return true;
4436 case GL_SHADER_COMPILER:
4437 *num_written = 1;
4438 if (params) {
4439 *params = GL_TRUE;
4440 }
4441 return true;
4442 case GL_ARRAY_BUFFER_BINDING:
4443 *num_written = 1;
4444 if (params) {
4445 if (state_.bound_array_buffer.get()) {
4446 GLuint client_id = 0;
4447 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
4448 &client_id);
4449 *params = client_id;
4450 } else {
4451 *params = 0;
4452 }
4453 }
4454 return true;
4455 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4456 *num_written = 1;
4457 if (params) {
4458 if (state_.vertex_attrib_manager->element_array_buffer()) {
4459 GLuint client_id = 0;
4460 buffer_manager()->GetClientId(
4461 state_.vertex_attrib_manager->element_array_buffer()->
4462 service_id(), &client_id);
4463 *params = client_id;
4464 } else {
4465 *params = 0;
4466 }
4467 }
4468 return true;
4469 case GL_FRAMEBUFFER_BINDING:
4470 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
4471 *num_written = 1;
4472 if (params) {
4473 Framebuffer* framebuffer =
4474 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4475 if (framebuffer) {
4476 GLuint client_id = 0;
4477 framebuffer_manager()->GetClientId(
4478 framebuffer->service_id(), &client_id);
4479 *params = client_id;
4480 } else {
4481 *params = 0;
4482 }
4483 }
4484 return true;
4485 case GL_READ_FRAMEBUFFER_BINDING_EXT:
4486 *num_written = 1;
4487 if (params) {
4488 Framebuffer* framebuffer =
4489 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
4490 if (framebuffer) {
4491 GLuint client_id = 0;
4492 framebuffer_manager()->GetClientId(
4493 framebuffer->service_id(), &client_id);
4494 *params = client_id;
4495 } else {
4496 *params = 0;
4497 }
4498 }
4499 return true;
4500 case GL_RENDERBUFFER_BINDING:
4501 *num_written = 1;
4502 if (params) {
4503 Renderbuffer* renderbuffer =
4504 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4505 if (renderbuffer) {
4506 *params = renderbuffer->client_id();
4507 } else {
4508 *params = 0;
4509 }
4510 }
4511 return true;
4512 case GL_CURRENT_PROGRAM:
4513 *num_written = 1;
4514 if (params) {
4515 if (state_.current_program.get()) {
4516 GLuint client_id = 0;
4517 program_manager()->GetClientId(
4518 state_.current_program->service_id(), &client_id);
4519 *params = client_id;
4520 } else {
4521 *params = 0;
4522 }
4523 }
4524 return true;
4525 case GL_VERTEX_ARRAY_BINDING_OES:
4526 *num_written = 1;
4527 if (params) {
4528 if (state_.vertex_attrib_manager.get() !=
4529 state_.default_vertex_attrib_manager.get()) {
4530 GLuint client_id = 0;
4531 vertex_array_manager_->GetClientId(
4532 state_.vertex_attrib_manager->service_id(), &client_id);
4533 *params = client_id;
4534 } else {
4535 *params = 0;
4536 }
4537 }
4538 return true;
4539 case GL_TEXTURE_BINDING_2D:
4540 *num_written = 1;
4541 if (params) {
4542 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
4543 if (unit.bound_texture_2d.get()) {
4544 *params = unit.bound_texture_2d->client_id();
4545 } else {
4546 *params = 0;
4547 }
4548 }
4549 return true;
4550 case GL_TEXTURE_BINDING_CUBE_MAP:
4551 *num_written = 1;
4552 if (params) {
4553 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
4554 if (unit.bound_texture_cube_map.get()) {
4555 *params = unit.bound_texture_cube_map->client_id();
4556 } else {
4557 *params = 0;
4558 }
4559 }
4560 return true;
4561 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4562 *num_written = 1;
4563 if (params) {
4564 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
4565 if (unit.bound_texture_external_oes.get()) {
4566 *params = unit.bound_texture_external_oes->client_id();
4567 } else {
4568 *params = 0;
4569 }
4570 }
4571 return true;
4572 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4573 *num_written = 1;
4574 if (params) {
4575 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
4576 if (unit.bound_texture_rectangle_arb.get()) {
4577 *params = unit.bound_texture_rectangle_arb->client_id();
4578 } else {
4579 *params = 0;
4580 }
4581 }
4582 return true;
4583 case GL_UNPACK_FLIP_Y_CHROMIUM:
4584 *num_written = 1;
4585 if (params) {
4586 params[0] = unpack_flip_y_;
4587 }
4588 return true;
4589 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4590 *num_written = 1;
4591 if (params) {
4592 params[0] = unpack_premultiply_alpha_;
4593 }
4594 return true;
4595 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4596 *num_written = 1;
4597 if (params) {
4598 params[0] = unpack_unpremultiply_alpha_;
4599 }
4600 return true;
4601 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4602 *num_written = 1;
4603 if (params) {
4604 params[0] = group_->bind_generates_resource() ? 1 : 0;
4605 }
4606 return true;
4607 default:
4608 if (pname >= GL_DRAW_BUFFER0_ARB &&
4609 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4610 *num_written = 1;
4611 if (params) {
4612 Framebuffer* framebuffer =
4613 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4614 if (framebuffer) {
4615 params[0] = framebuffer->GetDrawBuffer(pname);
4616 } else { // backbuffer
4617 if (pname == GL_DRAW_BUFFER0_ARB)
4618 params[0] = group_->draw_buffer();
4619 else
4620 params[0] = GL_NONE;
4621 }
4622 }
4623 return true;
4624 }
4625 *num_written = util_.GLGetNumValuesReturned(pname);
4626 return false;
4627 }
4628 }
4629
GetNumValuesReturnedForGLGet(GLenum pname,GLsizei * num_values)4630 bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4631 GLenum pname, GLsizei* num_values) {
4632 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
4633 return true;
4634 }
4635 return GetHelper(pname, NULL, num_values);
4636 }
4637
AdjustGetPname(GLenum pname)4638 GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4639 if (GL_MAX_SAMPLES == pname &&
4640 features().use_img_for_multisampled_render_to_texture) {
4641 return GL_MAX_SAMPLES_IMG;
4642 }
4643 return pname;
4644 }
4645
DoGetBooleanv(GLenum pname,GLboolean * params)4646 void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4647 DCHECK(params);
4648 GLsizei num_written = 0;
4649 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
4650 scoped_ptr<GLint[]> values(new GLint[num_written]);
4651 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
4652 GetHelper(pname, values.get(), &num_written);
4653 }
4654 for (GLsizei ii = 0; ii < num_written; ++ii) {
4655 params[ii] = static_cast<GLboolean>(values[ii]);
4656 }
4657 } else {
4658 pname = AdjustGetPname(pname);
4659 glGetBooleanv(pname, params);
4660 }
4661 }
4662
DoGetFloatv(GLenum pname,GLfloat * params)4663 void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4664 DCHECK(params);
4665 GLsizei num_written = 0;
4666 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
4667 if (GetHelper(pname, NULL, &num_written)) {
4668 scoped_ptr<GLint[]> values(new GLint[num_written]);
4669 GetHelper(pname, values.get(), &num_written);
4670 for (GLsizei ii = 0; ii < num_written; ++ii) {
4671 params[ii] = static_cast<GLfloat>(values[ii]);
4672 }
4673 } else {
4674 pname = AdjustGetPname(pname);
4675 glGetFloatv(pname, params);
4676 }
4677 }
4678 }
4679
DoGetIntegerv(GLenum pname,GLint * params)4680 void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4681 DCHECK(params);
4682 GLsizei num_written;
4683 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
4684 !GetHelper(pname, params, &num_written)) {
4685 pname = AdjustGetPname(pname);
4686 glGetIntegerv(pname, params);
4687 }
4688 }
4689
DoGetProgramiv(GLuint program_id,GLenum pname,GLint * params)4690 void GLES2DecoderImpl::DoGetProgramiv(
4691 GLuint program_id, GLenum pname, GLint* params) {
4692 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4693 if (!program) {
4694 return;
4695 }
4696 program->GetProgramiv(pname, params);
4697 }
4698
DoGetBufferParameteriv(GLenum target,GLenum pname,GLint * params)4699 void GLES2DecoderImpl::DoGetBufferParameteriv(
4700 GLenum target, GLenum pname, GLint* params) {
4701 // Just delegate it. Some validation is actually done before this.
4702 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4703 &state_, target, pname, params);
4704 }
4705
DoBindAttribLocation(GLuint program_id,GLuint index,const char * name)4706 void GLES2DecoderImpl::DoBindAttribLocation(
4707 GLuint program_id, GLuint index, const char* name) {
4708 if (!StringIsValidForGLES(name)) {
4709 LOCAL_SET_GL_ERROR(
4710 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
4711 return;
4712 }
4713 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
4714 LOCAL_SET_GL_ERROR(
4715 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
4716 return;
4717 }
4718 if (index >= group_->max_vertex_attribs()) {
4719 LOCAL_SET_GL_ERROR(
4720 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
4721 return;
4722 }
4723 Program* program = GetProgramInfoNotShader(
4724 program_id, "glBindAttribLocation");
4725 if (!program) {
4726 return;
4727 }
4728 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4729 glBindAttribLocation(program->service_id(), index, name);
4730 }
4731
HandleBindAttribLocationBucket(uint32 immediate_data_size,const cmds::BindAttribLocationBucket & c)4732 error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
4733 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
4734 GLuint program = static_cast<GLuint>(c.program);
4735 GLuint index = static_cast<GLuint>(c.index);
4736 Bucket* bucket = GetBucket(c.name_bucket_id);
4737 if (!bucket || bucket->size() == 0) {
4738 return error::kInvalidArguments;
4739 }
4740 std::string name_str;
4741 if (!bucket->GetAsString(&name_str)) {
4742 return error::kInvalidArguments;
4743 }
4744 DoBindAttribLocation(program, index, name_str.c_str());
4745 return error::kNoError;
4746 }
4747
DoBindUniformLocationCHROMIUM(GLuint program_id,GLint location,const char * name)4748 void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
4749 GLuint program_id, GLint location, const char* name) {
4750 if (!StringIsValidForGLES(name)) {
4751 LOCAL_SET_GL_ERROR(
4752 GL_INVALID_VALUE,
4753 "glBindUniformLocationCHROMIUM", "Invalid character");
4754 return;
4755 }
4756 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
4757 LOCAL_SET_GL_ERROR(
4758 GL_INVALID_OPERATION,
4759 "glBindUniformLocationCHROMIUM", "reserved prefix");
4760 return;
4761 }
4762 if (location < 0 || static_cast<uint32>(location) >=
4763 (group_->max_fragment_uniform_vectors() +
4764 group_->max_vertex_uniform_vectors()) * 4) {
4765 LOCAL_SET_GL_ERROR(
4766 GL_INVALID_VALUE,
4767 "glBindUniformLocationCHROMIUM", "location out of range");
4768 return;
4769 }
4770 Program* program = GetProgramInfoNotShader(
4771 program_id, "glBindUniformLocationCHROMIUM");
4772 if (!program) {
4773 return;
4774 }
4775 if (!program->SetUniformLocationBinding(name, location)) {
4776 LOCAL_SET_GL_ERROR(
4777 GL_INVALID_VALUE,
4778 "glBindUniformLocationCHROMIUM", "location out of range");
4779 }
4780 }
4781
HandleBindUniformLocationCHROMIUMBucket(uint32 immediate_data_size,const cmds::BindUniformLocationCHROMIUMBucket & c)4782 error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4783 uint32 immediate_data_size,
4784 const cmds::BindUniformLocationCHROMIUMBucket& c) {
4785 GLuint program = static_cast<GLuint>(c.program);
4786 GLint location = static_cast<GLint>(c.location);
4787 Bucket* bucket = GetBucket(c.name_bucket_id);
4788 if (!bucket || bucket->size() == 0) {
4789 return error::kInvalidArguments;
4790 }
4791 std::string name_str;
4792 if (!bucket->GetAsString(&name_str)) {
4793 return error::kInvalidArguments;
4794 }
4795 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4796 return error::kNoError;
4797 }
4798
HandleDeleteShader(uint32 immediate_data_size,const cmds::DeleteShader & c)4799 error::Error GLES2DecoderImpl::HandleDeleteShader(
4800 uint32 immediate_data_size, const cmds::DeleteShader& c) {
4801 GLuint client_id = c.shader;
4802 if (client_id) {
4803 Shader* shader = GetShader(client_id);
4804 if (shader) {
4805 if (!shader->IsDeleted()) {
4806 glDeleteShader(shader->service_id());
4807 shader_manager()->MarkAsDeleted(shader);
4808 }
4809 } else {
4810 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
4811 }
4812 }
4813 return error::kNoError;
4814 }
4815
HandleDeleteProgram(uint32 immediate_data_size,const cmds::DeleteProgram & c)4816 error::Error GLES2DecoderImpl::HandleDeleteProgram(
4817 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
4818 GLuint client_id = c.program;
4819 if (client_id) {
4820 Program* program = GetProgram(client_id);
4821 if (program) {
4822 if (!program->IsDeleted()) {
4823 program_manager()->MarkAsDeleted(shader_manager(), program);
4824 }
4825 } else {
4826 LOCAL_SET_GL_ERROR(
4827 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
4828 }
4829 }
4830 return error::kNoError;
4831 }
4832
DoDeleteSharedIdsCHROMIUM(GLuint namespace_id,GLsizei n,const GLuint * ids)4833 void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
4834 GLuint namespace_id, GLsizei n, const GLuint* ids) {
4835 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
4836 for (GLsizei ii = 0; ii < n; ++ii) {
4837 id_allocator->FreeID(ids[ii]);
4838 }
4839 }
4840
HandleDeleteSharedIdsCHROMIUM(uint32 immediate_data_size,const cmds::DeleteSharedIdsCHROMIUM & c)4841 error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
4842 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
4843 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4844 GLsizei n = static_cast<GLsizei>(c.n);
4845 uint32 data_size;
4846 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4847 return error::kOutOfBounds;
4848 }
4849 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4850 c.ids_shm_id, c.ids_shm_offset, data_size);
4851 if (n < 0) {
4852 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
4853 return error::kNoError;
4854 }
4855 if (ids == NULL) {
4856 return error::kOutOfBounds;
4857 }
4858 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
4859 return error::kNoError;
4860 }
4861
DoGenSharedIdsCHROMIUM(GLuint namespace_id,GLuint id_offset,GLsizei n,GLuint * ids)4862 void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
4863 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
4864 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
4865 if (id_offset == 0) {
4866 for (GLsizei ii = 0; ii < n; ++ii) {
4867 ids[ii] = id_allocator->AllocateID();
4868 }
4869 } else {
4870 for (GLsizei ii = 0; ii < n; ++ii) {
4871 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4872 id_offset = ids[ii] + 1;
4873 }
4874 }
4875 }
4876
HandleGenSharedIdsCHROMIUM(uint32 immediate_data_size,const cmds::GenSharedIdsCHROMIUM & c)4877 error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
4878 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
4879 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4880 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4881 GLsizei n = static_cast<GLsizei>(c.n);
4882 uint32 data_size;
4883 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4884 return error::kOutOfBounds;
4885 }
4886 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4887 c.ids_shm_id, c.ids_shm_offset, data_size);
4888 if (n < 0) {
4889 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
4890 return error::kNoError;
4891 }
4892 if (ids == NULL) {
4893 return error::kOutOfBounds;
4894 }
4895 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
4896 return error::kNoError;
4897 }
4898
DoRegisterSharedIdsCHROMIUM(GLuint namespace_id,GLsizei n,const GLuint * ids)4899 void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
4900 GLuint namespace_id, GLsizei n, const GLuint* ids) {
4901 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
4902 for (GLsizei ii = 0; ii < n; ++ii) {
4903 if (!id_allocator->MarkAsUsed(ids[ii])) {
4904 for (GLsizei jj = 0; jj < ii; ++jj) {
4905 id_allocator->FreeID(ids[jj]);
4906 }
4907 LOCAL_SET_GL_ERROR(
4908 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4909 "attempt to register id that already exists");
4910 return;
4911 }
4912 }
4913 }
4914
HandleRegisterSharedIdsCHROMIUM(uint32 immediate_data_size,const cmds::RegisterSharedIdsCHROMIUM & c)4915 error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
4916 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
4917 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4918 GLsizei n = static_cast<GLsizei>(c.n);
4919 uint32 data_size;
4920 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4921 return error::kOutOfBounds;
4922 }
4923 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4924 c.ids_shm_id, c.ids_shm_offset, data_size);
4925 if (n < 0) {
4926 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
4927 return error::kNoError;
4928 }
4929 if (ids == NULL) {
4930 return error::kOutOfBounds;
4931 }
4932 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
4933 return error::kNoError;
4934 }
4935
DoClear(GLbitfield mask)4936 error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
4937 DCHECK(!ShouldDeferDraws());
4938 if (CheckBoundFramebuffersValid("glClear")) {
4939 ApplyDirtyState();
4940 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
4941 glClear(mask);
4942 }
4943 return error::kNoError;
4944 }
4945
DoFramebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint client_renderbuffer_id)4946 void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4947 GLenum target, GLenum attachment, GLenum renderbuffertarget,
4948 GLuint client_renderbuffer_id) {
4949 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4950 if (!framebuffer) {
4951 LOCAL_SET_GL_ERROR(
4952 GL_INVALID_OPERATION,
4953 "glFramebufferRenderbuffer", "no framebuffer bound");
4954 return;
4955 }
4956 GLuint service_id = 0;
4957 Renderbuffer* renderbuffer = NULL;
4958 if (client_renderbuffer_id) {
4959 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4960 if (!renderbuffer) {
4961 LOCAL_SET_GL_ERROR(
4962 GL_INVALID_OPERATION,
4963 "glFramebufferRenderbuffer", "unknown renderbuffer");
4964 return;
4965 }
4966 service_id = renderbuffer->service_id();
4967 }
4968 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
4969 glFramebufferRenderbufferEXT(
4970 target, attachment, renderbuffertarget, service_id);
4971 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
4972 if (error == GL_NO_ERROR) {
4973 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
4974 }
4975 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
4976 framebuffer_state_.clear_state_dirty = true;
4977 }
4978 OnFboChanged();
4979 }
4980
DoDisable(GLenum cap)4981 void GLES2DecoderImpl::DoDisable(GLenum cap) {
4982 if (SetCapabilityState(cap, false)) {
4983 glDisable(cap);
4984 }
4985 }
4986
DoEnable(GLenum cap)4987 void GLES2DecoderImpl::DoEnable(GLenum cap) {
4988 if (SetCapabilityState(cap, true)) {
4989 glEnable(cap);
4990 }
4991 }
4992
DoDepthRangef(GLclampf znear,GLclampf zfar)4993 void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4994 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4995 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4996 glDepthRange(znear, zfar);
4997 }
4998
DoSampleCoverage(GLclampf value,GLboolean invert)4999 void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
5000 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5001 state_.sample_coverage_invert = (invert != 0);
5002 glSampleCoverage(state_.sample_coverage_value, invert);
5003 }
5004
5005 // Assumes framebuffer is complete.
ClearUnclearedAttachments(GLenum target,Framebuffer * framebuffer)5006 void GLES2DecoderImpl::ClearUnclearedAttachments(
5007 GLenum target, Framebuffer* framebuffer) {
5008 if (target == GL_READ_FRAMEBUFFER_EXT) {
5009 // bind this to the DRAW point, clear then bind back to READ
5010 // TODO(gman): I don't think there is any guarantee that an FBO that
5011 // is complete on the READ attachment will be complete as a DRAW
5012 // attachment.
5013 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
5014 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
5015 }
5016 GLbitfield clear_bits = 0;
5017 if (framebuffer->HasUnclearedColorAttachments()) {
5018 glClearColor(
5019 0.0f, 0.0f, 0.0f,
5020 (GLES2Util::GetChannelsForFormat(
5021 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5022 1.0f);
5023 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
5024 clear_bits |= GL_COLOR_BUFFER_BIT;
5025 if (feature_info_->feature_flags().ext_draw_buffers)
5026 framebuffer->PrepareDrawBuffersForClear();
5027 }
5028
5029 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5030 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
5031 glClearStencil(0);
5032 state_.SetDeviceStencilMaskSeparate(GL_FRONT, -1);
5033 state_.SetDeviceStencilMaskSeparate(GL_BACK, -1);
5034 clear_bits |= GL_STENCIL_BUFFER_BIT;
5035 }
5036
5037 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5038 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
5039 glClearDepth(1.0f);
5040 state_.SetDeviceDepthMask(GL_TRUE);
5041 clear_bits |= GL_DEPTH_BUFFER_BIT;
5042 }
5043
5044 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
5045 glClear(clear_bits);
5046
5047 if ((clear_bits | GL_COLOR_BUFFER_BIT) != 0 &&
5048 feature_info_->feature_flags().ext_draw_buffers)
5049 framebuffer->RestoreDrawBuffersAfterClear();
5050
5051 framebuffer_manager()->MarkAttachmentsAsCleared(
5052 framebuffer, renderbuffer_manager(), texture_manager());
5053
5054 RestoreClearState();
5055
5056 if (target == GL_READ_FRAMEBUFFER_EXT) {
5057 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5058 Framebuffer* draw_framebuffer =
5059 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
5060 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5061 GetBackbufferServiceId();
5062 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
5063 }
5064 }
5065
RestoreClearState()5066 void GLES2DecoderImpl::RestoreClearState() {
5067 framebuffer_state_.clear_state_dirty = true;
5068 glClearColor(
5069 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5070 state_.color_clear_alpha);
5071 glClearStencil(state_.stencil_clear);
5072 glClearDepth(state_.depth_clear);
5073 if (state_.enable_flags.scissor_test) {
5074 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
5075 }
5076 }
5077
DoCheckFramebufferStatus(GLenum target)5078 GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
5079 Framebuffer* framebuffer =
5080 GetFramebufferInfoForTarget(target);
5081 if (!framebuffer) {
5082 return GL_FRAMEBUFFER_COMPLETE;
5083 }
5084 GLenum completeness = framebuffer->IsPossiblyComplete();
5085 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5086 return completeness;
5087 }
5088 return framebuffer->GetStatus(texture_manager(), target);
5089 }
5090
DoFramebufferTexture2D(GLenum target,GLenum attachment,GLenum textarget,GLuint client_texture_id,GLint level)5091 void GLES2DecoderImpl::DoFramebufferTexture2D(
5092 GLenum target, GLenum attachment, GLenum textarget,
5093 GLuint client_texture_id, GLint level) {
5094 DoFramebufferTexture2DCommon(
5095 "glFramebufferTexture2D", target, attachment,
5096 textarget, client_texture_id, level, 0);
5097 }
5098
DoFramebufferTexture2DMultisample(GLenum target,GLenum attachment,GLenum textarget,GLuint client_texture_id,GLint level,GLsizei samples)5099 void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5100 GLenum target, GLenum attachment, GLenum textarget,
5101 GLuint client_texture_id, GLint level, GLsizei samples) {
5102 DoFramebufferTexture2DCommon(
5103 "glFramebufferTexture2DMultisample", target, attachment,
5104 textarget, client_texture_id, level, samples);
5105 }
5106
DoFramebufferTexture2DCommon(const char * name,GLenum target,GLenum attachment,GLenum textarget,GLuint client_texture_id,GLint level,GLsizei samples)5107 void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5108 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5109 GLuint client_texture_id, GLint level, GLsizei samples) {
5110 if (samples > renderbuffer_manager()->max_samples()) {
5111 LOCAL_SET_GL_ERROR(
5112 GL_INVALID_VALUE,
5113 "glFramebufferTexture2DMultisample", "samples too large");
5114 return;
5115 }
5116 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5117 if (!framebuffer) {
5118 LOCAL_SET_GL_ERROR(
5119 GL_INVALID_OPERATION,
5120 name, "no framebuffer bound.");
5121 return;
5122 }
5123 GLuint service_id = 0;
5124 TextureRef* texture_ref = NULL;
5125 if (client_texture_id) {
5126 texture_ref = GetTexture(client_texture_id);
5127 if (!texture_ref) {
5128 LOCAL_SET_GL_ERROR(
5129 GL_INVALID_OPERATION,
5130 name, "unknown texture_ref");
5131 return;
5132 }
5133 service_id = texture_ref->service_id();
5134 }
5135
5136 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
5137 LOCAL_SET_GL_ERROR(
5138 GL_INVALID_VALUE,
5139 name, "level out of range");
5140 return;
5141 }
5142
5143 if (texture_ref)
5144 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5145
5146 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5147 if (0 == samples) {
5148 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5149 } else {
5150 if (features().use_img_for_multisampled_render_to_texture) {
5151 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5152 service_id, level, samples);
5153 } else {
5154 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5155 service_id, level, samples);
5156 }
5157 }
5158 GLenum error = LOCAL_PEEK_GL_ERROR(name);
5159 if (error == GL_NO_ERROR) {
5160 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5161 samples);
5162 }
5163 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
5164 framebuffer_state_.clear_state_dirty = true;
5165 }
5166
5167 if (texture_ref)
5168 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5169
5170 OnFboChanged();
5171 }
5172
DoGetFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params)5173 void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5174 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
5175 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5176 if (!framebuffer) {
5177 LOCAL_SET_GL_ERROR(
5178 GL_INVALID_OPERATION,
5179 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
5180 return;
5181 }
5182 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
5183 const Framebuffer::Attachment* attachment_object =
5184 framebuffer->GetAttachment(attachment);
5185 *params = attachment_object ? attachment_object->object_name() : 0;
5186 } else {
5187 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5188 features().use_img_for_multisampled_render_to_texture) {
5189 pname = GL_TEXTURE_SAMPLES_IMG;
5190 }
5191 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
5192 }
5193 }
5194
DoGetRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params)5195 void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5196 GLenum target, GLenum pname, GLint* params) {
5197 Renderbuffer* renderbuffer =
5198 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5199 if (!renderbuffer) {
5200 LOCAL_SET_GL_ERROR(
5201 GL_INVALID_OPERATION,
5202 "glGetRenderbufferParameteriv", "no renderbuffer bound");
5203 return;
5204 }
5205 switch (pname) {
5206 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5207 *params = renderbuffer->internal_format();
5208 break;
5209 case GL_RENDERBUFFER_WIDTH:
5210 *params = renderbuffer->width();
5211 break;
5212 case GL_RENDERBUFFER_HEIGHT:
5213 *params = renderbuffer->height();
5214 break;
5215 case GL_RENDERBUFFER_SAMPLES_EXT:
5216 if (features().use_img_for_multisampled_render_to_texture) {
5217 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5218 params);
5219 } else {
5220 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5221 params);
5222 }
5223 default:
5224 glGetRenderbufferParameterivEXT(target, pname, params);
5225 break;
5226 }
5227 }
5228
DoBlitFramebufferCHROMIUM(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)5229 void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
5230 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5231 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5232 GLbitfield mask, GLenum filter) {
5233 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
5234
5235 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
5236 return;
5237 }
5238
5239 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
5240 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
5241 BlitFramebufferHelper(
5242 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5243 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5244 state_.enable_flags.scissor_test);
5245 }
5246
RenderbufferStorageMultisampleHelper(const FeatureInfo * feature_info,GLenum target,GLsizei samples,GLenum internal_format,GLsizei width,GLsizei height)5247 void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5248 const FeatureInfo* feature_info,
5249 GLenum target,
5250 GLsizei samples,
5251 GLenum internal_format,
5252 GLsizei width,
5253 GLsizei height) {
5254 // TODO(sievers): This could be resolved at the GL binding level, but the
5255 // binding process is currently a bit too 'brute force'.
5256 if (feature_info->feature_flags().is_angle) {
5257 glRenderbufferStorageMultisampleANGLE(
5258 target, samples, internal_format, width, height);
5259 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5260 glRenderbufferStorageMultisample(
5261 target, samples, internal_format, width, height);
5262 } else {
5263 glRenderbufferStorageMultisampleEXT(
5264 target, samples, internal_format, width, height);
5265 }
5266 }
5267
BlitFramebufferHelper(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)5268 void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5269 GLint srcY0,
5270 GLint srcX1,
5271 GLint srcY1,
5272 GLint dstX0,
5273 GLint dstY0,
5274 GLint dstX1,
5275 GLint dstY1,
5276 GLbitfield mask,
5277 GLenum filter) {
5278 // TODO(sievers): This could be resolved at the GL binding level, but the
5279 // binding process is currently a bit too 'brute force'.
5280 if (feature_info_->feature_flags().is_angle) {
5281 glBlitFramebufferANGLE(
5282 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5283 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5284 glBlitFramebuffer(
5285 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5286 } else {
5287 glBlitFramebufferEXT(
5288 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5289 }
5290 }
5291
ValidateRenderbufferStorageMultisample(GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)5292 bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5293 GLsizei samples,
5294 GLenum internalformat,
5295 GLsizei width,
5296 GLsizei height) {
5297 if (samples > renderbuffer_manager()->max_samples()) {
5298 LOCAL_SET_GL_ERROR(
5299 GL_INVALID_VALUE,
5300 "glRenderbufferStorageMultisample", "samples too large");
5301 return false;
5302 }
5303
5304 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5305 height > renderbuffer_manager()->max_renderbuffer_size()) {
5306 LOCAL_SET_GL_ERROR(
5307 GL_INVALID_VALUE,
5308 "glRenderbufferStorageMultisample", "dimensions too large");
5309 return false;
5310 }
5311
5312 uint32 estimated_size = 0;
5313 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5314 width, height, samples, internalformat, &estimated_size)) {
5315 LOCAL_SET_GL_ERROR(
5316 GL_OUT_OF_MEMORY,
5317 "glRenderbufferStorageMultisample", "dimensions too large");
5318 return false;
5319 }
5320
5321 if (!EnsureGPUMemoryAvailable(estimated_size)) {
5322 LOCAL_SET_GL_ERROR(
5323 GL_OUT_OF_MEMORY,
5324 "glRenderbufferStorageMultisample", "out of memory");
5325 return false;
5326 }
5327
5328 return true;
5329 }
5330
DoRenderbufferStorageMultisampleCHROMIUM(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)5331 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5332 GLenum target, GLsizei samples, GLenum internalformat,
5333 GLsizei width, GLsizei height) {
5334 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5335 if (!renderbuffer) {
5336 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5337 "glRenderbufferStorageMultisampleCHROMIUM",
5338 "no renderbuffer bound");
5339 return;
5340 }
5341
5342 if (!ValidateRenderbufferStorageMultisample(
5343 samples, internalformat, width, height)) {
5344 return;
5345 }
5346
5347 GLenum impl_format =
5348 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5349 internalformat);
5350 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5351 "glRenderbufferStorageMultisampleCHROMIUM");
5352 RenderbufferStorageMultisampleHelper(
5353 feature_info_, target, samples, impl_format, width, height);
5354 GLenum error =
5355 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
5356 if (error == GL_NO_ERROR) {
5357
5358 if (workarounds().validate_multisample_buffer_allocation) {
5359 if (!VerifyMultisampleRenderbufferIntegrity(
5360 renderbuffer->service_id(), impl_format)) {
5361 LOCAL_SET_GL_ERROR(
5362 GL_OUT_OF_MEMORY,
5363 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
5364 return;
5365 }
5366 }
5367
5368 // TODO(gman): If renderbuffers tracked which framebuffers they were
5369 // attached to we could just mark those framebuffers as not complete.
5370 framebuffer_manager()->IncFramebufferStateChangeCount();
5371 renderbuffer_manager()->SetInfo(
5372 renderbuffer, samples, internalformat, width, height);
5373 }
5374 }
5375
5376 // This is the handler for multisampled_render_to_texture extensions.
DoRenderbufferStorageMultisampleEXT(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)5377 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5378 GLenum target, GLsizei samples, GLenum internalformat,
5379 GLsizei width, GLsizei height) {
5380 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5381 if (!renderbuffer) {
5382 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5383 "glRenderbufferStorageMultisampleEXT",
5384 "no renderbuffer bound");
5385 return;
5386 }
5387
5388 if (!ValidateRenderbufferStorageMultisample(
5389 samples, internalformat, width, height)) {
5390 return;
5391 }
5392
5393 GLenum impl_format =
5394 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5395 internalformat);
5396 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5397 if (features().use_img_for_multisampled_render_to_texture) {
5398 glRenderbufferStorageMultisampleIMG(
5399 target, samples, impl_format, width, height);
5400 } else {
5401 glRenderbufferStorageMultisampleEXT(
5402 target, samples, impl_format, width, height);
5403 }
5404 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5405 if (error == GL_NO_ERROR) {
5406 // TODO(gman): If renderbuffers tracked which framebuffers they were
5407 // attached to we could just mark those framebuffers as not complete.
5408 framebuffer_manager()->IncFramebufferStateChangeCount();
5409 renderbuffer_manager()->SetInfo(
5410 renderbuffer, samples, internalformat, width, height);
5411 }
5412 }
5413
5414 // This function validates the allocation of a multisampled renderbuffer
5415 // by clearing it to a key color, blitting the contents to a texture, and
5416 // reading back the color to ensure it matches the key.
VerifyMultisampleRenderbufferIntegrity(GLuint renderbuffer,GLenum format)5417 bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5418 GLuint renderbuffer, GLenum format) {
5419
5420 // Only validate color buffers.
5421 // These formats have been selected because they are very common or are known
5422 // to be used by the WebGL backbuffer. If problems are observed with other
5423 // color formats they can be added here.
5424 switch(format) {
5425 case GL_RGB:
5426 case GL_RGB8:
5427 case GL_RGBA:
5428 case GL_RGBA8:
5429 break;
5430 default:
5431 return true;
5432 }
5433
5434 GLint draw_framebuffer, read_framebuffer;
5435
5436 // Cache framebuffer and texture bindings.
5437 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5438 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5439
5440 if (!validation_texture_) {
5441 GLint bound_texture;
5442 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5443
5444 // Create additional resources needed for the verification.
5445 glGenTextures(1, &validation_texture_);
5446 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5447 glGenFramebuffersEXT(1, &validation_fbo_);
5448
5449 // Texture only needs to be 1x1.
5450 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5451 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5452 GL_UNSIGNED_BYTE, NULL);
5453
5454 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5455 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5456 GL_TEXTURE_2D, validation_texture_, 0);
5457
5458 glBindTexture(GL_TEXTURE_2D, bound_texture);
5459 }
5460
5461 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5462 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5463 GL_RENDERBUFFER, renderbuffer);
5464
5465 // Cache current state and reset it to the values we require.
5466 GLboolean scissor_enabled = false;
5467 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5468 if (scissor_enabled)
5469 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
5470
5471 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
5472 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
5473 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
5474
5475 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5476 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5477 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5478
5479 // Clear the buffer to the desired key color.
5480 glClear(GL_COLOR_BUFFER_BIT);
5481
5482 // Blit from the multisample buffer to a standard texture.
5483 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5484 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5485
5486 BlitFramebufferHelper(
5487 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
5488
5489 // Read a pixel from the buffer.
5490 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5491
5492 unsigned char pixel[3] = {0, 0, 0};
5493 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5494
5495 // Detach the renderbuffer.
5496 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5497 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5498 GL_RENDERBUFFER, 0);
5499
5500 // Restore cached state.
5501 if (scissor_enabled)
5502 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
5503
5504 state_.SetDeviceColorMask(
5505 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
5506 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5507 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5508 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5509
5510 // Return true if the pixel matched the desired key color.
5511 return (pixel[0] == 0xFF &&
5512 pixel[1] == 0x00 &&
5513 pixel[2] == 0xFF);
5514 }
5515
DoRenderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)5516 void GLES2DecoderImpl::DoRenderbufferStorage(
5517 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
5518 Renderbuffer* renderbuffer =
5519 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5520 if (!renderbuffer) {
5521 LOCAL_SET_GL_ERROR(
5522 GL_INVALID_OPERATION,
5523 "glRenderbufferStorage", "no renderbuffer bound");
5524 return;
5525 }
5526
5527 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5528 height > renderbuffer_manager()->max_renderbuffer_size()) {
5529 LOCAL_SET_GL_ERROR(
5530 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
5531 return;
5532 }
5533
5534 uint32 estimated_size = 0;
5535 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5536 width, height, 1, internalformat, &estimated_size)) {
5537 LOCAL_SET_GL_ERROR(
5538 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
5539 return;
5540 }
5541
5542 if (!EnsureGPUMemoryAvailable(estimated_size)) {
5543 LOCAL_SET_GL_ERROR(
5544 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
5545 return;
5546 }
5547
5548 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
5549 glRenderbufferStorageEXT(
5550 target,
5551 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5552 internalformat),
5553 width,
5554 height);
5555 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
5556 if (error == GL_NO_ERROR) {
5557 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5558 // we could just mark those framebuffers as not complete.
5559 framebuffer_manager()->IncFramebufferStateChangeCount();
5560 renderbuffer_manager()->SetInfo(
5561 renderbuffer, 1, internalformat, width, height);
5562 }
5563 }
5564
DoLinkProgram(GLuint program_id)5565 void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
5566 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
5567 Program* program = GetProgramInfoNotShader(
5568 program_id, "glLinkProgram");
5569 if (!program) {
5570 return;
5571 }
5572
5573 LogClientServiceForInfo(program, program_id, "glLinkProgram");
5574 ShaderTranslator* vertex_translator = NULL;
5575 ShaderTranslator* fragment_translator = NULL;
5576 if (use_shader_translator_) {
5577 vertex_translator = vertex_translator_.get();
5578 fragment_translator = fragment_translator_.get();
5579 }
5580 if (program->Link(shader_manager(),
5581 vertex_translator,
5582 fragment_translator,
5583 workarounds().count_all_in_varyings_packing ?
5584 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
5585 shader_cache_callback_)) {
5586 if (program == state_.current_program.get()) {
5587 if (workarounds().use_current_program_after_successful_link)
5588 glUseProgram(program->service_id());
5589 if (workarounds().clear_uniforms_before_first_program_use)
5590 program_manager()->ClearUniforms(program);
5591 }
5592 }
5593 };
5594
DoTexParameterf(GLenum target,GLenum pname,GLfloat param)5595 void GLES2DecoderImpl::DoTexParameterf(
5596 GLenum target, GLenum pname, GLfloat param) {
5597 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5598 &state_, target);
5599 if (!texture) {
5600 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
5601 return;
5602 }
5603
5604 texture_manager()->SetParameterf(
5605 "glTexParameterf", GetErrorState(), texture, pname, param);
5606 }
5607
DoTexParameteri(GLenum target,GLenum pname,GLint param)5608 void GLES2DecoderImpl::DoTexParameteri(
5609 GLenum target, GLenum pname, GLint param) {
5610 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5611 &state_, target);
5612 if (!texture) {
5613 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
5614 return;
5615 }
5616
5617 texture_manager()->SetParameteri(
5618 "glTexParameteri", GetErrorState(), texture, pname, param);
5619 }
5620
DoTexParameterfv(GLenum target,GLenum pname,const GLfloat * params)5621 void GLES2DecoderImpl::DoTexParameterfv(
5622 GLenum target, GLenum pname, const GLfloat* params) {
5623 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5624 &state_, target);
5625 if (!texture) {
5626 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
5627 return;
5628 }
5629
5630 texture_manager()->SetParameterf(
5631 "glTexParameterfv", GetErrorState(), texture, pname, *params);
5632 }
5633
DoTexParameteriv(GLenum target,GLenum pname,const GLint * params)5634 void GLES2DecoderImpl::DoTexParameteriv(
5635 GLenum target, GLenum pname, const GLint* params) {
5636 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5637 &state_, target);
5638 if (!texture) {
5639 LOCAL_SET_GL_ERROR(
5640 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
5641 return;
5642 }
5643
5644 texture_manager()->SetParameteri(
5645 "glTexParameteriv", GetErrorState(), texture, pname, *params);
5646 }
5647
CheckCurrentProgram(const char * function_name)5648 bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
5649 if (!state_.current_program.get()) {
5650 // The program does not exist.
5651 LOCAL_SET_GL_ERROR(
5652 GL_INVALID_OPERATION, function_name, "no program in use");
5653 return false;
5654 }
5655 if (!state_.current_program->InUse()) {
5656 LOCAL_SET_GL_ERROR(
5657 GL_INVALID_OPERATION, function_name, "program not linked");
5658 return false;
5659 }
5660 return true;
5661 }
5662
CheckCurrentProgramForUniform(GLint location,const char * function_name)5663 bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5664 GLint location, const char* function_name) {
5665 if (!CheckCurrentProgram(function_name)) {
5666 return false;
5667 }
5668 return location != -1;
5669 }
5670
PrepForSetUniformByLocation(GLint fake_location,const char * function_name,Program::UniformApiType api_type,GLint * real_location,GLenum * type,GLsizei * count)5671 bool GLES2DecoderImpl::PrepForSetUniformByLocation(
5672 GLint fake_location,
5673 const char* function_name,
5674 Program::UniformApiType api_type,
5675 GLint* real_location,
5676 GLenum* type,
5677 GLsizei* count) {
5678 DCHECK(type);
5679 DCHECK(count);
5680 DCHECK(real_location);
5681
5682 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
5683 return false;
5684 }
5685 GLint array_index = -1;
5686 const Program::UniformInfo* info =
5687 state_.current_program->GetUniformInfoByFakeLocation(
5688 fake_location, real_location, &array_index);
5689 if (!info) {
5690 LOCAL_SET_GL_ERROR(
5691 GL_INVALID_OPERATION, function_name, "unknown location");
5692 return false;
5693 }
5694
5695 if ((api_type & info->accepts_api_type) == 0) {
5696 LOCAL_SET_GL_ERROR(
5697 GL_INVALID_OPERATION, function_name,
5698 "wrong uniform function for type");
5699 return false;
5700 }
5701 if (*count > 1 && !info->is_array) {
5702 LOCAL_SET_GL_ERROR(
5703 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
5704 return false;
5705 }
5706 *count = std::min(info->size - array_index, *count);
5707 if (*count <= 0) {
5708 return false;
5709 }
5710 *type = info->type;
5711 return true;
5712 }
5713
DoUniform1i(GLint fake_location,GLint v0)5714 void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5715 GLenum type = 0;
5716 GLsizei count = 1;
5717 GLint real_location = -1;
5718 if (!PrepForSetUniformByLocation(fake_location,
5719 "glUniform1i",
5720 Program::kUniform1i,
5721 &real_location,
5722 &type,
5723 &count)) {
5724 return;
5725 }
5726 if (!state_.current_program->SetSamplers(
5727 state_.texture_units.size(), fake_location, 1, &v0)) {
5728 LOCAL_SET_GL_ERROR(
5729 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
5730 return;
5731 }
5732 glUniform1i(real_location, v0);
5733 }
5734
DoUniform1iv(GLint fake_location,GLsizei count,const GLint * value)5735 void GLES2DecoderImpl::DoUniform1iv(
5736 GLint fake_location, GLsizei count, const GLint *value) {
5737 GLenum type = 0;
5738 GLint real_location = -1;
5739 if (!PrepForSetUniformByLocation(fake_location,
5740 "glUniform1iv",
5741 Program::kUniform1i,
5742 &real_location,
5743 &type,
5744 &count)) {
5745 return;
5746 }
5747 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5748 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
5749 if (!state_.current_program->SetSamplers(
5750 state_.texture_units.size(), fake_location, count, value)) {
5751 LOCAL_SET_GL_ERROR(
5752 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
5753 return;
5754 }
5755 }
5756 glUniform1iv(real_location, count, value);
5757 }
5758
DoUniform1fv(GLint fake_location,GLsizei count,const GLfloat * value)5759 void GLES2DecoderImpl::DoUniform1fv(
5760 GLint fake_location, GLsizei count, const GLfloat* value) {
5761 GLenum type = 0;
5762 GLint real_location = -1;
5763 if (!PrepForSetUniformByLocation(fake_location,
5764 "glUniform1fv",
5765 Program::kUniform1f,
5766 &real_location,
5767 &type,
5768 &count)) {
5769 return;
5770 }
5771 if (type == GL_BOOL) {
5772 scoped_ptr<GLint[]> temp(new GLint[count]);
5773 for (GLsizei ii = 0; ii < count; ++ii) {
5774 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
5775 }
5776 DoUniform1iv(real_location, count, temp.get());
5777 } else {
5778 glUniform1fv(real_location, count, value);
5779 }
5780 }
5781
DoUniform2fv(GLint fake_location,GLsizei count,const GLfloat * value)5782 void GLES2DecoderImpl::DoUniform2fv(
5783 GLint fake_location, GLsizei count, const GLfloat* value) {
5784 GLenum type = 0;
5785 GLint real_location = -1;
5786 if (!PrepForSetUniformByLocation(fake_location,
5787 "glUniform2fv",
5788 Program::kUniform2f,
5789 &real_location,
5790 &type,
5791 &count)) {
5792 return;
5793 }
5794 if (type == GL_BOOL_VEC2) {
5795 GLsizei num_values = count * 2;
5796 scoped_ptr<GLint[]> temp(new GLint[num_values]);
5797 for (GLsizei ii = 0; ii < num_values; ++ii) {
5798 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
5799 }
5800 glUniform2iv(real_location, count, temp.get());
5801 } else {
5802 glUniform2fv(real_location, count, value);
5803 }
5804 }
5805
DoUniform3fv(GLint fake_location,GLsizei count,const GLfloat * value)5806 void GLES2DecoderImpl::DoUniform3fv(
5807 GLint fake_location, GLsizei count, const GLfloat* value) {
5808 GLenum type = 0;
5809 GLint real_location = -1;
5810 if (!PrepForSetUniformByLocation(fake_location,
5811 "glUniform3fv",
5812 Program::kUniform3f,
5813 &real_location,
5814 &type,
5815 &count)) {
5816 return;
5817 }
5818 if (type == GL_BOOL_VEC3) {
5819 GLsizei num_values = count * 3;
5820 scoped_ptr<GLint[]> temp(new GLint[num_values]);
5821 for (GLsizei ii = 0; ii < num_values; ++ii) {
5822 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
5823 }
5824 glUniform3iv(real_location, count, temp.get());
5825 } else {
5826 glUniform3fv(real_location, count, value);
5827 }
5828 }
5829
DoUniform4fv(GLint fake_location,GLsizei count,const GLfloat * value)5830 void GLES2DecoderImpl::DoUniform4fv(
5831 GLint fake_location, GLsizei count, const GLfloat* value) {
5832 GLenum type = 0;
5833 GLint real_location = -1;
5834 if (!PrepForSetUniformByLocation(fake_location,
5835 "glUniform4fv",
5836 Program::kUniform4f,
5837 &real_location,
5838 &type,
5839 &count)) {
5840 return;
5841 }
5842 if (type == GL_BOOL_VEC4) {
5843 GLsizei num_values = count * 4;
5844 scoped_ptr<GLint[]> temp(new GLint[num_values]);
5845 for (GLsizei ii = 0; ii < num_values; ++ii) {
5846 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
5847 }
5848 glUniform4iv(real_location, count, temp.get());
5849 } else {
5850 glUniform4fv(real_location, count, value);
5851 }
5852 }
5853
DoUniform2iv(GLint fake_location,GLsizei count,const GLint * value)5854 void GLES2DecoderImpl::DoUniform2iv(
5855 GLint fake_location, GLsizei count, const GLint* value) {
5856 GLenum type = 0;
5857 GLint real_location = -1;
5858 if (!PrepForSetUniformByLocation(fake_location,
5859 "glUniform2iv",
5860 Program::kUniform2i,
5861 &real_location,
5862 &type,
5863 &count)) {
5864 return;
5865 }
5866 glUniform2iv(real_location, count, value);
5867 }
5868
DoUniform3iv(GLint fake_location,GLsizei count,const GLint * value)5869 void GLES2DecoderImpl::DoUniform3iv(
5870 GLint fake_location, GLsizei count, const GLint* value) {
5871 GLenum type = 0;
5872 GLint real_location = -1;
5873 if (!PrepForSetUniformByLocation(fake_location,
5874 "glUniform3iv",
5875 Program::kUniform3i,
5876 &real_location,
5877 &type,
5878 &count)) {
5879 return;
5880 }
5881 glUniform3iv(real_location, count, value);
5882 }
5883
DoUniform4iv(GLint fake_location,GLsizei count,const GLint * value)5884 void GLES2DecoderImpl::DoUniform4iv(
5885 GLint fake_location, GLsizei count, const GLint* value) {
5886 GLenum type = 0;
5887 GLint real_location = -1;
5888 if (!PrepForSetUniformByLocation(fake_location,
5889 "glUniform4iv",
5890 Program::kUniform4i,
5891 &real_location,
5892 &type,
5893 &count)) {
5894 return;
5895 }
5896 glUniform4iv(real_location, count, value);
5897 }
5898
DoUniformMatrix2fv(GLint fake_location,GLsizei count,GLboolean transpose,const GLfloat * value)5899 void GLES2DecoderImpl::DoUniformMatrix2fv(
5900 GLint fake_location, GLsizei count, GLboolean transpose,
5901 const GLfloat* value) {
5902 GLenum type = 0;
5903 GLint real_location = -1;
5904 if (!PrepForSetUniformByLocation(fake_location,
5905 "glUniformMatrix2fv",
5906 Program::kUniformMatrix2f,
5907 &real_location,
5908 &type,
5909 &count)) {
5910 return;
5911 }
5912 glUniformMatrix2fv(real_location, count, transpose, value);
5913 }
5914
DoUniformMatrix3fv(GLint fake_location,GLsizei count,GLboolean transpose,const GLfloat * value)5915 void GLES2DecoderImpl::DoUniformMatrix3fv(
5916 GLint fake_location, GLsizei count, GLboolean transpose,
5917 const GLfloat* value) {
5918 GLenum type = 0;
5919 GLint real_location = -1;
5920 if (!PrepForSetUniformByLocation(fake_location,
5921 "glUniformMatrix3fv",
5922 Program::kUniformMatrix3f,
5923 &real_location,
5924 &type,
5925 &count)) {
5926 return;
5927 }
5928 glUniformMatrix3fv(real_location, count, transpose, value);
5929 }
5930
DoUniformMatrix4fv(GLint fake_location,GLsizei count,GLboolean transpose,const GLfloat * value)5931 void GLES2DecoderImpl::DoUniformMatrix4fv(
5932 GLint fake_location, GLsizei count, GLboolean transpose,
5933 const GLfloat* value) {
5934 GLenum type = 0;
5935 GLint real_location = -1;
5936 if (!PrepForSetUniformByLocation(fake_location,
5937 "glUniformMatrix4fv",
5938 Program::kUniformMatrix4f,
5939 &real_location,
5940 &type,
5941 &count)) {
5942 return;
5943 }
5944 glUniformMatrix4fv(real_location, count, transpose, value);
5945 }
5946
DoUseProgram(GLuint program_id)5947 void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
5948 GLuint service_id = 0;
5949 Program* program = NULL;
5950 if (program_id) {
5951 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5952 if (!program) {
5953 return;
5954 }
5955 if (!program->IsValid()) {
5956 // Program was not linked successfully. (ie, glLinkProgram)
5957 LOCAL_SET_GL_ERROR(
5958 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
5959 return;
5960 }
5961 service_id = program->service_id();
5962 }
5963 if (state_.current_program.get()) {
5964 program_manager()->UnuseProgram(shader_manager(),
5965 state_.current_program.get());
5966 }
5967 state_.current_program = program;
5968 LogClientServiceMapping("glUseProgram", program_id, service_id);
5969 glUseProgram(service_id);
5970 if (state_.current_program.get()) {
5971 program_manager()->UseProgram(state_.current_program.get());
5972 if (workarounds().clear_uniforms_before_first_program_use)
5973 program_manager()->ClearUniforms(program);
5974 }
5975 }
5976
RenderWarning(const char * filename,int line,const std::string & msg)5977 void GLES2DecoderImpl::RenderWarning(
5978 const char* filename, int line, const std::string& msg) {
5979 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
5980 }
5981
PerformanceWarning(const char * filename,int line,const std::string & msg)5982 void GLES2DecoderImpl::PerformanceWarning(
5983 const char* filename, int line, const std::string& msg) {
5984 logger_.LogMessage(filename, line,
5985 std::string("PERFORMANCE WARNING: ") + msg);
5986 }
5987
DoWillUseTexImageIfNeeded(Texture * texture,GLenum textarget)5988 void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
5989 Texture* texture, GLenum textarget) {
5990 // Image is already in use if texture is attached to a framebuffer.
5991 if (texture && !texture->IsAttachedToFramebuffer()) {
5992 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5993 if (image) {
5994 ScopedGLErrorSuppressor suppressor(
5995 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
5996 GetErrorState());
5997 glBindTexture(textarget, texture->service_id());
5998 image->WillUseTexImage();
5999 RestoreCurrentTextureBindings(&state_, textarget);
6000 }
6001 }
6002 }
6003
DoDidUseTexImageIfNeeded(Texture * texture,GLenum textarget)6004 void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6005 Texture* texture, GLenum textarget) {
6006 // Image is still in use if texture is attached to a framebuffer.
6007 if (texture && !texture->IsAttachedToFramebuffer()) {
6008 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6009 if (image) {
6010 ScopedGLErrorSuppressor suppressor(
6011 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6012 GetErrorState());
6013 glBindTexture(textarget, texture->service_id());
6014 image->DidUseTexImage();
6015 RestoreCurrentTextureBindings(&state_, textarget);
6016 }
6017 }
6018 }
6019
PrepareTexturesForRender()6020 bool GLES2DecoderImpl::PrepareTexturesForRender() {
6021 DCHECK(state_.current_program.get());
6022 if (!texture_manager()->HaveUnrenderableTextures() &&
6023 !texture_manager()->HaveImages()) {
6024 return true;
6025 }
6026
6027 bool textures_set = false;
6028 const Program::SamplerIndices& sampler_indices =
6029 state_.current_program->sampler_indices();
6030 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6031 const Program::UniformInfo* uniform_info =
6032 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6033 DCHECK(uniform_info);
6034 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6035 GLuint texture_unit_index = uniform_info->texture_units[jj];
6036 if (texture_unit_index < state_.texture_units.size()) {
6037 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6038 TextureRef* texture_ref =
6039 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
6040 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6041 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
6042 textures_set = true;
6043 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6044 glBindTexture(
6045 textarget,
6046 texture_manager()->black_texture_id(uniform_info->type));
6047 LOCAL_RENDER_WARNING(
6048 std::string("texture bound to texture unit ") +
6049 base::IntToString(texture_unit_index) +
6050 " is not renderable. It maybe non-power-of-2 and have"
6051 " incompatible texture filtering or is not"
6052 " 'texture complete'");
6053 continue;
6054 }
6055
6056 if (textarget != GL_TEXTURE_CUBE_MAP) {
6057 Texture* texture = texture_ref->texture();
6058 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6059 if (image && !texture->IsAttachedToFramebuffer()) {
6060 ScopedGLErrorSuppressor suppressor(
6061 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6062 textures_set = true;
6063 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6064 image->WillUseTexImage();
6065 continue;
6066 }
6067 }
6068 }
6069 // else: should this be an error?
6070 }
6071 }
6072 return !textures_set;
6073 }
6074
RestoreStateForTextures()6075 void GLES2DecoderImpl::RestoreStateForTextures() {
6076 DCHECK(state_.current_program.get());
6077 const Program::SamplerIndices& sampler_indices =
6078 state_.current_program->sampler_indices();
6079 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6080 const Program::UniformInfo* uniform_info =
6081 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6082 DCHECK(uniform_info);
6083 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6084 GLuint texture_unit_index = uniform_info->texture_units[jj];
6085 if (texture_unit_index < state_.texture_units.size()) {
6086 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6087 TextureRef* texture_ref =
6088 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
6089 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
6090 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6091 // Get the texture_ref info that was previously bound here.
6092 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6093 ? texture_unit.bound_texture_2d.get()
6094 : texture_unit.bound_texture_cube_map.get();
6095 glBindTexture(texture_unit.bind_target,
6096 texture_ref ? texture_ref->service_id() : 0);
6097 continue;
6098 }
6099
6100 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6101 Texture* texture = texture_ref->texture();
6102 gfx::GLImage* image =
6103 texture->GetLevelImage(texture_unit.bind_target, 0);
6104 if (image && !texture->IsAttachedToFramebuffer()) {
6105 ScopedGLErrorSuppressor suppressor(
6106 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6107 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6108 image->DidUseTexImage();
6109 continue;
6110 }
6111 }
6112 }
6113 }
6114 }
6115 // Set the active texture back to whatever the user had it as.
6116 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
6117 }
6118
ClearUnclearedTextures()6119 bool GLES2DecoderImpl::ClearUnclearedTextures() {
6120 // Only check if there are some uncleared textures.
6121 if (!texture_manager()->HaveUnsafeTextures()) {
6122 return true;
6123 }
6124
6125 // 1: Check all textures we are about to render with.
6126 if (state_.current_program.get()) {
6127 const Program::SamplerIndices& sampler_indices =
6128 state_.current_program->sampler_indices();
6129 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6130 const Program::UniformInfo* uniform_info =
6131 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6132 DCHECK(uniform_info);
6133 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6134 GLuint texture_unit_index = uniform_info->texture_units[jj];
6135 if (texture_unit_index < state_.texture_units.size()) {
6136 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6137 TextureRef* texture_ref =
6138 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
6139 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6140 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
6141 return false;
6142 }
6143 }
6144 }
6145 }
6146 }
6147 }
6148 return true;
6149 }
6150
IsDrawValid(const char * function_name,GLuint max_vertex_accessed,GLsizei primcount)6151 bool GLES2DecoderImpl::IsDrawValid(
6152 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
6153 // NOTE: We specifically do not check current_program->IsValid() because
6154 // it could never be invalid since glUseProgram would have failed. While
6155 // glLinkProgram could later mark the program as invalid the previous
6156 // valid program will still function if it is still the current program.
6157 if (!state_.current_program.get()) {
6158 // The program does not exist.
6159 // But GL says no ERROR.
6160 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
6161 return false;
6162 }
6163
6164 return state_.vertex_attrib_manager
6165 ->ValidateBindings(function_name,
6166 this,
6167 feature_info_.get(),
6168 state_.current_program.get(),
6169 max_vertex_accessed,
6170 primcount);
6171 }
6172
SimulateAttrib0(const char * function_name,GLuint max_vertex_accessed,bool * simulated)6173 bool GLES2DecoderImpl::SimulateAttrib0(
6174 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
6175 DCHECK(simulated);
6176 *simulated = false;
6177
6178 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6179 return true;
6180
6181 const VertexAttrib* attrib =
6182 state_.vertex_attrib_manager->GetVertexAttrib(0);
6183 // If it's enabled or it's not used then we don't need to do anything.
6184 bool attrib_0_used =
6185 state_.current_program->GetAttribInfoByLocation(0) != NULL;
6186 if (attrib->enabled() && attrib_0_used) {
6187 return true;
6188 }
6189
6190 // Make a buffer with a single repeated vec4 value enough to
6191 // simulate the constant value that is supposed to be here.
6192 // This is required to emulate GLES2 on GL.
6193 GLuint num_vertices = max_vertex_accessed + 1;
6194 uint32 size_needed = 0;
6195
6196 if (num_vertices == 0 ||
6197 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
6198 size_needed > 0x7FFFFFFFU) {
6199 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
6200 return false;
6201 }
6202
6203 LOCAL_PERFORMANCE_WARNING(
6204 "Attribute 0 is disabled. This has signficant performance penalty");
6205
6206 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
6207 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6208
6209 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6210 if (new_buffer) {
6211 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
6212 GLenum error = glGetError();
6213 if (error != GL_NO_ERROR) {
6214 LOCAL_SET_GL_ERROR(
6215 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
6216 return false;
6217 }
6218 }
6219
6220 const Vec4& value = state_.attrib_values[0];
6221 if (new_buffer ||
6222 (attrib_0_used &&
6223 (!attrib_0_buffer_matches_value_ ||
6224 (value.v[0] != attrib_0_value_.v[0] ||
6225 value.v[1] != attrib_0_value_.v[1] ||
6226 value.v[2] != attrib_0_value_.v[2] ||
6227 value.v[3] != attrib_0_value_.v[3])))) {
6228 std::vector<Vec4> temp(num_vertices, value);
6229 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6230 attrib_0_buffer_matches_value_ = true;
6231 attrib_0_value_ = value;
6232 attrib_0_size_ = size_needed;
6233 }
6234
6235 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6236
6237 if (attrib->divisor())
6238 glVertexAttribDivisorANGLE(0, 0);
6239
6240 *simulated = true;
6241 return true;
6242 }
6243
RestoreStateForAttrib(GLuint attrib_index,bool restore_array_binding)6244 void GLES2DecoderImpl::RestoreStateForAttrib(
6245 GLuint attrib_index, bool restore_array_binding) {
6246 const VertexAttrib* attrib =
6247 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
6248 if (restore_array_binding) {
6249 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6250 Buffer* buffer = attrib->buffer();
6251 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6252 glVertexAttribPointer(
6253 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6254 attrib->gl_stride(), ptr);
6255 }
6256 if (attrib->divisor())
6257 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
6258 glBindBuffer(
6259 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6260 state_.bound_array_buffer->service_id() : 0);
6261
6262 // Never touch vertex attribute 0's state (in particular, never
6263 // disable it) when running on desktop GL because it will never be
6264 // re-enabled.
6265 if (attrib_index != 0 ||
6266 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
6267 if (attrib->enabled()) {
6268 glEnableVertexAttribArray(attrib_index);
6269 } else {
6270 glDisableVertexAttribArray(attrib_index);
6271 }
6272 }
6273 }
6274
SimulateFixedAttribs(const char * function_name,GLuint max_vertex_accessed,bool * simulated,GLsizei primcount)6275 bool GLES2DecoderImpl::SimulateFixedAttribs(
6276 const char* function_name,
6277 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
6278 DCHECK(simulated);
6279 *simulated = false;
6280 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6281 return true;
6282
6283 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
6284 return true;
6285 }
6286
6287 LOCAL_PERFORMANCE_WARNING(
6288 "GL_FIXED attributes have a signficant performance penalty");
6289
6290 // NOTE: we could be smart and try to check if a buffer is used
6291 // twice in 2 different attribs, find the overlapping parts and therefore
6292 // duplicate the minimum amount of data but this whole code path is not meant
6293 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6294 // tests so we just add to the buffer attrib used.
6295
6296 GLuint elements_needed = 0;
6297 const VertexAttribManager::VertexAttribList& enabled_attribs =
6298 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6299 for (VertexAttribManager::VertexAttribList::const_iterator it =
6300 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6301 const VertexAttrib* attrib = *it;
6302 const Program::VertexAttrib* attrib_info =
6303 state_.current_program->GetAttribInfoByLocation(attrib->index());
6304 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6305 max_vertex_accessed);
6306 GLuint num_vertices = max_accessed + 1;
6307 if (num_vertices == 0) {
6308 LOCAL_SET_GL_ERROR(
6309 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
6310 return false;
6311 }
6312 if (attrib_info &&
6313 attrib->CanAccess(max_accessed) &&
6314 attrib->type() == GL_FIXED) {
6315 uint32 elements_used = 0;
6316 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
6317 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
6318 LOCAL_SET_GL_ERROR(
6319 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
6320 return false;
6321 }
6322 }
6323 }
6324
6325 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6326 uint32 size_needed = 0;
6327 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
6328 size_needed > 0x7FFFFFFFU) {
6329 LOCAL_SET_GL_ERROR(
6330 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
6331 return false;
6332 }
6333
6334 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
6335
6336 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
6337 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
6338 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
6339 GLenum error = glGetError();
6340 if (error != GL_NO_ERROR) {
6341 LOCAL_SET_GL_ERROR(
6342 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
6343 return false;
6344 }
6345 }
6346
6347 // Copy the elements and convert to float
6348 GLintptr offset = 0;
6349 for (VertexAttribManager::VertexAttribList::const_iterator it =
6350 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6351 const VertexAttrib* attrib = *it;
6352 const Program::VertexAttrib* attrib_info =
6353 state_.current_program->GetAttribInfoByLocation(attrib->index());
6354 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6355 max_vertex_accessed);
6356 GLuint num_vertices = max_accessed + 1;
6357 if (num_vertices == 0) {
6358 LOCAL_SET_GL_ERROR(
6359 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
6360 return false;
6361 }
6362 if (attrib_info &&
6363 attrib->CanAccess(max_accessed) &&
6364 attrib->type() == GL_FIXED) {
6365 int num_elements = attrib->size() * kSizeOfFloat;
6366 int size = num_elements * num_vertices;
6367 scoped_ptr<float[]> data(new float[size]);
6368 const int32* src = reinterpret_cast<const int32 *>(
6369 attrib->buffer()->GetRange(attrib->offset(), size));
6370 const int32* end = src + num_elements;
6371 float* dst = data.get();
6372 while (src != end) {
6373 *dst++ = static_cast<float>(*src++) / 65536.0f;
6374 }
6375 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6376 glVertexAttribPointer(
6377 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
6378 reinterpret_cast<GLvoid*>(offset));
6379 offset += size;
6380 }
6381 }
6382 *simulated = true;
6383 return true;
6384 }
6385
RestoreStateForSimulatedFixedAttribs()6386 void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6387 // There's no need to call glVertexAttribPointer because we shadow all the
6388 // settings and passing GL_FIXED to it will not work.
6389 glBindBuffer(
6390 GL_ARRAY_BUFFER,
6391 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6392 : 0);
6393 }
6394
DoDrawArrays(const char * function_name,bool instanced,GLenum mode,GLint first,GLsizei count,GLsizei primcount)6395 error::Error GLES2DecoderImpl::DoDrawArrays(
6396 const char* function_name,
6397 bool instanced,
6398 GLenum mode,
6399 GLint first,
6400 GLsizei count,
6401 GLsizei primcount) {
6402 error::Error error = WillAccessBoundFramebufferForDraw();
6403 if (error != error::kNoError)
6404 return error;
6405 if (!validators_->draw_mode.IsValid(mode)) {
6406 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
6407 return error::kNoError;
6408 }
6409 if (count < 0) {
6410 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
6411 return error::kNoError;
6412 }
6413 if (primcount < 0) {
6414 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
6415 return error::kNoError;
6416 }
6417 if (!CheckBoundFramebuffersValid(function_name)) {
6418 return error::kNoError;
6419 }
6420 // We have to check this here because the prototype for glDrawArrays
6421 // is GLint not GLsizei.
6422 if (first < 0) {
6423 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
6424 return error::kNoError;
6425 }
6426
6427 if (count == 0 || (instanced && primcount == 0)) {
6428 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
6429 return error::kNoError;
6430 }
6431
6432 GLuint max_vertex_accessed = first + count - 1;
6433 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
6434 if (!ClearUnclearedTextures()) {
6435 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
6436 return error::kNoError;
6437 }
6438 bool simulated_attrib_0 = false;
6439 if (!SimulateAttrib0(
6440 function_name, max_vertex_accessed, &simulated_attrib_0)) {
6441 return error::kNoError;
6442 }
6443 bool simulated_fixed_attribs = false;
6444 if (SimulateFixedAttribs(
6445 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6446 primcount)) {
6447 bool textures_set = !PrepareTexturesForRender();
6448 ApplyDirtyState();
6449 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
6450 if (!instanced) {
6451 glDrawArrays(mode, first, count);
6452 } else {
6453 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6454 }
6455 if (textures_set) {
6456 RestoreStateForTextures();
6457 }
6458 if (simulated_fixed_attribs) {
6459 RestoreStateForSimulatedFixedAttribs();
6460 }
6461 }
6462 if (simulated_attrib_0) {
6463 // We don't have to restore attrib 0 generic data at the end of this
6464 // function even if it is simulated. This is because we will simulate
6465 // it in each draw call, and attrib 0 generic data queries use cached
6466 // values instead of passing down to the underlying driver.
6467 RestoreStateForAttrib(0, false);
6468 }
6469 }
6470 return error::kNoError;
6471 }
6472
HandleDrawArrays(uint32 immediate_data_size,const cmds::DrawArrays & c)6473 error::Error GLES2DecoderImpl::HandleDrawArrays(
6474 uint32 immediate_data_size, const cmds::DrawArrays& c) {
6475 return DoDrawArrays("glDrawArrays",
6476 false,
6477 static_cast<GLenum>(c.mode),
6478 static_cast<GLint>(c.first),
6479 static_cast<GLsizei>(c.count),
6480 0);
6481 }
6482
HandleDrawArraysInstancedANGLE(uint32 immediate_data_size,const cmds::DrawArraysInstancedANGLE & c)6483 error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
6484 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
6485 if (!features().angle_instanced_arrays) {
6486 LOCAL_SET_GL_ERROR(
6487 GL_INVALID_OPERATION,
6488 "glDrawArraysInstancedANGLE", "function not available");
6489 return error::kNoError;
6490 }
6491 return DoDrawArrays("glDrawArraysIntancedANGLE",
6492 true,
6493 static_cast<GLenum>(c.mode),
6494 static_cast<GLint>(c.first),
6495 static_cast<GLsizei>(c.count),
6496 static_cast<GLsizei>(c.primcount));
6497 }
6498
DoDrawElements(const char * function_name,bool instanced,GLenum mode,GLsizei count,GLenum type,int32 offset,GLsizei primcount)6499 error::Error GLES2DecoderImpl::DoDrawElements(
6500 const char* function_name,
6501 bool instanced,
6502 GLenum mode,
6503 GLsizei count,
6504 GLenum type,
6505 int32 offset,
6506 GLsizei primcount) {
6507 error::Error error = WillAccessBoundFramebufferForDraw();
6508 if (error != error::kNoError)
6509 return error;
6510 if (!state_.vertex_attrib_manager->element_array_buffer()) {
6511 LOCAL_SET_GL_ERROR(
6512 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
6513 return error::kNoError;
6514 }
6515
6516 if (count < 0) {
6517 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
6518 return error::kNoError;
6519 }
6520 if (offset < 0) {
6521 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
6522 return error::kNoError;
6523 }
6524 if (!validators_->draw_mode.IsValid(mode)) {
6525 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
6526 return error::kNoError;
6527 }
6528 if (!validators_->index_type.IsValid(type)) {
6529 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
6530 return error::kNoError;
6531 }
6532 if (primcount < 0) {
6533 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
6534 return error::kNoError;
6535 }
6536
6537 if (!CheckBoundFramebuffersValid(function_name)) {
6538 return error::kNoError;
6539 }
6540
6541 if (count == 0 || (instanced && primcount == 0)) {
6542 return error::kNoError;
6543 }
6544
6545 GLuint max_vertex_accessed;
6546 Buffer* element_array_buffer =
6547 state_.vertex_attrib_manager->element_array_buffer();
6548
6549 if (!element_array_buffer->GetMaxValueForRange(
6550 offset, count, type, &max_vertex_accessed)) {
6551 LOCAL_SET_GL_ERROR(
6552 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
6553 return error::kNoError;
6554 }
6555
6556 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
6557 if (!ClearUnclearedTextures()) {
6558 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
6559 return error::kNoError;
6560 }
6561 bool simulated_attrib_0 = false;
6562 if (!SimulateAttrib0(
6563 function_name, max_vertex_accessed, &simulated_attrib_0)) {
6564 return error::kNoError;
6565 }
6566 bool simulated_fixed_attribs = false;
6567 if (SimulateFixedAttribs(
6568 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6569 primcount)) {
6570 bool textures_set = !PrepareTexturesForRender();
6571 ApplyDirtyState();
6572 // TODO(gman): Refactor to hide these details in BufferManager or
6573 // VertexAttribManager.
6574 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
6575 bool used_client_side_array = false;
6576 if (element_array_buffer->IsClientSideArray()) {
6577 used_client_side_array = true;
6578 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6579 indices = element_array_buffer->GetRange(offset, 0);
6580 }
6581
6582 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
6583 if (!instanced) {
6584 glDrawElements(mode, count, type, indices);
6585 } else {
6586 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6587 }
6588
6589 if (used_client_side_array) {
6590 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6591 element_array_buffer->service_id());
6592 }
6593
6594 if (textures_set) {
6595 RestoreStateForTextures();
6596 }
6597 if (simulated_fixed_attribs) {
6598 RestoreStateForSimulatedFixedAttribs();
6599 }
6600 }
6601 if (simulated_attrib_0) {
6602 // We don't have to restore attrib 0 generic data at the end of this
6603 // function even if it is simulated. This is because we will simulate
6604 // it in each draw call, and attrib 0 generic data queries use cached
6605 // values instead of passing down to the underlying driver.
6606 RestoreStateForAttrib(0, false);
6607 }
6608 }
6609 return error::kNoError;
6610 }
6611
HandleDrawElements(uint32 immediate_data_size,const cmds::DrawElements & c)6612 error::Error GLES2DecoderImpl::HandleDrawElements(
6613 uint32 immediate_data_size, const cmds::DrawElements& c) {
6614 return DoDrawElements("glDrawElements",
6615 false,
6616 static_cast<GLenum>(c.mode),
6617 static_cast<GLsizei>(c.count),
6618 static_cast<GLenum>(c.type),
6619 static_cast<int32>(c.index_offset),
6620 0);
6621 }
6622
HandleDrawElementsInstancedANGLE(uint32 immediate_data_size,const cmds::DrawElementsInstancedANGLE & c)6623 error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
6624 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
6625 if (!features().angle_instanced_arrays) {
6626 LOCAL_SET_GL_ERROR(
6627 GL_INVALID_OPERATION,
6628 "glDrawElementsInstancedANGLE", "function not available");
6629 return error::kNoError;
6630 }
6631 return DoDrawElements("glDrawElementsInstancedANGLE",
6632 true,
6633 static_cast<GLenum>(c.mode),
6634 static_cast<GLsizei>(c.count),
6635 static_cast<GLenum>(c.type),
6636 static_cast<int32>(c.index_offset),
6637 static_cast<GLsizei>(c.primcount));
6638 }
6639
DoGetMaxValueInBufferCHROMIUM(GLuint buffer_id,GLsizei count,GLenum type,GLuint offset)6640 GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
6641 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6642 GLuint max_vertex_accessed = 0;
6643 Buffer* buffer = GetBuffer(buffer_id);
6644 if (!buffer) {
6645 // TODO(gman): Should this be a GL error or a command buffer error?
6646 LOCAL_SET_GL_ERROR(
6647 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
6648 } else {
6649 if (!buffer->GetMaxValueForRange(
6650 offset, count, type, &max_vertex_accessed)) {
6651 // TODO(gman): Should this be a GL error or a command buffer error?
6652 LOCAL_SET_GL_ERROR(
6653 GL_INVALID_OPERATION,
6654 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
6655 }
6656 }
6657 return max_vertex_accessed;
6658 }
6659
6660 // Calls glShaderSource for the various versions of the ShaderSource command.
6661 // Assumes that data / data_size points to a piece of memory that is in range
6662 // of whatever context it came from (shared memory, immediate memory, bucket
6663 // memory.)
ShaderSourceHelper(GLuint client_id,const char * data,uint32 data_size)6664 error::Error GLES2DecoderImpl::ShaderSourceHelper(
6665 GLuint client_id, const char* data, uint32 data_size) {
6666 std::string str(data, data + data_size);
6667 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6668 if (!shader) {
6669 return error::kNoError;
6670 }
6671 // Note: We don't actually call glShaderSource here. We wait until
6672 // the call to glCompileShader.
6673 shader->UpdateSource(str.c_str());
6674 return error::kNoError;
6675 }
6676
HandleShaderSourceBucket(uint32 immediate_data_size,const cmds::ShaderSourceBucket & c)6677 error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
6678 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
6679 Bucket* bucket = GetBucket(c.data_bucket_id);
6680 if (!bucket || bucket->size() == 0) {
6681 return error::kInvalidArguments;
6682 }
6683 return ShaderSourceHelper(
6684 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
6685 bucket->size() - 1);
6686 }
6687
DoCompileShader(GLuint client_id)6688 void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
6689 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
6690 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6691 if (!shader) {
6692 return;
6693 }
6694 ShaderTranslator* translator = NULL;
6695 if (use_shader_translator_) {
6696 translator = shader->shader_type() == GL_VERTEX_SHADER ?
6697 vertex_translator_.get() : fragment_translator_.get();
6698 }
6699
6700 program_manager()->DoCompileShader(
6701 shader,
6702 translator,
6703 feature_info_->feature_flags().angle_translated_shader_source ?
6704 ProgramManager::kANGLE : ProgramManager::kGL);
6705 };
6706
DoGetShaderiv(GLuint shader_id,GLenum pname,GLint * params)6707 void GLES2DecoderImpl::DoGetShaderiv(
6708 GLuint shader_id, GLenum pname, GLint* params) {
6709 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6710 if (!shader) {
6711 return;
6712 }
6713 switch (pname) {
6714 case GL_SHADER_SOURCE_LENGTH:
6715 *params = shader->source() ? shader->source()->size() + 1 : 0;
6716 return;
6717 case GL_COMPILE_STATUS:
6718 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
6719 return;
6720 case GL_INFO_LOG_LENGTH:
6721 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
6722 return;
6723 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
6724 *params = shader->translated_source() ?
6725 shader->translated_source()->size() + 1 : 0;
6726 return;
6727 default:
6728 break;
6729 }
6730 glGetShaderiv(shader->service_id(), pname, params);
6731 }
6732
HandleGetShaderSource(uint32 immediate_data_size,const cmds::GetShaderSource & c)6733 error::Error GLES2DecoderImpl::HandleGetShaderSource(
6734 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
6735 GLuint shader_id = c.shader;
6736 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6737 Bucket* bucket = CreateBucket(bucket_id);
6738 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6739 if (!shader || !shader->source()) {
6740 bucket->SetSize(0);
6741 return error::kNoError;
6742 }
6743 bucket->SetFromString(shader->source()->c_str());
6744 return error::kNoError;
6745 }
6746
HandleGetTranslatedShaderSourceANGLE(uint32 immediate_data_size,const cmds::GetTranslatedShaderSourceANGLE & c)6747 error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6748 uint32 immediate_data_size,
6749 const cmds::GetTranslatedShaderSourceANGLE& c) {
6750 GLuint shader_id = c.shader;
6751 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6752 Bucket* bucket = CreateBucket(bucket_id);
6753 Shader* shader = GetShaderInfoNotProgram(
6754 shader_id, "glGetTranslatedShaderSourceANGLE");
6755 if (!shader) {
6756 bucket->SetSize(0);
6757 return error::kNoError;
6758 }
6759
6760 bucket->SetFromString(shader->translated_source() ?
6761 shader->translated_source()->c_str() : NULL);
6762 return error::kNoError;
6763 }
6764
HandleGetProgramInfoLog(uint32 immediate_data_size,const cmds::GetProgramInfoLog & c)6765 error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
6766 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
6767 GLuint program_id = c.program;
6768 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6769 Bucket* bucket = CreateBucket(bucket_id);
6770 Program* program = GetProgramInfoNotShader(
6771 program_id, "glGetProgramInfoLog");
6772 if (!program || !program->log_info()) {
6773 bucket->SetFromString("");
6774 return error::kNoError;
6775 }
6776 bucket->SetFromString(program->log_info()->c_str());
6777 return error::kNoError;
6778 }
6779
HandleGetShaderInfoLog(uint32 immediate_data_size,const cmds::GetShaderInfoLog & c)6780 error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
6781 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
6782 GLuint shader_id = c.shader;
6783 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6784 Bucket* bucket = CreateBucket(bucket_id);
6785 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6786 if (!shader || !shader->log_info()) {
6787 bucket->SetFromString("");
6788 return error::kNoError;
6789 }
6790 bucket->SetFromString(shader->log_info()->c_str());
6791 return error::kNoError;
6792 }
6793
DoIsEnabled(GLenum cap)6794 bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6795 return state_.GetEnabled(cap);
6796 }
6797
DoIsBuffer(GLuint client_id)6798 bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
6799 const Buffer* buffer = GetBuffer(client_id);
6800 return buffer && buffer->IsValid() && !buffer->IsDeleted();
6801 }
6802
DoIsFramebuffer(GLuint client_id)6803 bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
6804 const Framebuffer* framebuffer =
6805 GetFramebuffer(client_id);
6806 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
6807 }
6808
DoIsProgram(GLuint client_id)6809 bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
6810 // IsProgram is true for programs as soon as they are created, until they are
6811 // deleted and no longer in use.
6812 const Program* program = GetProgram(client_id);
6813 return program != NULL && !program->IsDeleted();
6814 }
6815
DoIsRenderbuffer(GLuint client_id)6816 bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
6817 const Renderbuffer* renderbuffer =
6818 GetRenderbuffer(client_id);
6819 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
6820 }
6821
DoIsShader(GLuint client_id)6822 bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
6823 // IsShader is true for shaders as soon as they are created, until they
6824 // are deleted and not attached to any programs.
6825 const Shader* shader = GetShader(client_id);
6826 return shader != NULL && !shader->IsDeleted();
6827 }
6828
DoIsTexture(GLuint client_id)6829 bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
6830 const TextureRef* texture_ref = GetTexture(client_id);
6831 return texture_ref && texture_ref->texture()->IsValid();
6832 }
6833
DoAttachShader(GLuint program_client_id,GLint shader_client_id)6834 void GLES2DecoderImpl::DoAttachShader(
6835 GLuint program_client_id, GLint shader_client_id) {
6836 Program* program = GetProgramInfoNotShader(
6837 program_client_id, "glAttachShader");
6838 if (!program) {
6839 return;
6840 }
6841 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6842 if (!shader) {
6843 return;
6844 }
6845 if (!program->AttachShader(shader_manager(), shader)) {
6846 LOCAL_SET_GL_ERROR(
6847 GL_INVALID_OPERATION,
6848 "glAttachShader",
6849 "can not attach more than one shader of the same type.");
6850 return;
6851 }
6852 glAttachShader(program->service_id(), shader->service_id());
6853 }
6854
DoDetachShader(GLuint program_client_id,GLint shader_client_id)6855 void GLES2DecoderImpl::DoDetachShader(
6856 GLuint program_client_id, GLint shader_client_id) {
6857 Program* program = GetProgramInfoNotShader(
6858 program_client_id, "glDetachShader");
6859 if (!program) {
6860 return;
6861 }
6862 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6863 if (!shader) {
6864 return;
6865 }
6866 if (!program->DetachShader(shader_manager(), shader)) {
6867 LOCAL_SET_GL_ERROR(
6868 GL_INVALID_OPERATION,
6869 "glDetachShader", "shader not attached to program");
6870 return;
6871 }
6872 glDetachShader(program->service_id(), shader->service_id());
6873 }
6874
DoValidateProgram(GLuint program_client_id)6875 void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
6876 Program* program = GetProgramInfoNotShader(
6877 program_client_id, "glValidateProgram");
6878 if (!program) {
6879 return;
6880 }
6881 program->Validate();
6882 }
6883
GetVertexAttribHelper(const VertexAttrib * attrib,GLenum pname,GLint * params)6884 void GLES2DecoderImpl::GetVertexAttribHelper(
6885 const VertexAttrib* attrib, GLenum pname, GLint* params) {
6886 switch (pname) {
6887 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
6888 Buffer* buffer = attrib->buffer();
6889 if (buffer && !buffer->IsDeleted()) {
6890 GLuint client_id;
6891 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6892 *params = client_id;
6893 }
6894 break;
6895 }
6896 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
6897 *params = attrib->enabled();
6898 break;
6899 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
6900 *params = attrib->size();
6901 break;
6902 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
6903 *params = attrib->gl_stride();
6904 break;
6905 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
6906 *params = attrib->type();
6907 break;
6908 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
6909 *params = attrib->normalized();
6910 break;
6911 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
6912 *params = attrib->divisor();
6913 break;
6914 default:
6915 NOTREACHED();
6916 break;
6917 }
6918 }
6919
DoGetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)6920 void GLES2DecoderImpl::DoGetTexParameterfv(
6921 GLenum target, GLenum pname, GLfloat* params) {
6922 InitTextureMaxAnisotropyIfNeeded(target, pname);
6923 glGetTexParameterfv(target, pname, params);
6924 }
6925
DoGetTexParameteriv(GLenum target,GLenum pname,GLint * params)6926 void GLES2DecoderImpl::DoGetTexParameteriv(
6927 GLenum target, GLenum pname, GLint* params) {
6928 InitTextureMaxAnisotropyIfNeeded(target, pname);
6929 glGetTexParameteriv(target, pname, params);
6930 }
6931
InitTextureMaxAnisotropyIfNeeded(GLenum target,GLenum pname)6932 void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
6933 GLenum target, GLenum pname) {
6934 if (!workarounds().init_texture_max_anisotropy)
6935 return;
6936 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
6937 !validators_->texture_parameter.IsValid(pname)) {
6938 return;
6939 }
6940
6941 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
6942 &state_, target);
6943 if (!texture_ref) {
6944 LOCAL_SET_GL_ERROR(
6945 GL_INVALID_OPERATION,
6946 "glGetTexParamter{fi}v", "unknown texture for target");
6947 return;
6948 }
6949 Texture* texture = texture_ref->texture();
6950 texture->InitTextureMaxAnisotropyIfNeeded(target);
6951 }
6952
DoGetVertexAttribfv(GLuint index,GLenum pname,GLfloat * params)6953 void GLES2DecoderImpl::DoGetVertexAttribfv(
6954 GLuint index, GLenum pname, GLfloat* params) {
6955 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6956 if (!attrib) {
6957 LOCAL_SET_GL_ERROR(
6958 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
6959 return;
6960 }
6961 switch (pname) {
6962 case GL_CURRENT_VERTEX_ATTRIB: {
6963 const Vec4& value = state_.attrib_values[index];
6964 params[0] = value.v[0];
6965 params[1] = value.v[1];
6966 params[2] = value.v[2];
6967 params[3] = value.v[3];
6968 break;
6969 }
6970 default: {
6971 GLint value = 0;
6972 GetVertexAttribHelper(attrib, pname, &value);
6973 *params = static_cast<GLfloat>(value);
6974 break;
6975 }
6976 }
6977 }
6978
DoGetVertexAttribiv(GLuint index,GLenum pname,GLint * params)6979 void GLES2DecoderImpl::DoGetVertexAttribiv(
6980 GLuint index, GLenum pname, GLint* params) {
6981 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6982 if (!attrib) {
6983 LOCAL_SET_GL_ERROR(
6984 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
6985 return;
6986 }
6987 switch (pname) {
6988 case GL_CURRENT_VERTEX_ATTRIB: {
6989 const Vec4& value = state_.attrib_values[index];
6990 params[0] = static_cast<GLint>(value.v[0]);
6991 params[1] = static_cast<GLint>(value.v[1]);
6992 params[2] = static_cast<GLint>(value.v[2]);
6993 params[3] = static_cast<GLint>(value.v[3]);
6994 break;
6995 }
6996 default:
6997 GetVertexAttribHelper(attrib, pname, params);
6998 break;
6999 }
7000 }
7001
SetVertexAttribValue(const char * function_name,GLuint index,const GLfloat * value)7002 bool GLES2DecoderImpl::SetVertexAttribValue(
7003 const char* function_name, GLuint index, const GLfloat* value) {
7004 if (index >= state_.attrib_values.size()) {
7005 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
7006 return false;
7007 }
7008 Vec4& v = state_.attrib_values[index];
7009 v.v[0] = value[0];
7010 v.v[1] = value[1];
7011 v.v[2] = value[2];
7012 v.v[3] = value[3];
7013 return true;
7014 }
7015
DoVertexAttrib1f(GLuint index,GLfloat v0)7016 void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7017 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7018 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7019 glVertexAttrib1f(index, v0);
7020 }
7021 }
7022
DoVertexAttrib2f(GLuint index,GLfloat v0,GLfloat v1)7023 void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
7024 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7025 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7026 glVertexAttrib2f(index, v0, v1);
7027 }
7028 }
7029
DoVertexAttrib3f(GLuint index,GLfloat v0,GLfloat v1,GLfloat v2)7030 void GLES2DecoderImpl::DoVertexAttrib3f(
7031 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
7032 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7033 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7034 glVertexAttrib3f(index, v0, v1, v2);
7035 }
7036 }
7037
DoVertexAttrib4f(GLuint index,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)7038 void GLES2DecoderImpl::DoVertexAttrib4f(
7039 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
7040 GLfloat v[4] = { v0, v1, v2, v3, };
7041 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7042 glVertexAttrib4f(index, v0, v1, v2, v3);
7043 }
7044 }
7045
DoVertexAttrib1fv(GLuint index,const GLfloat * v)7046 void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
7047 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7048 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7049 glVertexAttrib1fv(index, v);
7050 }
7051 }
7052
DoVertexAttrib2fv(GLuint index,const GLfloat * v)7053 void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
7054 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7055 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7056 glVertexAttrib2fv(index, v);
7057 }
7058 }
7059
DoVertexAttrib3fv(GLuint index,const GLfloat * v)7060 void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
7061 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7062 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7063 glVertexAttrib3fv(index, v);
7064 }
7065 }
7066
DoVertexAttrib4fv(GLuint index,const GLfloat * v)7067 void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
7068 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7069 glVertexAttrib4fv(index, v);
7070 }
7071 }
7072
HandleVertexAttribPointer(uint32 immediate_data_size,const cmds::VertexAttribPointer & c)7073 error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
7074 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
7075
7076 if (!state_.bound_array_buffer.get() ||
7077 state_.bound_array_buffer->IsDeleted()) {
7078 if (state_.vertex_attrib_manager.get() ==
7079 state_.default_vertex_attrib_manager.get()) {
7080 LOCAL_SET_GL_ERROR(
7081 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
7082 return error::kNoError;
7083 } else if (c.offset != 0) {
7084 LOCAL_SET_GL_ERROR(
7085 GL_INVALID_VALUE,
7086 "glVertexAttribPointer", "client side arrays are not allowed");
7087 return error::kNoError;
7088 }
7089 }
7090
7091 GLuint indx = c.indx;
7092 GLint size = c.size;
7093 GLenum type = c.type;
7094 GLboolean normalized = c.normalized;
7095 GLsizei stride = c.stride;
7096 GLsizei offset = c.offset;
7097 const void* ptr = reinterpret_cast<const void*>(offset);
7098 if (!validators_->vertex_attrib_type.IsValid(type)) {
7099 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
7100 return error::kNoError;
7101 }
7102 if (!validators_->vertex_attrib_size.IsValid(size)) {
7103 LOCAL_SET_GL_ERROR(
7104 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
7105 return error::kNoError;
7106 }
7107 if (indx >= group_->max_vertex_attribs()) {
7108 LOCAL_SET_GL_ERROR(
7109 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
7110 return error::kNoError;
7111 }
7112 if (stride < 0) {
7113 LOCAL_SET_GL_ERROR(
7114 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
7115 return error::kNoError;
7116 }
7117 if (stride > 255) {
7118 LOCAL_SET_GL_ERROR(
7119 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
7120 return error::kNoError;
7121 }
7122 if (offset < 0) {
7123 LOCAL_SET_GL_ERROR(
7124 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
7125 return error::kNoError;
7126 }
7127 GLsizei component_size =
7128 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
7129 if (offset % component_size > 0) {
7130 LOCAL_SET_GL_ERROR(
7131 GL_INVALID_OPERATION,
7132 "glVertexAttribPointer", "offset not valid for type");
7133 return error::kNoError;
7134 }
7135 if (stride % component_size > 0) {
7136 LOCAL_SET_GL_ERROR(
7137 GL_INVALID_OPERATION,
7138 "glVertexAttribPointer", "stride not valid for type");
7139 return error::kNoError;
7140 }
7141 state_.vertex_attrib_manager
7142 ->SetAttribInfo(indx,
7143 state_.bound_array_buffer.get(),
7144 size,
7145 type,
7146 normalized,
7147 stride,
7148 stride != 0 ? stride : component_size * size,
7149 offset);
7150 if (type != GL_FIXED) {
7151 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7152 }
7153 return error::kNoError;
7154 }
7155
DoViewport(GLint x,GLint y,GLsizei width,GLsizei height)7156 void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7157 GLsizei height) {
7158 state_.viewport_x = x;
7159 state_.viewport_y = y;
7160 state_.viewport_width = std::min(width, viewport_max_width_);
7161 state_.viewport_height = std::min(height, viewport_max_height_);
7162 glViewport(x, y, width, height);
7163 }
7164
HandleVertexAttribDivisorANGLE(uint32 immediate_data_size,const cmds::VertexAttribDivisorANGLE & c)7165 error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
7166 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
7167 if (!features().angle_instanced_arrays) {
7168 LOCAL_SET_GL_ERROR(
7169 GL_INVALID_OPERATION,
7170 "glVertexAttribDivisorANGLE", "function not available");
7171 return error::kNoError;
7172 }
7173 GLuint index = c.index;
7174 GLuint divisor = c.divisor;
7175 if (index >= group_->max_vertex_attribs()) {
7176 LOCAL_SET_GL_ERROR(
7177 GL_INVALID_VALUE,
7178 "glVertexAttribDivisorANGLE", "index out of range");
7179 return error::kNoError;
7180 }
7181
7182 state_.vertex_attrib_manager->SetDivisor(
7183 index,
7184 divisor);
7185 glVertexAttribDivisorANGLE(index, divisor);
7186 return error::kNoError;
7187 }
7188
7189 template <typename pixel_data_type>
WriteAlphaData(void * pixels,uint32 row_count,uint32 channel_count,uint32 alpha_channel_index,uint32 unpadded_row_size,uint32 padded_row_size,pixel_data_type alpha_value)7190 static void WriteAlphaData(
7191 void *pixels, uint32 row_count, uint32 channel_count,
7192 uint32 alpha_channel_index, uint32 unpadded_row_size,
7193 uint32 padded_row_size, pixel_data_type alpha_value) {
7194 DCHECK_GT(channel_count, 0U);
7195 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7196 uint32 unpadded_row_size_in_elements =
7197 unpadded_row_size / sizeof(pixel_data_type);
7198 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7199 uint32 padded_row_size_in_elements =
7200 padded_row_size / sizeof(pixel_data_type);
7201 pixel_data_type* dst =
7202 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7203 for (uint32 yy = 0; yy < row_count; ++yy) {
7204 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7205 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7206 *d = alpha_value;
7207 }
7208 dst += padded_row_size_in_elements;
7209 }
7210 }
7211
FinishReadPixels(const cmds::ReadPixels & c,GLuint buffer)7212 void GLES2DecoderImpl::FinishReadPixels(
7213 const cmds::ReadPixels& c,
7214 GLuint buffer) {
7215 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7216 GLsizei width = c.width;
7217 GLsizei height = c.height;
7218 GLenum format = c.format;
7219 GLenum type = c.type;
7220 typedef cmds::ReadPixels::Result Result;
7221 uint32 pixels_size;
7222 Result* result = NULL;
7223 if (c.result_shm_id != 0) {
7224 result = GetSharedMemoryAs<Result*>(
7225 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7226 if (!result) {
7227 if (buffer != 0) {
7228 glDeleteBuffersARB(1, &buffer);
7229 }
7230 return;
7231 }
7232 }
7233 GLES2Util::ComputeImageDataSizes(
7234 width, height, format, type, state_.pack_alignment, &pixels_size,
7235 NULL, NULL);
7236 void* pixels = GetSharedMemoryAs<void*>(
7237 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7238 if (!pixels) {
7239 if (buffer != 0) {
7240 glDeleteBuffersARB(1, &buffer);
7241 }
7242 return;
7243 }
7244
7245 if (buffer != 0) {
7246 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7247 void* data;
7248 if (features().map_buffer_range) {
7249 data = glMapBufferRange(
7250 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7251 } else {
7252 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7253 }
7254 memcpy(pixels, data, pixels_size);
7255 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7256 // have to restore the state.
7257 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7258 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7259 glDeleteBuffersARB(1, &buffer);
7260 }
7261
7262 if (result != NULL) {
7263 *result = true;
7264 }
7265
7266 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7267 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7268 if ((channels_exist & 0x0008) == 0 &&
7269 workarounds().clear_alpha_in_readpixels) {
7270 // Set the alpha to 255 because some drivers are buggy in this regard.
7271 uint32 temp_size;
7272
7273 uint32 unpadded_row_size;
7274 uint32 padded_row_size;
7275 if (!GLES2Util::ComputeImageDataSizes(
7276 width, 2, format, type, state_.pack_alignment, &temp_size,
7277 &unpadded_row_size, &padded_row_size)) {
7278 return;
7279 }
7280
7281 uint32 channel_count = 0;
7282 uint32 alpha_channel = 0;
7283 switch (format) {
7284 case GL_RGBA:
7285 case GL_BGRA_EXT:
7286 channel_count = 4;
7287 alpha_channel = 3;
7288 break;
7289 case GL_ALPHA:
7290 channel_count = 1;
7291 alpha_channel = 0;
7292 break;
7293 }
7294
7295 if (channel_count > 0) {
7296 switch (type) {
7297 case GL_UNSIGNED_BYTE:
7298 WriteAlphaData<uint8>(
7299 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7300 padded_row_size, 0xFF);
7301 break;
7302 case GL_FLOAT:
7303 WriteAlphaData<float>(
7304 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7305 padded_row_size, 1.0f);
7306 break;
7307 case GL_HALF_FLOAT:
7308 WriteAlphaData<uint16>(
7309 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7310 padded_row_size, 0x3C00);
7311 break;
7312 }
7313 }
7314 }
7315 }
7316
7317
HandleReadPixels(uint32 immediate_data_size,const cmds::ReadPixels & c)7318 error::Error GLES2DecoderImpl::HandleReadPixels(
7319 uint32 immediate_data_size, const cmds::ReadPixels& c) {
7320 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
7321 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7322 if (fbo_error != error::kNoError)
7323 return fbo_error;
7324 GLint x = c.x;
7325 GLint y = c.y;
7326 GLsizei width = c.width;
7327 GLsizei height = c.height;
7328 GLenum format = c.format;
7329 GLenum type = c.type;
7330 GLboolean async = c.async;
7331 if (width < 0 || height < 0) {
7332 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
7333 return error::kNoError;
7334 }
7335 typedef cmds::ReadPixels::Result Result;
7336 uint32 pixels_size;
7337 if (!GLES2Util::ComputeImageDataSizes(
7338 width, height, format, type, state_.pack_alignment, &pixels_size,
7339 NULL, NULL)) {
7340 return error::kOutOfBounds;
7341 }
7342 void* pixels = GetSharedMemoryAs<void*>(
7343 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7344 if (!pixels) {
7345 return error::kOutOfBounds;
7346 }
7347 Result* result = NULL;
7348 if (c.result_shm_id != 0) {
7349 result = GetSharedMemoryAs<Result*>(
7350 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7351 if (!result) {
7352 return error::kOutOfBounds;
7353 }
7354 }
7355
7356 if (!validators_->read_pixel_format.IsValid(format)) {
7357 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
7358 return error::kNoError;
7359 }
7360 if (!validators_->read_pixel_type.IsValid(type)) {
7361 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
7362 return error::kNoError;
7363 }
7364 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7365 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7366 // format and type are acceptable enums but not guaranteed to be supported
7367 // for this framebuffer. Have to ask gl if they are valid.
7368 GLint preferred_format = 0;
7369 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7370 GLint preferred_type = 0;
7371 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7372 if (format != static_cast<GLenum>(preferred_format) ||
7373 type != static_cast<GLenum>(preferred_type)) {
7374 LOCAL_SET_GL_ERROR(
7375 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7376 "with the current read framebuffer");
7377 return error::kNoError;
7378 }
7379 }
7380 if (width == 0 || height == 0) {
7381 return error::kNoError;
7382 }
7383
7384 // Get the size of the current fbo or backbuffer.
7385 gfx::Size max_size = GetBoundReadFrameBufferSize();
7386
7387 int32 max_x;
7388 int32 max_y;
7389 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
7390 LOCAL_SET_GL_ERROR(
7391 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
7392 return error::kNoError;
7393 }
7394
7395 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7396 return error::kNoError;
7397 }
7398
7399 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
7400
7401 ScopedResolvedFrameBufferBinder binder(this, false, true);
7402
7403 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
7404 // The user requested an out of range area. Get the results 1 line
7405 // at a time.
7406 uint32 temp_size;
7407 uint32 unpadded_row_size;
7408 uint32 padded_row_size;
7409 if (!GLES2Util::ComputeImageDataSizes(
7410 width, 2, format, type, state_.pack_alignment, &temp_size,
7411 &unpadded_row_size, &padded_row_size)) {
7412 LOCAL_SET_GL_ERROR(
7413 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
7414 return error::kNoError;
7415 }
7416
7417 GLint dest_x_offset = std::max(-x, 0);
7418 uint32 dest_row_offset;
7419 if (!GLES2Util::ComputeImageDataSizes(
7420 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7421 NULL, NULL)) {
7422 LOCAL_SET_GL_ERROR(
7423 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
7424 return error::kNoError;
7425 }
7426
7427 // Copy each row into the larger dest rect.
7428 int8* dst = static_cast<int8*>(pixels);
7429 GLint read_x = std::max(0, x);
7430 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
7431 GLint read_width = read_end_x - read_x;
7432 for (GLint yy = 0; yy < height; ++yy) {
7433 GLint ry = y + yy;
7434
7435 // Clear the row.
7436 memset(dst, 0, unpadded_row_size);
7437
7438 // If the row is in range, copy it.
7439 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
7440 glReadPixels(
7441 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7442 }
7443 dst += padded_row_size;
7444 }
7445 } else {
7446 if (async && features().use_async_readpixels) {
7447 GLuint buffer;
7448 glGenBuffersARB(1, &buffer);
7449 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7450 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7451 GLenum error = glGetError();
7452 if (error == GL_NO_ERROR) {
7453 glReadPixels(x, y, width, height, format, type, 0);
7454 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7455 new FenceCallback()));
7456 WaitForReadPixels(base::Bind(
7457 &GLES2DecoderImpl::FinishReadPixels,
7458 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7459 <GLES2DecoderImpl>(this),
7460 c, buffer));
7461 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7462 return error::kNoError;
7463 } else {
7464 // On error, unbind pack buffer and fall through to sync readpixels
7465 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7466 }
7467 }
7468 glReadPixels(x, y, width, height, format, type, pixels);
7469 }
7470 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
7471 if (error == GL_NO_ERROR) {
7472 if (result != NULL) {
7473 *result = true;
7474 }
7475 FinishReadPixels(c, 0);
7476 }
7477
7478 return error::kNoError;
7479 }
7480
HandlePixelStorei(uint32 immediate_data_size,const cmds::PixelStorei & c)7481 error::Error GLES2DecoderImpl::HandlePixelStorei(
7482 uint32 immediate_data_size, const cmds::PixelStorei& c) {
7483 GLenum pname = c.pname;
7484 GLenum param = c.param;
7485 if (!validators_->pixel_store.IsValid(pname)) {
7486 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
7487 return error::kNoError;
7488 }
7489 switch (pname) {
7490 case GL_PACK_ALIGNMENT:
7491 case GL_UNPACK_ALIGNMENT:
7492 if (!validators_->pixel_store_alignment.IsValid(param)) {
7493 LOCAL_SET_GL_ERROR(
7494 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
7495 return error::kNoError;
7496 }
7497 break;
7498 case GL_UNPACK_FLIP_Y_CHROMIUM:
7499 unpack_flip_y_ = (param != 0);
7500 return error::kNoError;
7501 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7502 unpack_premultiply_alpha_ = (param != 0);
7503 return error::kNoError;
7504 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7505 unpack_unpremultiply_alpha_ = (param != 0);
7506 return error::kNoError;
7507 default:
7508 break;
7509 }
7510 glPixelStorei(pname, param);
7511 switch (pname) {
7512 case GL_PACK_ALIGNMENT:
7513 state_.pack_alignment = param;
7514 break;
7515 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
7516 state_.pack_reverse_row_order = (param != 0);
7517 break;
7518 case GL_UNPACK_ALIGNMENT:
7519 state_.unpack_alignment = param;
7520 break;
7521 default:
7522 // Validation should have prevented us from getting here.
7523 NOTREACHED();
7524 break;
7525 }
7526 return error::kNoError;
7527 }
7528
HandlePostSubBufferCHROMIUM(uint32 immediate_data_size,const cmds::PostSubBufferCHROMIUM & c)7529 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
7530 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
7531 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
7532 {
7533 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
7534 }
7535 if (!supports_post_sub_buffer_) {
7536 LOCAL_SET_GL_ERROR(
7537 GL_INVALID_OPERATION,
7538 "glPostSubBufferCHROMIUM", "command not supported by surface");
7539 return error::kNoError;
7540 }
7541 bool is_tracing;
7542 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7543 &is_tracing);
7544 if (is_tracing) {
7545 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7546 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7547 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7548 is_offscreen ? offscreen_size_ : surface_->GetSize());
7549 }
7550 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
7551 return error::kNoError;
7552 } else {
7553 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
7554 return error::kLostContext;
7555 }
7556 }
7557
HandleScheduleOverlayPlaneCHROMIUM(uint32 immediate_data_size,const cmds::ScheduleOverlayPlaneCHROMIUM & c)7558 error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
7559 uint32 immediate_data_size,
7560 const cmds::ScheduleOverlayPlaneCHROMIUM& c) {
7561 NOTIMPLEMENTED() << "Overlay supported isn't finished.";
7562 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
7563 "glScheduleOverlayPlaneCHROMIUM",
7564 "function not implemented");
7565 return error::kNoError;
7566 }
7567
GetAttribLocationHelper(GLuint client_id,uint32 location_shm_id,uint32 location_shm_offset,const std::string & name_str)7568 error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7569 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7570 const std::string& name_str) {
7571 if (!StringIsValidForGLES(name_str.c_str())) {
7572 LOCAL_SET_GL_ERROR(
7573 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
7574 return error::kNoError;
7575 }
7576 Program* program = GetProgramInfoNotShader(
7577 client_id, "glGetAttribLocation");
7578 if (!program) {
7579 return error::kNoError;
7580 }
7581 if (!program->IsValid()) {
7582 LOCAL_SET_GL_ERROR(
7583 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
7584 return error::kNoError;
7585 }
7586 GLint* location = GetSharedMemoryAs<GLint*>(
7587 location_shm_id, location_shm_offset, sizeof(GLint));
7588 if (!location) {
7589 return error::kOutOfBounds;
7590 }
7591 // Require the client to init this incase the context is lost and we are no
7592 // longer executing commands.
7593 if (*location != -1) {
7594 return error::kGenericError;
7595 }
7596 *location = program->GetAttribLocation(name_str);
7597 return error::kNoError;
7598 }
7599
HandleGetAttribLocation(uint32 immediate_data_size,const cmds::GetAttribLocation & c)7600 error::Error GLES2DecoderImpl::HandleGetAttribLocation(
7601 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
7602 Bucket* bucket = GetBucket(c.name_bucket_id);
7603 if (!bucket) {
7604 return error::kInvalidArguments;
7605 }
7606 std::string name_str;
7607 if (!bucket->GetAsString(&name_str)) {
7608 return error::kInvalidArguments;
7609 }
7610 return GetAttribLocationHelper(
7611 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7612 }
7613
GetUniformLocationHelper(GLuint client_id,uint32 location_shm_id,uint32 location_shm_offset,const std::string & name_str)7614 error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7615 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7616 const std::string& name_str) {
7617 if (!StringIsValidForGLES(name_str.c_str())) {
7618 LOCAL_SET_GL_ERROR(
7619 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
7620 return error::kNoError;
7621 }
7622 Program* program = GetProgramInfoNotShader(
7623 client_id, "glGetUniformLocation");
7624 if (!program) {
7625 return error::kNoError;
7626 }
7627 if (!program->IsValid()) {
7628 LOCAL_SET_GL_ERROR(
7629 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
7630 return error::kNoError;
7631 }
7632 GLint* location = GetSharedMemoryAs<GLint*>(
7633 location_shm_id, location_shm_offset, sizeof(GLint));
7634 if (!location) {
7635 return error::kOutOfBounds;
7636 }
7637 // Require the client to init this incase the context is lost an we are no
7638 // longer executing commands.
7639 if (*location != -1) {
7640 return error::kGenericError;
7641 }
7642 *location = program->GetUniformFakeLocation(name_str);
7643 return error::kNoError;
7644 }
7645
HandleGetUniformLocation(uint32 immediate_data_size,const cmds::GetUniformLocation & c)7646 error::Error GLES2DecoderImpl::HandleGetUniformLocation(
7647 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
7648 Bucket* bucket = GetBucket(c.name_bucket_id);
7649 if (!bucket) {
7650 return error::kInvalidArguments;
7651 }
7652 std::string name_str;
7653 if (!bucket->GetAsString(&name_str)) {
7654 return error::kInvalidArguments;
7655 }
7656 return GetUniformLocationHelper(
7657 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7658 }
7659
HandleGetString(uint32 immediate_data_size,const cmds::GetString & c)7660 error::Error GLES2DecoderImpl::HandleGetString(
7661 uint32 immediate_data_size, const cmds::GetString& c) {
7662 GLenum name = static_cast<GLenum>(c.name);
7663 if (!validators_->string_type.IsValid(name)) {
7664 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
7665 return error::kNoError;
7666 }
7667 const char* str = reinterpret_cast<const char*>(glGetString(name));
7668 std::string extensions;
7669 switch (name) {
7670 case GL_VERSION:
7671 str = "OpenGL ES 2.0 Chromium";
7672 break;
7673 case GL_SHADING_LANGUAGE_VERSION:
7674 str = "OpenGL ES GLSL ES 1.0 Chromium";
7675 break;
7676 case GL_RENDERER:
7677 case GL_VENDOR:
7678 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7679 // They are used by WEBGL_debug_renderer_info.
7680 if (!force_webgl_glsl_validation_)
7681 str = "Chromium";
7682 break;
7683 case GL_EXTENSIONS:
7684 {
7685 // For WebGL contexts, strip out the OES derivatives and
7686 // EXT frag depth extensions if they have not been enabled.
7687 if (force_webgl_glsl_validation_) {
7688 extensions = feature_info_->extensions();
7689 if (!derivatives_explicitly_enabled_) {
7690 size_t offset = extensions.find(kOESDerivativeExtension);
7691 if (std::string::npos != offset) {
7692 extensions.replace(offset, arraysize(kOESDerivativeExtension),
7693 std::string());
7694 }
7695 }
7696 if (!frag_depth_explicitly_enabled_) {
7697 size_t offset = extensions.find(kEXTFragDepthExtension);
7698 if (std::string::npos != offset) {
7699 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
7700 std::string());
7701 }
7702 }
7703 if (!draw_buffers_explicitly_enabled_) {
7704 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7705 if (std::string::npos != offset) {
7706 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
7707 std::string());
7708 }
7709 }
7710 if (!shader_texture_lod_explicitly_enabled_) {
7711 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
7712 if (std::string::npos != offset) {
7713 extensions.replace(offset,
7714 arraysize(kEXTShaderTextureLodExtension),
7715 std::string());
7716 }
7717 }
7718 } else {
7719 extensions = feature_info_->extensions().c_str();
7720 }
7721 if (supports_post_sub_buffer_)
7722 extensions += " GL_CHROMIUM_post_sub_buffer";
7723 str = extensions.c_str();
7724 }
7725 break;
7726 default:
7727 break;
7728 }
7729 Bucket* bucket = CreateBucket(c.bucket_id);
7730 bucket->SetFromString(str);
7731 return error::kNoError;
7732 }
7733
HandleBufferData(uint32 immediate_data_size,const cmds::BufferData & c)7734 error::Error GLES2DecoderImpl::HandleBufferData(
7735 uint32 immediate_data_size, const cmds::BufferData& c) {
7736 GLenum target = static_cast<GLenum>(c.target);
7737 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7738 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7739 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7740 GLenum usage = static_cast<GLenum>(c.usage);
7741 const void* data = NULL;
7742 if (data_shm_id != 0 || data_shm_offset != 0) {
7743 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7744 if (!data) {
7745 return error::kOutOfBounds;
7746 }
7747 }
7748 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
7749 return error::kNoError;
7750 }
7751
DoBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)7752 void GLES2DecoderImpl::DoBufferSubData(
7753 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
7754 // Just delegate it. Some validation is actually done before this.
7755 buffer_manager()->ValidateAndDoBufferSubData(
7756 &state_, target, offset, size, data);
7757 }
7758
ClearLevel(unsigned service_id,unsigned bind_target,unsigned target,int level,unsigned internal_format,unsigned format,unsigned type,int width,int height,bool is_texture_immutable)7759 bool GLES2DecoderImpl::ClearLevel(
7760 unsigned service_id,
7761 unsigned bind_target,
7762 unsigned target,
7763 int level,
7764 unsigned internal_format,
7765 unsigned format,
7766 unsigned type,
7767 int width,
7768 int height,
7769 bool is_texture_immutable) {
7770 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7771 if (feature_info_->feature_flags().angle_depth_texture &&
7772 (channels & GLES2Util::kDepth) != 0) {
7773 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7774 // on depth formats.
7775 GLuint fb = 0;
7776 glGenFramebuffersEXT(1, &fb);
7777 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7778
7779 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7780 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7781 GL_DEPTH_ATTACHMENT;
7782
7783 glFramebufferTexture2DEXT(
7784 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7785 // ANGLE promises a depth only attachment ok.
7786 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7787 GL_FRAMEBUFFER_COMPLETE) {
7788 return false;
7789 }
7790 glClearStencil(0);
7791 state_.SetDeviceStencilMaskSeparate(GL_FRONT, -1);
7792 state_.SetDeviceStencilMaskSeparate(GL_BACK, -1);
7793 glClearDepth(1.0f);
7794 state_.SetDeviceDepthMask(GL_TRUE);
7795 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
7796 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7797
7798 RestoreClearState();
7799
7800 glDeleteFramebuffersEXT(1, &fb);
7801 Framebuffer* framebuffer =
7802 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7803 GLuint fb_service_id =
7804 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7805 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7806 return true;
7807 }
7808
7809 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7810
7811 uint32 size;
7812 uint32 padded_row_size;
7813 if (!GLES2Util::ComputeImageDataSizes(
7814 width, height, format, type, state_.unpack_alignment, &size,
7815 NULL, &padded_row_size)) {
7816 return false;
7817 }
7818
7819 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7820
7821 int tile_height;
7822
7823 if (size > kMaxZeroSize) {
7824 if (kMaxZeroSize < padded_row_size) {
7825 // That'd be an awfully large texture.
7826 return false;
7827 }
7828 // We should never have a large total size with a zero row size.
7829 DCHECK_GT(padded_row_size, 0U);
7830 tile_height = kMaxZeroSize / padded_row_size;
7831 if (!GLES2Util::ComputeImageDataSizes(
7832 width, tile_height, format, type, state_.unpack_alignment, &size,
7833 NULL, NULL)) {
7834 return false;
7835 }
7836 } else {
7837 tile_height = height;
7838 }
7839
7840 // Assumes the size has already been checked.
7841 scoped_ptr<char[]> zero(new char[size]);
7842 memset(zero.get(), 0, size);
7843 glBindTexture(bind_target, service_id);
7844
7845 GLint y = 0;
7846 while (y < height) {
7847 GLint h = y + tile_height > height ? height - y : tile_height;
7848 if (is_texture_immutable || h != height) {
7849 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7850 } else {
7851 glTexImage2D(
7852 target, level, internal_format, width, h, 0, format, type,
7853 zero.get());
7854 }
7855 y += tile_height;
7856 }
7857 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
7858 &state_, bind_target);
7859 glBindTexture(bind_target, texture ? texture->service_id() : 0);
7860 return true;
7861 }
7862
7863 namespace {
7864
7865 const int kS3TCBlockWidth = 4;
7866 const int kS3TCBlockHeight = 4;
7867 const int kS3TCDXT1BlockSize = 8;
7868 const int kS3TCDXT3AndDXT5BlockSize = 16;
7869
IsValidDXTSize(GLint level,GLsizei size)7870 bool IsValidDXTSize(GLint level, GLsizei size) {
7871 return (size == 1) ||
7872 (size == 2) || !(size % kS3TCBlockWidth);
7873 }
7874
IsValidPVRTCSize(GLint level,GLsizei size)7875 bool IsValidPVRTCSize(GLint level, GLsizei size) {
7876 // Ensure that the size is a power of two
7877 return (size & (size - 1)) == 0;
7878 }
7879
7880 } // anonymous namespace.
7881
ValidateCompressedTexFuncData(const char * function_name,GLsizei width,GLsizei height,GLenum format,size_t size)7882 bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7883 const char* function_name,
7884 GLsizei width, GLsizei height, GLenum format, size_t size) {
7885 unsigned int bytes_required = 0;
7886
7887 switch (format) {
7888 case GL_ATC_RGB_AMD:
7889 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7890 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7891 case GL_ETC1_RGB8_OES: {
7892 int num_blocks_across =
7893 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7894 int num_blocks_down =
7895 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7896 int num_blocks = num_blocks_across * num_blocks_down;
7897 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7898 break;
7899 }
7900 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
7901 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
7902 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7903 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7904 int num_blocks_across =
7905 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7906 int num_blocks_down =
7907 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7908 int num_blocks = num_blocks_across * num_blocks_down;
7909 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7910 break;
7911 }
7912 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
7913 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
7914 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
7915 break;
7916 }
7917 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
7918 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
7919 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
7920 break;
7921 }
7922 default:
7923 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
7924 return false;
7925 }
7926
7927 if (size != bytes_required) {
7928 LOCAL_SET_GL_ERROR(
7929 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7930 return false;
7931 }
7932
7933 return true;
7934 }
7935
ValidateCompressedTexDimensions(const char * function_name,GLint level,GLsizei width,GLsizei height,GLenum format)7936 bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7937 const char* function_name,
7938 GLint level, GLsizei width, GLsizei height, GLenum format) {
7939 switch (format) {
7940 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7941 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7942 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7943 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7944 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
7945 LOCAL_SET_GL_ERROR(
7946 GL_INVALID_OPERATION, function_name,
7947 "width or height invalid for level");
7948 return false;
7949 }
7950 return true;
7951 }
7952 case GL_ATC_RGB_AMD:
7953 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
7954 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
7955 case GL_ETC1_RGB8_OES: {
7956 if (width <= 0 || height <= 0) {
7957 LOCAL_SET_GL_ERROR(
7958 GL_INVALID_OPERATION, function_name,
7959 "width or height invalid for level");
7960 return false;
7961 }
7962 return true;
7963 }
7964 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
7965 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
7966 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
7967 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
7968 if (!IsValidPVRTCSize(level, width) ||
7969 !IsValidPVRTCSize(level, height)) {
7970 LOCAL_SET_GL_ERROR(
7971 GL_INVALID_OPERATION, function_name,
7972 "width or height invalid for level");
7973 return false;
7974 }
7975 return true;
7976 }
7977 default:
7978 return false;
7979 }
7980 }
7981
ValidateCompressedTexSubDimensions(const char * function_name,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,Texture * texture)7982 bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7983 const char* function_name,
7984 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7985 GLsizei width, GLsizei height, GLenum format,
7986 Texture* texture) {
7987 if (xoffset < 0 || yoffset < 0) {
7988 LOCAL_SET_GL_ERROR(
7989 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7990 return false;
7991 }
7992
7993 switch (format) {
7994 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7995 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7996 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7997 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7998 const int kBlockWidth = 4;
7999 const int kBlockHeight = 4;
8000 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
8001 LOCAL_SET_GL_ERROR(
8002 GL_INVALID_OPERATION, function_name,
8003 "xoffset or yoffset not multiple of 4");
8004 return false;
8005 }
8006 GLsizei tex_width = 0;
8007 GLsizei tex_height = 0;
8008 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8009 width - xoffset > tex_width ||
8010 height - yoffset > tex_height) {
8011 LOCAL_SET_GL_ERROR(
8012 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8013 return false;
8014 }
8015 return ValidateCompressedTexDimensions(
8016 function_name, level, width, height, format);
8017 }
8018 case GL_ATC_RGB_AMD:
8019 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8020 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8021 LOCAL_SET_GL_ERROR(
8022 GL_INVALID_OPERATION, function_name,
8023 "not supported for ATC textures");
8024 return false;
8025 }
8026 case GL_ETC1_RGB8_OES: {
8027 LOCAL_SET_GL_ERROR(
8028 GL_INVALID_OPERATION, function_name,
8029 "not supported for ECT1_RGB8_OES textures");
8030 return false;
8031 }
8032 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8033 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8034 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8035 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8036 if ((xoffset != 0) || (yoffset != 0)) {
8037 LOCAL_SET_GL_ERROR(
8038 GL_INVALID_OPERATION, function_name,
8039 "xoffset and yoffset must be zero");
8040 return false;
8041 }
8042 GLsizei tex_width = 0;
8043 GLsizei tex_height = 0;
8044 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8045 width != tex_width ||
8046 height != tex_height) {
8047 LOCAL_SET_GL_ERROR(
8048 GL_INVALID_OPERATION, function_name,
8049 "dimensions must match existing texture level dimensions");
8050 return false;
8051 }
8052 return ValidateCompressedTexDimensions(
8053 function_name, level, width, height, format);
8054 }
8055 default:
8056 return false;
8057 }
8058 }
8059
DoCompressedTexImage2D(GLenum target,GLint level,GLenum internal_format,GLsizei width,GLsizei height,GLint border,GLsizei image_size,const void * data)8060 error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8061 GLenum target,
8062 GLint level,
8063 GLenum internal_format,
8064 GLsizei width,
8065 GLsizei height,
8066 GLint border,
8067 GLsizei image_size,
8068 const void* data) {
8069 // TODO(gman): Validate image_size is correct for width, height and format.
8070 if (!validators_->texture_target.IsValid(target)) {
8071 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8072 "glCompressedTexImage2D", target, "target");
8073 return error::kNoError;
8074 }
8075 if (!validators_->compressed_texture_format.IsValid(
8076 internal_format)) {
8077 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8078 "glCompressedTexImage2D", internal_format, "internal_format");
8079 return error::kNoError;
8080 }
8081 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
8082 border != 0) {
8083 LOCAL_SET_GL_ERROR(
8084 GL_INVALID_VALUE,
8085 "glCompressedTexImage2D", "dimensions out of range");
8086 return error::kNoError;
8087 }
8088 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8089 &state_, target);
8090 if (!texture_ref) {
8091 LOCAL_SET_GL_ERROR(
8092 GL_INVALID_VALUE,
8093 "glCompressedTexImage2D", "unknown texture target");
8094 return error::kNoError;
8095 }
8096 Texture* texture = texture_ref->texture();
8097 if (texture->IsImmutable()) {
8098 LOCAL_SET_GL_ERROR(
8099 GL_INVALID_OPERATION,
8100 "glCompressedTexImage2D", "texture is immutable");
8101 return error::kNoError;
8102 }
8103
8104 if (!ValidateCompressedTexDimensions(
8105 "glCompressedTexImage2D", level, width, height, internal_format) ||
8106 !ValidateCompressedTexFuncData(
8107 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
8108 return error::kNoError;
8109 }
8110
8111 if (!EnsureGPUMemoryAvailable(image_size)) {
8112 LOCAL_SET_GL_ERROR(
8113 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
8114 return error::kNoError;
8115 }
8116
8117 if (texture->IsAttachedToFramebuffer()) {
8118 framebuffer_state_.clear_state_dirty = true;
8119 }
8120
8121 scoped_ptr<int8[]> zero;
8122 if (!data) {
8123 zero.reset(new int8[image_size]);
8124 memset(zero.get(), 0, image_size);
8125 data = zero.get();
8126 }
8127 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
8128 glCompressedTexImage2D(
8129 target, level, internal_format, width, height, border, image_size, data);
8130 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
8131 if (error == GL_NO_ERROR) {
8132 texture_manager()->SetLevelInfo(
8133 texture_ref, target, level, internal_format,
8134 width, height, 1, border, 0, 0, true);
8135 }
8136 return error::kNoError;
8137 }
8138
HandleCompressedTexImage2D(uint32 immediate_data_size,const cmds::CompressedTexImage2D & c)8139 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
8140 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
8141 GLenum target = static_cast<GLenum>(c.target);
8142 GLint level = static_cast<GLint>(c.level);
8143 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8144 GLsizei width = static_cast<GLsizei>(c.width);
8145 GLsizei height = static_cast<GLsizei>(c.height);
8146 GLint border = static_cast<GLint>(c.border);
8147 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8148 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8149 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8150 const void* data = NULL;
8151 if (data_shm_id != 0 || data_shm_offset != 0) {
8152 data = GetSharedMemoryAs<const void*>(
8153 data_shm_id, data_shm_offset, image_size);
8154 if (!data) {
8155 return error::kOutOfBounds;
8156 }
8157 }
8158 return DoCompressedTexImage2D(
8159 target, level, internal_format, width, height, border, image_size, data);
8160 }
8161
HandleCompressedTexImage2DBucket(uint32 immediate_data_size,const cmds::CompressedTexImage2DBucket & c)8162 error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
8163 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
8164 GLenum target = static_cast<GLenum>(c.target);
8165 GLint level = static_cast<GLint>(c.level);
8166 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8167 GLsizei width = static_cast<GLsizei>(c.width);
8168 GLsizei height = static_cast<GLsizei>(c.height);
8169 GLint border = static_cast<GLint>(c.border);
8170 Bucket* bucket = GetBucket(c.bucket_id);
8171 if (!bucket) {
8172 return error::kInvalidArguments;
8173 }
8174 uint32 data_size = bucket->size();
8175 GLsizei imageSize = data_size;
8176 const void* data = bucket->GetData(0, data_size);
8177 if (!data) {
8178 return error::kInvalidArguments;
8179 }
8180 return DoCompressedTexImage2D(
8181 target, level, internal_format, width, height, border,
8182 imageSize, data);
8183 }
8184
HandleCompressedTexSubImage2DBucket(uint32 immediate_data_size,const cmds::CompressedTexSubImage2DBucket & c)8185 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8186 uint32 immediate_data_size,
8187 const cmds::CompressedTexSubImage2DBucket& c) {
8188 GLenum target = static_cast<GLenum>(c.target);
8189 GLint level = static_cast<GLint>(c.level);
8190 GLint xoffset = static_cast<GLint>(c.xoffset);
8191 GLint yoffset = static_cast<GLint>(c.yoffset);
8192 GLsizei width = static_cast<GLsizei>(c.width);
8193 GLsizei height = static_cast<GLsizei>(c.height);
8194 GLenum format = static_cast<GLenum>(c.format);
8195 Bucket* bucket = GetBucket(c.bucket_id);
8196 if (!bucket) {
8197 return error::kInvalidArguments;
8198 }
8199 uint32 data_size = bucket->size();
8200 GLsizei imageSize = data_size;
8201 const void* data = bucket->GetData(0, data_size);
8202 if (!data) {
8203 return error::kInvalidArguments;
8204 }
8205 if (!validators_->texture_target.IsValid(target)) {
8206 LOCAL_SET_GL_ERROR(
8207 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
8208 return error::kNoError;
8209 }
8210 if (!validators_->compressed_texture_format.IsValid(format)) {
8211 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8212 "glCompressedTexSubImage2D", format, "format");
8213 return error::kNoError;
8214 }
8215 if (width < 0) {
8216 LOCAL_SET_GL_ERROR(
8217 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
8218 return error::kNoError;
8219 }
8220 if (height < 0) {
8221 LOCAL_SET_GL_ERROR(
8222 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
8223 return error::kNoError;
8224 }
8225 if (imageSize < 0) {
8226 LOCAL_SET_GL_ERROR(
8227 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
8228 return error::kNoError;
8229 }
8230 DoCompressedTexSubImage2D(
8231 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8232 return error::kNoError;
8233 }
8234
HandleTexImage2D(uint32 immediate_data_size,const cmds::TexImage2D & c)8235 error::Error GLES2DecoderImpl::HandleTexImage2D(
8236 uint32 immediate_data_size, const cmds::TexImage2D& c) {
8237 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8238 "width", c.width, "height", c.height);
8239 // Set as failed for now, but if it successed, this will be set to not failed.
8240 texture_state_.tex_image_2d_failed = true;
8241 GLenum target = static_cast<GLenum>(c.target);
8242 GLint level = static_cast<GLint>(c.level);
8243 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8244 // for internalformat.
8245 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8246 GLsizei width = static_cast<GLsizei>(c.width);
8247 GLsizei height = static_cast<GLsizei>(c.height);
8248 GLint border = static_cast<GLint>(c.border);
8249 GLenum format = static_cast<GLenum>(c.format);
8250 GLenum type = static_cast<GLenum>(c.type);
8251 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8252 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
8253 uint32 pixels_size;
8254 if (!GLES2Util::ComputeImageDataSizes(
8255 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
8256 NULL)) {
8257 return error::kOutOfBounds;
8258 }
8259 const void* pixels = NULL;
8260 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8261 pixels = GetSharedMemoryAs<const void*>(
8262 pixels_shm_id, pixels_shm_offset, pixels_size);
8263 if (!pixels) {
8264 return error::kOutOfBounds;
8265 }
8266 }
8267
8268 TextureManager::DoTextImage2DArguments args = {
8269 target, level, internal_format, width, height, border, format, type,
8270 pixels, pixels_size};
8271 texture_manager()->ValidateAndDoTexImage2D(
8272 &texture_state_, &state_, &framebuffer_state_, args);
8273 return error::kNoError;
8274 }
8275
DoCompressedTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei image_size,const void * data)8276 void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8277 GLenum target,
8278 GLint level,
8279 GLint xoffset,
8280 GLint yoffset,
8281 GLsizei width,
8282 GLsizei height,
8283 GLenum format,
8284 GLsizei image_size,
8285 const void * data) {
8286 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8287 &state_, target);
8288 if (!texture_ref) {
8289 LOCAL_SET_GL_ERROR(
8290 GL_INVALID_OPERATION,
8291 "glCompressedTexSubImage2D", "unknown texture for target");
8292 return;
8293 }
8294 Texture* texture = texture_ref->texture();
8295 GLenum type = 0;
8296 GLenum internal_format = 0;
8297 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
8298 LOCAL_SET_GL_ERROR(
8299 GL_INVALID_OPERATION,
8300 "glCompressedTexSubImage2D", "level does not exist.");
8301 return;
8302 }
8303 if (internal_format != format) {
8304 LOCAL_SET_GL_ERROR(
8305 GL_INVALID_OPERATION,
8306 "glCompressedTexSubImage2D", "format does not match internal format.");
8307 return;
8308 }
8309 if (!texture->ValidForTexture(
8310 target, level, xoffset, yoffset, width, height, type)) {
8311 LOCAL_SET_GL_ERROR(
8312 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
8313 return;
8314 }
8315
8316 if (!ValidateCompressedTexFuncData(
8317 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8318 !ValidateCompressedTexSubDimensions(
8319 "glCompressedTexSubImage2D",
8320 target, level, xoffset, yoffset, width, height, format, texture)) {
8321 return;
8322 }
8323
8324
8325 // Note: There is no need to deal with texture cleared tracking here
8326 // because the validation above means you can only get here if the level
8327 // is already a matching compressed format and in that case
8328 // CompressedTexImage2D already cleared the texture.
8329 glCompressedTexSubImage2D(
8330 target, level, xoffset, yoffset, width, height, format, image_size, data);
8331 }
8332
Clip(GLint start,GLint range,GLint sourceRange,GLint * out_start,GLint * out_range)8333 static void Clip(
8334 GLint start, GLint range, GLint sourceRange,
8335 GLint* out_start, GLint* out_range) {
8336 DCHECK(out_start);
8337 DCHECK(out_range);
8338 if (start < 0) {
8339 range += start;
8340 start = 0;
8341 }
8342 GLint end = start + range;
8343 if (end > sourceRange) {
8344 range -= end - sourceRange;
8345 }
8346 *out_start = start;
8347 *out_range = range;
8348 }
8349
DoCopyTexImage2D(GLenum target,GLint level,GLenum internal_format,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)8350 void GLES2DecoderImpl::DoCopyTexImage2D(
8351 GLenum target,
8352 GLint level,
8353 GLenum internal_format,
8354 GLint x,
8355 GLint y,
8356 GLsizei width,
8357 GLsizei height,
8358 GLint border) {
8359 DCHECK(!ShouldDeferReads());
8360 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8361 &state_, target);
8362 if (!texture_ref) {
8363 LOCAL_SET_GL_ERROR(
8364 GL_INVALID_OPERATION,
8365 "glCopyTexImage2D", "unknown texture for target");
8366 return;
8367 }
8368 Texture* texture = texture_ref->texture();
8369 if (texture->IsImmutable()) {
8370 LOCAL_SET_GL_ERROR(
8371 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
8372 return;
8373 }
8374 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
8375 border != 0) {
8376 LOCAL_SET_GL_ERROR(
8377 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
8378 return;
8379 }
8380 if (!texture_manager()->ValidateFormatAndTypeCombination(
8381 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8382 GL_UNSIGNED_BYTE)) {
8383 return;
8384 }
8385
8386 // Check we have compatible formats.
8387 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8388 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8389 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8390
8391 if ((channels_needed & channels_exist) != channels_needed) {
8392 LOCAL_SET_GL_ERROR(
8393 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
8394 return;
8395 }
8396
8397 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
8398 LOCAL_SET_GL_ERROR(
8399 GL_INVALID_OPERATION,
8400 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8401 return;
8402 }
8403
8404 uint32 estimated_size = 0;
8405 if (!GLES2Util::ComputeImageDataSizes(
8406 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8407 &estimated_size, NULL, NULL)) {
8408 LOCAL_SET_GL_ERROR(
8409 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
8410 return;
8411 }
8412
8413 if (!EnsureGPUMemoryAvailable(estimated_size)) {
8414 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
8415 return;
8416 }
8417
8418 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8419 return;
8420 }
8421
8422 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
8423 ScopedResolvedFrameBufferBinder binder(this, false, true);
8424 gfx::Size size = GetBoundReadFrameBufferSize();
8425
8426 if (texture->IsAttachedToFramebuffer()) {
8427 framebuffer_state_.clear_state_dirty = true;
8428 }
8429
8430 // Clip to size to source dimensions
8431 GLint copyX = 0;
8432 GLint copyY = 0;
8433 GLint copyWidth = 0;
8434 GLint copyHeight = 0;
8435 Clip(x, width, size.width(), ©X, ©Width);
8436 Clip(y, height, size.height(), ©Y, ©Height);
8437
8438 if (copyX != x ||
8439 copyY != y ||
8440 copyWidth != width ||
8441 copyHeight != height) {
8442 // some part was clipped so clear the texture.
8443 if (!ClearLevel(
8444 texture->service_id(), texture->target(),
8445 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
8446 width, height, texture->IsImmutable())) {
8447 LOCAL_SET_GL_ERROR(
8448 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
8449 return;
8450 }
8451 if (copyHeight > 0 && copyWidth > 0) {
8452 GLint dx = copyX - x;
8453 GLint dy = copyY - y;
8454 GLint destX = dx;
8455 GLint destY = dy;
8456 ScopedModifyPixels modify(texture_ref);
8457 glCopyTexSubImage2D(target, level,
8458 destX, destY, copyX, copyY,
8459 copyWidth, copyHeight);
8460 }
8461 } else {
8462 ScopedModifyPixels modify(texture_ref);
8463 glCopyTexImage2D(target, level, internal_format,
8464 copyX, copyY, copyWidth, copyHeight, border);
8465 }
8466 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
8467 if (error == GL_NO_ERROR) {
8468 texture_manager()->SetLevelInfo(
8469 texture_ref, target, level, internal_format, width, height, 1,
8470 border, internal_format, GL_UNSIGNED_BYTE, true);
8471 }
8472 }
8473
DoCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)8474 void GLES2DecoderImpl::DoCopyTexSubImage2D(
8475 GLenum target,
8476 GLint level,
8477 GLint xoffset,
8478 GLint yoffset,
8479 GLint x,
8480 GLint y,
8481 GLsizei width,
8482 GLsizei height) {
8483 DCHECK(!ShouldDeferReads());
8484 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8485 &state_, target);
8486 if (!texture_ref) {
8487 LOCAL_SET_GL_ERROR(
8488 GL_INVALID_OPERATION,
8489 "glCopyTexSubImage2D", "unknown texture for target");
8490 return;
8491 }
8492 Texture* texture = texture_ref->texture();
8493 GLenum type = 0;
8494 GLenum format = 0;
8495 if (!texture->GetLevelType(target, level, &type, &format) ||
8496 !texture->ValidForTexture(
8497 target, level, xoffset, yoffset, width, height, type)) {
8498 LOCAL_SET_GL_ERROR(
8499 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
8500 return;
8501 }
8502 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
8503 LOCAL_SET_GL_ERROR(
8504 GL_INVALID_OPERATION,
8505 "glCopyTexSubImage2D", "async upload pending for texture");
8506 return;
8507 }
8508
8509 // Check we have compatible formats.
8510 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8511 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8512 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8513
8514 if (!channels_needed ||
8515 (channels_needed & channels_exist) != channels_needed) {
8516 LOCAL_SET_GL_ERROR(
8517 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
8518 return;
8519 }
8520
8521 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
8522 LOCAL_SET_GL_ERROR(
8523 GL_INVALID_OPERATION,
8524 "glCopySubImage2D", "can not be used with depth or stencil textures");
8525 return;
8526 }
8527
8528 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8529 return;
8530 }
8531
8532 ScopedResolvedFrameBufferBinder binder(this, false, true);
8533 gfx::Size size = GetBoundReadFrameBufferSize();
8534 GLint copyX = 0;
8535 GLint copyY = 0;
8536 GLint copyWidth = 0;
8537 GLint copyHeight = 0;
8538 Clip(x, width, size.width(), ©X, ©Width);
8539 Clip(y, height, size.height(), ©Y, ©Height);
8540
8541 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
8542 LOCAL_SET_GL_ERROR(
8543 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
8544 return;
8545 }
8546
8547 if (copyX != x ||
8548 copyY != y ||
8549 copyWidth != width ||
8550 copyHeight != height) {
8551 // some part was clipped so clear the sub rect.
8552 uint32 pixels_size = 0;
8553 if (!GLES2Util::ComputeImageDataSizes(
8554 width, height, format, type, state_.unpack_alignment, &pixels_size,
8555 NULL, NULL)) {
8556 LOCAL_SET_GL_ERROR(
8557 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
8558 return;
8559 }
8560 scoped_ptr<char[]> zero(new char[pixels_size]);
8561 memset(zero.get(), 0, pixels_size);
8562 ScopedModifyPixels modify(texture_ref);
8563 glTexSubImage2D(
8564 target, level, xoffset, yoffset, width, height,
8565 format, type, zero.get());
8566 }
8567
8568 if (copyHeight > 0 && copyWidth > 0) {
8569 GLint dx = copyX - x;
8570 GLint dy = copyY - y;
8571 GLint destX = xoffset + dx;
8572 GLint destY = yoffset + dy;
8573 ScopedModifyPixels modify(texture_ref);
8574 glCopyTexSubImage2D(target, level,
8575 destX, destY, copyX, copyY,
8576 copyWidth, copyHeight);
8577 }
8578 }
8579
ValidateTexSubImage2D(error::Error * error,const char * function_name,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const void * data)8580 bool GLES2DecoderImpl::ValidateTexSubImage2D(
8581 error::Error* error,
8582 const char* function_name,
8583 GLenum target,
8584 GLint level,
8585 GLint xoffset,
8586 GLint yoffset,
8587 GLsizei width,
8588 GLsizei height,
8589 GLenum format,
8590 GLenum type,
8591 const void * data) {
8592 (*error) = error::kNoError;
8593 if (!validators_->texture_target.IsValid(target)) {
8594 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
8595 return false;
8596 }
8597 if (width < 0) {
8598 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
8599 return false;
8600 }
8601 if (height < 0) {
8602 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
8603 return false;
8604 }
8605 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8606 &state_, target);
8607 if (!texture_ref) {
8608 LOCAL_SET_GL_ERROR(
8609 GL_INVALID_OPERATION,
8610 function_name, "unknown texture for target");
8611 return false;
8612 }
8613 Texture* texture = texture_ref->texture();
8614 GLenum current_type = 0;
8615 GLenum internal_format = 0;
8616 if (!texture->GetLevelType(target, level, ¤t_type, &internal_format)) {
8617 LOCAL_SET_GL_ERROR(
8618 GL_INVALID_OPERATION, function_name, "level does not exist.");
8619 return false;
8620 }
8621 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
8622 function_name, format, type, internal_format, level)) {
8623 return false;
8624 }
8625 if (type != current_type) {
8626 LOCAL_SET_GL_ERROR(
8627 GL_INVALID_OPERATION,
8628 function_name, "type does not match type of texture.");
8629 return false;
8630 }
8631 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
8632 LOCAL_SET_GL_ERROR(
8633 GL_INVALID_OPERATION,
8634 function_name, "async upload pending for texture");
8635 return false;
8636 }
8637 if (!texture->ValidForTexture(
8638 target, level, xoffset, yoffset, width, height, type)) {
8639 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
8640 return false;
8641 }
8642 if ((GLES2Util::GetChannelsForFormat(format) &
8643 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
8644 LOCAL_SET_GL_ERROR(
8645 GL_INVALID_OPERATION,
8646 function_name, "can not supply data for depth or stencil textures");
8647 return false;
8648 }
8649 if (data == NULL) {
8650 (*error) = error::kOutOfBounds;
8651 return false;
8652 }
8653 return true;
8654 }
8655
DoTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const void * data)8656 error::Error GLES2DecoderImpl::DoTexSubImage2D(
8657 GLenum target,
8658 GLint level,
8659 GLint xoffset,
8660 GLint yoffset,
8661 GLsizei width,
8662 GLsizei height,
8663 GLenum format,
8664 GLenum type,
8665 const void * data) {
8666 error::Error error = error::kNoError;
8667 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8668 xoffset, yoffset, width, height, format, type, data)) {
8669 return error;
8670 }
8671 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8672 &state_, target);
8673 Texture* texture = texture_ref->texture();
8674 GLsizei tex_width = 0;
8675 GLsizei tex_height = 0;
8676 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
8677 DCHECK(ok);
8678 if (xoffset != 0 || yoffset != 0 ||
8679 width != tex_width || height != tex_height) {
8680 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8681 target, level)) {
8682 LOCAL_SET_GL_ERROR(
8683 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
8684 return error::kNoError;
8685 }
8686 ScopedTextureUploadTimer timer(&texture_state_);
8687 glTexSubImage2D(
8688 target, level, xoffset, yoffset, width, height, format, type, data);
8689 return error::kNoError;
8690 }
8691
8692 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
8693 !texture->IsImmutable()) {
8694 ScopedTextureUploadTimer timer(&texture_state_);
8695 GLenum internal_format;
8696 GLenum tex_type;
8697 texture->GetLevelType(target, level, &tex_type, &internal_format);
8698 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
8699 // to look it up.
8700 glTexImage2D(
8701 target, level, internal_format, width, height, 0, format, type, data);
8702 } else {
8703 ScopedTextureUploadTimer timer(&texture_state_);
8704 glTexSubImage2D(
8705 target, level, xoffset, yoffset, width, height, format, type, data);
8706 }
8707 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
8708 return error::kNoError;
8709 }
8710
HandleTexSubImage2D(uint32 immediate_data_size,const cmds::TexSubImage2D & c)8711 error::Error GLES2DecoderImpl::HandleTexSubImage2D(
8712 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
8713 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
8714 "width", c.width, "height", c.height);
8715 GLboolean internal = static_cast<GLboolean>(c.internal);
8716 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
8717 return error::kNoError;
8718
8719 GLenum target = static_cast<GLenum>(c.target);
8720 GLint level = static_cast<GLint>(c.level);
8721 GLint xoffset = static_cast<GLint>(c.xoffset);
8722 GLint yoffset = static_cast<GLint>(c.yoffset);
8723 GLsizei width = static_cast<GLsizei>(c.width);
8724 GLsizei height = static_cast<GLsizei>(c.height);
8725 GLenum format = static_cast<GLenum>(c.format);
8726 GLenum type = static_cast<GLenum>(c.type);
8727 uint32 data_size;
8728 if (!GLES2Util::ComputeImageDataSizes(
8729 width, height, format, type, state_.unpack_alignment, &data_size,
8730 NULL, NULL)) {
8731 return error::kOutOfBounds;
8732 }
8733 const void* pixels = GetSharedMemoryAs<const void*>(
8734 c.pixels_shm_id, c.pixels_shm_offset, data_size);
8735 return DoTexSubImage2D(
8736 target, level, xoffset, yoffset, width, height, format, type, pixels);
8737 }
8738
HandleGetVertexAttribPointerv(uint32 immediate_data_size,const cmds::GetVertexAttribPointerv & c)8739 error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
8740 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
8741 GLuint index = static_cast<GLuint>(c.index);
8742 GLenum pname = static_cast<GLenum>(c.pname);
8743 typedef cmds::GetVertexAttribPointerv::Result Result;
8744 Result* result = GetSharedMemoryAs<Result*>(
8745 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
8746 if (!result) {
8747 return error::kOutOfBounds;
8748 }
8749 // Check that the client initialized the result.
8750 if (result->size != 0) {
8751 return error::kInvalidArguments;
8752 }
8753 if (!validators_->vertex_pointer.IsValid(pname)) {
8754 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8755 "glGetVertexAttribPointerv", pname, "pname");
8756 return error::kNoError;
8757 }
8758 if (index >= group_->max_vertex_attribs()) {
8759 LOCAL_SET_GL_ERROR(
8760 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
8761 return error::kNoError;
8762 }
8763 result->SetNumResults(1);
8764 *result->GetData() =
8765 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
8766 return error::kNoError;
8767 }
8768
GetUniformSetup(GLuint program_id,GLint fake_location,uint32 shm_id,uint32 shm_offset,error::Error * error,GLint * real_location,GLuint * service_id,void ** result_pointer,GLenum * result_type)8769 bool GLES2DecoderImpl::GetUniformSetup(
8770 GLuint program_id, GLint fake_location,
8771 uint32 shm_id, uint32 shm_offset,
8772 error::Error* error, GLint* real_location,
8773 GLuint* service_id, void** result_pointer, GLenum* result_type) {
8774 DCHECK(error);
8775 DCHECK(service_id);
8776 DCHECK(result_pointer);
8777 DCHECK(result_type);
8778 DCHECK(real_location);
8779 *error = error::kNoError;
8780 // Make sure we have enough room for the result on failure.
8781 SizedResult<GLint>* result;
8782 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8783 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8784 if (!result) {
8785 *error = error::kOutOfBounds;
8786 return false;
8787 }
8788 *result_pointer = result;
8789 // Set the result size to 0 so the client does not have to check for success.
8790 result->SetNumResults(0);
8791 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8792 if (!program) {
8793 return false;
8794 }
8795 if (!program->IsValid()) {
8796 // Program was not linked successfully. (ie, glLinkProgram)
8797 LOCAL_SET_GL_ERROR(
8798 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
8799 return false;
8800 }
8801 *service_id = program->service_id();
8802 GLint array_index = -1;
8803 const Program::UniformInfo* uniform_info =
8804 program->GetUniformInfoByFakeLocation(
8805 fake_location, real_location, &array_index);
8806 if (!uniform_info) {
8807 // No such location.
8808 LOCAL_SET_GL_ERROR(
8809 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
8810 return false;
8811 }
8812 GLenum type = uniform_info->type;
8813 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
8814 if (size == 0) {
8815 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
8816 return false;
8817 }
8818 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8819 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8820 if (!result) {
8821 *error = error::kOutOfBounds;
8822 return false;
8823 }
8824 result->size = size;
8825 *result_type = type;
8826 return true;
8827 }
8828
HandleGetUniformiv(uint32 immediate_data_size,const cmds::GetUniformiv & c)8829 error::Error GLES2DecoderImpl::HandleGetUniformiv(
8830 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
8831 GLuint program = c.program;
8832 GLint fake_location = c.location;
8833 GLuint service_id;
8834 GLenum result_type;
8835 GLint real_location = -1;
8836 Error error;
8837 void* result;
8838 if (GetUniformSetup(
8839 program, fake_location, c.params_shm_id, c.params_shm_offset,
8840 &error, &real_location, &service_id, &result, &result_type)) {
8841 glGetUniformiv(
8842 service_id, real_location,
8843 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
8844 }
8845 return error;
8846 }
8847
HandleGetUniformfv(uint32 immediate_data_size,const cmds::GetUniformfv & c)8848 error::Error GLES2DecoderImpl::HandleGetUniformfv(
8849 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
8850 GLuint program = c.program;
8851 GLint fake_location = c.location;
8852 GLuint service_id;
8853 GLint real_location = -1;
8854 Error error;
8855 typedef cmds::GetUniformfv::Result Result;
8856 Result* result;
8857 GLenum result_type;
8858 if (GetUniformSetup(
8859 program, fake_location, c.params_shm_id, c.params_shm_offset,
8860 &error, &real_location, &service_id,
8861 reinterpret_cast<void**>(&result), &result_type)) {
8862 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8863 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8864 GLsizei num_values = result->GetNumResults();
8865 scoped_ptr<GLint[]> temp(new GLint[num_values]);
8866 glGetUniformiv(service_id, real_location, temp.get());
8867 GLfloat* dst = result->GetData();
8868 for (GLsizei ii = 0; ii < num_values; ++ii) {
8869 dst[ii] = (temp[ii] != 0);
8870 }
8871 } else {
8872 glGetUniformfv(service_id, real_location, result->GetData());
8873 }
8874 }
8875 return error;
8876 }
8877
HandleGetShaderPrecisionFormat(uint32 immediate_data_size,const cmds::GetShaderPrecisionFormat & c)8878 error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
8879 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
8880 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8881 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
8882 typedef cmds::GetShaderPrecisionFormat::Result Result;
8883 Result* result = GetSharedMemoryAs<Result*>(
8884 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8885 if (!result) {
8886 return error::kOutOfBounds;
8887 }
8888 // Check that the client initialized the result.
8889 if (result->success != 0) {
8890 return error::kInvalidArguments;
8891 }
8892 if (!validators_->shader_type.IsValid(shader_type)) {
8893 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8894 "glGetShaderPrecisionFormat", shader_type, "shader_type");
8895 return error::kNoError;
8896 }
8897 if (!validators_->shader_precision.IsValid(precision_type)) {
8898 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8899 "glGetShaderPrecisionFormat", precision_type, "precision_type");
8900 return error::kNoError;
8901 }
8902
8903 result->success = 1; // true
8904
8905 GLint range[2] = { 0, 0 };
8906 GLint precision = 0;
8907 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
8908
8909 result->min_range = range[0];
8910 result->max_range = range[1];
8911 result->precision = precision;
8912
8913 return error::kNoError;
8914 }
8915
HandleGetAttachedShaders(uint32 immediate_data_size,const cmds::GetAttachedShaders & c)8916 error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
8917 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
8918 uint32 result_size = c.result_size;
8919 GLuint program_id = static_cast<GLuint>(c.program);
8920 Program* program = GetProgramInfoNotShader(
8921 program_id, "glGetAttachedShaders");
8922 if (!program) {
8923 return error::kNoError;
8924 }
8925 typedef cmds::GetAttachedShaders::Result Result;
8926 uint32 max_count = Result::ComputeMaxResults(result_size);
8927 Result* result = GetSharedMemoryAs<Result*>(
8928 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8929 if (!result) {
8930 return error::kOutOfBounds;
8931 }
8932 // Check that the client initialized the result.
8933 if (result->size != 0) {
8934 return error::kInvalidArguments;
8935 }
8936 GLsizei count = 0;
8937 glGetAttachedShaders(
8938 program->service_id(), max_count, &count, result->GetData());
8939 for (GLsizei ii = 0; ii < count; ++ii) {
8940 if (!shader_manager()->GetClientId(result->GetData()[ii],
8941 &result->GetData()[ii])) {
8942 NOTREACHED();
8943 return error::kGenericError;
8944 }
8945 }
8946 result->SetNumResults(count);
8947 return error::kNoError;
8948 }
8949
HandleGetActiveUniform(uint32 immediate_data_size,const cmds::GetActiveUniform & c)8950 error::Error GLES2DecoderImpl::HandleGetActiveUniform(
8951 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
8952 GLuint program_id = c.program;
8953 GLuint index = c.index;
8954 uint32 name_bucket_id = c.name_bucket_id;
8955 typedef cmds::GetActiveUniform::Result Result;
8956 Result* result = GetSharedMemoryAs<Result*>(
8957 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8958 if (!result) {
8959 return error::kOutOfBounds;
8960 }
8961 // Check that the client initialized the result.
8962 if (result->success != 0) {
8963 return error::kInvalidArguments;
8964 }
8965 Program* program = GetProgramInfoNotShader(
8966 program_id, "glGetActiveUniform");
8967 if (!program) {
8968 return error::kNoError;
8969 }
8970 const Program::UniformInfo* uniform_info =
8971 program->GetUniformInfo(index);
8972 if (!uniform_info) {
8973 LOCAL_SET_GL_ERROR(
8974 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
8975 return error::kNoError;
8976 }
8977 result->success = 1; // true.
8978 result->size = uniform_info->size;
8979 result->type = uniform_info->type;
8980 Bucket* bucket = CreateBucket(name_bucket_id);
8981 bucket->SetFromString(uniform_info->name.c_str());
8982 return error::kNoError;
8983 }
8984
HandleGetActiveAttrib(uint32 immediate_data_size,const cmds::GetActiveAttrib & c)8985 error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
8986 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
8987 GLuint program_id = c.program;
8988 GLuint index = c.index;
8989 uint32 name_bucket_id = c.name_bucket_id;
8990 typedef cmds::GetActiveAttrib::Result Result;
8991 Result* result = GetSharedMemoryAs<Result*>(
8992 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8993 if (!result) {
8994 return error::kOutOfBounds;
8995 }
8996 // Check that the client initialized the result.
8997 if (result->success != 0) {
8998 return error::kInvalidArguments;
8999 }
9000 Program* program = GetProgramInfoNotShader(
9001 program_id, "glGetActiveAttrib");
9002 if (!program) {
9003 return error::kNoError;
9004 }
9005 const Program::VertexAttrib* attrib_info =
9006 program->GetAttribInfo(index);
9007 if (!attrib_info) {
9008 LOCAL_SET_GL_ERROR(
9009 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
9010 return error::kNoError;
9011 }
9012 result->success = 1; // true.
9013 result->size = attrib_info->size;
9014 result->type = attrib_info->type;
9015 Bucket* bucket = CreateBucket(name_bucket_id);
9016 bucket->SetFromString(attrib_info->name.c_str());
9017 return error::kNoError;
9018 }
9019
HandleShaderBinary(uint32 immediate_data_size,const cmds::ShaderBinary & c)9020 error::Error GLES2DecoderImpl::HandleShaderBinary(
9021 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
9022 #if 1 // No binary shader support.
9023 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
9024 return error::kNoError;
9025 #else
9026 GLsizei n = static_cast<GLsizei>(c.n);
9027 if (n < 0) {
9028 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
9029 return error::kNoError;
9030 }
9031 GLsizei length = static_cast<GLsizei>(c.length);
9032 if (length < 0) {
9033 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
9034 return error::kNoError;
9035 }
9036 uint32 data_size;
9037 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9038 return error::kOutOfBounds;
9039 }
9040 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9041 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9042 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9043 const void* binary = GetSharedMemoryAs<const void*>(
9044 c.binary_shm_id, c.binary_shm_offset, length);
9045 if (shaders == NULL || binary == NULL) {
9046 return error::kOutOfBounds;
9047 }
9048 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
9049 for (GLsizei ii = 0; ii < n; ++ii) {
9050 Shader* shader = GetShader(shaders[ii]);
9051 if (!shader) {
9052 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
9053 return error::kNoError;
9054 }
9055 service_ids[ii] = shader->service_id();
9056 }
9057 // TODO(gman): call glShaderBinary
9058 return error::kNoError;
9059 #endif
9060 }
9061
DoSwapBuffers()9062 void GLES2DecoderImpl::DoSwapBuffers() {
9063 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
9064
9065 int this_frame_number = frame_number_++;
9066 // TRACE_EVENT for gpu tests:
9067 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
9068 TRACE_EVENT_SCOPE_THREAD,
9069 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9070 "width", (is_offscreen ? offscreen_size_.width() :
9071 surface_->GetSize().width()));
9072 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
9073 "offscreen", is_offscreen,
9074 "frame", this_frame_number);
9075 {
9076 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
9077 }
9078
9079 bool is_tracing;
9080 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9081 &is_tracing);
9082 if (is_tracing) {
9083 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9084 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9085 is_offscreen ? offscreen_size_ : surface_->GetSize());
9086 }
9087
9088 // If offscreen then don't actually SwapBuffers to the display. Just copy
9089 // the rendered frame to another frame buffer.
9090 if (is_offscreen) {
9091 TRACE_EVENT2("gpu", "Offscreen",
9092 "width", offscreen_size_.width(), "height", offscreen_size_.height());
9093 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9094 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9095 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9096 // fix this.
9097 if (workarounds().needs_offscreen_buffer_workaround) {
9098 offscreen_saved_frame_buffer_->Create();
9099 glFinish();
9100 }
9101
9102 // Allocate the offscreen saved color texture.
9103 DCHECK(offscreen_saved_color_format_);
9104 offscreen_saved_color_texture_->AllocateStorage(
9105 offscreen_size_, offscreen_saved_color_format_, false);
9106
9107 offscreen_saved_frame_buffer_->AttachRenderTexture(
9108 offscreen_saved_color_texture_.get());
9109 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9110 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9111 GL_FRAMEBUFFER_COMPLETE) {
9112 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9113 << "because offscreen saved FBO was incomplete.";
9114 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9115 return;
9116 }
9117
9118 // Clear the offscreen color texture.
9119 // TODO(piman): Is this still necessary?
9120 {
9121 ScopedFrameBufferBinder binder(this,
9122 offscreen_saved_frame_buffer_->id());
9123 glClearColor(0, 0, 0, 0);
9124 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9125 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
9126 glClear(GL_COLOR_BUFFER_BIT);
9127 RestoreClearState();
9128 }
9129 }
9130
9131 UpdateParentTextureInfo();
9132 }
9133
9134 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
9135 return;
9136 ScopedGLErrorSuppressor suppressor(
9137 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
9138
9139 if (IsOffscreenBufferMultisampled()) {
9140 // For multisampled buffers, resolve the frame buffer.
9141 ScopedResolvedFrameBufferBinder binder(this, true, false);
9142 } else {
9143 ScopedFrameBufferBinder binder(this,
9144 offscreen_target_frame_buffer_->id());
9145
9146 if (offscreen_target_buffer_preserved_) {
9147 // Copy the target frame buffer to the saved offscreen texture.
9148 offscreen_saved_color_texture_->Copy(
9149 offscreen_saved_color_texture_->size(),
9150 offscreen_saved_color_format_);
9151 } else {
9152 // Flip the textures in the parent context via the texture manager.
9153 if (!!offscreen_saved_color_texture_info_.get())
9154 offscreen_saved_color_texture_info_->texture()->
9155 SetServiceId(offscreen_target_color_texture_->id());
9156
9157 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9158 offscreen_target_frame_buffer_->AttachRenderTexture(
9159 offscreen_target_color_texture_.get());
9160 }
9161
9162 // Ensure the side effects of the copy are visible to the parent
9163 // context. There is no need to do this for ANGLE because it uses a
9164 // single D3D device for all contexts.
9165 if (!feature_info_->feature_flags().is_angle)
9166 glFlush();
9167 }
9168 } else {
9169 if (!surface_->SwapBuffers()) {
9170 LOG(ERROR) << "Context lost because SwapBuffers failed.";
9171 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9172 }
9173 }
9174 }
9175
HandleEnableFeatureCHROMIUM(uint32 immediate_data_size,const cmds::EnableFeatureCHROMIUM & c)9176 error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
9177 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
9178 Bucket* bucket = GetBucket(c.bucket_id);
9179 if (!bucket || bucket->size() == 0) {
9180 return error::kInvalidArguments;
9181 }
9182 typedef cmds::EnableFeatureCHROMIUM::Result Result;
9183 Result* result = GetSharedMemoryAs<Result*>(
9184 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9185 if (!result) {
9186 return error::kOutOfBounds;
9187 }
9188 // Check that the client initialized the result.
9189 if (*result != 0) {
9190 return error::kInvalidArguments;
9191 }
9192 std::string feature_str;
9193 if (!bucket->GetAsString(&feature_str)) {
9194 return error::kInvalidArguments;
9195 }
9196
9197 // TODO(gman): make this some kind of table to function pointer thingy.
9198 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
9199 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9200 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
9201 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9202 // TODO(gman): decide how to remove the need for this const_cast.
9203 // I could make validators_ non const but that seems bad as this is the only
9204 // place it is needed. I could make some special friend class of validators
9205 // just to allow this to set them. That seems silly. I could refactor this
9206 // code to use the extension mechanism or the initialization attributes to
9207 // turn this feature on. Given that the only real point of this is to make
9208 // the conformance tests pass and given that there is lots of real work that
9209 // needs to be done it seems like refactoring for one to one of those
9210 // methods is a very low priority.
9211 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
9212 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9213 force_webgl_glsl_validation_ = true;
9214 InitializeShaderTranslator();
9215 } else {
9216 return error::kNoError;
9217 }
9218
9219 *result = 1; // true.
9220 return error::kNoError;
9221 }
9222
HandleGetRequestableExtensionsCHROMIUM(uint32 immediate_data_size,const cmds::GetRequestableExtensionsCHROMIUM & c)9223 error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9224 uint32 immediate_data_size,
9225 const cmds::GetRequestableExtensionsCHROMIUM& c) {
9226 Bucket* bucket = CreateBucket(c.bucket_id);
9227 scoped_refptr<FeatureInfo> info(new FeatureInfo());
9228 info->Initialize(disallowed_features_);
9229 bucket->SetFromString(info->extensions().c_str());
9230 return error::kNoError;
9231 }
9232
HandleRequestExtensionCHROMIUM(uint32 immediate_data_size,const cmds::RequestExtensionCHROMIUM & c)9233 error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
9234 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
9235 Bucket* bucket = GetBucket(c.bucket_id);
9236 if (!bucket || bucket->size() == 0) {
9237 return error::kInvalidArguments;
9238 }
9239 std::string feature_str;
9240 if (!bucket->GetAsString(&feature_str)) {
9241 return error::kInvalidArguments;
9242 }
9243
9244 bool desire_webgl_glsl_validation =
9245 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9246 bool desire_standard_derivatives = false;
9247 bool desire_frag_depth = false;
9248 bool desire_draw_buffers = false;
9249 bool desire_shader_texture_lod = false;
9250 if (force_webgl_glsl_validation_) {
9251 desire_standard_derivatives =
9252 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
9253 desire_frag_depth =
9254 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
9255 desire_draw_buffers =
9256 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
9257 desire_shader_texture_lod =
9258 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
9259 }
9260
9261 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
9262 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
9263 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9264 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
9265 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9266 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9267 frag_depth_explicitly_enabled_ |= desire_frag_depth;
9268 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
9269 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
9270 InitializeShaderTranslator();
9271 }
9272
9273 UpdateCapabilities();
9274
9275 return error::kNoError;
9276 }
9277
HandleGetMultipleIntegervCHROMIUM(uint32 immediate_data_size,const cmds::GetMultipleIntegervCHROMIUM & c)9278 error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
9279 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
9280 GLuint count = c.count;
9281 uint32 pnames_size;
9282 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9283 return error::kOutOfBounds;
9284 }
9285 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9286 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9287 if (pnames == NULL) {
9288 return error::kOutOfBounds;
9289 }
9290
9291 // We have to copy them since we use them twice so the client
9292 // can't change them between the time we validate them and the time we use
9293 // them.
9294 scoped_ptr<GLenum[]> enums(new GLenum[count]);
9295 memcpy(enums.get(), pnames, pnames_size);
9296
9297 // Count up the space needed for the result.
9298 uint32 num_results = 0;
9299 for (GLuint ii = 0; ii < count; ++ii) {
9300 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9301 if (num == 0) {
9302 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9303 "glGetMultipleCHROMIUM", enums[ii], "pname");
9304 return error::kNoError;
9305 }
9306 // Num will never be more than 4.
9307 DCHECK_LE(num, 4u);
9308 if (!SafeAddUint32(num_results, num, &num_results)) {
9309 return error::kOutOfBounds;
9310 }
9311 }
9312
9313 uint32 result_size = 0;
9314 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9315 return error::kOutOfBounds;
9316 }
9317
9318 if (result_size != static_cast<uint32>(c.size)) {
9319 LOCAL_SET_GL_ERROR(
9320 GL_INVALID_VALUE,
9321 "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
9322 return error::kNoError;
9323 }
9324
9325 GLint* results = GetSharedMemoryAs<GLint*>(
9326 c.results_shm_id, c.results_shm_offset, result_size);
9327 if (results == NULL) {
9328 return error::kOutOfBounds;
9329 }
9330
9331 // Check the results have been cleared in case the context was lost.
9332 for (uint32 ii = 0; ii < num_results; ++ii) {
9333 if (results[ii]) {
9334 return error::kInvalidArguments;
9335 }
9336 }
9337
9338 // Get each result.
9339 GLint* start = results;
9340 for (GLuint ii = 0; ii < count; ++ii) {
9341 GLsizei num_written = 0;
9342 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
9343 !GetHelper(enums[ii], results, &num_written)) {
9344 DoGetIntegerv(enums[ii], results);
9345 }
9346 results += num_written;
9347 }
9348
9349 // Just to verify. Should this be a DCHECK?
9350 if (static_cast<uint32>(results - start) != num_results) {
9351 return error::kOutOfBounds;
9352 }
9353
9354 return error::kNoError;
9355 }
9356
HandleGetProgramInfoCHROMIUM(uint32 immediate_data_size,const cmds::GetProgramInfoCHROMIUM & c)9357 error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
9358 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
9359 GLuint program_id = static_cast<GLuint>(c.program);
9360 uint32 bucket_id = c.bucket_id;
9361 Bucket* bucket = CreateBucket(bucket_id);
9362 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
9363 Program* program = NULL;
9364 program = GetProgram(program_id);
9365 if (!program || !program->IsValid()) {
9366 return error::kNoError;
9367 }
9368 program->GetProgramInfo(program_manager(), bucket);
9369 return error::kNoError;
9370 }
9371
GetContextLostReason()9372 error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9373 switch (reset_status_) {
9374 case GL_NO_ERROR:
9375 // TODO(kbr): improve the precision of the error code in this case.
9376 // Consider delegating to context for error code if MakeCurrent fails.
9377 return error::kUnknown;
9378 case GL_GUILTY_CONTEXT_RESET_ARB:
9379 return error::kGuilty;
9380 case GL_INNOCENT_CONTEXT_RESET_ARB:
9381 return error::kInnocent;
9382 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9383 return error::kUnknown;
9384 }
9385
9386 NOTREACHED();
9387 return error::kUnknown;
9388 }
9389
WasContextLost()9390 bool GLES2DecoderImpl::WasContextLost() {
9391 if (reset_status_ != GL_NO_ERROR) {
9392 return true;
9393 }
9394 if (context_->WasAllocatedUsingRobustnessExtension()) {
9395 GLenum status = GL_NO_ERROR;
9396 if (has_robustness_extension_)
9397 status = glGetGraphicsResetStatusARB();
9398 if (status != GL_NO_ERROR) {
9399 // The graphics card was reset. Signal a lost context to the application.
9400 reset_status_ = status;
9401 reset_by_robustness_extension_ = true;
9402 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
9403 << " context lost via ARB/EXT_robustness. Reset status = "
9404 << GLES2Util::GetStringEnum(status);
9405 return true;
9406 }
9407 }
9408 return false;
9409 }
9410
WasContextLostByRobustnessExtension()9411 bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9412 return WasContextLost() && reset_by_robustness_extension_;
9413 }
9414
LoseContext(uint32 reset_status)9415 void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9416 // Only loses the context once.
9417 if (reset_status_ != GL_NO_ERROR) {
9418 return;
9419 }
9420
9421 // Marks this context as lost.
9422 reset_status_ = reset_status;
9423 current_decoder_error_ = error::kLostContext;
9424 }
9425
HandleInsertSyncPointCHROMIUM(uint32 immediate_data_size,const cmds::InsertSyncPointCHROMIUM & c)9426 error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9427 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9428 return error::kUnknownCommand;
9429 }
9430
HandleWaitSyncPointCHROMIUM(uint32 immediate_data_size,const cmds::WaitSyncPointCHROMIUM & c)9431 error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
9432 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
9433 group_->mailbox_manager()->PullTextureUpdates();
9434 if (wait_sync_point_callback_.is_null())
9435 return error::kNoError;
9436
9437 return wait_sync_point_callback_.Run(c.sync_point) ?
9438 error::kNoError : error::kDeferCommandUntilLater;
9439 }
9440
HandleDiscardBackbufferCHROMIUM(uint32 immediate_data_size,const cmds::DiscardBackbufferCHROMIUM & c)9441 error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
9442 uint32 immediate_data_size, const cmds::DiscardBackbufferCHROMIUM& c) {
9443 if (surface_->DeferDraws())
9444 return error::kDeferCommandUntilLater;
9445 if (!surface_->SetBackbufferAllocation(false))
9446 return error::kLostContext;
9447 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9448 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9449 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9450 return error::kNoError;
9451 }
9452
GenQueriesEXTHelper(GLsizei n,const GLuint * client_ids)9453 bool GLES2DecoderImpl::GenQueriesEXTHelper(
9454 GLsizei n, const GLuint* client_ids) {
9455 for (GLsizei ii = 0; ii < n; ++ii) {
9456 if (query_manager_->GetQuery(client_ids[ii])) {
9457 return false;
9458 }
9459 }
9460 query_manager_->GenQueries(n, client_ids);
9461 return true;
9462 }
9463
DeleteQueriesEXTHelper(GLsizei n,const GLuint * client_ids)9464 void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9465 GLsizei n, const GLuint* client_ids) {
9466 for (GLsizei ii = 0; ii < n; ++ii) {
9467 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9468 if (query && !query->IsDeleted()) {
9469 ContextState::QueryMap::iterator it =
9470 state_.current_queries.find(query->target());
9471 if (it != state_.current_queries.end())
9472 state_.current_queries.erase(it);
9473
9474 query->Destroy(true);
9475 }
9476 query_manager_->RemoveQuery(client_ids[ii]);
9477 }
9478 }
9479
ProcessPendingQueries()9480 bool GLES2DecoderImpl::ProcessPendingQueries() {
9481 if (query_manager_.get() == NULL) {
9482 return false;
9483 }
9484 if (!query_manager_->ProcessPendingQueries()) {
9485 current_decoder_error_ = error::kOutOfBounds;
9486 }
9487 return query_manager_->HavePendingQueries();
9488 }
9489
9490 // Note that if there are no pending readpixels right now,
9491 // this function will call the callback immediately.
WaitForReadPixels(base::Closure callback)9492 void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9493 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9494 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9495 } else {
9496 callback.Run();
9497 }
9498 }
9499
ProcessPendingReadPixels()9500 void GLES2DecoderImpl::ProcessPendingReadPixels() {
9501 while (!pending_readpixel_fences_.empty() &&
9502 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9503 std::vector<base::Closure> callbacks =
9504 pending_readpixel_fences_.front()->callbacks;
9505 pending_readpixel_fences_.pop();
9506 for (size_t i = 0; i < callbacks.size(); i++) {
9507 callbacks[i].Run();
9508 }
9509 }
9510 }
9511
HasMoreIdleWork()9512 bool GLES2DecoderImpl::HasMoreIdleWork() {
9513 return !pending_readpixel_fences_.empty() ||
9514 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
9515 }
9516
PerformIdleWork()9517 void GLES2DecoderImpl::PerformIdleWork() {
9518 ProcessPendingReadPixels();
9519 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
9520 return;
9521 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
9522 ProcessFinishedAsyncTransfers();
9523 }
9524
HandleBeginQueryEXT(uint32 immediate_data_size,const cmds::BeginQueryEXT & c)9525 error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
9526 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
9527 GLenum target = static_cast<GLenum>(c.target);
9528 GLuint client_id = static_cast<GLuint>(c.id);
9529 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9530 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9531
9532 switch (target) {
9533 case GL_COMMANDS_ISSUED_CHROMIUM:
9534 case GL_LATENCY_QUERY_CHROMIUM:
9535 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9536 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
9537 case GL_GET_ERROR_QUERY_CHROMIUM:
9538 break;
9539 case GL_COMMANDS_COMPLETED_CHROMIUM:
9540 if (!features().chromium_sync_query) {
9541 LOCAL_SET_GL_ERROR(
9542 GL_INVALID_OPERATION, "glBeginQueryEXT",
9543 "not enabled for commands completed queries");
9544 return error::kNoError;
9545 }
9546 break;
9547 default:
9548 if (!features().occlusion_query_boolean) {
9549 LOCAL_SET_GL_ERROR(
9550 GL_INVALID_OPERATION, "glBeginQueryEXT",
9551 "not enabled for occlusion queries");
9552 return error::kNoError;
9553 }
9554 break;
9555 }
9556
9557 if (state_.current_queries.find(target) != state_.current_queries.end()) {
9558 LOCAL_SET_GL_ERROR(
9559 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
9560 return error::kNoError;
9561 }
9562
9563 if (client_id == 0) {
9564 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
9565 return error::kNoError;
9566 }
9567
9568 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9569 if (!query) {
9570 if (!query_manager_->IsValidQuery(client_id)) {
9571 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9572 "glBeginQueryEXT",
9573 "id not made by glGenQueriesEXT");
9574 return error::kNoError;
9575 }
9576 query = query_manager_->CreateQuery(
9577 target, client_id, sync_shm_id, sync_shm_offset);
9578 }
9579
9580 if (query->target() != target) {
9581 LOCAL_SET_GL_ERROR(
9582 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
9583 return error::kNoError;
9584 } else if (query->shm_id() != sync_shm_id ||
9585 query->shm_offset() != sync_shm_offset) {
9586 DLOG(ERROR) << "Shared memory used by query not the same as before";
9587 return error::kInvalidArguments;
9588 }
9589
9590 if (!query_manager_->BeginQuery(query)) {
9591 return error::kOutOfBounds;
9592 }
9593
9594 state_.current_queries[target] = query;
9595 return error::kNoError;
9596 }
9597
HandleEndQueryEXT(uint32 immediate_data_size,const cmds::EndQueryEXT & c)9598 error::Error GLES2DecoderImpl::HandleEndQueryEXT(
9599 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
9600 GLenum target = static_cast<GLenum>(c.target);
9601 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9602 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
9603
9604 if (it == state_.current_queries.end()) {
9605 LOCAL_SET_GL_ERROR(
9606 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
9607 return error::kNoError;
9608 }
9609
9610 QueryManager::Query* query = it->second.get();
9611 if (!query_manager_->EndQuery(query, submit_count)) {
9612 return error::kOutOfBounds;
9613 }
9614
9615 query_manager_->ProcessPendingTransferQueries();
9616
9617 state_.current_queries.erase(it);
9618 return error::kNoError;
9619 }
9620
GenVertexArraysOESHelper(GLsizei n,const GLuint * client_ids)9621 bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9622 GLsizei n, const GLuint* client_ids) {
9623 for (GLsizei ii = 0; ii < n; ++ii) {
9624 if (GetVertexAttribManager(client_ids[ii])) {
9625 return false;
9626 }
9627 }
9628
9629 if (!features().native_vertex_array_object) {
9630 // Emulated VAO
9631 for (GLsizei ii = 0; ii < n; ++ii) {
9632 CreateVertexAttribManager(client_ids[ii], 0, true);
9633 }
9634 } else {
9635 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
9636
9637 glGenVertexArraysOES(n, service_ids.get());
9638 for (GLsizei ii = 0; ii < n; ++ii) {
9639 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
9640 }
9641 }
9642
9643 return true;
9644 }
9645
DeleteVertexArraysOESHelper(GLsizei n,const GLuint * client_ids)9646 void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9647 GLsizei n, const GLuint* client_ids) {
9648 for (GLsizei ii = 0; ii < n; ++ii) {
9649 VertexAttribManager* vao =
9650 GetVertexAttribManager(client_ids[ii]);
9651 if (vao && !vao->IsDeleted()) {
9652 if (state_.vertex_attrib_manager.get() == vao) {
9653 DoBindVertexArrayOES(0);
9654 }
9655 RemoveVertexAttribManager(client_ids[ii]);
9656 }
9657 }
9658 }
9659
DoBindVertexArrayOES(GLuint client_id)9660 void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
9661 VertexAttribManager* vao = NULL;
9662 if (client_id != 0) {
9663 vao = GetVertexAttribManager(client_id);
9664 if (!vao) {
9665 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9666 // only allows names that have been previously generated. As such, we do
9667 // not generate new names here.
9668 LOCAL_SET_GL_ERROR(
9669 GL_INVALID_OPERATION,
9670 "glBindVertexArrayOES", "bad vertex array id.");
9671 current_decoder_error_ = error::kNoError;
9672 return;
9673 }
9674 } else {
9675 vao = state_.default_vertex_attrib_manager.get();
9676 }
9677
9678 // Only set the VAO state if it's changed
9679 if (state_.vertex_attrib_manager.get() != vao) {
9680 state_.vertex_attrib_manager = vao;
9681 if (!features().native_vertex_array_object) {
9682 EmulateVertexArrayState();
9683 } else {
9684 GLuint service_id = vao->service_id();
9685 glBindVertexArrayOES(service_id);
9686 }
9687 }
9688 }
9689
9690 // Used when OES_vertex_array_object isn't natively supported
EmulateVertexArrayState()9691 void GLES2DecoderImpl::EmulateVertexArrayState() {
9692 // Setup the Vertex attribute state
9693 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9694 RestoreStateForAttrib(vv, true);
9695 }
9696
9697 // Setup the element buffer
9698 Buffer* element_array_buffer =
9699 state_.vertex_attrib_manager->element_array_buffer();
9700 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9701 element_array_buffer ? element_array_buffer->service_id() : 0);
9702 }
9703
DoIsVertexArrayOES(GLuint client_id)9704 bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
9705 const VertexAttribManager* vao =
9706 GetVertexAttribManager(client_id);
9707 return vao && vao->IsValid() && !vao->IsDeleted();
9708 }
9709
9710 #if defined(OS_MACOSX)
ReleaseIOSurfaceForTexture(GLuint texture_id)9711 void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9712 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9713 texture_id);
9714 if (it != texture_to_io_surface_map_.end()) {
9715 // Found a previous IOSurface bound to this texture; release it.
9716 IOSurfaceRef surface = it->second;
9717 CFRelease(surface);
9718 texture_to_io_surface_map_.erase(it);
9719 }
9720 }
9721 #endif
9722
DoTexImageIOSurface2DCHROMIUM(GLenum target,GLsizei width,GLsizei height,GLuint io_surface_id,GLuint plane)9723 void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9724 GLenum target, GLsizei width, GLsizei height,
9725 GLuint io_surface_id, GLuint plane) {
9726 #if defined(OS_MACOSX)
9727 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
9728 LOCAL_SET_GL_ERROR(
9729 GL_INVALID_OPERATION,
9730 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
9731 return;
9732 }
9733
9734 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9735 // This might be supported in the future, and if we could require
9736 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9737 // could delete a lot of code. For now, perform strict validation so we
9738 // know what's going on.
9739 LOCAL_SET_GL_ERROR(
9740 GL_INVALID_OPERATION,
9741 "glTexImageIOSurface2DCHROMIUM",
9742 "requires TEXTURE_RECTANGLE_ARB target");
9743 return;
9744 }
9745
9746 // Default target might be conceptually valid, but disallow it to avoid
9747 // accidents.
9748 TextureRef* texture_ref =
9749 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
9750 if (!texture_ref) {
9751 LOCAL_SET_GL_ERROR(
9752 GL_INVALID_OPERATION,
9753 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
9754 return;
9755 }
9756
9757 // Look up the new IOSurface. Note that because of asynchrony
9758 // between processes this might fail; during live resizing the
9759 // plugin process might allocate and release an IOSurface before
9760 // this process gets a chance to look it up. Hold on to any old
9761 // IOSurface in this case.
9762 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
9763 if (!surface) {
9764 LOCAL_SET_GL_ERROR(
9765 GL_INVALID_OPERATION,
9766 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
9767 return;
9768 }
9769
9770 // Release any IOSurface previously bound to this texture.
9771 ReleaseIOSurfaceForTexture(texture_ref->service_id());
9772
9773 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9774 texture_to_io_surface_map_.insert(
9775 std::make_pair(texture_ref->service_id(), surface));
9776
9777 CGLContextObj context =
9778 static_cast<CGLContextObj>(context_->GetHandle());
9779
9780 CGLError err = CGLTexImageIOSurface2D(
9781 context,
9782 target,
9783 GL_RGBA,
9784 width,
9785 height,
9786 GL_BGRA,
9787 GL_UNSIGNED_INT_8_8_8_8_REV,
9788 surface,
9789 plane);
9790
9791 if (err != kCGLNoError) {
9792 LOCAL_SET_GL_ERROR(
9793 GL_INVALID_OPERATION,
9794 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
9795 return;
9796 }
9797
9798 texture_manager()->SetLevelInfo(
9799 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
9800 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9801
9802 #else
9803 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9804 "glTexImageIOSurface2DCHROMIUM", "not supported.");
9805 #endif
9806 }
9807
ExtractFormatFromStorageFormat(GLenum internalformat)9808 static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9809 switch (internalformat) {
9810 case GL_RGB565:
9811 return GL_RGB;
9812 case GL_RGBA4:
9813 return GL_RGBA;
9814 case GL_RGB5_A1:
9815 return GL_RGBA;
9816 case GL_RGB8_OES:
9817 return GL_RGB;
9818 case GL_RGBA8_OES:
9819 return GL_RGBA;
9820 case GL_LUMINANCE8_ALPHA8_EXT:
9821 return GL_LUMINANCE_ALPHA;
9822 case GL_LUMINANCE8_EXT:
9823 return GL_LUMINANCE;
9824 case GL_ALPHA8_EXT:
9825 return GL_ALPHA;
9826 case GL_RGBA32F_EXT:
9827 return GL_RGBA;
9828 case GL_RGB32F_EXT:
9829 return GL_RGB;
9830 case GL_ALPHA32F_EXT:
9831 return GL_ALPHA;
9832 case GL_LUMINANCE32F_EXT:
9833 return GL_LUMINANCE;
9834 case GL_LUMINANCE_ALPHA32F_EXT:
9835 return GL_LUMINANCE_ALPHA;
9836 case GL_RGBA16F_EXT:
9837 return GL_RGBA;
9838 case GL_RGB16F_EXT:
9839 return GL_RGB;
9840 case GL_ALPHA16F_EXT:
9841 return GL_ALPHA;
9842 case GL_LUMINANCE16F_EXT:
9843 return GL_LUMINANCE;
9844 case GL_LUMINANCE_ALPHA16F_EXT:
9845 return GL_LUMINANCE_ALPHA;
9846 case GL_BGRA8_EXT:
9847 return GL_BGRA_EXT;
9848 default:
9849 return GL_NONE;
9850 }
9851 }
9852
DoCopyTextureCHROMIUM(GLenum target,GLuint source_id,GLuint dest_id,GLint level,GLenum internal_format,GLenum dest_type)9853 void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
9854 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
9855 GLenum internal_format, GLenum dest_type) {
9856 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
9857
9858 TextureRef* dest_texture_ref = GetTexture(dest_id);
9859 TextureRef* source_texture_ref = GetTexture(source_id);
9860
9861 if (!source_texture_ref || !dest_texture_ref) {
9862 LOCAL_SET_GL_ERROR(
9863 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
9864 return;
9865 }
9866
9867 if (GL_TEXTURE_2D != target) {
9868 LOCAL_SET_GL_ERROR(
9869 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
9870 return;
9871 }
9872
9873 Texture* source_texture = source_texture_ref->texture();
9874 Texture* dest_texture = dest_texture_ref->texture();
9875 if (dest_texture->target() != GL_TEXTURE_2D ||
9876 (source_texture->target() != GL_TEXTURE_2D &&
9877 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
9878 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
9879 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9880 "glCopyTextureCHROMIUM",
9881 "invalid texture target binding");
9882 return;
9883 }
9884
9885 int source_width, source_height, dest_width, dest_height;
9886
9887 gfx::GLImage* image =
9888 source_texture->GetLevelImage(source_texture->target(), 0);
9889 if (image) {
9890 gfx::Size size = image->GetSize();
9891 source_width = size.width();
9892 source_height = size.height();
9893 if (source_width <= 0 || source_height <= 0) {
9894 LOCAL_SET_GL_ERROR(
9895 GL_INVALID_VALUE,
9896 "glCopyTextureChromium", "invalid image size");
9897 return;
9898 }
9899 } else {
9900 if (!source_texture->GetLevelSize(
9901 source_texture->target(), 0, &source_width, &source_height)) {
9902 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9903 "glCopyTextureChromium",
9904 "source texture has no level 0");
9905 return;
9906 }
9907
9908 // Check that this type of texture is allowed.
9909 if (!texture_manager()->ValidForTarget(
9910 source_texture->target(), level, source_width, source_height, 1)) {
9911 LOCAL_SET_GL_ERROR(
9912 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
9913 return;
9914 }
9915 }
9916
9917 // Clear the source texture if necessary.
9918 if (!texture_manager()->ClearTextureLevel(
9919 this, source_texture_ref, source_texture->target(), 0)) {
9920 LOCAL_SET_GL_ERROR(
9921 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
9922 return;
9923 }
9924
9925 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9926 // needed because it takes 10s of milliseconds to initialize.
9927 if (!copy_texture_CHROMIUM_.get()) {
9928 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
9929 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
9930 copy_texture_CHROMIUM_->Initialize(this);
9931 RestoreCurrentFramebufferBindings();
9932 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
9933 return;
9934 }
9935
9936 GLenum dest_type_previous;
9937 GLenum dest_internal_format;
9938 bool dest_level_defined = dest_texture->GetLevelSize(
9939 GL_TEXTURE_2D, level, &dest_width, &dest_height);
9940
9941 if (dest_level_defined) {
9942 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
9943 &dest_internal_format);
9944 }
9945
9946 // Resize the destination texture to the dimensions of the source texture.
9947 if (!dest_level_defined || dest_width != source_width ||
9948 dest_height != source_height ||
9949 dest_internal_format != internal_format ||
9950 dest_type_previous != dest_type) {
9951 // Ensure that the glTexImage2D succeeds.
9952 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
9953 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
9954 glTexImage2D(
9955 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
9956 0, internal_format, dest_type, NULL);
9957 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
9958 if (error != GL_NO_ERROR) {
9959 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
9960 return;
9961 }
9962
9963 texture_manager()->SetLevelInfo(
9964 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
9965 source_height, 1, 0, internal_format, dest_type, true);
9966 } else {
9967 texture_manager()->SetLevelCleared(
9968 dest_texture_ref, GL_TEXTURE_2D, level, true);
9969 }
9970
9971 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
9972 ScopedModifyPixels modify(dest_texture_ref);
9973
9974 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9975 // before presenting.
9976 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9977 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9978 // instead of using default matrix crbug.com/226218.
9979 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9980 0.0f, 1.0f, 0.0f, 0.0f,
9981 0.0f, 0.0f, 1.0f, 0.0f,
9982 0.0f, 0.0f, 0.0f, 1.0f};
9983 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9984 this,
9985 source_texture->target(),
9986 dest_texture->target(),
9987 source_texture->service_id(),
9988 dest_texture->service_id(), level,
9989 source_width, source_height,
9990 unpack_flip_y_,
9991 unpack_premultiply_alpha_,
9992 unpack_unpremultiply_alpha_,
9993 default_matrix);
9994 } else {
9995 copy_texture_CHROMIUM_->DoCopyTexture(
9996 this,
9997 source_texture->target(),
9998 dest_texture->target(),
9999 source_texture->service_id(),
10000 dest_texture->service_id(), level,
10001 source_width, source_height,
10002 unpack_flip_y_,
10003 unpack_premultiply_alpha_,
10004 unpack_unpremultiply_alpha_);
10005 }
10006
10007 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
10008 }
10009
ExtractTypeFromStorageFormat(GLenum internalformat)10010 static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10011 switch (internalformat) {
10012 case GL_RGB565:
10013 return GL_UNSIGNED_SHORT_5_6_5;
10014 case GL_RGBA4:
10015 return GL_UNSIGNED_SHORT_4_4_4_4;
10016 case GL_RGB5_A1:
10017 return GL_UNSIGNED_SHORT_5_5_5_1;
10018 case GL_RGB8_OES:
10019 return GL_UNSIGNED_BYTE;
10020 case GL_RGBA8_OES:
10021 return GL_UNSIGNED_BYTE;
10022 case GL_LUMINANCE8_ALPHA8_EXT:
10023 return GL_UNSIGNED_BYTE;
10024 case GL_LUMINANCE8_EXT:
10025 return GL_UNSIGNED_BYTE;
10026 case GL_ALPHA8_EXT:
10027 return GL_UNSIGNED_BYTE;
10028 case GL_RGBA32F_EXT:
10029 return GL_FLOAT;
10030 case GL_RGB32F_EXT:
10031 return GL_FLOAT;
10032 case GL_ALPHA32F_EXT:
10033 return GL_FLOAT;
10034 case GL_LUMINANCE32F_EXT:
10035 return GL_FLOAT;
10036 case GL_LUMINANCE_ALPHA32F_EXT:
10037 return GL_FLOAT;
10038 case GL_RGBA16F_EXT:
10039 return GL_HALF_FLOAT_OES;
10040 case GL_RGB16F_EXT:
10041 return GL_HALF_FLOAT_OES;
10042 case GL_ALPHA16F_EXT:
10043 return GL_HALF_FLOAT_OES;
10044 case GL_LUMINANCE16F_EXT:
10045 return GL_HALF_FLOAT_OES;
10046 case GL_LUMINANCE_ALPHA16F_EXT:
10047 return GL_HALF_FLOAT_OES;
10048 case GL_BGRA8_EXT:
10049 return GL_UNSIGNED_BYTE;
10050 default:
10051 return GL_NONE;
10052 }
10053 }
10054
DoTexStorage2DEXT(GLenum target,GLint levels,GLenum internal_format,GLsizei width,GLsizei height)10055 void GLES2DecoderImpl::DoTexStorage2DEXT(
10056 GLenum target,
10057 GLint levels,
10058 GLenum internal_format,
10059 GLsizei width,
10060 GLsizei height) {
10061 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
10062 "width", width, "height", height);
10063 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
10064 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
10065 LOCAL_SET_GL_ERROR(
10066 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
10067 return;
10068 }
10069 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10070 &state_, target);
10071 if (!texture_ref) {
10072 LOCAL_SET_GL_ERROR(
10073 GL_INVALID_OPERATION,
10074 "glTexStorage2DEXT", "unknown texture for target");
10075 return;
10076 }
10077 Texture* texture = texture_ref->texture();
10078 if (texture->IsAttachedToFramebuffer()) {
10079 framebuffer_state_.clear_state_dirty = true;
10080 }
10081 if (texture->IsImmutable()) {
10082 LOCAL_SET_GL_ERROR(
10083 GL_INVALID_OPERATION,
10084 "glTexStorage2DEXT", "texture is immutable");
10085 return;
10086 }
10087
10088 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10089 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10090
10091 {
10092 GLsizei level_width = width;
10093 GLsizei level_height = height;
10094 uint32 estimated_size = 0;
10095 for (int ii = 0; ii < levels; ++ii) {
10096 uint32 level_size = 0;
10097 if (!GLES2Util::ComputeImageDataSizes(
10098 level_width, level_height, format, type, state_.unpack_alignment,
10099 &estimated_size, NULL, NULL) ||
10100 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
10101 LOCAL_SET_GL_ERROR(
10102 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
10103 return;
10104 }
10105 level_width = std::max(1, level_width >> 1);
10106 level_height = std::max(1, level_height >> 1);
10107 }
10108 if (!EnsureGPUMemoryAvailable(estimated_size)) {
10109 LOCAL_SET_GL_ERROR(
10110 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
10111 return;
10112 }
10113 }
10114
10115 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
10116 glTexStorage2DEXT(target, levels, internal_format, width, height);
10117 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
10118 if (error == GL_NO_ERROR) {
10119 GLsizei level_width = width;
10120 GLsizei level_height = height;
10121 for (int ii = 0; ii < levels; ++ii) {
10122 texture_manager()->SetLevelInfo(
10123 texture_ref, target, ii, format,
10124 level_width, level_height, 1, 0, format, type, false);
10125 level_width = std::max(1, level_width >> 1);
10126 level_height = std::max(1, level_height >> 1);
10127 }
10128 texture->SetImmutable(true);
10129 }
10130 }
10131
HandleGenMailboxCHROMIUM(uint32 immediate_data_size,const cmds::GenMailboxCHROMIUM & c)10132 error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
10133 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
10134 return error::kUnknownCommand;
10135 }
10136
DoProduceTextureCHROMIUM(GLenum target,const GLbyte * data)10137 void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
10138 const GLbyte* data) {
10139 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
10140 "context", logger_.GetLogPrefix(),
10141 "mailbox[0]", static_cast<unsigned char>(data[0]));
10142
10143 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10144 &state_, target);
10145 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
10146 }
10147
DoProduceTextureDirectCHROMIUM(GLuint client_id,GLenum target,const GLbyte * data)10148 void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
10149 GLenum target, const GLbyte* data) {
10150 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
10151 "context", logger_.GetLogPrefix(),
10152 "mailbox[0]", static_cast<unsigned char>(data[0]));
10153
10154 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
10155 target, data);
10156 }
10157
ProduceTextureRef(std::string func_name,TextureRef * texture_ref,GLenum target,const GLbyte * data)10158 void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
10159 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
10160 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10161 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
10162 "mailbox that was not generated by "
10163 "GenMailboxCHROMIUM.";
10164
10165 if (!texture_ref) {
10166 LOCAL_SET_GL_ERROR(
10167 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
10168 return;
10169 }
10170
10171 Texture* produced = texture_manager()->Produce(texture_ref);
10172 if (!produced) {
10173 LOCAL_SET_GL_ERROR(
10174 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
10175 return;
10176 }
10177
10178 if (produced->target() != target) {
10179 LOCAL_SET_GL_ERROR(
10180 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
10181 return;
10182 }
10183
10184 group_->mailbox_manager()->ProduceTexture(target, mailbox, produced);
10185 }
10186
DoConsumeTextureCHROMIUM(GLenum target,const GLbyte * data)10187 void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
10188 const GLbyte* data) {
10189 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
10190 "context", logger_.GetLogPrefix(),
10191 "mailbox[0]", static_cast<unsigned char>(data[0]));
10192 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10193 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10194 "mailbox that was not generated by "
10195 "GenMailboxCHROMIUM.";
10196
10197 scoped_refptr<TextureRef> texture_ref =
10198 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
10199 if (!texture_ref.get()) {
10200 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10201 "glConsumeTextureCHROMIUM",
10202 "unknown texture for target");
10203 return;
10204 }
10205 GLuint client_id = texture_ref->client_id();
10206 if (!client_id) {
10207 LOCAL_SET_GL_ERROR(
10208 GL_INVALID_OPERATION,
10209 "glConsumeTextureCHROMIUM", "unknown texture for target");
10210 return;
10211 }
10212 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
10213 if (!texture) {
10214 LOCAL_SET_GL_ERROR(
10215 GL_INVALID_OPERATION,
10216 "glConsumeTextureCHROMIUM", "invalid mailbox name");
10217 return;
10218 }
10219 if (texture->target() != target) {
10220 LOCAL_SET_GL_ERROR(
10221 GL_INVALID_OPERATION,
10222 "glConsumeTextureCHROMIUM", "invalid target");
10223 return;
10224 }
10225
10226 DeleteTexturesHelper(1, &client_id);
10227 texture_ref = texture_manager()->Consume(client_id, texture);
10228 glBindTexture(target, texture_ref->service_id());
10229
10230 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10231 unit.bind_target = target;
10232 switch (target) {
10233 case GL_TEXTURE_2D:
10234 unit.bound_texture_2d = texture_ref;
10235 break;
10236 case GL_TEXTURE_CUBE_MAP:
10237 unit.bound_texture_cube_map = texture_ref;
10238 break;
10239 case GL_TEXTURE_EXTERNAL_OES:
10240 unit.bound_texture_external_oes = texture_ref;
10241 break;
10242 case GL_TEXTURE_RECTANGLE_ARB:
10243 unit.bound_texture_rectangle_arb = texture_ref;
10244 break;
10245 default:
10246 NOTREACHED(); // Validation should prevent us getting here.
10247 break;
10248 }
10249 }
10250
HandleCreateAndConsumeTextureCHROMIUMImmediate(uint32_t immediate_data_size,const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate & c)10251 error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
10252 uint32_t immediate_data_size,
10253 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c) {
10254 GLenum target = static_cast<GLenum>(c.target);
10255 uint32_t data_size;
10256 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
10257 return error::kOutOfBounds;
10258 }
10259 if (data_size > immediate_data_size) {
10260 return error::kOutOfBounds;
10261 }
10262 const GLbyte* mailbox =
10263 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
10264 if (!validators_->texture_bind_target.IsValid(target)) {
10265 LOCAL_SET_GL_ERROR_INVALID_ENUM(
10266 "glCreateAndConsumeTextureCHROMIUM", target, "target");
10267 return error::kNoError;
10268 }
10269 if (mailbox == NULL) {
10270 return error::kOutOfBounds;
10271 }
10272 uint32_t client_id = c.client_id;
10273 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
10274 return error::kNoError;
10275 }
10276
DoCreateAndConsumeTextureCHROMIUM(GLenum target,const GLbyte * data,GLuint client_id)10277 void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
10278 const GLbyte* data, GLuint client_id) {
10279 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
10280 "context", logger_.GetLogPrefix(),
10281 "mailbox[0]", static_cast<unsigned char>(data[0]));
10282 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10283 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
10284 "passed a mailbox that was not "
10285 "generated by GenMailboxCHROMIUM.";
10286
10287 TextureRef* texture_ref = GetTexture(client_id);
10288 if (texture_ref) {
10289 LOCAL_SET_GL_ERROR(
10290 GL_INVALID_OPERATION,
10291 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
10292 return;
10293 }
10294 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
10295 if (!texture) {
10296 LOCAL_SET_GL_ERROR(
10297 GL_INVALID_OPERATION,
10298 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
10299 return;
10300 }
10301 if (texture->target() != target) {
10302 LOCAL_SET_GL_ERROR(
10303 GL_INVALID_OPERATION,
10304 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
10305 return;
10306 }
10307
10308 IdAllocatorInterface* id_allocator =
10309 group_->GetIdAllocator(id_namespaces::kTextures);
10310 id_allocator->MarkAsUsed(client_id);
10311
10312 texture_ref = texture_manager()->Consume(client_id, texture);
10313 }
10314
DoInsertEventMarkerEXT(GLsizei length,const GLchar * marker)10315 void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10316 GLsizei length, const GLchar* marker) {
10317 if (!marker) {
10318 marker = "";
10319 }
10320 debug_marker_manager_.SetMarker(
10321 length ? std::string(marker, length) : std::string(marker));
10322 }
10323
DoPushGroupMarkerEXT(GLsizei length,const GLchar * marker)10324 void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10325 GLsizei length, const GLchar* marker) {
10326 if (!marker) {
10327 marker = "";
10328 }
10329 std::string name = length ? std::string(marker, length) : std::string(marker);
10330 debug_marker_manager_.PushGroup(name);
10331 gpu_tracer_->Begin(name, kTraceGroupMarker);
10332 }
10333
DoPopGroupMarkerEXT(void)10334 void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10335 debug_marker_manager_.PopGroup();
10336 gpu_tracer_->End(kTraceGroupMarker);
10337 }
10338
DoBindTexImage2DCHROMIUM(GLenum target,GLint image_id)10339 void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10340 GLenum target, GLint image_id) {
10341 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
10342
10343 if (target == GL_TEXTURE_CUBE_MAP) {
10344 LOCAL_SET_GL_ERROR(
10345 GL_INVALID_ENUM,
10346 "glBindTexImage2DCHROMIUM", "invalid target");
10347 return;
10348 }
10349
10350 // Default target might be conceptually valid, but disallow it to avoid
10351 // accidents.
10352 TextureRef* texture_ref =
10353 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
10354 if (!texture_ref) {
10355 LOCAL_SET_GL_ERROR(
10356 GL_INVALID_OPERATION,
10357 "glBindTexImage2DCHROMIUM", "no texture bound");
10358 return;
10359 }
10360
10361 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10362 if (!gl_image) {
10363 LOCAL_SET_GL_ERROR(
10364 GL_INVALID_OPERATION,
10365 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
10366 return;
10367 }
10368
10369 {
10370 ScopedGLErrorSuppressor suppressor(
10371 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
10372 if (!gl_image->BindTexImage(target)) {
10373 LOCAL_SET_GL_ERROR(
10374 GL_INVALID_OPERATION,
10375 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10376 return;
10377 }
10378 }
10379
10380 gfx::Size size = gl_image->GetSize();
10381 texture_manager()->SetLevelInfo(
10382 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
10383 GL_RGBA, GL_UNSIGNED_BYTE, true);
10384 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
10385 }
10386
DoReleaseTexImage2DCHROMIUM(GLenum target,GLint image_id)10387 void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10388 GLenum target, GLint image_id) {
10389 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
10390
10391 // Default target might be conceptually valid, but disallow it to avoid
10392 // accidents.
10393 TextureRef* texture_ref =
10394 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
10395 if (!texture_ref) {
10396 LOCAL_SET_GL_ERROR(
10397 GL_INVALID_OPERATION,
10398 "glReleaseTexImage2DCHROMIUM", "no texture bound");
10399 return;
10400 }
10401
10402 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10403 if (!gl_image) {
10404 LOCAL_SET_GL_ERROR(
10405 GL_INVALID_OPERATION,
10406 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
10407 return;
10408 }
10409
10410 // Do nothing when image is not currently bound.
10411 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
10412 return;
10413
10414 {
10415 ScopedGLErrorSuppressor suppressor(
10416 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
10417 gl_image->ReleaseTexImage(target);
10418 }
10419
10420 texture_manager()->SetLevelInfo(
10421 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
10422 GL_RGBA, GL_UNSIGNED_BYTE, false);
10423 }
10424
HandleTraceBeginCHROMIUM(uint32 immediate_data_size,const cmds::TraceBeginCHROMIUM & c)10425 error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
10426 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
10427 Bucket* bucket = GetBucket(c.bucket_id);
10428 if (!bucket || bucket->size() == 0) {
10429 return error::kInvalidArguments;
10430 }
10431 std::string command_name;
10432 if (!bucket->GetAsString(&command_name)) {
10433 return error::kInvalidArguments;
10434 }
10435 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
10436 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
10437 LOCAL_SET_GL_ERROR(
10438 GL_INVALID_OPERATION,
10439 "glTraceBeginCHROMIUM", "unable to create begin trace");
10440 return error::kNoError;
10441 }
10442 return error::kNoError;
10443 }
10444
DoTraceEndCHROMIUM()10445 void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
10446 if (gpu_tracer_->CurrentName().empty()) {
10447 LOCAL_SET_GL_ERROR(
10448 GL_INVALID_OPERATION,
10449 "glTraceEndCHROMIUM", "no trace begin found");
10450 return;
10451 }
10452 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
10453 gpu_tracer_->End(kTraceCHROMIUM);
10454 }
10455
DoDrawBuffersEXT(GLsizei count,const GLenum * bufs)10456 void GLES2DecoderImpl::DoDrawBuffersEXT(
10457 GLsizei count, const GLenum* bufs) {
10458 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10459 LOCAL_SET_GL_ERROR(
10460 GL_INVALID_VALUE,
10461 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10462 return;
10463 }
10464
10465 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10466 if (framebuffer) {
10467 for (GLsizei i = 0; i < count; ++i) {
10468 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10469 bufs[i] != GL_NONE) {
10470 LOCAL_SET_GL_ERROR(
10471 GL_INVALID_OPERATION,
10472 "glDrawBuffersEXT",
10473 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10474 return;
10475 }
10476 }
10477 glDrawBuffersARB(count, bufs);
10478 framebuffer->SetDrawBuffers(count, bufs);
10479 } else { // backbuffer
10480 if (count > 1 ||
10481 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10482 LOCAL_SET_GL_ERROR(
10483 GL_INVALID_OPERATION,
10484 "glDrawBuffersEXT",
10485 "more than one buffer or bufs not GL_NONE or GL_BACK");
10486 return;
10487 }
10488 GLenum mapped_buf = bufs[0];
10489 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10490 bufs[0] == GL_BACK) {
10491 mapped_buf = GL_COLOR_ATTACHMENT0;
10492 }
10493 glDrawBuffersARB(count, &mapped_buf);
10494 group_->set_draw_buffer(bufs[0]);
10495 }
10496 }
10497
DoLoseContextCHROMIUM(GLenum current,GLenum other)10498 void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
10499 group_->LoseContexts(other);
10500 reset_status_ = current;
10501 current_decoder_error_ = error::kLostContext;
10502 }
10503
ValidateAsyncTransfer(const char * function_name,TextureRef * texture_ref,GLenum target,GLint level,const void * data)10504 bool GLES2DecoderImpl::ValidateAsyncTransfer(
10505 const char* function_name,
10506 TextureRef* texture_ref,
10507 GLenum target,
10508 GLint level,
10509 const void * data) {
10510 // We only support async uploads to 2D textures for now.
10511 if (GL_TEXTURE_2D != target) {
10512 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
10513 return false;
10514 }
10515 // We only support uploads to level zero for now.
10516 if (level != 0) {
10517 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
10518 return false;
10519 }
10520 // A transfer buffer must be bound, even for asyncTexImage2D.
10521 if (data == NULL) {
10522 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
10523 return false;
10524 }
10525 // We only support one async transfer in progress.
10526 if (!texture_ref ||
10527 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
10528 LOCAL_SET_GL_ERROR(
10529 GL_INVALID_OPERATION,
10530 function_name, "transfer already in progress");
10531 return false;
10532 }
10533 return true;
10534 }
10535
AsyncUploadTokenCompletionClosure(uint32 async_upload_token,uint32 sync_data_shm_id,uint32 sync_data_shm_offset)10536 base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
10537 uint32 async_upload_token,
10538 uint32 sync_data_shm_id,
10539 uint32 sync_data_shm_offset) {
10540 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
10541 if (!buffer || !buffer->GetDataAddress(sync_data_shm_offset,
10542 sizeof(AsyncUploadSync)))
10543 return base::Closure();
10544
10545 AsyncMemoryParams mem_params(buffer,
10546 sync_data_shm_offset,
10547 sizeof(AsyncUploadSync));
10548
10549 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
10550 new AsyncUploadTokenCompletionObserver(async_upload_token));
10551
10552 return base::Bind(
10553 &AsyncPixelTransferManager::AsyncNotifyCompletion,
10554 base::Unretained(GetAsyncPixelTransferManager()),
10555 mem_params,
10556 observer);
10557 }
10558
HandleAsyncTexImage2DCHROMIUM(uint32 immediate_data_size,const cmds::AsyncTexImage2DCHROMIUM & c)10559 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
10560 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
10561 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
10562 GLenum target = static_cast<GLenum>(c.target);
10563 GLint level = static_cast<GLint>(c.level);
10564 GLenum internal_format = static_cast<GLenum>(c.internalformat);
10565 GLsizei width = static_cast<GLsizei>(c.width);
10566 GLsizei height = static_cast<GLsizei>(c.height);
10567 GLint border = static_cast<GLint>(c.border);
10568 GLenum format = static_cast<GLenum>(c.format);
10569 GLenum type = static_cast<GLenum>(c.type);
10570 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10571 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10572 uint32 pixels_size;
10573 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
10574 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
10575 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10576
10577 base::ScopedClosureRunner scoped_completion_callback;
10578 if (async_upload_token) {
10579 base::Closure completion_closure =
10580 AsyncUploadTokenCompletionClosure(async_upload_token,
10581 sync_data_shm_id,
10582 sync_data_shm_offset);
10583 if (completion_closure.is_null())
10584 return error::kInvalidArguments;
10585
10586 scoped_completion_callback.Reset(completion_closure);
10587 }
10588
10589 // TODO(epenner): Move this and copies of this memory validation
10590 // into ValidateTexImage2D step.
10591 if (!GLES2Util::ComputeImageDataSizes(
10592 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10593 NULL)) {
10594 return error::kOutOfBounds;
10595 }
10596 const void* pixels = NULL;
10597 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10598 pixels = GetSharedMemoryAs<const void*>(
10599 pixels_shm_id, pixels_shm_offset, pixels_size);
10600 if (!pixels) {
10601 return error::kOutOfBounds;
10602 }
10603 }
10604
10605 TextureManager::DoTextImage2DArguments args = {
10606 target, level, internal_format, width, height, border, format, type,
10607 pixels, pixels_size};
10608 TextureRef* texture_ref;
10609 // All the normal glTexSubImage2D validation.
10610 if (!texture_manager()->ValidateTexImage2D(
10611 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
10612 return error::kNoError;
10613 }
10614
10615 // Extra async validation.
10616 Texture* texture = texture_ref->texture();
10617 if (!ValidateAsyncTransfer(
10618 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
10619 return error::kNoError;
10620
10621 // Don't allow async redefinition of a textures.
10622 if (texture->IsDefined()) {
10623 LOCAL_SET_GL_ERROR(
10624 GL_INVALID_OPERATION,
10625 "glAsyncTexImage2DCHROMIUM", "already defined");
10626 return error::kNoError;
10627 }
10628
10629 if (!EnsureGPUMemoryAvailable(pixels_size)) {
10630 LOCAL_SET_GL_ERROR(
10631 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
10632 return error::kNoError;
10633 }
10634
10635 // Setup the parameters.
10636 AsyncTexImage2DParams tex_params = {
10637 target, level, static_cast<GLenum>(internal_format),
10638 width, height, border, format, type};
10639 AsyncMemoryParams mem_params(
10640 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
10641
10642 // Set up the async state if needed, and make the texture
10643 // immutable so the async state stays valid. The level info
10644 // is set up lazily when the transfer completes.
10645 AsyncPixelTransferDelegate* delegate =
10646 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
10647 tex_params);
10648 texture->SetImmutable(true);
10649
10650 delegate->AsyncTexImage2D(
10651 tex_params,
10652 mem_params,
10653 base::Bind(&TextureManager::SetLevelInfoFromParams,
10654 // The callback is only invoked if the transfer delegate still
10655 // exists, which implies through manager->texture_ref->state
10656 // ownership that both of these pointers are valid.
10657 base::Unretained(texture_manager()),
10658 base::Unretained(texture_ref),
10659 tex_params));
10660 return error::kNoError;
10661 }
10662
HandleAsyncTexSubImage2DCHROMIUM(uint32 immediate_data_size,const cmds::AsyncTexSubImage2DCHROMIUM & c)10663 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
10664 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
10665 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
10666 GLenum target = static_cast<GLenum>(c.target);
10667 GLint level = static_cast<GLint>(c.level);
10668 GLint xoffset = static_cast<GLint>(c.xoffset);
10669 GLint yoffset = static_cast<GLint>(c.yoffset);
10670 GLsizei width = static_cast<GLsizei>(c.width);
10671 GLsizei height = static_cast<GLsizei>(c.height);
10672 GLenum format = static_cast<GLenum>(c.format);
10673 GLenum type = static_cast<GLenum>(c.type);
10674 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
10675 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
10676 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10677
10678 base::ScopedClosureRunner scoped_completion_callback;
10679 if (async_upload_token) {
10680 base::Closure completion_closure =
10681 AsyncUploadTokenCompletionClosure(async_upload_token,
10682 sync_data_shm_id,
10683 sync_data_shm_offset);
10684 if (completion_closure.is_null())
10685 return error::kInvalidArguments;
10686
10687 scoped_completion_callback.Reset(completion_closure);
10688 }
10689
10690 // TODO(epenner): Move this and copies of this memory validation
10691 // into ValidateTexSubImage2D step.
10692 uint32 data_size;
10693 if (!GLES2Util::ComputeImageDataSizes(
10694 width, height, format, type, state_.unpack_alignment, &data_size,
10695 NULL, NULL)) {
10696 return error::kOutOfBounds;
10697 }
10698 const void* pixels = GetSharedMemoryAs<const void*>(
10699 c.data_shm_id, c.data_shm_offset, data_size);
10700
10701 // All the normal glTexSubImage2D validation.
10702 error::Error error = error::kNoError;
10703 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10704 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10705 return error;
10706 }
10707
10708 // Extra async validation.
10709 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10710 &state_, target);
10711 Texture* texture = texture_ref->texture();
10712 if (!ValidateAsyncTransfer(
10713 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
10714 return error::kNoError;
10715
10716 // Guarantee async textures are always 'cleared' as follows:
10717 // - AsyncTexImage2D can not redefine an existing texture
10718 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10719 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10720 // - Textures become immutable after an async call.
10721 // This way we know in all cases that an async texture is always clear.
10722 if (!texture->SafeToRenderFrom()) {
10723 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10724 target, level)) {
10725 LOCAL_SET_GL_ERROR(
10726 GL_OUT_OF_MEMORY,
10727 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
10728 return error::kNoError;
10729 }
10730 }
10731
10732 // Setup the parameters.
10733 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
10734 width, height, format, type};
10735 AsyncMemoryParams mem_params(
10736 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
10737 AsyncPixelTransferDelegate* delegate =
10738 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10739 if (!delegate) {
10740 // TODO(epenner): We may want to enforce exclusive use
10741 // of async APIs in which case this should become an error,
10742 // (the texture should have been async defined).
10743 AsyncTexImage2DParams define_params = {target, level,
10744 0, 0, 0, 0, 0, 0};
10745 texture->GetLevelSize(target, level, &define_params.width,
10746 &define_params.height);
10747 texture->GetLevelType(target, level, &define_params.type,
10748 &define_params.internal_format);
10749 // Set up the async state if needed, and make the texture
10750 // immutable so the async state stays valid.
10751 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
10752 texture_ref, define_params);
10753 texture->SetImmutable(true);
10754 }
10755
10756 delegate->AsyncTexSubImage2D(tex_params, mem_params);
10757 return error::kNoError;
10758 }
10759
HandleWaitAsyncTexImage2DCHROMIUM(uint32 immediate_data_size,const cmds::WaitAsyncTexImage2DCHROMIUM & c)10760 error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10761 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10762 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10763 GLenum target = static_cast<GLenum>(c.target);
10764
10765 if (GL_TEXTURE_2D != target) {
10766 LOCAL_SET_GL_ERROR(
10767 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
10768 return error::kNoError;
10769 }
10770 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10771 &state_, target);
10772 if (!texture_ref) {
10773 LOCAL_SET_GL_ERROR(
10774 GL_INVALID_OPERATION,
10775 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
10776 return error::kNoError;
10777 }
10778 AsyncPixelTransferDelegate* delegate =
10779 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10780 if (!delegate) {
10781 LOCAL_SET_GL_ERROR(
10782 GL_INVALID_OPERATION,
10783 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10784 return error::kNoError;
10785 }
10786 delegate->WaitForTransferCompletion();
10787 ProcessFinishedAsyncTransfers();
10788 return error::kNoError;
10789 }
10790
HandleWaitAllAsyncTexImage2DCHROMIUM(uint32 immediate_data_size,const cmds::WaitAllAsyncTexImage2DCHROMIUM & c)10791 error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
10792 uint32 immediate_data_size, const cmds::WaitAllAsyncTexImage2DCHROMIUM& c) {
10793 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10794
10795 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
10796 ProcessFinishedAsyncTransfers();
10797 return error::kNoError;
10798 }
10799
OnTextureRefDetachedFromFramebuffer(TextureRef * texture_ref)10800 void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
10801 TextureRef* texture_ref) {
10802 Texture* texture = texture_ref->texture();
10803 DoDidUseTexImageIfNeeded(texture, texture->target());
10804 }
10805
OnOutOfMemoryError()10806 void GLES2DecoderImpl::OnOutOfMemoryError() {
10807 if (lose_context_when_out_of_memory_) {
10808 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
10809 LoseContext(GL_GUILTY_CONTEXT_RESET_ARB);
10810 }
10811 }
10812
10813 // Include the auto-generated part of this file. We split this because it means
10814 // we can easily edit the non-auto generated parts right here in this file
10815 // instead of having to edit some template or the code generator.
10816 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10817
10818 } // namespace gles2
10819 } // namespace gpu
10820