blob: 2d80b70f9ccdf8dd62c7b90d6135eabb99cf5f0c [file] [log] [blame]
[email protected]529c6672012-01-04 02:18:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]96449d2c2009-11-25 00:01:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8a837bb2010-01-05 00:21:245#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
[email protected]74470702010-01-06 18:51:166
7#include <stdio.h>
8
[email protected]1aef98132010-02-23 18:00:079#include <algorithm>
[email protected]f39f4b3f2010-05-12 17:04:0810#include <list>
[email protected]96449d2c2009-11-25 00:01:3211#include <map>
[email protected]94307712012-11-16 23:26:1112#include <stack>
[email protected]f39f4b3f2010-05-12 17:04:0813#include <string>
14#include <vector>
[email protected]5a6db6c2010-04-22 18:32:0615
[email protected]00eb49a2010-08-12 20:46:5716#include "base/at_exit.h"
[email protected]d353541f2012-05-03 22:45:4117#include "base/atomicops.h"
[email protected]9d37f062011-11-22 01:24:5218#include "base/bind.h"
[email protected]e844ae22012-01-14 03:36:2619#include "base/command_line.h"
[email protected]1078f912011-12-23 13:12:1420#include "base/debug/trace_event.h"
[email protected]e51bdf32011-11-23 22:21:4621#if defined(OS_MACOSX)
22#include "base/mac/scoped_cftyperef.h"
23#endif
[email protected]3b63f8f42011-03-28 01:54:1524#include "base/memory/scoped_ptr.h"
[email protected]0f8afe82012-05-14 23:43:0125#include "base/string_number_conversions.h"
[email protected]445a8762012-12-06 15:43:2126#include "base/stringprintf.h"
[email protected]d37231fa2010-04-09 21:16:0227#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3228#define GLES2_GPU_SERVICE 1
29#include "gpu/command_buffer/common/gles2_cmd_format.h"
30#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]d2a0e1a2012-08-12 02:25:0131#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]066849e32010-05-03 19:14:1032#include "gpu/command_buffer/common/id_allocator.h"
[email protected]3916c97e2010-02-25 03:20:5033#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3234#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5035#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2436#include "gpu/command_buffer/service/context_state.h"
[email protected]915a59a12010-09-30 21:29:1137#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5838#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3239#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2840#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4641#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]e844ae22012-01-14 03:36:2642#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]94307712012-11-16 23:26:1143#include "gpu/command_buffer/service/gpu_trace.h"
[email protected]09d50362012-10-18 20:54:3744#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5945#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2546#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4747#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5348#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5849#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4750#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4551#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0452#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]b0af4f52011-09-28 22:04:4253#include "gpu/command_buffer/service/stream_texture.h"
54#include "gpu/command_buffer/service/stream_texture_manager.h"
[email protected]78b514b2012-05-01 21:50:5955#include "gpu/command_buffer/service/texture_definition.h"
[email protected]a93bb842010-02-16 23:03:4756#include "gpu/command_buffer/service/texture_manager.h"
[email protected]d8ea9772011-07-11 18:11:4357#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]944b62f32012-09-27 02:20:4658#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]32145a92012-12-17 09:01:5959#include "ui/gl/async_pixel_transfer_delegate.h"
[email protected]09d50362012-10-18 20:54:3760#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2761#include "ui/gl/gl_implementation.h"
62#include "ui/gl/gl_surface.h"
[email protected]e51bdf32011-11-23 22:21:4663#if defined(OS_MACOSX)
[email protected]d353541f2012-05-03 22:45:4164#include "ui/surface/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4665#endif
[email protected]de17df392010-04-23 21:09:4166
[email protected]6217d392010-03-25 22:08:3567#if !defined(GL_DEPTH24_STENCIL8)
68#define GL_DEPTH24_STENCIL8 0x88F0
69#endif
70
[email protected]693ca512012-11-13 18:09:1371// TODO(zmo): we can't include "City.h" due to type def conflicts.
72extern uint64 CityHash64(const char*, size_t);
73
[email protected]a7a27ace2009-12-12 00:11:2574namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3275namespace gles2 {
76
[email protected]f0d74742011-10-03 16:31:0477namespace {
[email protected]693ca512012-11-13 18:09:1378
[email protected]f0d74742011-10-03 16:31:0479static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]693ca512012-11-13 18:09:1380
81khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
82 return static_cast<khronos_uint64_t>(
83 CityHash64(name, static_cast<size_t>(len)));
84}
85
[email protected]f0d74742011-10-03 16:31:0486}
87
[email protected]6217d392010-03-25 22:08:3588class GLES2DecoderImpl;
89
[email protected]07f54fcc2009-12-22 02:46:3090// Check that certain assumptions the code makes are true. There are places in
91// the code where shared memory is passed direclty to GL. Example, glUniformiv,
92// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
93// a few others) are 32bits. If they are not 32bits the code will have to change
94// to call those GL functions with service side memory and then copy the results
95// to shared memory, converting the sizes.
96COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
97 GLint_not_same_size_as_uint32);
98COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
99 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37100COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
101 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30102
[email protected]43f28f832010-02-03 02:28:48103// TODO(kbr): the use of this anonymous namespace core dumps the
104// linker on Mac OS X 10.6 when the symbol ordering file is used
105// namespace {
[email protected]96449d2c2009-11-25 00:01:32106
107// Returns the address of the first byte after a struct.
108template <typename T>
109const void* AddressAfterStruct(const T& pod) {
110 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
111}
112
[email protected]07f54fcc2009-12-22 02:46:30113// Returns the address of the frst byte after the struct or NULL if size >
114// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32115template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30116RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
117 uint32 size,
118 uint32 immediate_data_size) {
119 return (size <= immediate_data_size) ?
120 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
121 NULL;
[email protected]96449d2c2009-11-25 00:01:32122}
123
[email protected]07f54fcc2009-12-22 02:46:30124// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18125bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32126 GLuint count,
127 size_t size,
[email protected]a76b0052010-03-05 00:33:18128 unsigned int elements_per_unit,
129 uint32* dst) {
130 uint32 value;
131 if (!SafeMultiplyUint32(count, size, &value)) {
132 return false;
133 }
134 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
135 return false;
136 }
137 *dst = value;
138 return true;
[email protected]96449d2c2009-11-25 00:01:32139}
140
141// A struct to hold info about each command.
142struct CommandInfo {
143 int arg_flags; // How to handle the arguments for this command
144 int arg_count; // How many arguments are expected for this command.
145};
146
147// A table of CommandInfo for all the commands.
148const CommandInfo g_command_info[] = {
149 #define GLES2_CMD_OP(name) { \
150 name::kArgFlags, \
151 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
152
153 GLES2_COMMAND_LIST(GLES2_CMD_OP)
154
155 #undef GLES2_CMD_OP
156};
157
[email protected]258a3313f2011-10-18 20:13:57158// Return true if a character belongs to the ASCII subset as defined in
159// GLSL ES 1.0 spec section 3.1.
160static bool CharacterIsValidForGLES(unsigned char c) {
161 // Printing characters are valid except " $ ` @ \ ' DEL.
162 if (c >= 32 && c <= 126 &&
163 c != '"' &&
164 c != '$' &&
165 c != '`' &&
166 c != '@' &&
167 c != '\\' &&
168 c != '\'') {
169 return true;
170 }
171 // Horizontal tab, line feed, vertical tab, form feed, carriage return
172 // are also valid.
173 if (c >= 9 && c <= 13) {
174 return true;
175 }
176
177 return false;
178}
179
180static bool StringIsValidForGLES(const char* str) {
181 for (; *str; ++str) {
182 if (!CharacterIsValidForGLES(*str)) {
183 return false;
184 }
185 }
186 return true;
187}
188
[email protected]f0e6a34f2012-01-04 20:53:40189static inline GLenum GetTexInternalFormat(GLenum internal_format) {
190 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
191 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT)
192 return GL_RGBA8;
193 }
194 return internal_format;
195}
196
[email protected]32145a92012-12-17 09:01:59197// TODO(epenner): Could the above function be merged into this and removed?
198static inline GLenum GetTexInternalFormat(GLenum internal_format,
199 GLenum format,
200 GLenum type) {
201 GLenum gl_internal_format = GetTexInternalFormat(internal_format);
202
203 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
204 return gl_internal_format;
205
206 if (type == GL_FLOAT) {
207 switch (format) {
208 case GL_RGBA:
209 gl_internal_format = GL_RGBA32F_ARB;
210 break;
211 case GL_RGB:
212 gl_internal_format = GL_RGB32F_ARB;
213 break;
214 case GL_LUMINANCE_ALPHA:
215 gl_internal_format = GL_LUMINANCE_ALPHA32F_ARB;
216 break;
217 case GL_LUMINANCE:
218 gl_internal_format = GL_LUMINANCE32F_ARB;
219 break;
220 case GL_ALPHA:
221 gl_internal_format = GL_ALPHA32F_ARB;
222 break;
223 default:
224 NOTREACHED();
225 break;
226 }
227 } else if (type == GL_HALF_FLOAT_OES) {
228 switch (format) {
229 case GL_RGBA:
230 gl_internal_format = GL_RGBA16F_ARB;
231 break;
232 case GL_RGB:
233 gl_internal_format = GL_RGB16F_ARB;
234 break;
235 case GL_LUMINANCE_ALPHA:
236 gl_internal_format = GL_LUMINANCE_ALPHA16F_ARB;
237 break;
238 case GL_LUMINANCE:
239 gl_internal_format = GL_LUMINANCE16F_ARB;
240 break;
241 case GL_ALPHA:
242 gl_internal_format = GL_ALPHA16F_ARB;
243 break;
244 default:
245 NOTREACHED();
246 break;
247 }
248 }
249 return gl_internal_format;
250}
251
[email protected]297ca1c2011-06-20 23:08:46252static void WrappedTexImage2D(
[email protected]473c01ccb2011-06-07 01:33:30253 GLenum target,
254 GLint level,
255 GLenum internal_format,
256 GLsizei width,
257 GLsizei height,
258 GLint border,
259 GLenum format,
260 GLenum type,
261 const void* pixels) {
[email protected]473c01ccb2011-06-07 01:33:30262 glTexImage2D(
[email protected]32145a92012-12-17 09:01:59263 target, level, GetTexInternalFormat(internal_format, format, type),
264 width, height, border, format, type, pixels);
[email protected]473c01ccb2011-06-07 01:33:30265}
266
[email protected]297ca1c2011-06-20 23:08:46267// Wrapper for glEnable/glDisable that doesn't suck.
268static void EnableDisable(GLenum pname, bool enable) {
269 if (enable) {
270 glEnable(pname);
271 } else {
272 glDisable(pname);
273 }
274}
275
[email protected]6217d392010-03-25 22:08:35276// This class prevents any GL errors that occur when it is in scope from
277// being reported to the client.
278class ScopedGLErrorSuppressor {
279 public:
280 explicit ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder);
281 ~ScopedGLErrorSuppressor();
282 private:
283 GLES2DecoderImpl* decoder_;
284 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
285};
286
287// Temporarily changes a decoder's bound 2D texture and restore it when this
288// object goes out of scope. Also temporarily switches to using active texture
289// unit zero in case the client has changed that to something invalid.
290class ScopedTexture2DBinder {
291 public:
292 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
293 ~ScopedTexture2DBinder();
294
295 private:
296 GLES2DecoderImpl* decoder_;
297 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
298};
299
300// Temporarily changes a decoder's bound render buffer and restore it when this
301// object goes out of scope.
302class ScopedRenderBufferBinder {
303 public:
304 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
305 ~ScopedRenderBufferBinder();
306
307 private:
308 GLES2DecoderImpl* decoder_;
309 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
310};
311
312// Temporarily changes a decoder's bound frame buffer and restore it when this
313// object goes out of scope.
314class ScopedFrameBufferBinder {
315 public:
316 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
317 ~ScopedFrameBufferBinder();
318
319 private:
320 GLES2DecoderImpl* decoder_;
321 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
322};
323
[email protected]34ff8b0c2010-10-01 20:06:02324// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52325// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27326// if it is bound or enforce_internal_framebuffer is true. If internal is
327// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02328class ScopedResolvedFrameBufferBinder {
329 public:
[email protected]e7e38032011-07-26 17:25:25330 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27331 bool enforce_internal_framebuffer,
332 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02333 ~ScopedResolvedFrameBufferBinder();
334
335 private:
336 GLES2DecoderImpl* decoder_;
337 bool resolve_and_bind_;
338 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
339};
340
[email protected]63b465922012-09-06 02:04:52341// This class records texture upload time when in scope.
342class ScopedTextureUploadTimer {
343 public:
344 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder);
345 ~ScopedTextureUploadTimer();
346
347 private:
348 GLES2DecoderImpl* decoder_;
349 base::TimeTicks begin_time_;
350 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer);
351};
352
[email protected]6217d392010-03-25 22:08:35353// Encapsulates an OpenGL texture.
354class Texture {
355 public:
356 explicit Texture(GLES2DecoderImpl* decoder);
357 ~Texture();
358
359 // Create a new render texture.
360 void Create();
361
362 // Set the initial size and format of a render texture or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02363 bool AllocateStorage(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35364
365 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58366 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35367
368 // Destroy the render texture. This must be explicitly called before
369 // destroying this object.
370 void Destroy();
371
[email protected]97872062010-11-03 19:07:05372 // Invalidate the texture. This can be used when a context is lost and it is
373 // not possible to make it current in order to free the resource.
374 void Invalidate();
375
[email protected]6217d392010-03-25 22:08:35376 GLuint id() const {
377 return id_;
378 }
379
[email protected]d37231fa2010-04-09 21:16:02380 gfx::Size size() const {
381 return size_;
382 }
383
[email protected]1078f912011-12-23 13:12:14384 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25385 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14386 }
387
[email protected]6217d392010-03-25 22:08:35388 private:
389 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25390 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48391 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35392 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02393 gfx::Size size_;
[email protected]6217d392010-03-25 22:08:35394 DISALLOW_COPY_AND_ASSIGN(Texture);
395};
396
397// Encapsulates an OpenGL render buffer of any format.
398class RenderBuffer {
399 public:
400 explicit RenderBuffer(GLES2DecoderImpl* decoder);
401 ~RenderBuffer();
402
403 // Create a new render buffer.
404 void Create();
405
406 // Set the initial size and format of a render buffer or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02407 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
[email protected]6217d392010-03-25 22:08:35408
409 // Destroy the render buffer. This must be explicitly called before destroying
410 // this object.
411 void Destroy();
412
[email protected]97872062010-11-03 19:07:05413 // Invalidate the render buffer. This can be used when a context is lost and
414 // it is not possible to make it current in order to free the resource.
415 void Invalidate();
416
[email protected]6217d392010-03-25 22:08:35417 GLuint id() const {
418 return id_;
419 }
420
[email protected]1078f912011-12-23 13:12:14421 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25422 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14423 }
424
[email protected]6217d392010-03-25 22:08:35425 private:
426 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25427 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48428 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35429 GLuint id_;
430 DISALLOW_COPY_AND_ASSIGN(RenderBuffer);
431};
432
433// Encapsulates an OpenGL frame buffer.
434class FrameBuffer {
435 public:
436 explicit FrameBuffer(GLES2DecoderImpl* decoder);
437 ~FrameBuffer();
438
439 // Create a new frame buffer.
440 void Create();
441
442 // Attach a color render buffer to a frame buffer.
443 void AttachRenderTexture(Texture* texture);
444
[email protected]b9363b22010-06-09 22:06:15445 // Attach a render buffer to a frame buffer. Note that this unbinds any
446 // currently bound frame buffer.
447 void AttachRenderBuffer(GLenum target, RenderBuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35448
[email protected]6217d392010-03-25 22:08:35449 // Destroy the frame buffer. This must be explicitly called before destroying
450 // this object.
451 void Destroy();
452
[email protected]97872062010-11-03 19:07:05453 // Invalidate the frame buffer. This can be used when a context is lost and it
454 // is not possible to make it current in order to free the resource.
455 void Invalidate();
456
[email protected]6217d392010-03-25 22:08:35457 // See glCheckFramebufferStatusEXT.
458 GLenum CheckStatus();
459
460 GLuint id() const {
461 return id_;
462 }
463
464 private:
465 GLES2DecoderImpl* decoder_;
466 GLuint id_;
467 DISALLOW_COPY_AND_ASSIGN(FrameBuffer);
468};
[email protected]34ff8b0c2010-10-01 20:06:02469
[email protected]43f28f832010-02-03 02:28:48470// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32471
[email protected]ddb1e5a2010-12-13 20:10:45472bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
473 uint32* service_texture_id) {
474 return false;
475}
476
[email protected]a3ded6d2010-10-19 06:44:39477GLES2Decoder::GLES2Decoder()
[email protected]e844ae22012-01-14 03:36:26478 : debug_(false),
[email protected]b5d647c2012-02-10 01:41:32479 log_commands_(false),
480 log_synthesized_gl_errors_(true) {
[email protected]96449d2c2009-11-25 00:01:32481}
482
[email protected]3916c97e2010-02-25 03:20:50483GLES2Decoder::~GLES2Decoder() {
484}
485
[email protected]57edfdad2012-02-07 04:57:15486bool GLES2Decoder::testing_force_is_angle_;
487
488void GLES2Decoder::set_testing_force_is_angle(bool force) {
489 testing_force_is_angle_ = force;
490}
491
492bool GLES2Decoder::IsAngle() {
493#if defined(OS_WIN)
494 return testing_force_is_angle_ ||
495 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
496#else
497 return testing_force_is_angle_;
498#endif
499}
500
[email protected]f39f4b3f2010-05-12 17:04:08501// This class implements GLES2Decoder so we don't have to expose all the GLES2
502// cmd stuff to outside this class.
[email protected]ee1e6aa2012-11-29 09:24:10503class GLES2DecoderImpl : public GLES2Decoder {
[email protected]f39f4b3f2010-05-12 17:04:08504 public:
[email protected]0f8afe82012-05-14 23:43:01505 static const int kMaxLogMessages = 256;
[email protected]fa20ec82012-05-04 04:02:48506
[email protected]476ccb72012-12-06 15:52:52507 // Used by PrepForSetUniformByLocation to validate types.
508 struct BaseUniformInfo {
509 const GLenum* const valid_types;
510 size_t num_valid_types;
511 };
512
[email protected]aa7666122011-09-02 19:45:52513 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00514 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08515
[email protected]96449d2c2009-11-25 00:01:32516 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14517 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50518 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00519 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32520
521 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00522 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32523
524 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38525 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
526 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23527 bool offscreen,
[email protected]6217d392010-03-25 22:08:35528 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29529 const DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39530 const char* allowed_extensions,
[email protected]b8e97b62012-09-30 15:09:00531 const std::vector<int32>& attribs) OVERRIDE;
532 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38533 virtual void SetSurface(
534 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]3c644d82011-06-20 19:58:24535 virtual bool SetParent(GLES2Decoder* parent_decoder,
[email protected]b8e97b62012-09-30 15:09:00536 uint32 parent_texture_id) OVERRIDE;
537 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39538 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00539 virtual bool MakeCurrent() OVERRIDE;
540 virtual void ReleaseCurrent() OVERRIDE;
541 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
542 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
543 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]1868a342012-11-07 15:56:02544 virtual void RestoreState() const OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00545 virtual QueryManager* GetQueryManager() OVERRIDE {
546 return query_manager_.get();
547 }
548 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46549 return vertex_array_manager_.get();
550 }
[email protected]b8e97b62012-09-30 15:09:00551 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48552
[email protected]b8e97b62012-09-30 15:09:00553 virtual void SetGLError(GLenum error,
554 const char* function_name,
555 const char* msg);
556 virtual void SetGLErrorInvalidEnum(const char* function_name,
557 GLenum value,
558 const char* label);
[email protected]9d37f062011-11-22 01:24:52559 virtual void SetResizeCallback(
[email protected]b8e97b62012-09-30 15:09:00560 const base::Callback<void(gfx::Size)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00561
[email protected]b8e97b62012-09-30 15:09:00562 virtual void SetMsgCallback(const MsgCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00563
[email protected]b8e97b62012-09-30 15:09:00564 virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE;
[email protected]32145a92012-12-17 09:01:59565
566 virtual gfx::AsyncPixelTransferDelegate*
567 GetAsyncPixelTransferDelegate() OVERRIDE;
568 virtual void SetAsyncPixelTransferDelegate(
569 gfx::AsyncPixelTransferDelegate* delegate) OVERRIDE;
570
[email protected]1318e922010-09-17 22:03:16571 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00572 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48573
[email protected]efcdd2362012-07-09 21:07:00574 virtual uint32 GetGLError() OVERRIDE;
575
[email protected]63b465922012-09-06 02:04:52576 virtual uint32 GetTextureUploadCount() OVERRIDE;
577 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
578 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30579 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52580
[email protected]8e3e0662010-08-23 18:46:30581 // Restores the current state to the user's settings.
582 void RestoreCurrentFramebufferBindings();
583 void RestoreCurrentRenderbufferBindings();
584 void RestoreCurrentTexture2DBindings();
585
[email protected]297ca1c2011-06-20 23:08:46586 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
587 void ApplyDirtyState();
588
[email protected]78b514b2012-05-01 21:50:59589 // Reapply the texture parameters to the given texture.
590 void BindAndApplyTextureParameters(TextureManager::TextureInfo* info);
591
[email protected]297ca1c2011-06-20 23:08:46592 // These check the state of the currently bound framebuffer or the
593 // backbuffer if no framebuffer is bound.
594 bool BoundFramebufferHasColorAttachmentWithAlpha();
595 bool BoundFramebufferHasDepthAttachment();
596 bool BoundFramebufferHasStencilAttachment();
597
[email protected]b8e97b62012-09-30 15:09:00598 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43599
[email protected]96449d2c2009-11-25 00:01:32600 private:
[email protected]6217d392010-03-25 22:08:35601 friend class ScopedGLErrorSuppressor;
[email protected]34ff8b0c2010-10-01 20:06:02602 friend class ScopedResolvedFrameBufferBinder;
[email protected]63b465922012-09-06 02:04:52603 friend class ScopedTextureUploadTimer;
[email protected]1078f912011-12-23 13:12:14604 friend class Texture;
[email protected]6217d392010-03-25 22:08:35605 friend class RenderBuffer;
606 friend class FrameBuffer;
607
[email protected]c2f8c8402010-12-06 18:07:24608 // Initialize or re-initialize the shader translator.
609 bool InitializeShaderTranslator();
610
[email protected]302ce6d2011-07-07 23:28:11611 void UpdateCapabilities();
612
[email protected]ae51d192010-04-27 00:48:03613 // Helpers for the glGen and glDelete functions.
614 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
615 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
616 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
617 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
618 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
619 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
620 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
621 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53622 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
623 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46624 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
625 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47626
[email protected]3916c97e2010-02-25 03:20:50627 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50628 BufferManager* buffer_manager() {
629 return group_->buffer_manager();
630 }
631
[email protected]a25fa872010-03-25 02:57:58632 RenderbufferManager* renderbuffer_manager() {
633 return group_->renderbuffer_manager();
634 }
635
636 FramebufferManager* framebuffer_manager() {
637 return group_->framebuffer_manager();
638 }
639
[email protected]3916c97e2010-02-25 03:20:50640 ProgramManager* program_manager() {
641 return group_->program_manager();
642 }
643
644 ShaderManager* shader_manager() {
645 return group_->shader_manager();
646 }
647
648 TextureManager* texture_manager() {
649 return group_->texture_manager();
650 }
651
[email protected]78b514b2012-05-01 21:50:59652 MailboxManager* mailbox_manager() {
653 return group_->mailbox_manager();
654 }
655
[email protected]09d50362012-10-18 20:54:37656 ImageManager* image_manager() {
657 return group_->image_manager();
658 }
659
[email protected]944b62f32012-09-27 02:20:46660 VertexArrayManager* vertex_array_manager() {
661 return vertex_array_manager_.get();
662 }
663
[email protected]34ff8b0c2010-10-01 20:06:02664 bool IsOffscreenBufferMultisampled() const {
665 return offscreen_target_samples_ > 1;
666 }
667
[email protected]a93bb842010-02-16 23:03:47668 // Creates a TextureInfo for the given texture.
[email protected]ae51d192010-04-27 00:48:03669 TextureManager::TextureInfo* CreateTextureInfo(
670 GLuint client_id, GLuint service_id) {
[email protected]80eb6b52012-01-19 00:14:41671 return texture_manager()->CreateTextureInfo(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47672 }
673
674 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]ae51d192010-04-27 00:48:03675 TextureManager::TextureInfo* GetTextureInfo(GLuint client_id) {
[email protected]3916c97e2010-02-25 03:20:50676 TextureManager::TextureInfo* info =
[email protected]ae51d192010-04-27 00:48:03677 texture_manager()->GetTextureInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10678 return info;
[email protected]a93bb842010-02-16 23:03:47679 }
680
681 // Deletes the texture info for the given texture.
[email protected]ae51d192010-04-27 00:48:03682 void RemoveTextureInfo(GLuint client_id) {
[email protected]80eb6b52012-01-19 00:14:41683 texture_manager()->RemoveTextureInfo(client_id);
[email protected]3916c97e2010-02-25 03:20:50684 }
[email protected]a93bb842010-02-16 23:03:47685
[email protected]d37231fa2010-04-09 21:16:02686 // Get the size (in pixels) of the currently bound frame buffer (either FBO
687 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30688 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02689
[email protected]9edc6b22010-12-23 02:00:26690 // Get the format of the currently bound frame buffer (either FBO or regular
691 // back buffer)
692 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46693 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26694
[email protected]a93bb842010-02-16 23:03:47695 // Wrapper for CompressedTexImage2D commands.
696 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37697 GLenum target,
698 GLint level,
699 GLenum internal_format,
700 GLsizei width,
701 GLsizei height,
702 GLint border,
703 GLsizei image_size,
704 const void* data);
[email protected]a93bb842010-02-16 23:03:47705
[email protected]cadde4a2010-07-31 17:10:43706 // Wrapper for CompressedTexSubImage2D.
707 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37708 GLenum target,
709 GLint level,
710 GLint xoffset,
711 GLint yoffset,
712 GLsizei width,
713 GLsizei height,
714 GLenum format,
715 GLsizei imageSize,
716 const void * data);
[email protected]cadde4a2010-07-31 17:10:43717
718 // Wrapper for CopyTexImage2D.
719 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37720 GLenum target,
721 GLint level,
722 GLenum internal_format,
723 GLint x,
724 GLint y,
725 GLsizei width,
726 GLsizei height,
727 GLint border);
[email protected]cadde4a2010-07-31 17:10:43728
729 // Wrapper for CopyTexSubImage2D.
730 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37731 GLenum target,
732 GLint level,
733 GLint xoffset,
734 GLint yoffset,
735 GLint x,
736 GLint y,
737 GLsizei width,
738 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43739
[email protected]f598f422012-12-07 08:30:03740 // Validation for TexImage2D commands.
741 bool ValidateTexImage2D(
742 const char* function_name,
[email protected]09d50362012-10-18 20:54:37743 GLenum target,
744 GLint level,
745 GLenum internal_format,
746 GLsizei width,
747 GLsizei height,
748 GLint border,
749 GLenum format,
750 GLenum type,
751 const void* pixels,
752 uint32 pixels_size);
[email protected]a93bb842010-02-16 23:03:47753
[email protected]f598f422012-12-07 08:30:03754 // Wrapper for TexImage2D commands.
755 void DoTexImage2D(
756 GLenum target,
757 GLint level,
758 GLenum internal_format,
759 GLsizei width,
760 GLsizei height,
761 GLint border,
762 GLenum format,
763 GLenum type,
764 const void* pixels,
765 uint32 pixels_size);
766
767 // Validation for TexSubImage2D.
768 bool ValidateTexSubImage2D(
769 error::Error* error,
770 const char* function_name,
771 GLenum target,
772 GLint level,
773 GLint xoffset,
774 GLint yoffset,
775 GLsizei width,
776 GLsizei height,
777 GLenum format,
778 GLenum type,
779 const void * data);
780
[email protected]cadde4a2010-07-31 17:10:43781 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03782 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37783 GLenum target,
784 GLint level,
785 GLint xoffset,
786 GLint yoffset,
787 GLsizei width,
788 GLsizei height,
789 GLenum format,
790 GLenum type,
791 const void * data);
[email protected]cadde4a2010-07-31 17:10:43792
[email protected]32145a92012-12-17 09:01:59793 // Extra validation for async tex(Sub)Image2D.
794 bool ValidateAsyncTransfer(
795 const char* function_name,
796 TextureManager::TextureInfo* info,
797 GLenum target,
798 GLint level,
799 const void * data);
800
[email protected]e51bdf32011-11-23 22:21:46801 // Wrapper for TexImageIOSurface2DCHROMIUM.
802 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37803 GLenum target,
804 GLsizei width,
805 GLsizei height,
806 GLuint io_surface_id,
807 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46808
[email protected]43410e92012-04-20 17:06:28809 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37810 GLenum target,
811 GLuint source_id,
812 GLuint target_id,
813 GLint level,
814 GLenum internal_format);
[email protected]43410e92012-04-20 17:06:28815
[email protected]97dc7cbe2011-12-06 17:26:17816 // Wrapper for TexStorage2DEXT.
817 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37818 GLenum target,
819 GLint levels,
820 GLenum internal_format,
821 GLsizei width,
822 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17823
[email protected]78b514b2012-05-01 21:50:59824 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
825 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
826
[email protected]09d50362012-10-18 20:54:37827 void DoBindTexImage2DCHROMIUM(
828 GLenum target,
829 GLint image_id);
830 void DoReleaseTexImage2DCHROMIUM(
831 GLenum target,
832 GLint image_id);
833
[email protected]94307712012-11-16 23:26:11834 void DoTraceEndCHROMIUM(void);
835
[email protected]a93bb842010-02-16 23:03:47836 // Creates a ProgramInfo for the given program.
[email protected]d685a682011-04-29 16:19:57837 ProgramManager::ProgramInfo* CreateProgramInfo(
838 GLuint client_id, GLuint service_id) {
839 return program_manager()->CreateProgramInfo(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47840 }
841
[email protected]07f54fcc2009-12-22 02:46:30842 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ae51d192010-04-27 00:48:03843 ProgramManager::ProgramInfo* GetProgramInfo(GLuint client_id) {
[email protected]ca488e12010-12-13 20:06:14844 return program_manager()->GetProgramInfo(client_id);
[email protected]1d32bc82010-01-13 22:06:46845 }
[email protected]07f54fcc2009-12-22 02:46:30846
[email protected]cae20172012-12-07 00:06:19847#if defined(NDEBUG)
848 void LogClientServiceMapping(
849 const char* /* function_name */,
850 GLuint /* client_id */,
851 GLuint /* service_id */) {
852 }
853 template<typename T>
854 void LogClientServiceForInfo(
855 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
856 }
857#else
858 void LogClientServiceMapping(
859 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26860 if (service_logging_) {
861 DLOG(INFO) << "[" << GetLogPrefix() << "] " << function_name
862 << ": client_id = " << client_id
863 << ", service_id = " << service_id;
864 }
[email protected]cae20172012-12-07 00:06:19865 }
866 template<typename T>
867 void LogClientServiceForInfo(
868 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26869 if (info) {
[email protected]cae20172012-12-07 00:06:19870 LogClientServiceMapping(function_name, client_id, info->service_id());
871 }
872 }
873#endif
874
[email protected]6b8cf1a2010-05-06 16:13:58875 // Gets the program info for the given program. If it's not a program
876 // generates a GL error. Returns NULL if not program.
877 ProgramManager::ProgramInfo* GetProgramInfoNotShader(
878 GLuint client_id, const char* function_name) {
879 ProgramManager::ProgramInfo* info = GetProgramInfo(client_id);
880 if (!info) {
881 if (GetShaderInfo(client_id)) {
[email protected]ad84a3a2012-06-08 21:42:43882 SetGLError(
883 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58884 } else {
[email protected]ad84a3a2012-06-08 21:42:43885 SetGLError(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58886 }
887 }
[email protected]cae20172012-12-07 00:06:19888 LogClientServiceForInfo(info, client_id, function_name);
[email protected]6b8cf1a2010-05-06 16:13:58889 return info;
890 }
891
892
[email protected]45bf5152010-02-12 00:11:31893 // Creates a ShaderInfo for the given shader.
[email protected]d685a682011-04-29 16:19:57894 ShaderManager::ShaderInfo* CreateShaderInfo(
895 GLuint client_id,
896 GLuint service_id,
897 GLenum shader_type) {
898 return shader_manager()->CreateShaderInfo(
899 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31900 }
901
902 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ae51d192010-04-27 00:48:03903 ShaderManager::ShaderInfo* GetShaderInfo(GLuint client_id) {
[email protected]ca488e12010-12-13 20:06:14904 return shader_manager()->GetShaderInfo(client_id);
[email protected]45bf5152010-02-12 00:11:31905 }
906
[email protected]6b8cf1a2010-05-06 16:13:58907 // Gets the shader info for the given shader. If it's not a shader generates a
908 // GL error. Returns NULL if not shader.
909 ShaderManager::ShaderInfo* GetShaderInfoNotProgram(
910 GLuint client_id, const char* function_name) {
911 ShaderManager::ShaderInfo* info = GetShaderInfo(client_id);
912 if (!info) {
913 if (GetProgramInfo(client_id)) {
914 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:43915 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58916 } else {
[email protected]ad84a3a2012-06-08 21:42:43917 SetGLError(
918 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58919 }
920 }
[email protected]cae20172012-12-07 00:06:19921 LogClientServiceForInfo(info, client_id, function_name);
[email protected]6b8cf1a2010-05-06 16:13:58922 return info;
923 }
924
[email protected]a93bb842010-02-16 23:03:47925 // Creates a buffer info for the given buffer.
[email protected]ae51d192010-04-27 00:48:03926 void CreateBufferInfo(GLuint client_id, GLuint service_id) {
927 return buffer_manager()->CreateBufferInfo(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47928 }
929
[email protected]07f54fcc2009-12-22 02:46:30930 // Gets the buffer info for the given buffer.
[email protected]ae51d192010-04-27 00:48:03931 BufferManager::BufferInfo* GetBufferInfo(GLuint client_id) {
932 BufferManager::BufferInfo* info =
933 buffer_manager()->GetBufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10934 return info;
[email protected]1d32bc82010-01-13 22:06:46935 }
[email protected]07f54fcc2009-12-22 02:46:30936
[email protected]a93bb842010-02-16 23:03:47937 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
938 // on glDeleteBuffers so we can make sure the user does not try to render
939 // with deleted buffers.
[email protected]ae51d192010-04-27 00:48:03940 void RemoveBufferInfo(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:47941
[email protected]a25fa872010-03-25 02:57:58942 // Creates a framebuffer info for the given framebuffer.
[email protected]ae51d192010-04-27 00:48:03943 void CreateFramebufferInfo(GLuint client_id, GLuint service_id) {
944 return framebuffer_manager()->CreateFramebufferInfo(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58945 }
946
947 // Gets the framebuffer info for the given framebuffer.
948 FramebufferManager::FramebufferInfo* GetFramebufferInfo(
[email protected]ae51d192010-04-27 00:48:03949 GLuint client_id) {
[email protected]a25fa872010-03-25 02:57:58950 FramebufferManager::FramebufferInfo* info =
[email protected]ae51d192010-04-27 00:48:03951 framebuffer_manager()->GetFramebufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10952 return info;
[email protected]a25fa872010-03-25 02:57:58953 }
954
955 // Removes the framebuffer info for the given framebuffer.
[email protected]ae51d192010-04-27 00:48:03956 void RemoveFramebufferInfo(GLuint client_id) {
957 framebuffer_manager()->RemoveFramebufferInfo(client_id);
[email protected]a25fa872010-03-25 02:57:58958 }
959
960 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ae51d192010-04-27 00:48:03961 void CreateRenderbufferInfo(GLuint client_id, GLuint service_id) {
962 return renderbuffer_manager()->CreateRenderbufferInfo(
963 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58964 }
965
966 // Gets the renderbuffer info for the given renderbuffer.
967 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfo(
[email protected]ae51d192010-04-27 00:48:03968 GLuint client_id) {
[email protected]a25fa872010-03-25 02:57:58969 RenderbufferManager::RenderbufferInfo* info =
[email protected]ae51d192010-04-27 00:48:03970 renderbuffer_manager()->GetRenderbufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10971 return info;
[email protected]a25fa872010-03-25 02:57:58972 }
973
974 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ae51d192010-04-27 00:48:03975 void RemoveRenderbufferInfo(GLuint client_id) {
976 renderbuffer_manager()->RemoveRenderbufferInfo(client_id);
[email protected]a25fa872010-03-25 02:57:58977 }
978
[email protected]944b62f32012-09-27 02:20:46979 // Gets the vertex attrib manager for the given vertex array.
980 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
981 VertexAttribManager* info =
982 vertex_array_manager()->GetVertexAttribManager(client_id);
983 return info;
984 }
985
986 // Removes the vertex attrib manager for the given vertex array.
987 void RemoveVertexAttribManager(GLuint client_id) {
988 vertex_array_manager()->RemoveVertexAttribManager(client_id);
989 }
990
991 // Creates a vertex attrib manager for the given vertex array.
992 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
993 return vertex_array_manager()->CreateVertexAttribManager(
994 client_id, service_id, group_->max_vertex_attribs());
995 }
996
[email protected]258a3313f2011-10-18 20:13:57997 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:33998 void DoBindUniformLocationCHROMIUM(
999 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571000
[email protected]558847a2010-03-24 07:02:541001 error::Error GetAttribLocationHelper(
1002 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1003 const std::string& name_str);
1004
1005 error::Error GetUniformLocationHelper(
1006 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1007 const std::string& name_str);
1008
[email protected]3916c97e2010-02-25 03:20:501009 // Helper for glShaderSource.
1010 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031011 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301012
[email protected]0d6bfdc2011-11-02 01:32:201013 // Clear any textures used by the current program.
1014 bool ClearUnclearedTextures();
1015
1016 // Clear any uncleared level in texture.
1017 // Returns false if there was a generated GL error.
1018 bool ClearTexture(TextureManager::TextureInfo* info);
1019
1020 // Clears any uncleared attachments attached to the given frame buffer.
1021 // Returns false if there was a generated GL error.
1022 void ClearUnclearedAttachments(
[email protected]8e3e0662010-08-23 18:46:301023 GLenum target, FramebufferManager::FramebufferInfo* info);
[email protected]3a2e7c7b2010-08-06 01:12:281024
[email protected]0d6bfdc2011-11-02 01:32:201025 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001026 virtual bool ClearLevel(unsigned service_id,
1027 unsigned bind_target,
1028 unsigned target,
1029 int level,
1030 unsigned format,
1031 unsigned type,
1032 int width,
1033 int height,
1034 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201035
[email protected]c007aa02010-09-02 22:22:401036 // Restore all GL state that affects clearing.
1037 void RestoreClearState();
1038
[email protected]3a2e7c7b2010-08-06 01:12:281039 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461040 // Returns: true if glEnable/glDisable should actually be called.
1041 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281042
[email protected]0d6bfdc2011-11-02 01:32:201043 // Check that the currently bound framebuffers are valid.
1044 // Generates GL error if not.
1045 bool CheckBoundFramebuffersValid(const char* func_name);
1046
1047 // Check if a framebuffer meets our requirements.
1048 bool CheckFramebufferValid(
1049 FramebufferManager::FramebufferInfo* framebuffer,
1050 GLenum target,
1051 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271052
[email protected]939e7362010-05-13 20:49:101053 // Checks if the current program exists and is valid. If not generates the
1054 // appropriate GL error. Returns true if the current program is in a usable
1055 // state.
1056 bool CheckCurrentProgram(const char* function_name);
1057
1058 // Checks if the current program exists and is valid and that location is not
1059 // -1. If the current program is not valid generates the appropriate GL
1060 // error. Returns true if the current program is in a usable state and
1061 // location is not -1.
1062 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1063
1064 // Gets the type of a uniform for a location in the current program. Sets GL
1065 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361066 // program is valid and the location exists. Adjusts count so it
1067 // does not overflow the uniform.
1068 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121069 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521070 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121071 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101072
[email protected]b177ae22011-11-01 03:29:111073 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021074 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111075
[email protected]b273e432010-04-12 17:23:581076 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1077 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1078
[email protected]96449d2c2009-11-25 00:01:321079 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031080 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321081
1082 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031083 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321084
[email protected]3916c97e2010-02-25 03:20:501085 // Wrapper for glActiveTexture
1086 void DoActiveTexture(GLenum texture_unit);
1087
[email protected]ae51d192010-04-27 00:48:031088 // Wrapper for glAttachShader
1089 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1090
[email protected]96449d2c2009-11-25 00:01:321091 // Wrapper for glBindBuffer since we need to track the current targets.
1092 void DoBindBuffer(GLenum target, GLuint buffer);
1093
[email protected]86093972010-03-11 00:13:561094 // Wrapper for glBindFramebuffer since we need to track the current targets.
1095 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1096
1097 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1098 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1099
[email protected]a93bb842010-02-16 23:03:471100 // Wrapper for glBindTexture since we need to track the current targets.
1101 void DoBindTexture(GLenum target, GLuint texture);
1102
[email protected]944b62f32012-09-27 02:20:461103 // Wrapper for glBindVertexArrayOES
1104 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571105 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461106
[email protected]8e3e0662010-08-23 18:46:301107 // Wrapper for glBlitFramebufferEXT.
1108 void DoBlitFramebufferEXT(
1109 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1110 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1111 GLbitfield mask, GLenum filter);
1112
[email protected]36cef8ce2010-03-16 07:34:451113 // Wrapper for glBufferData.
[email protected]0c86dbf2010-03-05 08:14:111114 void DoBufferData(
1115 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
1116
[email protected]36cef8ce2010-03-16 07:34:451117 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111118 void DoBufferSubData(
1119 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1120
[email protected]36cef8ce2010-03-16 07:34:451121 // Wrapper for glCheckFramebufferStatus
1122 GLenum DoCheckFramebufferStatus(GLenum target);
1123
[email protected]3a03a8f2011-03-19 00:51:271124 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081125 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271126
[email protected]88a61bf2012-10-27 13:00:421127 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421128 void DoDepthRangef(GLclampf znear, GLclampf zfar);
1129 void DoHint(GLenum target, GLenum mode);
1130 void DoSampleCoverage (GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281131
[email protected]45bf5152010-02-12 00:11:311132 // Wrapper for glCompileShader.
1133 void DoCompileShader(GLuint shader);
1134
[email protected]269200b12010-11-18 22:53:061135 // Helper for DeleteSharedIdsCHROMIUM commands.
1136 void DoDeleteSharedIdsCHROMIUM(
1137 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101138
[email protected]ae51d192010-04-27 00:48:031139 // Wrapper for glDetachShader
1140 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1141
[email protected]3a2e7c7b2010-08-06 01:12:281142 // Wrapper for glDisable
1143 void DoDisable(GLenum cap);
1144
[email protected]07f54fcc2009-12-22 02:46:301145 // Wrapper for glDisableVertexAttribArray.
1146 void DoDisableVertexAttribArray(GLuint index);
1147
[email protected]60f22d32012-12-12 00:31:581148 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1149 // attachments.
1150 void DoDiscardFramebufferEXT(GLenum target,
1151 GLsizei numAttachments,
1152 const GLenum* attachments);
1153
[email protected]3a2e7c7b2010-08-06 01:12:281154 // Wrapper for glEnable
1155 void DoEnable(GLenum cap);
1156
[email protected]07f54fcc2009-12-22 02:46:301157 // Wrapper for glEnableVertexAttribArray.
1158 void DoEnableVertexAttribArray(GLuint index);
1159
[email protected]882ba1e22012-03-08 19:02:531160 // Wrapper for glFinish.
1161 void DoFinish();
1162
1163 // Wrapper for glFlush.
1164 void DoFlush();
1165
[email protected]36cef8ce2010-03-16 07:34:451166 // Wrapper for glFramebufferRenderbufffer.
1167 void DoFramebufferRenderbuffer(
1168 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1169 GLuint renderbuffer);
1170
1171 // Wrapper for glFramebufferTexture2D.
1172 void DoFramebufferTexture2D(
1173 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1174 GLint level);
1175
[email protected]a93bb842010-02-16 23:03:471176 // Wrapper for glGenerateMipmap
1177 void DoGenerateMipmap(GLenum target);
1178
[email protected]269200b12010-11-18 22:53:061179 // Helper for GenSharedIdsCHROMIUM commands.
1180 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101181 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1182
[email protected]b273e432010-04-12 17:23:581183 // Wrapper for DoGetBooleanv.
1184 void DoGetBooleanv(GLenum pname, GLboolean* params);
1185
1186 // Wrapper for DoGetFloatv.
1187 void DoGetFloatv(GLenum pname, GLfloat* params);
1188
[email protected]36cef8ce2010-03-16 07:34:451189 // Wrapper for glGetFramebufferAttachmentParameteriv.
1190 void DoGetFramebufferAttachmentParameteriv(
1191 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1192
[email protected]a0c3e972010-04-21 00:49:131193 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581194 void DoGetIntegerv(GLenum pname, GLint* params);
1195
[email protected]29a9eb52010-04-13 09:04:231196 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061197 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231198 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1199
[email protected]a0c3e972010-04-21 00:49:131200 // Wrapper for glGetProgramiv.
1201 void DoGetProgramiv(
1202 GLuint program_id, GLenum pname, GLint* params);
1203
[email protected]36cef8ce2010-03-16 07:34:451204 // Wrapper for glRenderbufferParameteriv.
1205 void DoGetRenderbufferParameteriv(
1206 GLenum target, GLenum pname, GLint* params);
1207
[email protected]ddd968b82010-03-02 00:44:291208 // Wrapper for glGetShaderiv
1209 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1210
[email protected]b1122982010-05-17 23:04:241211 // Wrappers for glGetVertexAttrib.
1212 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1213 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1214
[email protected]1958e0e2010-04-22 05:17:151215 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241216 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151217 bool DoIsBuffer(GLuint client_id);
1218 bool DoIsFramebuffer(GLuint client_id);
1219 bool DoIsProgram(GLuint client_id);
1220 bool DoIsRenderbuffer(GLuint client_id);
1221 bool DoIsShader(GLuint client_id);
1222 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461223 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151224
[email protected]07f54fcc2009-12-22 02:46:301225 // Wrapper for glLinkProgram
1226 void DoLinkProgram(GLuint program);
1227
[email protected]269200b12010-11-18 22:53:061228 // Helper for RegisterSharedIdsCHROMIUM.
1229 void DoRegisterSharedIdsCHROMIUM(
1230 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101231
[email protected]36cef8ce2010-03-16 07:34:451232 // Wrapper for glRenderbufferStorage.
1233 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031234 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451235
[email protected]8e3e0662010-08-23 18:46:301236 // Wrapper for glRenderbufferStorageMultisampleEXT.
1237 void DoRenderbufferStorageMultisample(
1238 GLenum target, GLsizei samples, GLenum internalformat,
1239 GLsizei width, GLsizei height);
1240
[email protected]b273e432010-04-12 17:23:581241 // Wrapper for glReleaseShaderCompiler.
1242 void DoReleaseShaderCompiler() { }
1243
[email protected]3916c97e2010-02-25 03:20:501244 // Wrappers for glTexParameter functions.
1245 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1246 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1247 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1248 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1249
1250 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1251 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121252 void DoUniform1i(GLint fake_location, GLint v0);
1253 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1254 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1255 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1256 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101257
1258 // Wrappers for glUniformfv because some drivers don't correctly accept
1259 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121260 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1261 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1262 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1263 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501264
[email protected]43c2f1f2011-03-25 18:35:361265 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121266 GLint fake_location, GLsizei count, GLboolean transpose,
1267 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361268 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121269 GLint fake_location, GLsizei count, GLboolean transpose,
1270 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361271 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121272 GLint fake_location, GLsizei count, GLboolean transpose,
1273 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361274
[email protected]af6380962012-11-29 23:24:131275 bool SetVertexAttribValue(
1276 const char* function_name, GLuint index, const GLfloat* value);
1277
[email protected]b1122982010-05-17 23:04:241278 // Wrappers for glVertexAttrib??
1279 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1280 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1281 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1282 void DoVertexAttrib4f(
1283 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1284 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1285 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1286 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1287 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1288
[email protected]43410e92012-04-20 17:06:281289 // Wrapper for glViewport
1290 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1291
[email protected]07f54fcc2009-12-22 02:46:301292 // Wrapper for glUseProgram
1293 void DoUseProgram(GLuint program);
1294
[email protected]ae51d192010-04-27 00:48:031295 // Wrapper for glValidateProgram.
1296 void DoValidateProgram(GLuint program_client_id);
1297
[email protected]d2a0e1a2012-08-12 02:25:011298 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1299 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1300 void DoPopGroupMarkerEXT(void);
1301
[email protected]4e8a5b122010-05-08 22:00:101302 // Gets the number of values that will be returned by glGetXXX. Returns
1303 // false if pname is unknown.
1304 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1305
[email protected]1002c2d2011-06-28 22:39:041306 // Gets the GLError and stores it in our wrapper. Effectively
1307 // this lets us peek at the error without losing it.
1308 GLenum PeekGLError();
1309
[email protected]07f54fcc2009-12-22 02:46:301310 // Copies the real GL errors to the wrapper. This is so we can
1311 // make sure there are no native GL errors before calling some GL function
1312 // so that on return we know any error generated was for that specific
1313 // command.
1314 void CopyRealGLErrorsToWrapper();
1315
[email protected]6217d392010-03-25 22:08:351316 // Clear all real GL errors. This is to prevent the client from seeing any
1317 // errors caused by GL calls that it was not responsible for issuing.
1318 void ClearRealGLErrors();
1319
[email protected]445a8762012-12-06 15:43:211320 // Generates a GL error for a bad parameter.
1321 void SetGLErrorInvalidParam(
1322 GLenum error,
1323 const char* function_name,
1324 GLenum pname,
1325 GLint param);
1326
[email protected]07f54fcc2009-12-22 02:46:301327 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431328 bool IsDrawValid(
1329 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301330
[email protected]c13e1da62011-09-09 21:48:301331 // Returns true if successful, simulated will be true if attrib0 was
1332 // simulated.
[email protected]c6aef902012-02-14 03:31:421333 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431334 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281335 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241336
[email protected]ef526492010-06-02 23:12:251337 // Returns true if textures were set.
1338 bool SetBlackTextureForNonRenderableTextures();
[email protected]3916c97e2010-02-25 03:20:501339 void RestoreStateForNonRenderableTextures();
1340
[email protected]8fbedc02010-11-18 18:43:401341 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421342 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431343 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421344 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401345 void RestoreStateForSimulatedFixedAttribs();
1346
[email protected]c6aef902012-02-14 03:31:421347 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1348 // cases (primcount is 0 for non-instanced).
1349 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431350 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421351 bool instanced, GLenum mode, GLint first, GLsizei count,
1352 GLsizei primcount);
1353 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431354 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421355 bool instanced, GLenum mode, GLsizei count, GLenum type,
1356 int32 offset, GLsizei primcount);
1357
[email protected]07f54fcc2009-12-22 02:46:301358 // Gets the buffer id for a given target.
[email protected]3916c97e2010-02-25 03:20:501359 BufferManager::BufferInfo* GetBufferInfoForTarget(GLenum target) {
[email protected]07f54fcc2009-12-22 02:46:301360 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
[email protected]944b62f32012-09-27 02:20:461361 if (target == GL_ARRAY_BUFFER) {
[email protected]e259eb412012-10-13 05:47:241362 return state_.bound_array_buffer;
[email protected]944b62f32012-09-27 02:20:461363 } else {
[email protected]e259eb412012-10-13 05:47:241364 return state_.vertex_attrib_manager->element_array_buffer();
[email protected]944b62f32012-09-27 02:20:461365 }
[email protected]07f54fcc2009-12-22 02:46:301366 }
1367
[email protected]a93bb842010-02-16 23:03:471368 // Gets the texture id for a given target.
[email protected]3916c97e2010-02-25 03:20:501369 TextureManager::TextureInfo* GetTextureInfoForTarget(GLenum target) {
[email protected]e259eb412012-10-13 05:47:241370 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:501371 TextureManager::TextureInfo* info = NULL;
[email protected]a93bb842010-02-16 23:03:471372 switch (target) {
1373 case GL_TEXTURE_2D:
[email protected]3916c97e2010-02-25 03:20:501374 info = unit.bound_texture_2d;
1375 break;
[email protected]a93bb842010-02-16 23:03:471376 case GL_TEXTURE_CUBE_MAP:
1377 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1378 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1379 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1380 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1381 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1382 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
[email protected]3916c97e2010-02-25 03:20:501383 info = unit.bound_texture_cube_map;
1384 break;
[email protected]61eeb33f2011-07-26 15:30:311385 case GL_TEXTURE_EXTERNAL_OES:
1386 info = unit.bound_texture_external_oes;
1387 break;
[email protected]e51bdf32011-11-23 22:21:461388 case GL_TEXTURE_RECTANGLE_ARB:
1389 info = unit.bound_texture_rectangle_arb;
1390 break;
[email protected]a93bb842010-02-16 23:03:471391 default:
1392 NOTREACHED();
[email protected]3916c97e2010-02-25 03:20:501393 return NULL;
[email protected]a93bb842010-02-16 23:03:471394 }
[email protected]a0b78dc2011-11-11 10:43:101395 return info;
[email protected]a93bb842010-02-16 23:03:471396 }
1397
[email protected]09d50362012-10-18 20:54:371398 TextureManager::TextureInfo* GetTextureInfoForTargetUnlessDefault(
1399 GLenum target) {
1400 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
1401 if (!info)
1402 return NULL;
1403 if (info == texture_manager()->GetDefaultTextureInfo(target))
1404 return NULL;
1405 return info;
1406 }
1407
[email protected]61eeb33f2011-07-26 15:30:311408 GLenum GetBindTargetForSamplerType(GLenum type) {
1409 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461410 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1411 switch (type) {
1412 case GL_SAMPLER_2D:
1413 return GL_TEXTURE_2D;
1414 case GL_SAMPLER_CUBE:
1415 return GL_TEXTURE_CUBE_MAP;
1416 case GL_SAMPLER_EXTERNAL_OES:
1417 return GL_TEXTURE_EXTERNAL_OES;
1418 case GL_SAMPLER_2D_RECT_ARB:
1419 return GL_TEXTURE_RECTANGLE_ARB;
1420 }
1421
1422 NOTREACHED();
1423 return 0;
[email protected]61eeb33f2011-07-26 15:30:311424 }
1425
[email protected]8e3e0662010-08-23 18:46:301426 // Gets the framebuffer info for a particular target.
1427 FramebufferManager::FramebufferInfo* GetFramebufferInfoForTarget(
1428 GLenum target) {
1429 FramebufferManager::FramebufferInfo* info = NULL;
1430 switch (target) {
1431 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451432 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]e259eb412012-10-13 05:47:241433 info = state_.bound_draw_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301434 break;
[email protected]ebfb73c2012-08-15 02:37:451435 case GL_READ_FRAMEBUFFER_EXT:
[email protected]e259eb412012-10-13 05:47:241436 info = state_.bound_read_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301437 break;
1438 default:
1439 NOTREACHED();
1440 break;
1441 }
[email protected]a0b78dc2011-11-11 10:43:101442 return info;
[email protected]8e3e0662010-08-23 18:46:301443 }
1444
[email protected]0d6bfdc2011-11-02 01:32:201445 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfoForTarget(
1446 GLenum target) {
1447 RenderbufferManager::RenderbufferInfo* info = NULL;
1448 switch (target) {
1449 case GL_RENDERBUFFER:
[email protected]e259eb412012-10-13 05:47:241450 info = state_.bound_renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201451 break;
1452 default:
1453 NOTREACHED();
1454 break;
1455 }
[email protected]a0b78dc2011-11-11 10:43:101456 return info;
[email protected]0d6bfdc2011-11-02 01:32:201457 }
1458
[email protected]f7b85372010-02-03 01:11:371459 // Validates the program and location for a glGetUniform call and returns
1460 // a SizeResult setup to receive the result. Returns true if glGetUniform
1461 // should be called.
1462 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121463 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371464 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121465 error::Error* error, GLint* real_location, GLuint* service_id,
1466 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371467
[email protected]1078f912011-12-23 13:12:141468 // Computes the estimated memory used for the backbuffer and passes it to
1469 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531470 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141471
[email protected]a10b4a02012-11-26 23:09:501472 virtual bool WasContextLost() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091473 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431474
[email protected]e51bdf32011-11-23 22:21:461475#if defined(OS_MACOSX)
1476 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1477#endif
1478
[email protected]81375742012-06-08 00:04:001479 // Validates the combination of texture parameters. For example validates that
1480 // for a given format the specific type, level and targets are valid.
1481 // Synthesizes the correct GL error if invalid. Returns true if valid.
1482 bool ValidateTextureParameters(
1483 const char* function_name,
1484 GLenum target, GLenum format, GLenum type, GLint level);
1485
[email protected]ad84a3a2012-06-08 21:42:431486 bool ValidateCompressedTexDimensions(
1487 const char* function_name,
1488 GLint level, GLsizei width, GLsizei height, GLenum format);
1489 bool ValidateCompressedTexFuncData(
1490 const char* function_name,
1491 GLsizei width, GLsizei height, GLenum format, size_t size);
1492 bool ValidateCompressedTexSubDimensions(
1493 const char* function_name,
1494 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1495 GLsizei width, GLsizei height, GLenum format,
1496 TextureManager::TextureInfo* texture);
1497
[email protected]0f8afe82012-05-14 23:43:011498 void LogMessage(const std::string& msg);
1499 void RenderWarning(const std::string& msg);
1500 void PerformanceWarning(const std::string& msg);
[email protected]d2a0e1a2012-08-12 02:25:011501 const std::string& GetLogPrefix() const;
[email protected]0f8afe82012-05-14 23:43:011502
[email protected]62e155e2012-10-23 22:43:151503 const FeatureInfo::FeatureFlags& features() const {
1504 return feature_info_->feature_flags();
1505 }
1506
1507 const FeatureInfo::Workarounds& workarounds() const {
1508 return feature_info_->workarounds();
1509 }
1510
[email protected]a7266a92012-06-28 02:11:081511 bool ShouldDeferDraws() {
1512 return !offscreen_target_frame_buffer_.get() &&
[email protected]e259eb412012-10-13 05:47:241513 state_.bound_draw_framebuffer == NULL &&
[email protected]a7266a92012-06-28 02:11:081514 surface_->DeferDraws();
1515 }
1516
[email protected]09e17272012-11-30 10:30:441517 bool ShouldDeferReads() {
1518 return !offscreen_target_frame_buffer_.get() &&
1519 state_.bound_read_framebuffer == NULL &&
1520 surface_->DeferDraws();
1521 }
1522
[email protected]c447acd2012-07-23 23:48:411523 void ForceCompileShaderIfPending(ShaderManager::ShaderInfo* info);
1524
[email protected]96449d2c2009-11-25 00:01:321525 // Generate a member function prototype for each command in an automated and
1526 // typesafe way.
1527 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141528 Error Handle ## name( \
[email protected]b9849abf2009-11-25 19:13:191529 uint32 immediate_data_size, \
[email protected]96449d2c2009-11-25 00:01:321530 const gles2::name& args); \
1531
1532 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1533
1534 #undef GLES2_CMD_OP
1535
[email protected]2f2d7042010-04-14 21:45:581536 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381537 scoped_refptr<gfx::GLSurface> surface_;
1538 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021539
[email protected]a3ded6d2010-10-19 06:44:391540 // The ContextGroup for this decoder uses to track resources.
1541 ContextGroup::Ref group_;
1542
[email protected]e259eb412012-10-13 05:47:241543 // All the state for this context.
1544 ContextState state_;
1545
[email protected]6217d392010-03-25 22:08:351546 // A parent decoder can access this decoders saved offscreen frame buffer.
1547 // The parent pointer is reset if the parent is destroyed.
1548 base::WeakPtr<GLES2DecoderImpl> parent_;
1549
[email protected]34ff8b0c2010-10-01 20:06:021550 // Current width and height of the offscreen frame buffer.
1551 gfx::Size offscreen_size_;
1552
[email protected]96449d2c2009-11-25 00:01:321553 // Current GL error bits.
1554 uint32 error_bits_;
1555
[email protected]96449d2c2009-11-25 00:01:321556 // Util to help with GL.
1557 GLES2Util util_;
1558
[email protected]43410e92012-04-20 17:06:281559 // unpack flip y as last set by glPixelStorei
1560 bool unpack_flip_y_;
1561
[email protected]6c75c712012-06-19 15:43:171562 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281563 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171564 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281565
[email protected]944b62f32012-09-27 02:20:461566 // Default vertex attribs manager, used when no VAOs are bound.
1567 VertexAttribManager::Ref default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301568
[email protected]b1122982010-05-17 23:04:241569 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1570 GLuint attrib_0_buffer_id_;
1571
1572 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131573 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241574
[email protected]fc753442011-02-04 19:49:491575 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1576 bool attrib_0_buffer_matches_value_;
1577
[email protected]b1122982010-05-17 23:04:241578 // The size of attrib 0.
1579 GLsizei attrib_0_size_;
1580
[email protected]8fbedc02010-11-18 18:43:401581 // The buffer used to simulate GL_FIXED attribs.
1582 GLuint fixed_attrib_buffer_id_;
1583
1584 // The size of fiixed attrib buffer.
1585 GLsizei fixed_attrib_buffer_size_;
1586
[email protected]3a2e7c7b2010-08-06 01:12:281587 // state saved for clearing so we can clear render buffers and then
1588 // restore to these values.
[email protected]88a61bf2012-10-27 13:00:421589 bool clear_state_dirty_;
[email protected]3a2e7c7b2010-08-06 01:12:281590
[email protected]b9363b22010-06-09 22:06:151591 // The offscreen frame buffer that the client renders to. With EGL, the
1592 // depth and stencil buffers are separate. With regular GL there is a single
1593 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1594 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]6217d392010-03-25 22:08:351595 scoped_ptr<FrameBuffer> offscreen_target_frame_buffer_;
1596 scoped_ptr<Texture> offscreen_target_color_texture_;
[email protected]34ff8b0c2010-10-01 20:06:021597 scoped_ptr<RenderBuffer> offscreen_target_color_render_buffer_;
[email protected]b9363b22010-06-09 22:06:151598 scoped_ptr<RenderBuffer> offscreen_target_depth_render_buffer_;
1599 scoped_ptr<RenderBuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021600 GLenum offscreen_target_color_format_;
1601 GLenum offscreen_target_depth_format_;
1602 GLenum offscreen_target_stencil_format_;
1603 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561604 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351605
[email protected]de26b3c2011-08-03 21:54:271606 // The copy that is saved when SwapBuffers is called.
[email protected]34ff8b0c2010-10-01 20:06:021607 scoped_ptr<FrameBuffer> offscreen_saved_frame_buffer_;
[email protected]6217d392010-03-25 22:08:351608 scoped_ptr<Texture> offscreen_saved_color_texture_;
[email protected]8a61d872012-01-20 12:43:561609 TextureManager::TextureInfo::Ref offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271610
1611 // The copy that is used as the destination for multi-sample resolves.
1612 scoped_ptr<FrameBuffer> offscreen_resolved_frame_buffer_;
1613 scoped_ptr<Texture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051614 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351615
[email protected]882ba1e22012-03-08 19:02:531616 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531617
[email protected]944b62f32012-09-27 02:20:461618 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1619
[email protected]9d37f062011-11-22 01:24:521620 base::Callback<void(gfx::Size)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001621
[email protected]6b6e7ee2011-12-13 08:04:521622 MsgCallback msg_callback_;
[email protected]43f28f832010-02-03 02:28:481623
[email protected]b0af4f52011-09-28 22:04:421624 StreamTextureManager* stream_texture_manager_;
[email protected]32145a92012-12-17 09:01:591625 scoped_ptr<gfx::AsyncPixelTransferDelegate> async_pixel_transfer_delegate_;
[email protected]b0af4f52011-09-28 22:04:421626
[email protected]32fe9aa2011-01-21 23:47:131627 // The format of the back buffer_
1628 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461629 bool back_buffer_has_depth_;
1630 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131631
[email protected]60f22d32012-12-12 00:31:581632 // Backbuffer attachments that are currently undefined.
1633 uint32 backbuffer_needs_clear_bits_;
1634
[email protected]473c01ccb2011-06-07 01:33:301635 bool teximage2d_faster_than_texsubimage2d_;
[email protected]473c01ccb2011-06-07 01:33:301636
[email protected]8eee29c2010-04-29 03:38:291637 // The last error message set.
1638 std::string last_error_;
1639
[email protected]0f8afe82012-05-14 23:43:011640 int log_message_count_;
[email protected]fa20ec82012-05-04 04:02:481641
[email protected]a3a93e7b2010-08-28 00:48:561642 // The current decoder error.
1643 error::Error current_decoder_error_;
1644
[email protected]d2a0e1a2012-08-12 02:25:011645 DebugMarkerManager debug_marker_manager_;
1646 std::string this_in_hex_;
1647
[email protected]b1d2dcb2010-05-17 19:24:181648 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041649 scoped_refptr<ShaderTranslator> vertex_translator_;
1650 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181651
[email protected]e82fb792011-09-22 00:33:291652 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411653
[email protected]915a59a12010-09-30 21:29:111654 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051655 const Validators* validators_;
[email protected]80eb6b52012-01-19 00:14:411656 FeatureInfo::Ref feature_info_;
[email protected]9438b012010-06-15 22:55:051657
[email protected]b493ee622011-04-13 23:52:001658 // This indicates all the following texSubImage2D calls that are part of the
1659 // failed texImage2D call should be ignored.
1660 bool tex_image_2d_failed_;
1661
[email protected]65225772011-05-12 21:10:241662 int frame_number_;
1663
[email protected]706b69f2012-07-27 04:59:301664 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431665 GLenum reset_status_;
1666
[email protected]f0d74742011-10-03 16:31:041667 // These flags are used to override the state of the shared feature_info_
1668 // member. Because the same FeatureInfo instance may be shared among many
1669 // contexts, the assumptions on the availablity of extensions in WebGL
1670 // contexts may be broken. These flags override the shared state to preserve
1671 // WebGL semantics.
1672 bool force_webgl_glsl_validation_;
1673 bool derivatives_explicitly_enabled_;
1674
[email protected]062c38b2012-01-18 03:25:101675 bool compile_shader_always_succeeds_;
1676
[email protected]cae20172012-12-07 00:06:191677 // Log extra info.
1678 bool service_logging_;
1679
[email protected]e51bdf32011-11-23 22:21:461680#if defined(OS_MACOSX)
1681 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1682 TextureToIOSurfaceMap texture_to_io_surface_map_;
1683#endif
1684
[email protected]c826d732012-02-09 04:40:261685 typedef std::vector<GLES2DecoderImpl*> ChildList;
1686 ChildList children_;
1687
[email protected]43410e92012-04-20 17:06:281688 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1689
[email protected]1868a342012-11-07 15:56:021690 // Cached values of the currently assigned viewport dimensions.
1691 GLsizei viewport_max_width_;
1692 GLsizei viewport_max_height_;
1693
[email protected]63b465922012-09-06 02:04:521694 // Command buffer stats.
1695 int texture_upload_count_;
1696 base::TimeDelta total_texture_upload_time_;
1697 base::TimeDelta total_processing_commands_time_;
1698
[email protected]94307712012-11-16 23:26:111699 std::stack<linked_ptr<GPUTrace> > gpu_trace_stack_;
1700
[email protected]96449d2c2009-11-25 00:01:321701 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1702};
1703
[email protected]6217d392010-03-25 22:08:351704ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder)
1705 : decoder_(decoder) {
1706 decoder_->CopyRealGLErrorsToWrapper();
1707}
1708
1709ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
1710 decoder_->ClearRealGLErrors();
1711}
1712
1713ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1714 GLuint id)
1715 : decoder_(decoder) {
1716 ScopedGLErrorSuppressor suppressor(decoder_);
1717
1718 // TODO(apatrick): Check if there are any other states that need to be reset
1719 // before binding a new texture.
1720 glActiveTexture(GL_TEXTURE0);
1721 glBindTexture(GL_TEXTURE_2D, id);
1722}
1723
1724ScopedTexture2DBinder::~ScopedTexture2DBinder() {
1725 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301726 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351727}
1728
1729ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1730 GLuint id)
1731 : decoder_(decoder) {
1732 ScopedGLErrorSuppressor suppressor(decoder_);
1733 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1734}
1735
1736ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
1737 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301738 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351739}
1740
1741ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1742 GLuint id)
1743 : decoder_(decoder) {
1744 ScopedGLErrorSuppressor suppressor(decoder_);
1745 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
1746}
1747
1748ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
1749 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301750 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351751}
1752
[email protected]34ff8b0c2010-10-01 20:06:021753ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271754 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521755 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021756 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1757 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241758 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521759 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021760 if (!resolve_and_bind_)
1761 return;
1762
1763 ScopedGLErrorSuppressor suppressor(decoder_);
1764 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1765 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271766 GLuint targetid;
1767 if (internal) {
1768 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1769 decoder_->offscreen_resolved_frame_buffer_.reset(
1770 new FrameBuffer(decoder_));
1771 decoder_->offscreen_resolved_frame_buffer_->Create();
1772 decoder_->offscreen_resolved_color_texture_.reset(new Texture(decoder_));
1773 decoder_->offscreen_resolved_color_texture_->Create();
1774
1775 DCHECK(decoder_->offscreen_saved_color_format_);
1776 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
1777 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_);
[email protected]de26b3c2011-08-03 21:54:271778 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1779 decoder_->offscreen_resolved_color_texture_.get());
1780 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1781 GL_FRAMEBUFFER_COMPLETE) {
1782 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1783 << "because offscreen resolved FBO was incomplete.";
1784 return;
1785 }
1786 }
1787 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1788 } else {
1789 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1790 }
1791 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021792 const int width = decoder_->offscreen_size_.width();
1793 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181794 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151795 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021796 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1797 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1798 } else {
1799 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1800 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1801 }
[email protected]de26b3c2011-08-03 21:54:271802 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021803}
1804
1805ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1806 if (!resolve_and_bind_)
1807 return;
1808
1809 ScopedGLErrorSuppressor suppressor(decoder_);
1810 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221811 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181812 glEnable(GL_SCISSOR_TEST);
1813 }
[email protected]34ff8b0c2010-10-01 20:06:021814}
1815
[email protected]63b465922012-09-06 02:04:521816ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder)
1817 : decoder_(decoder),
1818 begin_time_(base::TimeTicks::HighResNow()) {
1819}
1820
1821ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1822 decoder_->texture_upload_count_++;
1823 decoder_->total_texture_upload_time_ +=
1824 base::TimeTicks::HighResNow() - begin_time_;
1825}
1826
[email protected]6217d392010-03-25 22:08:351827Texture::Texture(GLES2DecoderImpl* decoder)
1828 : decoder_(decoder),
[email protected]68e81a4a62012-12-13 01:16:481829 memory_tracker_(decoder->GetContextGroup()->memory_tracker(),
1830 MemoryTracker::kUnmanaged),
1831 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251832 id_(0) {
[email protected]6217d392010-03-25 22:08:351833}
1834
1835Texture::~Texture() {
1836 // This does not destroy the render texture because that would require that
1837 // the associated GL context was current. Just check that it was explicitly
1838 // destroyed.
1839 DCHECK_EQ(id_, 0u);
1840}
1841
1842void Texture::Create() {
1843 ScopedGLErrorSuppressor suppressor(decoder_);
1844 Destroy();
1845 glGenTextures(1, &id_);
[email protected]3a4d0c52011-06-29 23:11:581846 ScopedTexture2DBinder binder(decoder_, id_);
1847 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1848 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1849 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1850 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161851
1852 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1853 // never called on an offscreen context, no data will ever be uploaded to the
1854 // saved offscreen color texture (it is deferred until to when SwapBuffers
1855 // is called). My idea is that some nvidia drivers might have a bug where
1856 // deleting a texture that has never been populated might cause a
1857 // crash.
1858 glTexImage2D(
1859 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481860
1861 bytes_allocated_ = 16u * 16u * 4u;
1862 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351863}
1864
[email protected]34ff8b0c2010-10-01 20:06:021865bool Texture::AllocateStorage(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351866 DCHECK_NE(id_, 0u);
1867 ScopedGLErrorSuppressor suppressor(decoder_);
1868 ScopedTexture2DBinder binder(decoder_, id_);
[email protected]6217d392010-03-25 22:08:351869
[email protected]f0e6a34f2012-01-04 20:53:401870 WrappedTexImage2D(GL_TEXTURE_2D,
1871 0, // mip level
1872 format,
1873 size.width(),
1874 size.height(),
1875 0, // border
1876 format,
1877 GL_UNSIGNED_BYTE,
1878 NULL);
[email protected]6217d392010-03-25 22:08:351879
[email protected]d37231fa2010-04-09 21:16:021880 size_ = size;
1881
[email protected]1078f912011-12-23 13:12:141882 bool success = glGetError() == GL_NO_ERROR;
1883 if (success) {
1884 uint32 image_size = 0;
[email protected]3458a64a2012-04-10 17:39:341885 GLES2Util::ComputeImageDataSizes(
1886 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 4, &image_size,
1887 NULL, NULL);
[email protected]68e81a4a62012-12-13 01:16:481888 memory_tracker_.TrackMemFree(bytes_allocated_);
1889 bytes_allocated_ = image_size;
1890 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141891 }
1892 return success;
[email protected]6217d392010-03-25 22:08:351893}
1894
[email protected]3a4d0c52011-06-29 23:11:581895void Texture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351896 DCHECK_NE(id_, 0u);
1897 ScopedGLErrorSuppressor suppressor(decoder_);
1898 ScopedTexture2DBinder binder(decoder_, id_);
1899 glCopyTexImage2D(GL_TEXTURE_2D,
1900 0, // level
[email protected]3a4d0c52011-06-29 23:11:581901 format,
[email protected]6217d392010-03-25 22:08:351902 0, 0,
1903 size.width(),
1904 size.height(),
1905 0); // border
1906}
1907
1908void Texture::Destroy() {
1909 if (id_ != 0) {
1910 ScopedGLErrorSuppressor suppressor(decoder_);
1911 glDeleteTextures(1, &id_);
1912 id_ = 0;
[email protected]6217d392010-03-25 22:08:351913 }
[email protected]68e81a4a62012-12-13 01:16:481914 memory_tracker_.TrackMemFree(bytes_allocated_);
1915 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351916}
1917
[email protected]97872062010-11-03 19:07:051918void Texture::Invalidate() {
1919 id_ = 0;
1920}
1921
[email protected]6217d392010-03-25 22:08:351922RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder)
1923 : decoder_(decoder),
[email protected]68e81a4a62012-12-13 01:16:481924 memory_tracker_(decoder->GetContextGroup()->memory_tracker(),
1925 MemoryTracker::kUnmanaged),
1926 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251927 id_(0) {
[email protected]6217d392010-03-25 22:08:351928}
1929
1930RenderBuffer::~RenderBuffer() {
1931 // This does not destroy the render buffer because that would require that
1932 // the associated GL context was current. Just check that it was explicitly
1933 // destroyed.
1934 DCHECK_EQ(id_, 0u);
1935}
1936
1937void RenderBuffer::Create() {
1938 ScopedGLErrorSuppressor suppressor(decoder_);
1939 Destroy();
1940 glGenRenderbuffersEXT(1, &id_);
1941}
1942
[email protected]34ff8b0c2010-10-01 20:06:021943bool RenderBuffer::AllocateStorage(const gfx::Size& size, GLenum format,
1944 GLsizei samples) {
[email protected]6217d392010-03-25 22:08:351945 ScopedGLErrorSuppressor suppressor(decoder_);
1946 ScopedRenderBufferBinder binder(decoder_, id_);
[email protected]34ff8b0c2010-10-01 20:06:021947 if (samples <= 1) {
1948 glRenderbufferStorageEXT(GL_RENDERBUFFER,
1949 format,
1950 size.width(),
1951 size.height());
1952 } else {
[email protected]57edfdad2012-02-07 04:57:151953 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021954 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
1955 samples,
1956 format,
1957 size.width(),
1958 size.height());
1959 } else {
1960 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
1961 samples,
1962 format,
1963 size.width(),
1964 size.height());
1965 }
1966 }
[email protected]1078f912011-12-23 13:12:141967 bool success = glGetError() == GL_NO_ERROR;
1968 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481969 memory_tracker_.TrackMemFree(bytes_allocated_);
1970 bytes_allocated_ =
[email protected]ff6493f2012-07-31 19:52:251971 size.width() * size.height() * samples *
[email protected]68e81a4a62012-12-13 01:16:481972 GLES2Util::RenderbufferBytesPerPixel(format);
1973 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141974 }
1975 return success;
[email protected]6217d392010-03-25 22:08:351976}
1977
1978void RenderBuffer::Destroy() {
1979 if (id_ != 0) {
1980 ScopedGLErrorSuppressor suppressor(decoder_);
1981 glDeleteRenderbuffersEXT(1, &id_);
1982 id_ = 0;
[email protected]6217d392010-03-25 22:08:351983 }
[email protected]68e81a4a62012-12-13 01:16:481984 memory_tracker_.TrackMemFree(bytes_allocated_);
1985 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351986}
1987
[email protected]97872062010-11-03 19:07:051988void RenderBuffer::Invalidate() {
1989 id_ = 0;
1990}
1991
[email protected]6217d392010-03-25 22:08:351992FrameBuffer::FrameBuffer(GLES2DecoderImpl* decoder)
1993 : decoder_(decoder),
1994 id_(0) {
1995}
1996
1997FrameBuffer::~FrameBuffer() {
1998 // This does not destroy the frame buffer because that would require that
1999 // the associated GL context was current. Just check that it was explicitly
2000 // destroyed.
2001 DCHECK_EQ(id_, 0u);
2002}
2003
2004void FrameBuffer::Create() {
2005 ScopedGLErrorSuppressor suppressor(decoder_);
2006 Destroy();
2007 glGenFramebuffersEXT(1, &id_);
2008}
2009
2010void FrameBuffer::AttachRenderTexture(Texture* texture) {
2011 DCHECK_NE(id_, 0u);
2012 ScopedGLErrorSuppressor suppressor(decoder_);
2013 ScopedFrameBufferBinder binder(decoder_, id_);
2014 GLuint attach_id = texture ? texture->id() : 0;
2015 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2016 GL_COLOR_ATTACHMENT0,
2017 GL_TEXTURE_2D,
2018 attach_id,
2019 0);
2020}
2021
[email protected]b9363b22010-06-09 22:06:152022void FrameBuffer::AttachRenderBuffer(GLenum target,
2023 RenderBuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352024 DCHECK_NE(id_, 0u);
2025 ScopedGLErrorSuppressor suppressor(decoder_);
2026 ScopedFrameBufferBinder binder(decoder_, id_);
2027 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2028 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152029 target,
[email protected]6217d392010-03-25 22:08:352030 GL_RENDERBUFFER,
2031 attach_id);
2032}
2033
[email protected]6217d392010-03-25 22:08:352034void FrameBuffer::Destroy() {
2035 if (id_ != 0) {
2036 ScopedGLErrorSuppressor suppressor(decoder_);
2037 glDeleteFramebuffersEXT(1, &id_);
2038 id_ = 0;
2039 }
2040}
2041
[email protected]97872062010-11-03 19:07:052042void FrameBuffer::Invalidate() {
2043 id_ = 0;
2044}
2045
[email protected]6217d392010-03-25 22:08:352046GLenum FrameBuffer::CheckStatus() {
2047 DCHECK_NE(id_, 0u);
2048 ScopedGLErrorSuppressor suppressor(decoder_);
2049 ScopedFrameBufferBinder binder(decoder_, id_);
2050 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2051}
2052
[email protected]aa7666122011-09-02 19:45:522053GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2054 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322055}
2056
[email protected]aa7666122011-09-02 19:45:522057GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392058 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572059 group_(group),
[email protected]b3cbad12012-12-05 19:56:362060 state_(group_->feature_info()),
[email protected]96449d2c2009-11-25 00:01:322061 error_bits_(0),
[email protected]43410e92012-04-20 17:06:282062 unpack_flip_y_(false),
2063 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172064 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242065 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492066 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242067 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402068 fixed_attrib_buffer_id_(0),
2069 fixed_attrib_buffer_size_(0),
[email protected]88a61bf2012-10-27 13:00:422070 clear_state_dirty_(true),
[email protected]34ff8b0c2010-10-01 20:06:022071 offscreen_target_color_format_(0),
2072 offscreen_target_depth_format_(0),
2073 offscreen_target_stencil_format_(0),
2074 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562075 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052076 offscreen_saved_color_format_(0),
[email protected]b0af4f52011-09-28 22:04:422077 stream_texture_manager_(NULL),
[email protected]32fe9aa2011-01-21 23:47:132078 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462079 back_buffer_has_depth_(false),
2080 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582081 backbuffer_needs_clear_bits_(0),
[email protected]473c01ccb2011-06-07 01:33:302082 teximage2d_faster_than_texsubimage2d_(true),
[email protected]0f8afe82012-05-14 23:43:012083 log_message_count_(0),
[email protected]a3a93e7b2010-08-28 00:48:562084 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052085 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112086 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002087 feature_info_(group_->feature_info()),
[email protected]65225772011-05-12 21:10:242088 tex_image_2d_failed_(false),
[email protected]38d139d2011-07-14 00:38:432089 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302090 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512091 reset_status_(GL_NO_ERROR),
[email protected]f0d74742011-10-03 16:31:042092 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102093 derivatives_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282094 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192095 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2096 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022097 viewport_max_width_(0),
2098 viewport_max_height_(0),
[email protected]63b465922012-09-06 02:04:522099 texture_upload_count_(0) {
[email protected]3b1ecc262011-08-03 22:49:572100 DCHECK(group);
2101
[email protected]d2a0e1a2012-08-12 02:25:012102 GLES2DecoderImpl* this_temp = this;
2103 this_in_hex_ = HexEncode(&this_temp, sizeof(this_temp));
2104
[email protected]b1122982010-05-17 23:04:242105 attrib_0_value_.v[0] = 0.0f;
2106 attrib_0_value_.v[1] = 0.0f;
2107 attrib_0_value_.v[2] = 0.0f;
2108 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152109
[email protected]c2f8c8402010-12-06 18:07:242110 // The shader translator is used for WebGL even when running on EGL
2111 // because additional restrictions are needed (like only enabling
2112 // GL_OES_standard_derivatives on demand). It is used for the unit
2113 // tests because
2114 // GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes the
2115 // empty string to CompileShader and this is not a valid shader.
2116 // TODO(apatrick): fix this test.
2117 if ((gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
[email protected]62e155e2012-10-23 22:43:152118 !features().chromium_webglsl && !force_webgl_glsl_validation_) ||
[email protected]39ba4f02012-03-26 01:16:002119 gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
2120 CommandLine::ForCurrentProcess()->HasSwitch(
2121 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152122 use_shader_translator_ = false;
2123 }
[email protected]473c01ccb2011-06-07 01:33:302124
[email protected]a39370652012-09-25 21:52:132125 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:302126 if (IsAngle()) {
2127 teximage2d_faster_than_texsubimage2d_ = false;
[email protected]473c01ccb2011-06-07 01:33:302128 }
[email protected]96449d2c2009-11-25 00:01:322129}
2130
[email protected]80eb6b52012-01-19 00:14:412131GLES2DecoderImpl::~GLES2DecoderImpl() {
2132}
2133
[email protected]c410da802011-03-14 19:17:412134bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382135 const scoped_refptr<gfx::GLSurface>& surface,
2136 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232137 bool offscreen,
[email protected]c410da802011-03-14 19:17:412138 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292139 const DisallowedFeatures& disallowed_features,
[email protected]c410da802011-03-14 19:17:412140 const char* allowed_extensions,
[email protected]3c644d82011-06-20 19:58:242141 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322142 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382143 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302144 DCHECK(!context_.get());
2145
[email protected]e844ae22012-01-14 03:36:262146 if (CommandLine::ForCurrentProcess()->HasSwitch(
2147 switches::kEnableGPUDebugging)) {
2148 set_debug(true);
2149 }
2150
[email protected]39ba4f02012-03-26 01:16:002151 if (CommandLine::ForCurrentProcess()->HasSwitch(
2152 switches::kEnableGPUCommandLogging)) {
2153 set_log_commands(true);
2154 }
2155
[email protected]062c38b2012-01-18 03:25:102156 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2157 switches::kCompileShaderAlwaysSucceeds);
2158
[email protected]f62a5ab2011-05-23 20:34:152159
[email protected]63c9b052012-05-17 18:27:382160 // Take ownership of the context and surface. The surface can be replaced with
2161 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382162 context_ = context;
[email protected]63c9b052012-05-17 18:27:382163 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182164
[email protected]c4485aad62012-12-17 10:19:092165 if (!group_->Initialize(this, disallowed_features, allowed_extensions)) {
[email protected]09ddb91f2011-04-14 23:16:222166 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392167 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422168 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382169 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032170 return false;
[email protected]a3ded6d2010-10-19 06:44:392171 }
[email protected]b64c24952012-04-19 03:20:272172 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282173
[email protected]e82fb792011-09-22 00:33:292174 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502175
[email protected]af6380962012-11-29 23:24:132176 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462177 default_vertex_attrib_manager_ = new VertexAttribManager();
2178 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2179
[email protected]ab4fd7282012-10-12 16:25:572180 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2181 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322182
[email protected]d6ca4792012-05-14 19:24:132183 query_manager_.reset(new QueryManager(this, feature_info_));
[email protected]944b62f32012-09-27 02:20:462184 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532185
[email protected]302ce6d2011-07-07 23:28:112186 util_.set_num_compressed_texture_formats(
2187 validators_->compressed_texture_format.GetValues().size());
2188
[email protected]1071e572011-02-09 20:00:122189 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2190 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2191 // OpenGL ES 2.0 does not have this issue.
2192 glEnableVertexAttribArray(0);
2193 }
[email protected]b1122982010-05-17 23:04:242194 glGenBuffersARB(1, &attrib_0_buffer_id_);
2195 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2196 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2197 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402198 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082199
[email protected]1868a342012-11-07 15:56:022200 state_.texture_units.resize(group_->max_texture_units());
2201 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492202 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312203 // We want the last bind to be 2D.
2204 TextureManager::TextureInfo* info;
[email protected]62e155e2012-10-23 22:43:152205 if (features().oes_egl_image_external) {
[email protected]61eeb33f2011-07-26 15:30:312206 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_EXTERNAL_OES);
[email protected]e259eb412012-10-13 05:47:242207 state_.texture_units[tt].bound_texture_external_oes = info;
[email protected]61eeb33f2011-07-26 15:30:312208 glBindTexture(GL_TEXTURE_EXTERNAL_OES, info->service_id());
2209 }
[email protected]62e155e2012-10-23 22:43:152210 if (features().arb_texture_rectangle) {
[email protected]e51bdf32011-11-23 22:21:462211 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_RECTANGLE_ARB);
[email protected]e259eb412012-10-13 05:47:242212 state_.texture_units[tt].bound_texture_rectangle_arb = info;
[email protected]e51bdf32011-11-23 22:21:462213 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, info->service_id());
2214 }
[email protected]61eeb33f2011-07-26 15:30:312215 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
[email protected]e259eb412012-10-13 05:47:242216 state_.texture_units[tt].bound_texture_cube_map = info;
[email protected]00f893d2010-08-24 18:55:492217 glBindTexture(GL_TEXTURE_CUBE_MAP, info->service_id());
2218 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
[email protected]e259eb412012-10-13 05:47:242219 state_.texture_units[tt].bound_texture_2d = info;
[email protected]00f893d2010-08-24 18:55:492220 glBindTexture(GL_TEXTURE_2D, info->service_id());
[email protected]1958e0e2010-04-22 05:17:152221 }
[email protected]00f893d2010-08-24 18:55:492222 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502223 CHECK_GL_ERROR();
2224
[email protected]297ca1c2011-06-20 23:08:462225 ContextCreationAttribParser attrib_parser;
2226 if (!attrib_parser.Parse(attribs))
2227 return false;
[email protected]41c56362011-06-14 16:47:432228
[email protected]297ca1c2011-06-20 23:08:462229 // These are NOT if the back buffer has these proprorties. They are
2230 // if we want the command buffer to enforce them regardless of what
2231 // the real backbuffer is assuming the real back buffer gives us more than
2232 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2233 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2234 // can't do anything about that.
2235
2236 GLint v = 0;
2237 glGetIntegerv(GL_ALPHA_BITS, &v);
2238 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2239 // user requested RGB then RGB. If the user did not specify a preference than
2240 // use whatever we were given. Same for DEPTH and STENCIL.
2241 back_buffer_color_format_ =
2242 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2243 glGetIntegerv(GL_DEPTH_BITS, &v);
2244 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2245 glGetIntegerv(GL_STENCIL_BITS, &v);
2246 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
2247
[email protected]069944672012-04-25 20:52:232248 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022249 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542250 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022251 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432252 // max_sample_count must be initialized to a sane value. If
2253 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2254 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022255 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2256 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2257 max_sample_count);
2258 } else {
2259 offscreen_target_samples_ = 1;
2260 }
[email protected]8a61d872012-01-20 12:43:562261 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022262
2263 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2264 const bool rgb8_supported =
2265 context_->HasExtension("GL_OES_rgb8_rgba8");
2266 // The only available default render buffer formats in GLES2 have very
2267 // little precision. Don't enable multisampling unless 8-bit render
2268 // buffer formats are available--instead fall back to 8-bit textures.
2269 if (rgb8_supported && offscreen_target_samples_ > 1) {
2270 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2271 GL_RGBA8 : GL_RGB8;
2272 } else {
2273 offscreen_target_samples_ = 1;
2274 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2275 GL_RGBA : GL_RGB;
2276 }
2277
2278 // ANGLE only supports packed depth/stencil formats, so use it if it is
2279 // available.
2280 const bool depth24_stencil8_supported =
2281 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272282 VLOG(1) << "GL_OES_packed_depth_stencil "
2283 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002284 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2285 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022286 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2287 offscreen_target_stencil_format_ = 0;
2288 } else {
2289 // It may be the case that this depth/stencil combination is not
2290 // supported, but this will be checked later by CheckFramebufferStatus.
2291 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2292 GL_DEPTH_COMPONENT16 : 0;
2293 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2294 GL_STENCIL_INDEX8 : 0;
2295 }
2296 } else {
2297 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2298 GL_RGBA : GL_RGB;
2299
2300 // If depth is requested at all, use the packed depth stencil format if
2301 // it's available, as some desktop GL drivers don't support any non-packed
2302 // formats for depth attachments.
2303 const bool depth24_stencil8_supported =
2304 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272305 VLOG(1) << "GL_EXT_packed_depth_stencil "
2306 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022307
[email protected]71ee3642010-10-14 18:08:002308 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2309 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022310 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2311 offscreen_target_stencil_format_ = 0;
2312 } else {
2313 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2314 GL_DEPTH_COMPONENT : 0;
2315 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2316 GL_STENCIL_INDEX : 0;
2317 }
2318 }
2319
[email protected]97872062010-11-03 19:07:052320 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2321 GL_RGBA : GL_RGB;
2322
[email protected]6217d392010-03-25 22:08:352323 // Create the target frame buffer. This is the one that the client renders
2324 // directly to.
2325 offscreen_target_frame_buffer_.reset(new FrameBuffer(this));
2326 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022327 // Due to GLES2 format limitations, either the color texture (for
2328 // non-multisampling) or the color render buffer (for multisampling) will be
2329 // attached to the offscreen frame buffer. The render buffer has more
2330 // limited formats available to it, but the texture can't do multisampling.
2331 if (IsOffscreenBufferMultisampled()) {
2332 offscreen_target_color_render_buffer_.reset(new RenderBuffer(this));
2333 offscreen_target_color_render_buffer_->Create();
2334 } else {
2335 offscreen_target_color_texture_.reset(new Texture(this));
2336 offscreen_target_color_texture_->Create();
2337 }
2338 offscreen_target_depth_render_buffer_.reset(new RenderBuffer(this));
[email protected]b9363b22010-06-09 22:06:152339 offscreen_target_depth_render_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022340 offscreen_target_stencil_render_buffer_.reset(new RenderBuffer(this));
[email protected]b9363b22010-06-09 22:06:152341 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352342
2343 // Create the saved offscreen texture. The target frame buffer is copied
2344 // here when SwapBuffers is called.
[email protected]34ff8b0c2010-10-01 20:06:022345 offscreen_saved_frame_buffer_.reset(new FrameBuffer(this));
2346 offscreen_saved_frame_buffer_->Create();
2347 //
[email protected]6217d392010-03-25 22:08:352348 offscreen_saved_color_texture_.reset(new Texture(this));
2349 offscreen_saved_color_texture_->Create();
2350
[email protected]6217d392010-03-25 22:08:352351 // Allocate the render buffers at their initial size and check the status
2352 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592353 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012354 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382355 Destroy(true);
[email protected]6217d392010-03-25 22:08:352356 return false;
2357 }
2358
2359 // Bind to the new default frame buffer (the offscreen target frame buffer).
2360 // This should now be associated with ID zero.
2361 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2362 }
2363
[email protected]295faf4b2012-01-25 23:31:412364 // Clear the backbuffer.
2365 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2366
[email protected]76a0ee102010-04-07 21:03:042367 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2368 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2369 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372370 // mailing list archives. It also implicitly enables the desktop GL
2371 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2372 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152373 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2374 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372375 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152376 }
[email protected]de17df392010-04-23 21:09:412377
[email protected]706b69f2012-07-27 04:59:302378 has_robustness_extension_ =
2379 context->HasExtension("GL_ARB_robustness") ||
2380 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432381
[email protected]c2f8c8402010-12-06 18:07:242382 if (!InitializeShaderTranslator()) {
2383 return false;
[email protected]de17df392010-04-23 21:09:412384 }
[email protected]76a0ee102010-04-07 21:03:042385
[email protected]e259eb412012-10-13 05:47:242386 state_.viewport_width = size.width();
2387 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282388
[email protected]5904806b2012-05-08 18:10:222389 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282390 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022391 viewport_max_width_ = viewport_params[0];
2392 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282393
[email protected]88a61bf2012-10-27 13:00:422394 state_.scissor_width = state_.viewport_width;
2395 state_.scissor_height = state_.viewport_height;
2396
[email protected]11f3e702012-06-19 19:00:012397 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222398 state_.InitCapabilities();
2399 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242400 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]88a61bf2012-10-27 13:00:422401 glHint(GL_GENERATE_MIPMAP_HINT, state_.hint_generate_mipmap);
[email protected]e259eb412012-10-13 05:47:242402 glPixelStorei(GL_PACK_ALIGNMENT, state_.pack_alignment);
[email protected]e259eb412012-10-13 05:47:242403 glPixelStorei(GL_UNPACK_ALIGNMENT, state_.unpack_alignment);
[email protected]11f3e702012-06-19 19:00:012404
2405 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2406 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2407 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2408 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2409
[email protected]6d9374e2012-07-17 03:31:242410 // AMD and Intel drivers on Mac OS apparently get gl_PointCoord
2411 // backward from the spec and this setting makes them work
2412 // correctly. rdar://problem/11883495
[email protected]62e155e2012-10-23 22:43:152413 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462414 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2415 }
[email protected]dd289a5d62012-06-30 22:05:462416
[email protected]32145a92012-12-17 09:01:592417 // Create a delegate to perform async pixel transfers.
2418 async_pixel_transfer_delegate_ =
2419 gfx::AsyncPixelTransferDelegate::Create(context.get());
2420
[email protected]246a70452010-03-05 21:53:502421 return true;
[email protected]96449d2c2009-11-25 00:01:322422}
2423
[email protected]302ce6d2011-07-07 23:28:112424void GLES2DecoderImpl::UpdateCapabilities() {
2425 util_.set_num_compressed_texture_formats(
2426 validators_->compressed_texture_format.GetValues().size());
2427 util_.set_num_shader_binary_formats(
2428 validators_->shader_binary_format.GetValues().size());
2429}
2430
[email protected]c2f8c8402010-12-06 18:07:242431bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442432 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2433
[email protected]c2f8c8402010-12-06 18:07:242434 // Re-check the state of use_shader_translator_ each time this is called.
2435 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
[email protected]62e155e2012-10-23 22:43:152436 (features().chromium_webglsl || force_webgl_glsl_validation_) &&
[email protected]c2f8c8402010-12-06 18:07:242437 !use_shader_translator_) {
2438 use_shader_translator_ = true;
2439 }
2440 if (!use_shader_translator_) {
2441 return true;
2442 }
2443 ShBuiltInResources resources;
2444 ShInitBuiltInResources(&resources);
2445 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2446 resources.MaxVertexUniformVectors =
2447 group_->max_vertex_uniform_vectors();
2448 resources.MaxVaryingVectors = group_->max_varying_vectors();
2449 resources.MaxVertexTextureImageUnits =
2450 group_->max_vertex_texture_image_units();
2451 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2452 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2453 resources.MaxFragmentUniformVectors =
2454 group_->max_fragment_uniform_vectors();
2455 resources.MaxDrawBuffers = 1;
[email protected]f0d74742011-10-03 16:31:042456
2457 if (force_webgl_glsl_validation_) {
2458 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
2459 } else {
2460 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152461 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462462 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152463 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062464 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152465 features().oes_egl_image_external ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042466 }
2467
[email protected]693ca512012-11-13 18:09:132468 if (features().enable_shader_name_hashing)
2469 resources.HashFunction = &CityHashForAngle;
2470
[email protected]f0d74742011-10-03 16:31:042471 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ||
[email protected]62e155e2012-10-23 22:43:152472 features().chromium_webglsl ? SH_WEBGL_SPEC : SH_GLES2_SPEC;
[email protected]a2a0fe762011-09-20 00:59:122473 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2474 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2475 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2476 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
[email protected]62e155e2012-10-23 22:43:152477 workarounds().needs_glsl_built_in_function_emulation ?
[email protected]a2a0fe762011-09-20 00:59:122478 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
2479 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
[email protected]87fb6ab2012-06-13 22:28:042480
2481 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2482 vertex_translator_ = cache->GetTranslator(
2483 SH_VERTEX_SHADER, shader_spec, &resources,
2484 implementation_type, function_behavior);
2485 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242486 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382487 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242488 return false;
2489 }
[email protected]87fb6ab2012-06-13 22:28:042490
2491 fragment_translator_ = cache->GetTranslator(
2492 SH_FRAGMENT_SHADER, shader_spec, &resources,
2493 implementation_type, function_behavior);
2494 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242495 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382496 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242497 return false;
2498 }
2499 return true;
2500}
2501
[email protected]ae51d192010-04-27 00:48:032502bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472503 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ae51d192010-04-27 00:48:032504 if (GetBufferInfo(client_ids[ii])) {
2505 return false;
2506 }
2507 }
2508 scoped_array<GLuint> service_ids(new GLuint[n]);
2509 glGenBuffersARB(n, service_ids.get());
2510 for (GLsizei ii = 0; ii < n; ++ii) {
2511 CreateBufferInfo(client_ids[ii], service_ids[ii]);
2512 }
2513 return true;
2514}
2515
2516bool GLES2DecoderImpl::GenFramebuffersHelper(
2517 GLsizei n, const GLuint* client_ids) {
2518 for (GLsizei ii = 0; ii < n; ++ii) {
2519 if (GetFramebufferInfo(client_ids[ii])) {
2520 return false;
2521 }
2522 }
2523 scoped_array<GLuint> service_ids(new GLuint[n]);
2524 glGenFramebuffersEXT(n, service_ids.get());
2525 for (GLsizei ii = 0; ii < n; ++ii) {
2526 CreateFramebufferInfo(client_ids[ii], service_ids[ii]);
2527 }
2528 return true;
2529}
2530
2531bool GLES2DecoderImpl::GenRenderbuffersHelper(
2532 GLsizei n, const GLuint* client_ids) {
2533 for (GLsizei ii = 0; ii < n; ++ii) {
2534 if (GetRenderbufferInfo(client_ids[ii])) {
2535 return false;
2536 }
2537 }
2538 scoped_array<GLuint> service_ids(new GLuint[n]);
2539 glGenRenderbuffersEXT(n, service_ids.get());
2540 for (GLsizei ii = 0; ii < n; ++ii) {
2541 CreateRenderbufferInfo(client_ids[ii], service_ids[ii]);
2542 }
2543 return true;
2544}
2545
2546bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2547 for (GLsizei ii = 0; ii < n; ++ii) {
2548 if (GetTextureInfo(client_ids[ii])) {
2549 return false;
2550 }
2551 }
2552 scoped_array<GLuint> service_ids(new GLuint[n]);
2553 glGenTextures(n, service_ids.get());
2554 for (GLsizei ii = 0; ii < n; ++ii) {
2555 CreateTextureInfo(client_ids[ii], service_ids[ii]);
2556 }
2557 return true;
2558}
2559
2560void GLES2DecoderImpl::DeleteBuffersHelper(
2561 GLsizei n, const GLuint* client_ids) {
2562 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102563 BufferManager::BufferInfo* buffer = GetBufferInfo(client_ids[ii]);
2564 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242565 state_.vertex_attrib_manager->Unbind(buffer);
2566 if (state_.bound_array_buffer == buffer) {
2567 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102568 }
[email protected]ae51d192010-04-27 00:48:032569 RemoveBufferInfo(client_ids[ii]);
2570 }
[email protected]a93bb842010-02-16 23:03:472571 }
[email protected]07f54fcc2009-12-22 02:46:302572}
2573
[email protected]ae51d192010-04-27 00:48:032574void GLES2DecoderImpl::DeleteFramebuffersHelper(
2575 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452576 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152577 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112578
[email protected]a25fa872010-03-25 02:57:582579 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102580 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ae51d192010-04-27 00:48:032581 GetFramebufferInfo(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102582 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242583 if (framebuffer == state_.bound_draw_framebuffer) {
2584 state_.bound_draw_framebuffer = NULL;
[email protected]88a61bf2012-10-27 13:00:422585 clear_state_dirty_ = true;
[email protected]ebfb73c2012-08-15 02:37:452586 GLenum target = supports_separate_framebuffer_binds ?
2587 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112588 glBindFramebufferEXT(target, GetBackbufferServiceId());
2589 }
[email protected]e259eb412012-10-13 05:47:242590 if (framebuffer == state_.bound_read_framebuffer) {
2591 state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452592 GLenum target = supports_separate_framebuffer_binds ?
2593 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112594 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462595 }
[email protected]ae51d192010-04-27 00:48:032596 RemoveFramebufferInfo(client_ids[ii]);
2597 }
[email protected]a25fa872010-03-25 02:57:582598 }
[email protected]07f54fcc2009-12-22 02:46:302599}
2600
[email protected]ae51d192010-04-27 00:48:032601void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2602 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452603 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152604 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582605 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102606 RenderbufferManager::RenderbufferInfo* renderbuffer =
[email protected]ae51d192010-04-27 00:48:032607 GetRenderbufferInfo(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102608 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242609 if (state_.bound_renderbuffer == renderbuffer) {
2610 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102611 }
2612 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452613 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242614 if (state_.bound_read_framebuffer) {
2615 state_.bound_read_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452616 GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102617 }
[email protected]e259eb412012-10-13 05:47:242618 if (state_.bound_draw_framebuffer) {
2619 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452620 GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102621 }
2622 } else {
[email protected]e259eb412012-10-13 05:47:242623 if (state_.bound_draw_framebuffer) {
2624 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]a0b78dc2011-11-11 10:43:102625 GL_FRAMEBUFFER, renderbuffer);
2626 }
2627 }
[email protected]88a61bf2012-10-27 13:00:422628 clear_state_dirty_ = true;
[email protected]ae51d192010-04-27 00:48:032629 RemoveRenderbufferInfo(client_ids[ii]);
2630 }
[email protected]a25fa872010-03-25 02:57:582631 }
[email protected]07f54fcc2009-12-22 02:46:302632}
2633
[email protected]ae51d192010-04-27 00:48:032634void GLES2DecoderImpl::DeleteTexturesHelper(
2635 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452636 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152637 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472638 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102639 TextureManager::TextureInfo* texture = GetTextureInfo(client_ids[ii]);
2640 if (texture && !texture->IsDeleted()) {
2641 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:422642 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462643 }
[email protected]a0b78dc2011-11-11 10:43:102644 // Unbind texture from texture units.
[email protected]1868a342012-11-07 15:56:022645 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]e259eb412012-10-13 05:47:242646 state_.texture_units[jj].Unbind(texture);
[email protected]a0b78dc2011-11-11 10:43:102647 }
2648 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452649 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242650 if (state_.bound_read_framebuffer) {
2651 state_.bound_read_framebuffer->UnbindTexture(
[email protected]ebfb73c2012-08-15 02:37:452652 GL_READ_FRAMEBUFFER_EXT, texture);
[email protected]a0b78dc2011-11-11 10:43:102653 }
[email protected]e259eb412012-10-13 05:47:242654 if (state_.bound_draw_framebuffer) {
2655 state_.bound_draw_framebuffer->UnbindTexture(
[email protected]ebfb73c2012-08-15 02:37:452656 GL_DRAW_FRAMEBUFFER_EXT, texture);
[email protected]a0b78dc2011-11-11 10:43:102657 }
2658 } else {
[email protected]e259eb412012-10-13 05:47:242659 if (state_.bound_draw_framebuffer) {
2660 state_.bound_draw_framebuffer->UnbindTexture(GL_FRAMEBUFFER, texture);
[email protected]a0b78dc2011-11-11 10:43:102661 }
2662 }
2663 GLuint service_id = texture->service_id();
2664 if (texture->IsStreamTexture() && stream_texture_manager_) {
[email protected]b0af4f52011-09-28 22:04:422665 stream_texture_manager_->DestroyStreamTexture(service_id);
2666 }
[email protected]e51bdf32011-11-23 22:21:462667#if defined(OS_MACOSX)
2668 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2669 ReleaseIOSurfaceForTexture(service_id);
2670 }
2671#endif
[email protected]ae51d192010-04-27 00:48:032672 RemoveTextureInfo(client_ids[ii]);
2673 }
[email protected]a93bb842010-02-16 23:03:472674 }
[email protected]07f54fcc2009-12-22 02:46:302675}
2676
[email protected]43f28f832010-02-03 02:28:482677// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322678
[email protected]eb54a562010-01-20 21:55:182679bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382680 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2681 return false;
2682
2683 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432684 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]63c9b052012-05-17 18:27:382685 return false;
[email protected]38d139d2011-07-14 00:38:432686 }
2687
[email protected]32145a92012-12-17 09:01:592688 // TODO(epenner): Is there a better place to do this? Transfers
2689 // can complete any time we yield the main thread. So we *must*
2690 // process transfers after any such yield, before resuming.
2691 bool frame_buffer_dirty = false;
2692 bool texture_dirty = false;
2693 texture_manager()->BindFinishedAsyncPixelTransfers(
2694 &texture_dirty, &frame_buffer_dirty);
2695 // Texture unit zero might be stomped.
2696 if (texture_dirty)
2697 RestoreCurrentTexture2DBindings();
2698 // A texture attached to frame-buffer might have changed size.
2699 if (frame_buffer_dirty) {
2700 clear_state_dirty_ = true;
2701 // TODO(gman): If textures tracked which framebuffers they were attached to
2702 // we could just mark those framebuffers as not complete.
2703 framebuffer_manager()->IncFramebufferStateChangeCount();
2704 }
2705
[email protected]63c9b052012-05-17 18:27:382706 return true;
[email protected]eb54a562010-01-20 21:55:182707}
2708
[email protected]a96a6022011-11-04 00:58:122709void GLES2DecoderImpl::ReleaseCurrent() {
2710 if (context_.get())
2711 context_->ReleaseCurrent(surface_.get());
2712}
2713
[email protected]8e3e0662010-08-23 18:46:302714void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
[email protected]0d6bfdc2011-11-02 01:32:202715 RenderbufferManager::RenderbufferInfo* renderbuffer =
2716 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
[email protected]8e3e0662010-08-23 18:46:302717 glBindRenderbufferEXT(
[email protected]0d6bfdc2011-11-02 01:32:202718 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
[email protected]8e3e0662010-08-23 18:46:302719}
2720
2721static void RebindCurrentFramebuffer(
2722 GLenum target,
2723 FramebufferManager::FramebufferInfo* info,
[email protected]a3783712012-01-20 22:18:242724 GLuint back_buffer_service_id) {
[email protected]8e3e0662010-08-23 18:46:302725 GLuint framebuffer_id = info ? info->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462726
[email protected]a3783712012-01-20 22:18:242727 if (framebuffer_id == 0) {
2728 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302729 }
[email protected]297ca1c2011-06-20 23:08:462730
[email protected]8e3e0662010-08-23 18:46:302731 glBindFramebufferEXT(target, framebuffer_id);
2732}
2733
2734void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]88a61bf2012-10-27 13:00:422735 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462736
[email protected]62e155e2012-10-23 22:43:152737 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302738 RebindCurrentFramebuffer(
2739 GL_FRAMEBUFFER,
[email protected]e259eb412012-10-13 05:47:242740 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242741 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302742 } else {
2743 RebindCurrentFramebuffer(
2744 GL_READ_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242745 state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242746 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302747 RebindCurrentFramebuffer(
2748 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242749 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242750 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302751 }
2752}
2753
2754void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
[email protected]e259eb412012-10-13 05:47:242755 TextureUnit& info = state_.texture_units[0];
[email protected]8e3e0662010-08-23 18:46:302756 GLuint last_id;
2757 if (info.bound_texture_2d) {
2758 last_id = info.bound_texture_2d->service_id();
2759 } else {
2760 last_id = 0;
2761 }
2762
2763 glBindTexture(GL_TEXTURE_2D, last_id);
[email protected]e259eb412012-10-13 05:47:242764 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]8e3e0662010-08-23 18:46:302765}
2766
[email protected]0d6bfdc2011-11-02 01:32:202767bool GLES2DecoderImpl::CheckFramebufferValid(
2768 FramebufferManager::FramebufferInfo* framebuffer,
2769 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102770 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582771 if (backbuffer_needs_clear_bits_) {
2772 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2773 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2774 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2775 glClearStencil(0);
2776 glStencilMask(-1);
2777 glClearDepth(1.0f);
2778 glDepthMask(true);
2779 glDisable(GL_SCISSOR_TEST);
2780 glClear(backbuffer_needs_clear_bits_);
2781 backbuffer_needs_clear_bits_ = 0;
2782 RestoreClearState();
2783 }
[email protected]0d6bfdc2011-11-02 01:32:202784 return true;
2785 }
2786
[email protected]968351b2011-12-20 08:26:512787 if (framebuffer_manager()->IsComplete(framebuffer)) {
2788 return true;
2789 }
2790
[email protected]0d6bfdc2011-11-02 01:32:202791 GLenum completeness = framebuffer->IsPossiblyComplete();
2792 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
2793 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:432794 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272795 return false;
2796 }
[email protected]0d6bfdc2011-11-02 01:32:202797
2798 // Are all the attachments cleared?
2799 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2800 texture_manager()->HaveUnclearedMips()) {
2801 if (!framebuffer->IsCleared()) {
2802 // Can we clear them?
[email protected]73276522012-11-09 05:50:202803 if (framebuffer->GetStatus(texture_manager(), target) !=
2804 GL_FRAMEBUFFER_COMPLETE) {
[email protected]0d6bfdc2011-11-02 01:32:202805 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:432806 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2807 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202808 return false;
2809 }
2810 ClearUnclearedAttachments(target, framebuffer);
2811 }
2812 }
2813
[email protected]968351b2011-12-20 08:26:512814 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202815 if (framebuffer->GetStatus(texture_manager(), target) !=
2816 GL_FRAMEBUFFER_COMPLETE) {
[email protected]968351b2011-12-20 08:26:512817 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:432818 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2819 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512820 return false;
2821 }
2822 framebuffer_manager()->MarkAsComplete(framebuffer);
2823 }
2824
[email protected]0d6bfdc2011-11-02 01:32:202825 // NOTE: At this point we don't know if the framebuffer is complete but
2826 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272827 return true;
2828}
2829
[email protected]0d6bfdc2011-11-02 01:32:202830bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:152831 if (!features().chromium_framebuffer_multisample) {
[email protected]0d6bfdc2011-11-02 01:32:202832 return CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242833 state_.bound_draw_framebuffer, GL_FRAMEBUFFER_EXT, func_name);
[email protected]0d6bfdc2011-11-02 01:32:202834 }
2835 return CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242836 state_.bound_draw_framebuffer,
2837 GL_DRAW_FRAMEBUFFER_EXT, func_name) &&
[email protected]0d6bfdc2011-11-02 01:32:202838 CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242839 state_.bound_read_framebuffer,
2840 GL_READ_FRAMEBUFFER_EXT, func_name);
[email protected]0d6bfdc2011-11-02 01:32:202841}
2842
[email protected]8e3e0662010-08-23 18:46:302843gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]0d6bfdc2011-11-02 01:32:202844 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452845 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202846 if (framebuffer != NULL) {
[email protected]9edc6b22010-12-23 02:00:262847 const FramebufferManager::FramebufferInfo::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:202848 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:262849 if (attachment) {
2850 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:502851 }
[email protected]9edc6b22010-12-23 02:00:262852 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:022853 } else if (offscreen_target_frame_buffer_.get()) {
2854 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:352855 } else {
[email protected]f62a5ab2011-05-23 20:34:152856 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:022857 }
[email protected]246a70452010-03-05 21:53:502858}
2859
[email protected]9edc6b22010-12-23 02:00:262860GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]0d6bfdc2011-11-02 01:32:202861 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452862 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202863 if (framebuffer != NULL) {
2864 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:462865 } else if (offscreen_target_frame_buffer_.get()) {
2866 return offscreen_target_color_format_;
2867 } else {
2868 return back_buffer_color_format_;
2869 }
2870}
2871
2872GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]0d6bfdc2011-11-02 01:32:202873 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452874 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202875 if (framebuffer != NULL) {
2876 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:262877 } else if (offscreen_target_frame_buffer_.get()) {
2878 return offscreen_target_color_format_;
2879 } else {
[email protected]32fe9aa2011-01-21 23:47:132880 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:262881 }
2882}
2883
[email protected]9a5afa432011-07-22 18:16:392884void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]34ff8b0c2010-10-01 20:06:022885 if (parent_) {
[email protected]2f2d7042010-04-14 21:45:582886 // Update the info about the offscreen saved color texture in the parent.
2887 // The reference to the parent is a weak pointer and will become null if the
2888 // parent is later destroyed.
[email protected]262d7aa2010-12-03 22:07:292889 TextureManager* parent_texture_manager = parent_->texture_manager();
[email protected]262d7aa2010-12-03 22:07:292890 parent_texture_manager->SetLevelInfo(
[email protected]8a61d872012-01-20 12:43:562891 offscreen_saved_color_texture_info_,
[email protected]ef526492010-06-02 23:12:252892 GL_TEXTURE_2D,
2893 0, // level
2894 GL_RGBA,
[email protected]799b4b22011-08-22 17:09:592895 offscreen_size_.width(),
2896 offscreen_size_.height(),
[email protected]ef526492010-06-02 23:12:252897 1, // depth
2898 0, // border
2899 GL_RGBA,
[email protected]0d6bfdc2011-11-02 01:32:202900 GL_UNSIGNED_BYTE,
2901 true);
[email protected]262d7aa2010-12-03 22:07:292902 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562903 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042904 GL_TEXTURE_MAG_FILTER,
2905 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:292906 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562907 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042908 GL_TEXTURE_MIN_FILTER,
2909 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:292910 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562911 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042912 GL_TEXTURE_WRAP_S,
2913 GL_CLAMP_TO_EDGE);
[email protected]262d7aa2010-12-03 22:07:292914 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562915 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042916 GL_TEXTURE_WRAP_T,
2917 GL_CLAMP_TO_EDGE);
[email protected]8a61d872012-01-20 12:43:562918 } else {
2919 offscreen_saved_color_texture_info_ = NULL;
[email protected]0c8c9d22010-06-25 17:36:392920 }
[email protected]6217d392010-03-25 22:08:352921}
2922
[email protected]799b4b22011-08-22 17:09:592923void GLES2DecoderImpl::SetResizeCallback(
[email protected]9d37f062011-11-22 01:24:522924 const base::Callback<void(gfx::Size)>& callback) {
2925 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:002926}
2927
[email protected]6b6e7ee2011-12-13 08:04:522928void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) {
2929 msg_callback_ = callback;
2930}
2931
[email protected]b0af4f52011-09-28 22:04:422932void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) {
2933 stream_texture_manager_ = manager;
2934}
2935
[email protected]32145a92012-12-17 09:01:592936gfx::AsyncPixelTransferDelegate*
2937 GLES2DecoderImpl::GetAsyncPixelTransferDelegate() {
2938 return async_pixel_transfer_delegate_.get();
2939}
2940
2941void GLES2DecoderImpl::SetAsyncPixelTransferDelegate(
2942 gfx::AsyncPixelTransferDelegate* delegate) {
2943 async_pixel_transfer_delegate_ = make_scoped_ptr(delegate);
2944}
2945
[email protected]1318e922010-09-17 22:03:162946bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
2947 uint32* service_texture_id) {
2948 TextureManager::TextureInfo* texture =
2949 texture_manager()->GetTextureInfo(client_texture_id);
2950 if (texture) {
2951 *service_texture_id = texture->service_id();
2952 return true;
2953 }
2954 return false;
2955}
2956
[email protected]63b465922012-09-06 02:04:522957uint32 GLES2DecoderImpl::GetTextureUploadCount() {
2958 return texture_upload_count_;
2959}
2960
2961base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
2962 return total_texture_upload_time_;
2963}
2964
2965base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
2966 return total_processing_commands_time_;
2967}
2968
[email protected]dc25dda2012-09-27 21:36:302969void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
2970 total_processing_commands_time_ += time;
2971}
2972
[email protected]63c9b052012-05-17 18:27:382973void GLES2DecoderImpl::Destroy(bool have_context) {
2974 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:052975
[email protected]c826d732012-02-09 04:40:262976 ChildList children = children_;
2977 for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
2978 (*it)->SetParent(NULL, 0);
2979 DCHECK(children_.empty());
[email protected]3c644d82011-06-20 19:58:242980 SetParent(NULL, 0);
2981
[email protected]80eb6b52012-01-19 00:14:412982 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:242983 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:462984 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:022985 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:242986 state_.bound_array_buffer = NULL;
2987 state_.current_query = NULL;
2988 state_.current_program = NULL;
2989 state_.bound_read_framebuffer = NULL;
2990 state_.bound_draw_framebuffer = NULL;
2991 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:412992
[email protected]eadc96792010-10-27 19:39:392993 if (have_context) {
[email protected]c322e882012-05-23 18:06:182994 if (copy_texture_CHROMIUM_.get()) {
2995 copy_texture_CHROMIUM_->Destroy();
2996 copy_texture_CHROMIUM_.reset();
2997 }
[email protected]43410e92012-04-20 17:06:282998
[email protected]e259eb412012-10-13 05:47:242999 if (state_.current_program) {
3000 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
3001 state_.current_program = NULL;
[email protected]ca488e12010-12-13 20:06:143002 }
3003
[email protected]b1122982010-05-17 23:04:243004 if (attrib_0_buffer_id_) {
3005 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3006 }
[email protected]8fbedc02010-11-18 18:43:403007 if (fixed_attrib_buffer_id_) {
3008 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3009 }
[email protected]b1122982010-05-17 23:04:243010
[email protected]97872062010-11-03 19:07:053011 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543012 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053013 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543014 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053015 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023016 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053017 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153018 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053019 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153020 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053021 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023022 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053023 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543024 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273025 if (offscreen_resolved_frame_buffer_.get())
3026 offscreen_resolved_frame_buffer_->Destroy();
3027 if (offscreen_resolved_color_texture_.get())
3028 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053029 } else {
3030 if (offscreen_target_frame_buffer_.get())
3031 offscreen_target_frame_buffer_->Invalidate();
3032 if (offscreen_target_color_texture_.get())
3033 offscreen_target_color_texture_->Invalidate();
3034 if (offscreen_target_color_render_buffer_.get())
3035 offscreen_target_color_render_buffer_->Invalidate();
3036 if (offscreen_target_depth_render_buffer_.get())
3037 offscreen_target_depth_render_buffer_->Invalidate();
3038 if (offscreen_target_stencil_render_buffer_.get())
3039 offscreen_target_stencil_render_buffer_->Invalidate();
3040 if (offscreen_saved_frame_buffer_.get())
3041 offscreen_saved_frame_buffer_->Invalidate();
3042 if (offscreen_saved_color_texture_.get())
3043 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273044 if (offscreen_resolved_frame_buffer_.get())
3045 offscreen_resolved_frame_buffer_->Invalidate();
3046 if (offscreen_resolved_color_texture_.get())
3047 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023048 }
[email protected]43410e92012-04-20 17:06:283049 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053050
[email protected]882ba1e22012-03-08 19:02:533051 if (query_manager_.get()) {
3052 query_manager_->Destroy(have_context);
3053 query_manager_.reset();
3054 }
3055
[email protected]944b62f32012-09-27 02:20:463056 if (vertex_array_manager_ .get()) {
3057 vertex_array_manager_->Destroy(have_context);
3058 vertex_array_manager_.reset();
3059 }
3060
[email protected]1871a092011-10-10 21:46:423061 if (group_) {
[email protected]c4485aad62012-12-17 10:19:093062 group_->Destroy(this, have_context);
[email protected]1871a092011-10-10 21:46:423063 group_ = NULL;
3064 }
[email protected]3ae019382011-10-05 19:42:413065
[email protected]fe871662011-06-16 20:43:053066 if (context_.get()) {
3067 context_->ReleaseCurrent(NULL);
[email protected]79311e82011-09-20 00:40:503068 context_ = NULL;
[email protected]fe871662011-06-16 20:43:053069 }
[email protected]0fc35742011-04-13 17:57:543070
[email protected]97872062010-11-03 19:07:053071 offscreen_target_frame_buffer_.reset();
3072 offscreen_target_color_texture_.reset();
3073 offscreen_target_color_render_buffer_.reset();
3074 offscreen_target_depth_render_buffer_.reset();
3075 offscreen_target_stencil_render_buffer_.reset();
3076 offscreen_saved_frame_buffer_.reset();
3077 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273078 offscreen_resolved_frame_buffer_.reset();
3079 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463080
3081#if defined(OS_MACOSX)
3082 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3083 it != texture_to_io_surface_map_.end(); ++it) {
3084 CFRelease(it->second);
3085 }
3086 texture_to_io_surface_map_.clear();
3087#endif
[email protected]96449d2c2009-11-25 00:01:323088}
3089
[email protected]63c9b052012-05-17 18:27:383090void GLES2DecoderImpl::SetSurface(
3091 const scoped_refptr<gfx::GLSurface>& surface) {
3092 DCHECK(context_->IsCurrent(NULL));
3093 DCHECK(surface_.get());
3094 surface_ = surface;
3095 RestoreCurrentFramebufferBindings();
3096}
3097
[email protected]3c644d82011-06-20 19:58:243098bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent,
3099 uint32 new_parent_texture_id) {
[email protected]9a5afa432011-07-22 18:16:393100 if (!offscreen_saved_color_texture_.get())
3101 return false;
3102
[email protected]3c644d82011-06-20 19:58:243103 // Remove the saved frame buffer mapping from the parent decoder. The
3104 // parent pointer is a weak pointer so it will be null if the parent has
3105 // already been destroyed.
3106 if (parent_) {
[email protected]c826d732012-02-09 04:40:263107 ChildList::iterator it = std::find(
3108 parent_->children_.begin(),
3109 parent_->children_.end(),
3110 this);
3111 DCHECK(it != parent_->children_.end());
3112 parent_->children_.erase(it);
[email protected]3c644d82011-06-20 19:58:243113 // First check the texture has been mapped into the parent. This might not
3114 // be the case if initialization failed midway through.
3115 GLuint service_id = offscreen_saved_color_texture_->id();
3116 GLuint client_id = 0;
3117 if (parent_->texture_manager()->GetClientId(service_id, &client_id)) {
[email protected]80eb6b52012-01-19 00:14:413118 parent_->texture_manager()->RemoveTextureInfo(client_id);
[email protected]3c644d82011-06-20 19:58:243119 }
3120 }
3121
3122 GLES2DecoderImpl* new_parent_impl = static_cast<GLES2DecoderImpl*>(
3123 new_parent);
3124 if (new_parent_impl) {
[email protected]c826d732012-02-09 04:40:263125#ifndef NDEBUG
3126 ChildList::iterator it = std::find(
3127 new_parent_impl->children_.begin(),
3128 new_parent_impl->children_.end(),
3129 this);
3130 DCHECK(it == new_parent_impl->children_.end());
3131#endif
3132 new_parent_impl->children_.push_back(this);
[email protected]3c644d82011-06-20 19:58:243133 // Map the ID of the saved offscreen texture into the parent so that
3134 // it can reference it.
3135 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]98687862011-07-11 23:31:303136
3137 // Replace texture info when ID is already in use by parent.
3138 if (new_parent_impl->texture_manager()->GetTextureInfo(
[email protected]80eb6b52012-01-19 00:14:413139 new_parent_texture_id))
[email protected]98687862011-07-11 23:31:303140 new_parent_impl->texture_manager()->RemoveTextureInfo(
[email protected]80eb6b52012-01-19 00:14:413141 new_parent_texture_id);
[email protected]98687862011-07-11 23:31:303142
[email protected]8a61d872012-01-20 12:43:563143 offscreen_saved_color_texture_info_ =
[email protected]5f4f2a732011-07-30 00:47:553144 new_parent_impl->CreateTextureInfo(new_parent_texture_id, service_id);
[email protected]8a61d872012-01-20 12:43:563145 offscreen_saved_color_texture_info_->SetNotOwned();
3146 new_parent_impl->texture_manager()->
3147 SetInfoTarget(offscreen_saved_color_texture_info_, GL_TEXTURE_2D);
[email protected]3c644d82011-06-20 19:58:243148
[email protected]ee1e6aa2012-11-29 09:24:103149 parent_ = base::AsWeakPtr<GLES2DecoderImpl>(new_parent_impl);
[email protected]9a5afa432011-07-22 18:16:393150
3151 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243152 } else {
3153 parent_.reset();
[email protected]8a61d872012-01-20 12:43:563154 offscreen_saved_color_texture_info_ = NULL;
[email protected]3c644d82011-06-20 19:58:243155 }
3156
3157 return true;
3158}
3159
[email protected]260ddc4e2012-06-28 00:01:533160size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143161 size_t total = 0;
3162 if (offscreen_target_frame_buffer_.get()) {
3163 if (offscreen_target_color_texture_.get()) {
3164 total += offscreen_target_color_texture_->estimated_size();
3165 }
3166 if (offscreen_target_color_render_buffer_.get()) {
3167 total += offscreen_target_color_render_buffer_->estimated_size();
3168 }
3169 if (offscreen_target_depth_render_buffer_.get()) {
3170 total += offscreen_target_depth_render_buffer_->estimated_size();
3171 }
3172 if (offscreen_target_stencil_render_buffer_.get()) {
3173 total += offscreen_target_stencil_render_buffer_->estimated_size();
3174 }
3175 if (offscreen_saved_color_texture_.get()) {
3176 total += offscreen_saved_color_texture_->estimated_size();
3177 }
3178 if (offscreen_resolved_color_texture_.get()) {
3179 total += offscreen_resolved_color_texture_->estimated_size();
3180 }
3181 } else {
3182 gfx::Size size = surface_->GetSize();
3183 total += size.width() * size.height() *
3184 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3185 }
[email protected]260ddc4e2012-06-28 00:01:533186 return total;
[email protected]1078f912011-12-23 13:12:143187}
3188
[email protected]799b4b22011-08-22 17:09:593189bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3190 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3191 if (!is_offscreen) {
3192 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3193 << " with an onscreen framebuffer.";
3194 return false;
3195 }
3196
3197 if (offscreen_size_ == size)
3198 return true;
3199
3200 offscreen_size_ = size;
3201 int w = offscreen_size_.width();
3202 int h = offscreen_size_.height();
3203 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3204 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3205 << "to allocate storage due to excessive dimensions.";
3206 return false;
3207 }
3208
3209 // Reallocate the offscreen target buffers.
3210 DCHECK(offscreen_target_color_format_);
3211 if (IsOffscreenBufferMultisampled()) {
3212 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3213 offscreen_size_, offscreen_target_color_format_,
3214 offscreen_target_samples_)) {
3215 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3216 << "to allocate storage for offscreen target color buffer.";
3217 return false;
3218 }
3219 } else {
3220 if (!offscreen_target_color_texture_->AllocateStorage(
3221 offscreen_size_, offscreen_target_color_format_)) {
3222 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3223 << "to allocate storage for offscreen target color texture.";
3224 return false;
3225 }
3226 }
3227 if (offscreen_target_depth_format_ &&
3228 !offscreen_target_depth_render_buffer_->AllocateStorage(
3229 offscreen_size_, offscreen_target_depth_format_,
3230 offscreen_target_samples_)) {
3231 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3232 << "to allocate storage for offscreen target depth buffer.";
3233 return false;
3234 }
3235 if (offscreen_target_stencil_format_ &&
3236 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3237 offscreen_size_, offscreen_target_stencil_format_,
3238 offscreen_target_samples_)) {
3239 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3240 << "to allocate storage for offscreen target stencil buffer.";
3241 return false;
3242 }
3243
3244 // Attach the offscreen target buffers to the target frame buffer.
3245 if (IsOffscreenBufferMultisampled()) {
3246 offscreen_target_frame_buffer_->AttachRenderBuffer(
3247 GL_COLOR_ATTACHMENT0,
3248 offscreen_target_color_render_buffer_.get());
3249 } else {
3250 offscreen_target_frame_buffer_->AttachRenderTexture(
3251 offscreen_target_color_texture_.get());
3252 }
3253 if (offscreen_target_depth_format_) {
3254 offscreen_target_frame_buffer_->AttachRenderBuffer(
3255 GL_DEPTH_ATTACHMENT,
3256 offscreen_target_depth_render_buffer_.get());
3257 }
3258 const bool packed_depth_stencil =
3259 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3260 if (packed_depth_stencil) {
3261 offscreen_target_frame_buffer_->AttachRenderBuffer(
3262 GL_STENCIL_ATTACHMENT,
3263 offscreen_target_depth_render_buffer_.get());
3264 } else if (offscreen_target_stencil_format_) {
3265 offscreen_target_frame_buffer_->AttachRenderBuffer(
3266 GL_STENCIL_ATTACHMENT,
3267 offscreen_target_stencil_render_buffer_.get());
3268 }
3269
3270 if (offscreen_target_frame_buffer_->CheckStatus() !=
3271 GL_FRAMEBUFFER_COMPLETE) {
3272 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3273 << "because offscreen FBO was incomplete.";
3274 return false;
3275 }
3276
3277 // Clear the target frame buffer.
3278 {
3279 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3280 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3281 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3282 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3283 glClearStencil(0);
3284 glStencilMaskSeparate(GL_FRONT, -1);
3285 glStencilMaskSeparate(GL_BACK, -1);
3286 glClearDepth(0);
3287 glDepthMask(GL_TRUE);
3288 glDisable(GL_SCISSOR_TEST);
3289 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3290 RestoreClearState();
3291 }
[email protected]d85ef76d2011-09-08 22:21:433292
3293 // Destroy the offscreen resolved framebuffers.
3294 if (offscreen_resolved_frame_buffer_.get())
3295 offscreen_resolved_frame_buffer_->Destroy();
3296 if (offscreen_resolved_color_texture_.get())
3297 offscreen_resolved_color_texture_->Destroy();
3298 offscreen_resolved_color_texture_.reset();
3299 offscreen_resolved_frame_buffer_.reset();
3300
[email protected]799b4b22011-08-22 17:09:593301 return true;
[email protected]6217d392010-03-25 22:08:353302}
3303
[email protected]799b4b22011-08-22 17:09:593304error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
3305 uint32 immediate_data_size, const gles2::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443306 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023307 return error::kDeferCommandUntilLater;
3308
[email protected]799b4b22011-08-22 17:09:593309 GLuint width = static_cast<GLuint>(c.width);
3310 GLuint height = static_cast<GLuint>(c.height);
3311 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]a0d989162011-11-22 13:15:073312#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3313 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003314 // Make sure that we are done drawing to the back buffer before resizing.
3315 glFinish();
3316#endif
[email protected]799b4b22011-08-22 17:09:593317 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3318 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493319 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3320 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3321 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593322 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493323 }
[email protected]7ff86b92010-11-25 17:50:003324 }
[email protected]799b4b22011-08-22 17:09:593325
[email protected]9d37f062011-11-22 01:24:523326 if (!resize_callback_.is_null()) {
3327 resize_callback_.Run(gfx::Size(width, height));
[email protected]c777de52011-09-09 23:08:563328 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493329 if (!context_->IsCurrent(surface_.get())) {
3330 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3331 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053332 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493333 }
[email protected]658f7562011-09-09 05:24:053334 }
[email protected]799b4b22011-08-22 17:09:593335
3336 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393337}
3338
[email protected]96449d2c2009-11-25 00:01:323339const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3340 if (command_id > kStartPoint && command_id < kNumCommands) {
3341 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3342 }
3343 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3344}
3345
3346// Decode command with its arguments, and call the corresponding GL function.
3347// Note: args is a pointer to the command buffer. As such, it could be changed
3348// by a (malicious) client at any time, so if validation has to happen, it
3349// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143350error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323351 unsigned int command,
3352 unsigned int arg_count,
3353 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143354 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263355 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003356 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3357 // LOG(INFO), tried VLOG(1), no luck.
[email protected]d2a0e1a2012-08-12 02:25:013358 LOG(ERROR) << "[" << GetLogPrefix() << "]" << "cmd: "
3359 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193360 }
[email protected]96449d2c2009-11-25 00:01:323361 unsigned int command_index = command - kStartPoint - 1;
3362 if (command_index < arraysize(g_command_info)) {
3363 const CommandInfo& info = g_command_info[command_index];
3364 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3365 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3366 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193367 uint32 immediate_data_size =
3368 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323369 switch (command) {
3370 #define GLES2_CMD_OP(name) \
3371 case name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193372 result = Handle ## name( \
3373 immediate_data_size, \
[email protected]96449d2c2009-11-25 00:01:323374 *static_cast<const name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193375 break; \
[email protected]96449d2c2009-11-25 00:01:323376
3377 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323378 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383379 }
3380 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303381 GLenum error;
3382 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]d2a0e1a2012-08-12 02:25:013383 LOG(ERROR) << "[" << GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003384 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3385 << GetCommandName(command);
[email protected]ad84a3a2012-06-08 21:42:433386 SetGLError(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193387 }
[email protected]96449d2c2009-11-25 00:01:323388 }
3389 } else {
[email protected]f7a64ee2010-02-01 22:24:143390 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323391 }
[email protected]b9849abf2009-11-25 19:13:193392 } else {
3393 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323394 }
[email protected]a3a93e7b2010-08-28 00:48:563395 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3396 result = current_decoder_error_;
3397 current_decoder_error_ = error::kNoError;
3398 }
[email protected]b9849abf2009-11-25 19:13:193399 return result;
[email protected]96449d2c2009-11-25 00:01:323400}
3401
[email protected]ae51d192010-04-27 00:48:033402void GLES2DecoderImpl::RemoveBufferInfo(GLuint client_id) {
3403 buffer_manager()->RemoveBufferInfo(client_id);
[email protected]3916c97e2010-02-25 03:20:503404}
3405
[email protected]ae51d192010-04-27 00:48:033406bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
3407 if (GetProgramInfo(client_id)) {
3408 return false;
3409 }
[email protected]96449d2c2009-11-25 00:01:323410 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033411 if (service_id != 0) {
3412 CreateProgramInfo(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323413 }
[email protected]ae51d192010-04-27 00:48:033414 return true;
[email protected]96449d2c2009-11-25 00:01:323415}
3416
[email protected]ae51d192010-04-27 00:48:033417bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
3418 if (GetShaderInfo(client_id)) {
3419 return false;
[email protected]96449d2c2009-11-25 00:01:323420 }
[email protected]ae51d192010-04-27 00:48:033421 GLuint service_id = glCreateShader(type);
3422 if (service_id != 0) {
[email protected]7cea56d92010-04-28 17:21:383423 CreateShaderInfo(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033424 }
3425 return true;
[email protected]96449d2c2009-11-25 00:01:323426}
3427
[email protected]882ba1e22012-03-08 19:02:533428void GLES2DecoderImpl::DoFinish() {
3429 glFinish();
[email protected]22e3f552012-03-13 01:54:193430 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533431}
3432
3433void GLES2DecoderImpl::DoFlush() {
3434 glFlush();
[email protected]22e3f552012-03-13 01:54:193435 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533436}
3437
[email protected]3916c97e2010-02-25 03:20:503438void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453439 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023440 if (texture_index >= state_.texture_units.size()) {
[email protected]f80e6e12012-08-31 00:43:533441 SetGLErrorInvalidEnum(
3442 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503443 return;
3444 }
[email protected]e259eb412012-10-13 05:47:243445 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453446 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503447}
3448
[email protected]051b1372010-04-12 02:42:083449void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]3916c97e2010-02-25 03:20:503450 BufferManager::BufferInfo* info = NULL;
[email protected]051b1372010-04-12 02:42:083451 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033452 if (client_id != 0) {
3453 info = GetBufferInfo(client_id);
3454 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353455 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153456 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3457 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353458 return;
3459 }
3460
[email protected]ae51d192010-04-27 00:48:033461 // It's a new id so make a buffer info for it.
3462 glGenBuffersARB(1, &service_id);
3463 CreateBufferInfo(client_id, service_id);
3464 info = GetBufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573465 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103466 group_->GetIdAllocator(id_namespaces::kBuffers);
3467 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033468 }
[email protected]051b1372010-04-12 02:42:083469 }
[email protected]cae20172012-12-07 00:06:193470 LogClientServiceForInfo(info, client_id, "glBindBuffer");
[email protected]ae51d192010-04-27 00:48:033471 if (info) {
[email protected]4e8a5b122010-05-08 22:00:103472 if (!buffer_manager()->SetTarget(info, target)) {
[email protected]8eee29c2010-04-29 03:38:293473 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433474 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473475 return;
3476 }
[email protected]ae51d192010-04-27 00:48:033477 service_id = info->service_id();
[email protected]a93bb842010-02-16 23:03:473478 }
[email protected]96449d2c2009-11-25 00:01:323479 switch (target) {
3480 case GL_ARRAY_BUFFER:
[email protected]e259eb412012-10-13 05:47:243481 state_.bound_array_buffer = info;
[email protected]96449d2c2009-11-25 00:01:323482 break;
3483 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]e259eb412012-10-13 05:47:243484 state_.vertex_attrib_manager->SetElementArrayBuffer(info);
[email protected]96449d2c2009-11-25 00:01:323485 break;
3486 default:
[email protected]a93bb842010-02-16 23:03:473487 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323488 break;
3489 }
[email protected]051b1372010-04-12 02:42:083490 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323491}
3492
[email protected]297ca1c2011-06-20 23:08:463493bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
3494 return (GLES2Util::GetChannelsForFormat(
3495 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3496}
3497
3498bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]0d6bfdc2011-11-02 01:32:203499 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453500 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203501 if (framebuffer) {
3502 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463503 }
3504 if (offscreen_target_frame_buffer_.get()) {
3505 return offscreen_target_depth_format_ != 0;
3506 }
3507 return back_buffer_has_depth_;
3508}
3509
3510bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]0d6bfdc2011-11-02 01:32:203511 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453512 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203513 if (framebuffer) {
3514 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463515 }
3516 if (offscreen_target_frame_buffer_.get()) {
3517 return offscreen_target_stencil_format_ != 0 ||
3518 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3519 }
3520 return back_buffer_has_stencil_;
3521}
3522
3523void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]88a61bf2012-10-27 13:00:423524 if (clear_state_dirty_) {
[email protected]297ca1c2011-06-20 23:08:463525 glColorMask(
[email protected]e259eb412012-10-13 05:47:243526 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3527 state_.color_mask_alpha &&
3528 BoundFramebufferHasColorAttachmentWithAlpha());
[email protected]297ca1c2011-06-20 23:08:463529 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243530 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223531 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463532 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243533 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423534 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243535 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423536 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223537 EnableDisable(
3538 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3539 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3540 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3541 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]88a61bf2012-10-27 13:00:423542 clear_state_dirty_ = false;
[email protected]297ca1c2011-06-20 23:08:463543 }
3544}
3545
[email protected]78b514b2012-05-01 21:50:593546void GLES2DecoderImpl::BindAndApplyTextureParameters(
3547 TextureManager::TextureInfo* info) {
3548 glBindTexture(info->target(), info->service_id());
3549 glTexParameteri(info->target(), GL_TEXTURE_MIN_FILTER, info->min_filter());
3550 glTexParameteri(info->target(), GL_TEXTURE_MAG_FILTER, info->mag_filter());
3551 glTexParameteri(info->target(), GL_TEXTURE_WRAP_S, info->wrap_s());
3552 glTexParameteri(info->target(), GL_TEXTURE_WRAP_T, info->wrap_t());
3553}
3554
[email protected]1868a342012-11-07 15:56:023555GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]b177ae22011-11-01 03:29:113556 return (offscreen_target_frame_buffer_.get()) ?
3557 offscreen_target_frame_buffer_->id() :
[email protected]1868a342012-11-07 15:56:023558 (surface_ ? surface_->GetBackingFrameBufferObject() : 0);
3559}
3560
3561void GLES2DecoderImpl::RestoreState() const {
3562 state_.RestoreState();
3563
3564 // TODO: Restore multisample bindings
3565 GLuint service_id = state_.bound_draw_framebuffer ?
3566 state_.bound_draw_framebuffer->service_id() :
3567 GetBackbufferServiceId();
3568 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
[email protected]b177ae22011-11-01 03:29:113569}
3570
[email protected]051b1372010-04-12 02:42:083571void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
3572 FramebufferManager::FramebufferInfo* info = NULL;
3573 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033574 if (client_id != 0) {
3575 info = GetFramebufferInfo(client_id);
[email protected]051b1372010-04-12 02:42:083576 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353577 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153578 LOG(ERROR)
3579 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3580 current_decoder_error_ = error::kGenericError;
3581 return;
[email protected]bf5a8d132011-08-16 08:39:353582 }
3583
[email protected]ae51d192010-04-27 00:48:033584 // It's a new id so make a framebuffer info for it.
3585 glGenFramebuffersEXT(1, &service_id);
3586 CreateFramebufferInfo(client_id, service_id);
3587 info = GetFramebufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573588 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103589 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3590 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033591 } else {
3592 service_id = info->service_id();
[email protected]051b1372010-04-12 02:42:083593 }
[email protected]06c8b082011-01-05 18:00:363594 info->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083595 }
[email protected]cae20172012-12-07 00:06:193596 LogClientServiceForInfo(info, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303597
3598 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]e259eb412012-10-13 05:47:243599 state_.bound_draw_framebuffer = info;
[email protected]8e3e0662010-08-23 18:46:303600 }
3601 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]e259eb412012-10-13 05:47:243602 state_.bound_read_framebuffer = info;
[email protected]8e3e0662010-08-23 18:46:303603 }
[email protected]6217d392010-03-25 22:08:353604
[email protected]88a61bf2012-10-27 13:00:423605 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:463606
[email protected]b177ae22011-11-01 03:29:113607 // If we are rendering to the backbuffer get the FBO id for any simulated
3608 // backbuffer.
3609 if (info == NULL) {
3610 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463611 }
[email protected]6217d392010-03-25 22:08:353612
[email protected]051b1372010-04-12 02:42:083613 glBindFramebufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563614}
3615
[email protected]051b1372010-04-12 02:42:083616void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
3617 RenderbufferManager::RenderbufferInfo* info = NULL;
3618 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033619 if (client_id != 0) {
3620 info = GetRenderbufferInfo(client_id);
[email protected]051b1372010-04-12 02:42:083621 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353622 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153623 LOG(ERROR)
3624 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3625 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353626 return;
3627 }
3628
[email protected]ae51d192010-04-27 00:48:033629 // It's a new id so make a renderbuffer info for it.
3630 glGenRenderbuffersEXT(1, &service_id);
3631 CreateRenderbufferInfo(client_id, service_id);
[email protected]066849e32010-05-03 19:14:103632 info = GetRenderbufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573633 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103634 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3635 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033636 } else {
3637 service_id = info->service_id();
[email protected]051b1372010-04-12 02:42:083638 }
[email protected]06c8b082011-01-05 18:00:363639 info->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083640 }
[email protected]cae20172012-12-07 00:06:193641 LogClientServiceForInfo(info, client_id, "glBindRenerbuffer");
[email protected]e259eb412012-10-13 05:47:243642 state_.bound_renderbuffer = info;
[email protected]051b1372010-04-12 02:42:083643 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563644}
3645
[email protected]051b1372010-04-12 02:42:083646void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]ae51d192010-04-27 00:48:033647 TextureManager::TextureInfo* info = NULL;
[email protected]051b1372010-04-12 02:42:083648 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033649 if (client_id != 0) {
3650 info = GetTextureInfo(client_id);
3651 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353652 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153653 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3654 current_decoder_error_ = error::kGenericError;
3655 return;
[email protected]bf5a8d132011-08-16 08:39:353656 }
3657
[email protected]ae51d192010-04-27 00:48:033658 // It's a new id so make a texture info for it.
3659 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413660 DCHECK_NE(0u, service_id);
[email protected]ae51d192010-04-27 00:48:033661 CreateTextureInfo(client_id, service_id);
3662 info = GetTextureInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573663 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103664 group_->GetIdAllocator(id_namespaces::kTextures);
3665 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033666 }
3667 } else {
3668 info = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083669 }
[email protected]ae51d192010-04-27 00:48:033670
[email protected]1958e0e2010-04-22 05:17:153671 // Check the texture exists
3672 // Check that we are not trying to bind it to a different target.
[email protected]ae51d192010-04-27 00:48:033673 if (info->target() != 0 && info->target() != target) {
[email protected]8eee29c2010-04-29 03:38:293674 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433675 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153676 return;
3677 }
[email protected]b0af4f52011-09-28 22:04:423678 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
3679 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433680 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423681 return;
3682 }
[email protected]cae20172012-12-07 00:06:193683 LogClientServiceForInfo(info, client_id, "glBindTexture");
[email protected]1958e0e2010-04-22 05:17:153684 if (info->target() == 0) {
[email protected]80eb6b52012-01-19 00:14:413685 texture_manager()->SetInfoTarget(info, target);
[email protected]a93bb842010-02-16 23:03:473686 }
[email protected]ae51d192010-04-27 00:48:033687 glBindTexture(target, info->service_id());
[email protected]32145a92012-12-17 09:01:593688
[email protected]e259eb412012-10-13 05:47:243689 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503690 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473691 switch (target) {
3692 case GL_TEXTURE_2D:
[email protected]3916c97e2010-02-25 03:20:503693 unit.bound_texture_2d = info;
[email protected]a93bb842010-02-16 23:03:473694 break;
3695 case GL_TEXTURE_CUBE_MAP:
[email protected]3916c97e2010-02-25 03:20:503696 unit.bound_texture_cube_map = info;
[email protected]a93bb842010-02-16 23:03:473697 break;
[email protected]61eeb33f2011-07-26 15:30:313698 case GL_TEXTURE_EXTERNAL_OES:
3699 unit.bound_texture_external_oes = info;
[email protected]b0af4f52011-09-28 22:04:423700 if (info->IsStreamTexture()) {
3701 DCHECK(stream_texture_manager_);
3702 StreamTexture* stream_tex =
3703 stream_texture_manager_->LookupStreamTexture(info->service_id());
3704 if (stream_tex)
3705 stream_tex->Update();
3706 }
[email protected]61eeb33f2011-07-26 15:30:313707 break;
[email protected]e51bdf32011-11-23 22:21:463708 case GL_TEXTURE_RECTANGLE_ARB:
3709 unit.bound_texture_rectangle_arb = info;
3710 break;
[email protected]a93bb842010-02-16 23:03:473711 default:
3712 NOTREACHED(); // Validation should prevent us getting here.
3713 break;
3714 }
3715}
3716
[email protected]07f54fcc2009-12-22 02:46:303717void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243718 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123719 if (index != 0 ||
3720 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243721 glDisableVertexAttribArray(index);
3722 }
[email protected]07f54fcc2009-12-22 02:46:303723 } else {
[email protected]8eee29c2010-04-29 03:38:293724 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:433725 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303726 }
3727}
3728
[email protected]60f22d32012-12-12 00:31:583729void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3730 GLsizei numAttachments,
3731 const GLenum* attachments) {
3732 FramebufferManager::FramebufferInfo* framebuffer =
3733 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3734
3735 // Validates the attachments. If one of them fails
3736 // the whole command fails.
3737 for (GLsizei i = 0; i < numAttachments; ++i) {
3738 if ((framebuffer &&
3739 !validators_->attachment.IsValid(attachments[i])) ||
3740 (!framebuffer &&
3741 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
3742 SetGLErrorInvalidEnum("glDiscardFramebufferEXT",
3743 attachments[i],
3744 "attachments");
3745 return;
3746 }
3747 }
3748
3749 // Marks each one of them as not cleared
3750 for (GLsizei i = 0; i < numAttachments; ++i) {
3751 if (framebuffer) {
3752 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3753 texture_manager(),
3754 attachments[i],
3755 false);
3756 } else {
3757 switch (attachments[i]) {
3758 case GL_COLOR_EXT:
3759 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3760 break;
3761 case GL_DEPTH_EXT:
3762 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
3763 case GL_STENCIL_EXT:
3764 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
3765 break;
3766 default:
3767 NOTREACHED();
3768 break;
3769 }
3770 }
3771 }
3772
3773 glDiscardFramebufferEXT(target, numAttachments, attachments);
3774}
3775
[email protected]07f54fcc2009-12-22 02:46:303776void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243777 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:303778 glEnableVertexAttribArray(index);
3779 } else {
[email protected]8eee29c2010-04-29 03:38:293780 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:433781 "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303782 }
3783}
3784
[email protected]a93bb842010-02-16 23:03:473785void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]3916c97e2010-02-25 03:20:503786 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]97dc7cbe2011-12-06 17:26:173787 if (!info ||
[email protected]38c0a972012-05-12 00:48:023788 !texture_manager()->CanGenerateMipmaps(info)) {
[email protected]8eee29c2010-04-29 03:38:293789 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433790 "glGenerateMipmaps", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:473791 return;
3792 }
[email protected]38c0a972012-05-12 00:48:023793
[email protected]12d95352012-12-14 07:23:543794 if (target == GL_TEXTURE_CUBE_MAP) {
3795 for (int i = 0; i < 6; ++i) {
3796 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
3797 if (!texture_manager()->ClearTextureLevel(this, info, face, 0)) {
3798 SetGLError(GL_OUT_OF_MEMORY, "glGenerateMipmaps", "dimensions too big");
3799 return;
3800 }
3801 }
3802 } else {
3803 if (!texture_manager()->ClearTextureLevel(this, info, target, 0)) {
3804 SetGLError(GL_OUT_OF_MEMORY, "glGenerateMipmaps", "dimensions too big");
3805 return;
3806 }
[email protected]7687479c2012-05-14 23:54:043807 }
3808
[email protected]38c0a972012-05-12 00:48:023809 CopyRealGLErrorsToWrapper();
[email protected]59f3ca02011-03-26 22:24:193810 // Workaround for Mac driver bug. In the large scheme of things setting
3811 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:563812 // hit so there's probably no need to make this conditional. The bug appears
3813 // to be that if the filtering mode is set to something that doesn't require
3814 // mipmaps for rendering, or is never set to something other than the default,
3815 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:153816 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193817 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3818 }
[email protected]a93bb842010-02-16 23:03:473819 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:153820 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193821 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, info->min_filter());
3822 }
[email protected]38c0a972012-05-12 00:48:023823 GLenum error = PeekGLError();
3824 if (error == GL_NO_ERROR) {
3825 texture_manager()->MarkMipmapsGenerated(info);
3826 }
[email protected]a93bb842010-02-16 23:03:473827}
3828
[email protected]b273e432010-04-12 17:23:583829bool GLES2DecoderImpl::GetHelper(
3830 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:583831 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:153832 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
3833 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:433834 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3835 *num_written = 1;
3836 if (params) {
3837 *params = GL_RGBA; // We don't support other formats.
3838 }
3839 return true;
3840 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3841 *num_written = 1;
3842 if (params) {
3843 *params = GL_UNSIGNED_BYTE; // We don't support other types.
3844 }
3845 return true;
3846 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
3847 *num_written = 1;
3848 if (params) {
3849 *params = group_->max_fragment_uniform_vectors();
3850 }
3851 return true;
3852 case GL_MAX_VARYING_VECTORS:
3853 *num_written = 1;
3854 if (params) {
3855 *params = group_->max_varying_vectors();
3856 }
3857 return true;
3858 case GL_MAX_VERTEX_UNIFORM_VECTORS:
3859 *num_written = 1;
3860 if (params) {
3861 *params = group_->max_vertex_uniform_vectors();
3862 }
3863 return true;
[email protected]4e8a5b122010-05-08 22:00:103864 }
[email protected]5cb735d2011-10-13 01:37:233865 }
3866 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:243867 case GL_MAX_VIEWPORT_DIMS:
3868 if (offscreen_target_frame_buffer_.get()) {
3869 *num_written = 2;
3870 if (params) {
3871 params[0] = renderbuffer_manager()->max_renderbuffer_size();
3872 params[1] = renderbuffer_manager()->max_renderbuffer_size();
3873 }
3874 return true;
3875 }
[email protected]5cb735d2011-10-13 01:37:233876 return false;
[email protected]84afefa2011-10-19 21:45:533877 case GL_MAX_SAMPLES:
3878 *num_written = 1;
3879 if (params) {
3880 params[0] = renderbuffer_manager()->max_samples();
3881 }
3882 return true;
3883 case GL_MAX_RENDERBUFFER_SIZE:
3884 *num_written = 1;
3885 if (params) {
3886 params[0] = renderbuffer_manager()->max_renderbuffer_size();
3887 }
3888 return true;
[email protected]5cb735d2011-10-13 01:37:233889 case GL_MAX_TEXTURE_SIZE:
3890 *num_written = 1;
3891 if (params) {
3892 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
3893 }
3894 return true;
3895 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
3896 *num_written = 1;
3897 if (params) {
3898 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
3899 }
3900 return true;
[email protected]297ca1c2011-06-20 23:08:463901 case GL_ALPHA_BITS:
3902 *num_written = 1;
3903 if (params) {
3904 GLint v = 0;
3905 glGetIntegerv(GL_ALPHA_BITS, &v);
3906 params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0;
3907 }
3908 return true;
3909 case GL_DEPTH_BITS:
3910 *num_written = 1;
3911 if (params) {
3912 GLint v = 0;
3913 glGetIntegerv(GL_DEPTH_BITS, &v);
3914 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
3915 }
3916 return true;
3917 case GL_STENCIL_BITS:
3918 *num_written = 1;
3919 if (params) {
3920 GLint v = 0;
3921 glGetIntegerv(GL_STENCIL_BITS, &v);
3922 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
3923 }
3924 return true;
[email protected]656dcaad2010-05-07 17:18:373925 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:113926 *num_written = validators_->compressed_texture_format.GetValues().size();
3927 if (params) {
3928 for (GLint ii = 0; ii < *num_written; ++ii) {
3929 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
3930 }
3931 }
[email protected]656dcaad2010-05-07 17:18:373932 return true;
[email protected]b273e432010-04-12 17:23:583933 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
3934 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103935 if (params) {
[email protected]302ce6d2011-07-07 23:28:113936 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:103937 }
[email protected]b273e432010-04-12 17:23:583938 return true;
3939 case GL_NUM_SHADER_BINARY_FORMATS:
3940 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103941 if (params) {
[email protected]302ce6d2011-07-07 23:28:113942 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:103943 }
[email protected]b273e432010-04-12 17:23:583944 return true;
3945 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:113946 *num_written = validators_->shader_binary_format.GetValues().size();
3947 if (params) {
3948 for (GLint ii = 0; ii < *num_written; ++ii) {
3949 params[ii] = validators_->shader_binary_format.GetValues()[ii];
3950 }
3951 }
3952 return true;
[email protected]b273e432010-04-12 17:23:583953 case GL_SHADER_COMPILER:
3954 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103955 if (params) {
3956 *params = GL_TRUE;
3957 }
[email protected]b273e432010-04-12 17:23:583958 return true;
[email protected]6b8cf1a2010-05-06 16:13:583959 case GL_ARRAY_BUFFER_BINDING:
3960 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103961 if (params) {
[email protected]e259eb412012-10-13 05:47:243962 if (state_.bound_array_buffer) {
[email protected]4e8a5b122010-05-08 22:00:103963 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:243964 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:103965 &client_id);
3966 *params = client_id;
3967 } else {
3968 *params = 0;
3969 }
[email protected]6b8cf1a2010-05-06 16:13:583970 }
3971 return true;
3972 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
3973 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103974 if (params) {
[email protected]e259eb412012-10-13 05:47:243975 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:103976 GLuint client_id = 0;
3977 buffer_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:243978 state_.vertex_attrib_manager->element_array_buffer(
3979 )->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:103980 *params = client_id;
3981 } else {
3982 *params = 0;
3983 }
[email protected]6b8cf1a2010-05-06 16:13:583984 }
3985 return true;
3986 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:303987 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:583988 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103989 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:203990 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453991 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:203992 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:103993 GLuint client_id = 0;
3994 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:203995 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:303996 *params = client_id;
3997 } else {
3998 *params = 0;
3999 }
4000 }
4001 return true;
[email protected]ebfb73c2012-08-15 02:37:454002 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304003 *num_written = 1;
4004 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:204005 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454006 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204007 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304008 GLuint client_id = 0;
4009 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204010 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104011 *params = client_id;
4012 } else {
4013 *params = 0;
4014 }
[email protected]6b8cf1a2010-05-06 16:13:584015 }
4016 return true;
4017 case GL_RENDERBUFFER_BINDING:
4018 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104019 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:204020 RenderbufferManager::RenderbufferInfo* renderbuffer =
4021 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4022 if (renderbuffer) {
[email protected]4e8a5b122010-05-08 22:00:104023 GLuint client_id = 0;
4024 renderbuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204025 renderbuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104026 *params = client_id;
4027 } else {
4028 *params = 0;
4029 }
[email protected]6b8cf1a2010-05-06 16:13:584030 }
4031 return true;
4032 case GL_CURRENT_PROGRAM:
4033 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104034 if (params) {
[email protected]e259eb412012-10-13 05:47:244035 if (state_.current_program) {
[email protected]4e8a5b122010-05-08 22:00:104036 GLuint client_id = 0;
4037 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244038 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104039 *params = client_id;
4040 } else {
4041 *params = 0;
4042 }
[email protected]6b8cf1a2010-05-06 16:13:584043 }
4044 return true;
[email protected]bf835842012-11-19 15:21:514045 case GL_VERTEX_ARRAY_BINDING_OES:
4046 *num_written = 1;
4047 if (params) {
4048 if (state_.vertex_attrib_manager != default_vertex_attrib_manager_) {
4049 GLuint client_id = 0;
4050 vertex_array_manager_->GetClientId(
4051 state_.vertex_attrib_manager->service_id(), &client_id);
4052 *params = client_id;
4053 } else {
4054 *params = 0;
4055 }
4056 }
4057 return true;
[email protected]4e8a5b122010-05-08 22:00:104058 case GL_TEXTURE_BINDING_2D:
4059 *num_written = 1;
4060 if (params) {
[email protected]e259eb412012-10-13 05:47:244061 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584062 if (unit.bound_texture_2d) {
4063 GLuint client_id = 0;
4064 texture_manager()->GetClientId(
4065 unit.bound_texture_2d->service_id(), &client_id);
4066 *params = client_id;
4067 } else {
4068 *params = 0;
4069 }
[email protected]6b8cf1a2010-05-06 16:13:584070 }
[email protected]4e8a5b122010-05-08 22:00:104071 return true;
4072 case GL_TEXTURE_BINDING_CUBE_MAP:
4073 *num_written = 1;
4074 if (params) {
[email protected]e259eb412012-10-13 05:47:244075 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584076 if (unit.bound_texture_cube_map) {
4077 GLuint client_id = 0;
4078 texture_manager()->GetClientId(
4079 unit.bound_texture_cube_map->service_id(), &client_id);
4080 *params = client_id;
4081 } else {
4082 *params = 0;
4083 }
[email protected]6b8cf1a2010-05-06 16:13:584084 }
[email protected]4e8a5b122010-05-08 22:00:104085 return true;
[email protected]61eeb33f2011-07-26 15:30:314086 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4087 *num_written = 1;
4088 if (params) {
[email protected]e259eb412012-10-13 05:47:244089 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]61eeb33f2011-07-26 15:30:314090 if (unit.bound_texture_external_oes) {
4091 GLuint client_id = 0;
4092 texture_manager()->GetClientId(
4093 unit.bound_texture_external_oes->service_id(), &client_id);
4094 *params = client_id;
4095 } else {
4096 *params = 0;
4097 }
4098 }
4099 return true;
[email protected]e51bdf32011-11-23 22:21:464100 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4101 *num_written = 1;
4102 if (params) {
[email protected]e259eb412012-10-13 05:47:244103 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]e51bdf32011-11-23 22:21:464104 if (unit.bound_texture_rectangle_arb) {
4105 GLuint client_id = 0;
4106 texture_manager()->GetClientId(
4107 unit.bound_texture_rectangle_arb->service_id(), &client_id);
4108 *params = client_id;
4109 } else {
4110 *params = 0;
4111 }
4112 }
4113 return true;
[email protected]6c75c712012-06-19 15:43:174114 case GL_UNPACK_FLIP_Y_CHROMIUM:
4115 *num_written = 1;
4116 if (params) {
4117 params[0] = unpack_flip_y_;
4118 }
4119 return true;
4120 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4121 *num_written = 1;
4122 if (params) {
4123 params[0] = unpack_premultiply_alpha_;
4124 }
4125 return true;
4126 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4127 *num_written = 1;
4128 if (params) {
4129 params[0] = unpack_unpremultiply_alpha_;
4130 }
4131 return true;
[email protected]b273e432010-04-12 17:23:584132 default:
[email protected]4e8a5b122010-05-08 22:00:104133 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534134 return false;
[email protected]b273e432010-04-12 17:23:584135 }
4136}
4137
[email protected]4e8a5b122010-05-08 22:00:104138bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4139 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264140 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534141 return true;
4142 }
[email protected]4e8a5b122010-05-08 22:00:104143 return GetHelper(pname, NULL, num_values);
4144}
4145
[email protected]b273e432010-04-12 17:23:584146void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4147 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104148 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534149 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]4e8a5b122010-05-08 22:00:104150 scoped_array<GLint> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264151 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534152 GetHelper(pname, values.get(), &num_written);
4153 }
[email protected]b273e432010-04-12 17:23:584154 for (GLsizei ii = 0; ii < num_written; ++ii) {
4155 params[ii] = static_cast<GLboolean>(values[ii]);
4156 }
4157 } else {
4158 glGetBooleanv(pname, params);
4159 }
4160}
4161
4162void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4163 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104164 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264165 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534166 if (GetHelper(pname, NULL, &num_written)) {
4167 scoped_array<GLint> values(new GLint[num_written]);
4168 GetHelper(pname, values.get(), &num_written);
4169 for (GLsizei ii = 0; ii < num_written; ++ii) {
4170 params[ii] = static_cast<GLfloat>(values[ii]);
4171 }
4172 } else {
4173 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584174 }
[email protected]b273e432010-04-12 17:23:584175 }
4176}
4177
4178void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4179 DCHECK(params);
4180 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264181 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534182 !GetHelper(pname, params, &num_written)) {
[email protected]b273e432010-04-12 17:23:584183 glGetIntegerv(pname, params);
4184 }
4185}
4186
[email protected]a0c3e972010-04-21 00:49:134187void GLES2DecoderImpl::DoGetProgramiv(
4188 GLuint program_id, GLenum pname, GLint* params) {
[email protected]6b8cf1a2010-05-06 16:13:584189 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4190 program_id, "glGetProgramiv");
[email protected]a0c3e972010-04-21 00:49:134191 if (!info) {
[email protected]a0c3e972010-04-21 00:49:134192 return;
4193 }
4194 info->GetProgramiv(pname, params);
4195}
4196
[email protected]258a3313f2011-10-18 20:13:574197void GLES2DecoderImpl::DoBindAttribLocation(
4198 GLuint program, GLuint index, const char* name) {
4199 if (!StringIsValidForGLES(name)) {
[email protected]ad84a3a2012-06-08 21:42:434200 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574201 return;
4202 }
[email protected]68dcb1f2012-04-07 00:14:564203 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ad84a3a2012-06-08 21:42:434204 SetGLError(GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564205 return;
4206 }
4207 if (index >= group_->max_vertex_attribs()) {
[email protected]ad84a3a2012-06-08 21:42:434208 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564209 return;
4210 }
[email protected]6b8cf1a2010-05-06 16:13:584211 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4212 program, "glBindAttribLocation");
[email protected]ae51d192010-04-27 00:48:034213 if (!info) {
[email protected]258a3313f2011-10-18 20:13:574214 return;
[email protected]558847a2010-03-24 07:02:544215 }
[email protected]c3e4c4e2012-03-02 19:23:244216 info->SetAttribLocationBinding(name, static_cast<GLint>(index));
[email protected]258a3313f2011-10-18 20:13:574217 glBindAttribLocation(info->service_id(), index, name);
4218}
4219
4220error::Error GLES2DecoderImpl::HandleBindAttribLocation(
4221 uint32 immediate_data_size, const gles2::BindAttribLocation& c) {
4222 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544223 GLuint index = static_cast<GLuint>(c.index);
4224 uint32 name_size = c.data_size;
4225 const char* name = GetSharedMemoryAs<const char*>(
4226 c.name_shm_id, c.name_shm_offset, name_size);
4227 if (name == NULL) {
4228 return error::kOutOfBounds;
4229 }
4230 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574231 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544232 return error::kNoError;
4233}
4234
4235error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate(
4236 uint32 immediate_data_size, const gles2::BindAttribLocationImmediate& c) {
[email protected]6b8cf1a2010-05-06 16:13:584237 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544238 GLuint index = static_cast<GLuint>(c.index);
4239 uint32 name_size = c.data_size;
4240 const char* name = GetImmediateDataAs<const char*>(
4241 c, name_size, immediate_data_size);
4242 if (name == NULL) {
4243 return error::kOutOfBounds;
4244 }
4245 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574246 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544247 return error::kNoError;
4248}
4249
4250error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
4251 uint32 immediate_data_size, const gles2::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584252 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544253 GLuint index = static_cast<GLuint>(c.index);
4254 Bucket* bucket = GetBucket(c.name_bucket_id);
4255 if (!bucket || bucket->size() == 0) {
4256 return error::kInvalidArguments;
4257 }
4258 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184259 if (!bucket->GetAsString(&name_str)) {
4260 return error::kInvalidArguments;
4261 }
[email protected]258a3313f2011-10-18 20:13:574262 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544263 return error::kNoError;
4264}
4265
[email protected]2be6abf32012-06-26 00:28:334266void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
4267 GLuint program, GLint location, const char* name) {
4268 if (!StringIsValidForGLES(name)) {
4269 SetGLError(GL_INVALID_VALUE,
4270 "glBindUniformLocationCHROMIUM", "Invalid character");
4271 return;
4272 }
4273 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
4274 SetGLError(GL_INVALID_OPERATION,
4275 "glBindUniformLocationCHROMIUM", "reserved prefix");
4276 return;
4277 }
4278 if (location < 0 || static_cast<uint32>(location) >=
4279 (group_->max_fragment_uniform_vectors() +
4280 group_->max_vertex_uniform_vectors()) * 4) {
4281 SetGLError(GL_INVALID_VALUE,
4282 "glBindUniformLocationCHROMIUM", "location out of range");
4283 return;
4284 }
4285 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4286 program, "glBindUniformLocationCHROMIUM");
4287 if (!info) {
4288 return;
4289 }
4290 if (!info->SetUniformLocationBinding(name, location)) {
4291 SetGLError(GL_INVALID_VALUE,
4292 "glBindUniformLocationCHROMIUM", "location out of range");
4293 }
4294}
4295
4296error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
4297 uint32 immediate_data_size, const gles2::BindUniformLocationCHROMIUM& c) {
4298 GLuint program = static_cast<GLuint>(c.program);
4299 GLint location = static_cast<GLint>(c.location);
4300 uint32 name_size = c.data_size;
4301 const char* name = GetSharedMemoryAs<const char*>(
4302 c.name_shm_id, c.name_shm_offset, name_size);
4303 if (name == NULL) {
4304 return error::kOutOfBounds;
4305 }
4306 String name_str(name, name_size);
4307 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4308 return error::kNoError;
4309}
4310
4311error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4312 uint32 immediate_data_size,
4313 const gles2::BindUniformLocationCHROMIUMImmediate& c) {
4314 GLuint program = static_cast<GLuint>(c.program);
4315 GLint location = static_cast<GLint>(c.location);
4316 uint32 name_size = c.data_size;
4317 const char* name = GetImmediateDataAs<const char*>(
4318 c, name_size, immediate_data_size);
4319 if (name == NULL) {
4320 return error::kOutOfBounds;
4321 }
4322 String name_str(name, name_size);
4323 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4324 return error::kNoError;
4325}
4326
4327error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4328 uint32 immediate_data_size,
4329 const gles2::BindUniformLocationCHROMIUMBucket& c) {
4330 GLuint program = static_cast<GLuint>(c.program);
4331 GLint location = static_cast<GLint>(c.location);
4332 Bucket* bucket = GetBucket(c.name_bucket_id);
4333 if (!bucket || bucket->size() == 0) {
4334 return error::kInvalidArguments;
4335 }
4336 std::string name_str;
4337 if (!bucket->GetAsString(&name_str)) {
4338 return error::kInvalidArguments;
4339 }
4340 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4341 return error::kNoError;
4342}
4343
[email protected]f7a64ee2010-02-01 22:24:144344error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ba3176a2009-12-16 18:19:464345 uint32 immediate_data_size, const gles2::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034346 GLuint client_id = c.shader;
4347 if (client_id) {
4348 ShaderManager::ShaderInfo* info = GetShaderInfo(client_id);
4349 if (info) {
[email protected]ca488e12010-12-13 20:06:144350 if (!info->IsDeleted()) {
4351 glDeleteShader(info->service_id());
4352 shader_manager()->MarkAsDeleted(info);
4353 }
[email protected]ae51d192010-04-27 00:48:034354 } else {
[email protected]ad84a3a2012-06-08 21:42:434355 SetGLError(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034356 }
[email protected]96449d2c2009-11-25 00:01:324357 }
[email protected]f7a64ee2010-02-01 22:24:144358 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324359}
4360
[email protected]f7a64ee2010-02-01 22:24:144361error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ba3176a2009-12-16 18:19:464362 uint32 immediate_data_size, const gles2::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034363 GLuint client_id = c.program;
4364 if (client_id) {
4365 ProgramManager::ProgramInfo* info = GetProgramInfo(client_id);
4366 if (info) {
[email protected]ca488e12010-12-13 20:06:144367 if (!info->IsDeleted()) {
[email protected]ca488e12010-12-13 20:06:144368 program_manager()->MarkAsDeleted(shader_manager(), info);
4369 }
[email protected]ae51d192010-04-27 00:48:034370 } else {
[email protected]ad84a3a2012-06-08 21:42:434371 SetGLError(GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034372 }
[email protected]96449d2c2009-11-25 00:01:324373 }
[email protected]f7a64ee2010-02-01 22:24:144374 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324375}
4376
[email protected]269200b12010-11-18 22:53:064377void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104378 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574379 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104380 for (GLsizei ii = 0; ii < n; ++ii) {
4381 id_allocator->FreeID(ids[ii]);
4382 }
4383}
4384
[email protected]269200b12010-11-18 22:53:064385error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
4386 uint32 immediate_data_size, const gles2::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104387 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4388 GLsizei n = static_cast<GLsizei>(c.n);
4389 uint32 data_size;
4390 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4391 return error::kOutOfBounds;
4392 }
4393 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4394 c.ids_shm_id, c.ids_shm_offset, data_size);
4395 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434396 SetGLError(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104397 return error::kNoError;
4398 }
4399 if (ids == NULL) {
4400 return error::kOutOfBounds;
4401 }
[email protected]269200b12010-11-18 22:53:064402 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104403 return error::kNoError;
4404}
4405
[email protected]269200b12010-11-18 22:53:064406void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104407 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574408 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104409 if (id_offset == 0) {
4410 for (GLsizei ii = 0; ii < n; ++ii) {
4411 ids[ii] = id_allocator->AllocateID();
4412 }
4413 } else {
4414 for (GLsizei ii = 0; ii < n; ++ii) {
4415 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4416 id_offset = ids[ii] + 1;
4417 }
4418 }
4419}
4420
[email protected]269200b12010-11-18 22:53:064421error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
4422 uint32 immediate_data_size, const gles2::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104423 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4424 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4425 GLsizei n = static_cast<GLsizei>(c.n);
4426 uint32 data_size;
4427 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4428 return error::kOutOfBounds;
4429 }
4430 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4431 c.ids_shm_id, c.ids_shm_offset, data_size);
4432 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434433 SetGLError(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104434 return error::kNoError;
4435 }
4436 if (ids == NULL) {
4437 return error::kOutOfBounds;
4438 }
[email protected]269200b12010-11-18 22:53:064439 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104440 return error::kNoError;
4441}
4442
[email protected]269200b12010-11-18 22:53:064443void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104444 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574445 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104446 for (GLsizei ii = 0; ii < n; ++ii) {
4447 if (!id_allocator->MarkAsUsed(ids[ii])) {
4448 for (GLsizei jj = 0; jj < ii; ++jj) {
4449 id_allocator->FreeID(ids[jj]);
4450 }
4451 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:434452 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4453 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104454 return;
4455 }
4456 }
4457}
4458
[email protected]269200b12010-11-18 22:53:064459error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
4460 uint32 immediate_data_size, const gles2::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104461 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4462 GLsizei n = static_cast<GLsizei>(c.n);
4463 uint32 data_size;
4464 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4465 return error::kOutOfBounds;
4466 }
4467 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4468 c.ids_shm_id, c.ids_shm_offset, data_size);
4469 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434470 SetGLError(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104471 return error::kNoError;
4472 }
4473 if (ids == NULL) {
4474 return error::kOutOfBounds;
4475 }
[email protected]269200b12010-11-18 22:53:064476 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104477 return error::kNoError;
4478}
4479
[email protected]a7266a92012-06-28 02:11:084480error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444481 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204482 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]e259eb412012-10-13 05:47:244483 UNSHIPPED_TRACE_EVENT_INSTANT2(
4484 "test_gpu", "DoClear",
4485 "red", state_.color_clear_red,
4486 "green", state_.color_clear_green);
[email protected]297ca1c2011-06-20 23:08:464487 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274488 glClear(mask);
4489 }
[email protected]a7266a92012-06-28 02:11:084490 return error::kNoError;
4491}
4492
[email protected]36cef8ce2010-03-16 07:34:454493void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4494 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034495 GLuint client_renderbuffer_id) {
[email protected]8e3e0662010-08-23 18:46:304496 FramebufferManager::FramebufferInfo* framebuffer_info =
4497 GetFramebufferInfoForTarget(target);
4498 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294499 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434500 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454501 return;
4502 }
[email protected]ae51d192010-04-27 00:48:034503 GLuint service_id = 0;
[email protected]3a2e7c7b2010-08-06 01:12:284504 RenderbufferManager::RenderbufferInfo* info = NULL;
[email protected]ae51d192010-04-27 00:48:034505 if (client_renderbuffer_id) {
[email protected]3a2e7c7b2010-08-06 01:12:284506 info = GetRenderbufferInfo(client_renderbuffer_id);
[email protected]ae51d192010-04-27 00:48:034507 if (!info) {
[email protected]8eee29c2010-04-29 03:38:294508 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434509 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034510 return;
4511 }
4512 service_id = info->service_id();
4513 }
[email protected]9edc6b22010-12-23 02:00:264514 CopyRealGLErrorsToWrapper();
[email protected]ae51d192010-04-27 00:48:034515 glFramebufferRenderbufferEXT(
4516 target, attachment, renderbuffertarget, service_id);
[email protected]1002c2d2011-06-28 22:39:044517 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264518 if (error == GL_NO_ERROR) {
[email protected]8e3e0662010-08-23 18:46:304519 framebuffer_info->AttachRenderbuffer(attachment, info);
[email protected]3a2e7c7b2010-08-06 01:12:284520 }
[email protected]e259eb412012-10-13 05:47:244521 if (framebuffer_info == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424522 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464523 }
[email protected]3a2e7c7b2010-08-06 01:12:284524}
4525
[email protected]3a2e7c7b2010-08-06 01:12:284526void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464527 if (SetCapabilityState(cap, false)) {
4528 glDisable(cap);
4529 }
[email protected]3a2e7c7b2010-08-06 01:12:284530}
4531
4532void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464533 if (SetCapabilityState(cap, true)) {
4534 glEnable(cap);
4535 }
[email protected]3a2e7c7b2010-08-06 01:12:284536}
4537
[email protected]88a61bf2012-10-27 13:00:424538void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4539 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4540 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4541 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284542}
4543
[email protected]88a61bf2012-10-27 13:00:424544void GLES2DecoderImpl::DoHint(GLenum target, GLenum mode) {
4545 switch (target) {
4546 case GL_GENERATE_MIPMAP_HINT:
4547 state_.hint_generate_mipmap = mode;
4548 break;
4549 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4550 state_.hint_fragment_shader_derivative = mode;
4551 break;
4552 default:
4553 NOTREACHED();
4554 }
4555 glHint(target, mode);
4556}
4557
4558void GLES2DecoderImpl::DoSampleCoverage (GLclampf value, GLboolean invert) {
4559 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4560 state_.sample_coverage_invert = (invert != 0);
4561 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284562}
4563
[email protected]0d6bfdc2011-11-02 01:32:204564// Assumes framebuffer is complete.
4565void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]8e3e0662010-08-23 18:46:304566 GLenum target, FramebufferManager::FramebufferInfo* info) {
4567 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204568 // bind this to the DRAW point, clear then bind back to READ
4569 // TODO(gman): I don't think there is any guarantee that an FBO that
4570 // is complete on the READ attachment will be complete as a DRAW
4571 // attachment.
4572 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
4573 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, info->service_id());
[email protected]8e3e0662010-08-23 18:46:304574 }
[email protected]3a2e7c7b2010-08-06 01:12:284575 GLbitfield clear_bits = 0;
4576 if (info->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464577 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204578 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464579 (GLES2Util::GetChannelsForFormat(
[email protected]0d6bfdc2011-11-02 01:32:204580 info->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f : 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284581 glColorMask(true, true, true, true);
4582 clear_bits |= GL_COLOR_BUFFER_BIT;
4583 }
4584
4585 if (info->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4586 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
4587 glClearStencil(0);
4588 glStencilMask(-1);
4589 clear_bits |= GL_STENCIL_BUFFER_BIT;
4590 }
4591
4592 if (info->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4593 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
4594 glClearDepth(1.0f);
4595 glDepthMask(true);
4596 clear_bits |= GL_DEPTH_BUFFER_BIT;
4597 }
4598
4599 glDisable(GL_SCISSOR_TEST);
4600 glClear(clear_bits);
4601
[email protected]968351b2011-12-20 08:26:514602 framebuffer_manager()->MarkAttachmentsAsCleared(
4603 info, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284604
[email protected]c007aa02010-09-02 22:22:404605 RestoreClearState();
4606
4607 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204608 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, info->service_id());
[email protected]87d1a3fe2011-12-01 04:25:484609 FramebufferManager::FramebufferInfo* framebuffer =
4610 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4611 GLuint service_id =
4612 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
4613 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404614 }
4615}
4616
4617void GLES2DecoderImpl::RestoreClearState() {
[email protected]88a61bf2012-10-27 13:00:424618 clear_state_dirty_ = true;
[email protected]e259eb412012-10-13 05:47:244619 glClearColor(
4620 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4621 state_.color_clear_alpha);
4622 glClearStencil(state_.stencil_clear);
4623 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224624 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284625 glEnable(GL_SCISSOR_TEST);
4626 }
[email protected]36cef8ce2010-03-16 07:34:454627}
4628
4629GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]0d6bfdc2011-11-02 01:32:204630 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304631 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204632 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454633 return GL_FRAMEBUFFER_COMPLETE;
4634 }
[email protected]0d6bfdc2011-11-02 01:32:204635 GLenum completeness = framebuffer->IsPossiblyComplete();
4636 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4637 return completeness;
4638 }
[email protected]73276522012-11-09 05:50:204639 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454640}
4641
4642void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034643 GLenum target, GLenum attachment, GLenum textarget,
4644 GLuint client_texture_id, GLint level) {
[email protected]8e3e0662010-08-23 18:46:304645 FramebufferManager::FramebufferInfo* framebuffer_info =
4646 GetFramebufferInfoForTarget(target);
4647 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294648 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434649 "glFramebufferTexture2D", "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454650 return;
4651 }
[email protected]ae51d192010-04-27 00:48:034652 GLuint service_id = 0;
[email protected]3a2e7c7b2010-08-06 01:12:284653 TextureManager::TextureInfo* info = NULL;
[email protected]ae51d192010-04-27 00:48:034654 if (client_texture_id) {
[email protected]3a2e7c7b2010-08-06 01:12:284655 info = GetTextureInfo(client_texture_id);
[email protected]ae51d192010-04-27 00:48:034656 if (!info) {
[email protected]8eee29c2010-04-29 03:38:294657 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434658 "glFramebufferTexture2D", "unknown texture");
[email protected]ae51d192010-04-27 00:48:034659 return;
4660 }
4661 service_id = info->service_id();
4662 }
[email protected]0d6bfdc2011-11-02 01:32:204663
[email protected]80eb6b52012-01-19 00:14:414664 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]0d6bfdc2011-11-02 01:32:204665 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434666 "glFramebufferTexture2D", "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204667 return;
4668 }
4669
[email protected]9edc6b22010-12-23 02:00:264670 CopyRealGLErrorsToWrapper();
[email protected]ae51d192010-04-27 00:48:034671 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
[email protected]1002c2d2011-06-28 22:39:044672 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264673 if (error == GL_NO_ERROR) {
4674 framebuffer_info->AttachTexture(attachment, info, textarget, level);
[email protected]3a2e7c7b2010-08-06 01:12:284675 }
[email protected]e259eb412012-10-13 05:47:244676 if (framebuffer_info == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424677 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464678 }
[email protected]36cef8ce2010-03-16 07:34:454679}
4680
4681void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4682 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]8e3e0662010-08-23 18:46:304683 FramebufferManager::FramebufferInfo* framebuffer_info =
4684 GetFramebufferInfoForTarget(target);
4685 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294686 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434687 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454688 return;
4689 }
4690 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:574691 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
4692 GLint type = 0;
4693 GLuint client_id = 0;
4694 glGetFramebufferAttachmentParameterivEXT(
4695 target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
4696 switch (type) {
4697 case GL_RENDERBUFFER: {
4698 renderbuffer_manager()->GetClientId(*params, &client_id);
4699 break;
4700 }
4701 case GL_TEXTURE: {
4702 texture_manager()->GetClientId(*params, &client_id);
4703 break;
4704 }
4705 default:
4706 break;
4707 }
4708 *params = client_id;
4709 }
[email protected]36cef8ce2010-03-16 07:34:454710}
4711
4712void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
4713 GLenum target, GLenum pname, GLint* params) {
[email protected]0d6bfdc2011-11-02 01:32:204714 RenderbufferManager::RenderbufferInfo* renderbuffer =
4715 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4716 if (!renderbuffer) {
[email protected]8eee29c2010-04-29 03:38:294717 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434718 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454719 return;
4720 }
[email protected]3a03a8f2011-03-19 00:51:274721 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434722 case GL_RENDERBUFFER_INTERNAL_FORMAT:
4723 *params = renderbuffer->internal_format();
4724 break;
4725 case GL_RENDERBUFFER_WIDTH:
4726 *params = renderbuffer->width();
4727 break;
4728 case GL_RENDERBUFFER_HEIGHT:
4729 *params = renderbuffer->height();
4730 break;
4731 default:
4732 glGetRenderbufferParameterivEXT(target, pname, params);
4733 break;
[email protected]b71f52c2010-06-18 22:20:204734 }
[email protected]36cef8ce2010-03-16 07:34:454735}
4736
[email protected]8e3e0662010-08-23 18:46:304737void GLES2DecoderImpl::DoBlitFramebufferEXT(
4738 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4739 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4740 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:444741 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:154742 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:304743 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434744 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304745 }
[email protected]d058bca2012-11-26 10:27:264746 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:244747 if (IsAngle()) {
4748 glBlitFramebufferANGLE(
4749 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4750 } else {
4751 glBlitFramebufferEXT(
4752 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4753 }
[email protected]d058bca2012-11-26 10:27:264754 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]529c6672012-01-04 02:18:264755 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", "width", srcX1 - srcX0);
[email protected]8e3e0662010-08-23 18:46:304756}
4757
4758void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
4759 GLenum target, GLsizei samples, GLenum internalformat,
4760 GLsizei width, GLsizei height) {
[email protected]62e155e2012-10-23 22:43:154761 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:304762 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434763 "glRenderbufferStorageMultisampleEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304764 return;
4765 }
[email protected]8e3e0662010-08-23 18:46:304766
[email protected]0d6bfdc2011-11-02 01:32:204767 RenderbufferManager::RenderbufferInfo* renderbuffer =
4768 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4769 if (!renderbuffer) {
4770 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434771 "glGetRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:204772 return;
4773 }
4774
[email protected]84afefa2011-10-19 21:45:534775 if (samples > renderbuffer_manager()->max_samples()) {
4776 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434777 "glGetRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:534778 return;
4779 }
4780
4781 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
4782 height > renderbuffer_manager()->max_renderbuffer_size()) {
4783 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434784 "glGetRenderbufferStorageMultisample", "size too large");
[email protected]84afefa2011-10-19 21:45:534785 return;
4786 }
4787
[email protected]9edc6b22010-12-23 02:00:264788 GLenum impl_format = internalformat;
[email protected]8e3e0662010-08-23 18:46:304789 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
[email protected]9edc6b22010-12-23 02:00:264790 switch (impl_format) {
[email protected]8e3e0662010-08-23 18:46:304791 case GL_DEPTH_COMPONENT16:
[email protected]9edc6b22010-12-23 02:00:264792 impl_format = GL_DEPTH_COMPONENT;
[email protected]8e3e0662010-08-23 18:46:304793 break;
4794 case GL_RGBA4:
4795 case GL_RGB5_A1:
[email protected]9edc6b22010-12-23 02:00:264796 impl_format = GL_RGBA;
[email protected]8e3e0662010-08-23 18:46:304797 break;
4798 case GL_RGB565:
[email protected]9edc6b22010-12-23 02:00:264799 impl_format = GL_RGB;
[email protected]8e3e0662010-08-23 18:46:304800 break;
4801 }
4802 }
4803
[email protected]9edc6b22010-12-23 02:00:264804 CopyRealGLErrorsToWrapper();
[email protected]866b91c52011-03-23 14:38:084805 if (IsAngle()) {
4806 glRenderbufferStorageMultisampleANGLE(
4807 target, samples, impl_format, width, height);
4808 } else {
4809 glRenderbufferStorageMultisampleEXT(
4810 target, samples, impl_format, width, height);
4811 }
[email protected]1002c2d2011-06-28 22:39:044812 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264813 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:514814 // TODO(gman): If renderbuffers tracked which framebuffers they were
4815 // attached to we could just mark those framebuffers as not complete.
4816 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:204817 renderbuffer_manager()->SetInfo(
4818 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:264819 }
[email protected]8e3e0662010-08-23 18:46:304820}
4821
[email protected]36cef8ce2010-03-16 07:34:454822void GLES2DecoderImpl::DoRenderbufferStorage(
4823 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]0d6bfdc2011-11-02 01:32:204824 RenderbufferManager::RenderbufferInfo* renderbuffer =
4825 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4826 if (!renderbuffer) {
[email protected]8eee29c2010-04-29 03:38:294827 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434828 "glGetRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454829 return;
4830 }
[email protected]876f6fee2010-08-02 23:10:324831
[email protected]84afefa2011-10-19 21:45:534832 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
4833 height > renderbuffer_manager()->max_renderbuffer_size()) {
4834 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434835 "glGetRenderbufferStorage", "size too large");
[email protected]84afefa2011-10-19 21:45:534836 return;
4837 }
4838
[email protected]9edc6b22010-12-23 02:00:264839 GLenum impl_format = internalformat;
[email protected]876f6fee2010-08-02 23:10:324840 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
[email protected]9edc6b22010-12-23 02:00:264841 switch (impl_format) {
[email protected]876f6fee2010-08-02 23:10:324842 case GL_DEPTH_COMPONENT16:
[email protected]9edc6b22010-12-23 02:00:264843 impl_format = GL_DEPTH_COMPONENT;
[email protected]876f6fee2010-08-02 23:10:324844 break;
4845 case GL_RGBA4:
4846 case GL_RGB5_A1:
[email protected]9edc6b22010-12-23 02:00:264847 impl_format = GL_RGBA;
[email protected]876f6fee2010-08-02 23:10:324848 break;
4849 case GL_RGB565:
[email protected]9edc6b22010-12-23 02:00:264850 impl_format = GL_RGB;
[email protected]876f6fee2010-08-02 23:10:324851 break;
4852 }
[email protected]b71f52c2010-06-18 22:20:204853 }
[email protected]876f6fee2010-08-02 23:10:324854
[email protected]9edc6b22010-12-23 02:00:264855 CopyRealGLErrorsToWrapper();
4856 glRenderbufferStorageEXT(target, impl_format, width, height);
[email protected]1002c2d2011-06-28 22:39:044857 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264858 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:514859 // TODO(gman): If tetxures tracked which framebuffers they were attached to
4860 // we could just mark those framebuffers as not complete.
4861 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:204862 renderbuffer_manager()->SetInfo(
4863 renderbuffer, 0, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:264864 }
[email protected]36cef8ce2010-03-16 07:34:454865}
4866
[email protected]07f54fcc2009-12-22 02:46:304867void GLES2DecoderImpl::DoLinkProgram(GLuint program) {
[email protected]43ed3a72012-05-30 22:55:384868 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]6b8cf1a2010-05-06 16:13:584869 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4870 program, "glLinkProgram");
[email protected]a93bb842010-02-16 23:03:474871 if (!info) {
[email protected]a93bb842010-02-16 23:03:474872 return;
4873 }
[email protected]05afda12011-01-20 00:17:344874
[email protected]cae20172012-12-07 00:06:194875 LogClientServiceForInfo(info, program, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:394876 ShaderTranslator* vertex_translator = NULL;
4877 ShaderTranslator* fragment_translator = NULL;
4878 if (use_shader_translator_) {
4879 vertex_translator = vertex_translator_;
4880 fragment_translator = fragment_translator_;
4881 }
4882 if (info->Link(shader_manager(),
4883 vertex_translator,
4884 fragment_translator,
4885 feature_info_)) {
[email protected]e259eb412012-10-13 05:47:244886 if (info == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:154887 if (workarounds().use_current_program_after_successful_link) {
4888 glUseProgram(info->service_id());
[email protected]c2a3caf12012-10-23 19:32:004889 }
[email protected]62e155e2012-10-23 22:43:154890 program_manager()->ClearUniforms(info);
[email protected]2df73892012-04-28 01:09:544891 }
4892 }
[email protected]07f54fcc2009-12-22 02:46:304893};
4894
[email protected]3916c97e2010-02-25 03:20:504895void GLES2DecoderImpl::DoTexParameterf(
4896 GLenum target, GLenum pname, GLfloat param) {
4897 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]07f54fcc2009-12-22 02:46:304898 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434899 SetGLError(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244900 return;
[email protected]07f54fcc2009-12-22 02:46:304901 }
[email protected]cbb22e42011-05-12 23:36:244902
[email protected]445a8762012-12-06 15:43:214903 GLenum error = texture_manager()->SetParameter(
4904 info, pname, static_cast<GLint>(param));
4905 if (error != GL_NO_ERROR) {
4906 SetGLErrorInvalidParam(
4907 error, "glTexParameterf", pname, static_cast<GLint>(param));
[email protected]cbb22e42011-05-12 23:36:244908 return;
4909 }
4910 glTexParameterf(target, pname, param);
[email protected]07f54fcc2009-12-22 02:46:304911}
4912
[email protected]3916c97e2010-02-25 03:20:504913void GLES2DecoderImpl::DoTexParameteri(
4914 GLenum target, GLenum pname, GLint param) {
4915 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4916 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434917 SetGLError(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244918 return;
[email protected]3916c97e2010-02-25 03:20:504919 }
[email protected]cbb22e42011-05-12 23:36:244920
[email protected]445a8762012-12-06 15:43:214921 GLenum error = texture_manager()->SetParameter(info, pname, param);
4922 if(error != GL_NO_ERROR) {
4923 SetGLErrorInvalidParam(error, "glTexParameteri", pname, param);
[email protected]cbb22e42011-05-12 23:36:244924 return;
4925 }
[email protected]36f65962012-12-14 21:38:564926 // Texture tracking pools exist only for the command decoder, so
4927 // do not pass them on to the native GL implementation.
4928 if (pname == GL_TEXTURE_POOL_CHROMIUM) {
4929 return;
4930 }
[email protected]cbb22e42011-05-12 23:36:244931 glTexParameteri(target, pname, param);
[email protected]3916c97e2010-02-25 03:20:504932}
4933
4934void GLES2DecoderImpl::DoTexParameterfv(
4935 GLenum target, GLenum pname, const GLfloat* params) {
4936 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4937 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434938 SetGLError(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244939 return;
[email protected]3916c97e2010-02-25 03:20:504940 }
[email protected]cbb22e42011-05-12 23:36:244941
[email protected]445a8762012-12-06 15:43:214942 GLenum error =texture_manager()->SetParameter(
4943 info, pname, static_cast<GLint>(params[0]));
4944 if (error != GL_NO_ERROR) {
4945 SetGLErrorInvalidParam(
4946 error, "glTexParameterfv", pname, static_cast<GLint>(params[0]));
[email protected]cbb22e42011-05-12 23:36:244947 return;
4948 }
4949 glTexParameterfv(target, pname, params);
[email protected]3916c97e2010-02-25 03:20:504950}
4951
4952void GLES2DecoderImpl::DoTexParameteriv(
4953 GLenum target, GLenum pname, const GLint* params) {
4954 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4955 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434956 SetGLError(GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244957 return;
[email protected]3916c97e2010-02-25 03:20:504958 }
[email protected]cbb22e42011-05-12 23:36:244959
[email protected]445a8762012-12-06 15:43:214960 GLenum error = texture_manager()->SetParameter(info, pname, *params);
4961 if (error != GL_NO_ERROR) {
4962 SetGLErrorInvalidParam(error, "glTexParameteriv", pname, *params);
[email protected]cbb22e42011-05-12 23:36:244963 return;
4964 }
4965 glTexParameteriv(target, pname, params);
[email protected]3916c97e2010-02-25 03:20:504966}
4967
[email protected]939e7362010-05-13 20:49:104968bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]e259eb412012-10-13 05:47:244969 if (!state_.current_program) {
[email protected]ad84a3a2012-06-08 21:42:434970 // The program does not exist.
4971 SetGLError(GL_INVALID_OPERATION, function_name, "no program in use");
4972 return false;
[email protected]939e7362010-05-13 20:49:104973 }
[email protected]e259eb412012-10-13 05:47:244974 if (!state_.current_program->InUse()) {
[email protected]ad84a3a2012-06-08 21:42:434975 SetGLError(GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:104976 return false;
4977 }
4978 return true;
4979}
4980
4981bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
4982 GLint location, const char* function_name) {
4983 if (!CheckCurrentProgram(function_name)) {
4984 return false;
4985 }
4986 return location != -1;
4987}
4988
[email protected]476ccb72012-12-06 15:52:524989namespace {
4990
4991static const GLenum valid_int_vec1_types_list[] = {
4992 GL_INT,
4993 GL_BOOL,
4994 GL_SAMPLER_2D,
4995 GL_SAMPLER_2D_RECT_ARB,
4996 GL_SAMPLER_CUBE,
4997 GL_SAMPLER_EXTERNAL_OES,
4998};
4999
5000static const GLenum valid_int_vec2_types_list[] = {
5001 GL_INT_VEC2,
5002 GL_BOOL_VEC2,
5003};
5004
5005static const GLenum valid_int_vec3_types_list[] = {
5006 GL_INT_VEC3,
5007 GL_BOOL_VEC3,
5008};
5009
5010static const GLenum valid_int_vec4_types_list[] = {
5011 GL_INT_VEC4,
5012 GL_BOOL_VEC4,
5013};
5014
5015static const GLenum valid_float_vec1_types_list[] = {
5016 GL_FLOAT,
5017 GL_BOOL,
5018};
5019
5020static const GLenum valid_float_vec2_types_list[] = {
5021 GL_FLOAT_VEC2,
5022 GL_BOOL_VEC2,
5023};
5024
5025static const GLenum valid_float_vec3_types_list[] = {
5026 GL_FLOAT_VEC3,
5027 GL_BOOL_VEC3,
5028};
5029
5030static const GLenum valid_float_vec4_types_list[] = {
5031 GL_FLOAT_VEC4,
5032 GL_BOOL_VEC4,
5033};
5034
5035static const GLenum valid_float_mat2_types_list[] = {
5036 GL_FLOAT_MAT2,
5037};
5038
5039static const GLenum valid_float_mat3_types_list[] = {
5040 GL_FLOAT_MAT3,
5041};
5042
5043static const GLenum valid_float_mat4_types_list[] = {
5044 GL_FLOAT_MAT4,
5045};
5046
5047static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5048 valid_int_vec1_types_list,
5049 arraysize(valid_int_vec1_types_list),
5050};
5051
5052static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5053 valid_int_vec2_types_list,
5054 arraysize(valid_int_vec2_types_list),
5055};
5056
5057static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5058 valid_int_vec3_types_list,
5059 arraysize(valid_int_vec3_types_list),
5060};
5061
5062static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5063 valid_int_vec4_types_list,
5064 arraysize(valid_int_vec4_types_list),
5065};
5066
5067static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5068 valid_float_vec1_types_list,
5069 arraysize(valid_float_vec1_types_list),
5070};
5071
5072static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5073 valid_float_vec2_types_list,
5074 arraysize(valid_float_vec2_types_list),
5075};
5076
5077static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5078 valid_float_vec3_types_list,
5079 arraysize(valid_float_vec3_types_list),
5080};
5081
5082static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5083 valid_float_vec4_types_list,
5084 arraysize(valid_float_vec4_types_list),
5085};
5086
5087static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5088 valid_float_mat2_types_list,
5089 arraysize(valid_float_mat2_types_list),
5090};
5091
5092static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5093 valid_float_mat3_types_list,
5094 arraysize(valid_float_mat3_types_list),
5095};
5096
5097static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5098 valid_float_mat4_types_list,
5099 arraysize(valid_float_mat4_types_list),
5100};
5101
5102} // anonymous namespace.
5103
[email protected]43c2f1f2011-03-25 18:35:365104bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125105 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525106 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125107 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365108 DCHECK(type);
5109 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125110 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525111
[email protected]1b0a6752012-02-22 03:44:125112 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105113 return false;
5114 }
[email protected]43c2f1f2011-03-25 18:35:365115 GLint array_index = -1;
5116 const ProgramManager::ProgramInfo::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245117 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125118 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365119 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:435120 SetGLError(GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105121 return false;
5122 }
[email protected]476ccb72012-12-06 15:52:525123 bool okay = false;
5124 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5125 if (base_info.valid_types[ii] == info->type) {
5126 okay = true;
5127 break;
5128 }
5129 }
5130 if (!okay) {
5131 SetGLError(
5132 GL_INVALID_OPERATION, function_name, "wrong uniform function for type");
5133 return false;
5134 }
[email protected]43c2f1f2011-03-25 18:35:365135 if (*count > 1 && !info->is_array) {
5136 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435137 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365138 return false;
5139 }
5140 *count = std::min(info->size - array_index, *count);
5141 if (*count <= 0) {
5142 return false;
5143 }
5144 *type = info->type;
[email protected]939e7362010-05-13 20:49:105145 return true;
5146}
5147
[email protected]1b0a6752012-02-22 03:44:125148void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5149 GLenum type = 0;
5150 GLsizei count = 1;
5151 GLint real_location = -1;
5152 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525153 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5154 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505155 return;
5156 }
[email protected]e259eb412012-10-13 05:47:245157 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025158 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ad84a3a2012-06-08 21:42:435159 SetGLError(GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465160 return;
5161 }
[email protected]1b0a6752012-02-22 03:44:125162 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505163}
5164
5165void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125166 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365167 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125168 GLint real_location = -1;
5169 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525170 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5171 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365172 return;
5173 }
[email protected]74727112012-06-13 21:18:085174 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5175 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245176 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025177 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ad84a3a2012-06-08 21:42:435178 SetGLError(GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465179 return;
5180 }
[email protected]43c2f1f2011-03-25 18:35:365181 }
[email protected]1b0a6752012-02-22 03:44:125182 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505183}
5184
[email protected]939e7362010-05-13 20:49:105185void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125186 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365187 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125188 GLint real_location = -1;
5189 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525190 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5191 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105192 return;
5193 }
5194 if (type == GL_BOOL) {
5195 scoped_array<GLint> temp(new GLint[count]);
5196 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535197 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105198 }
[email protected]1b0a6752012-02-22 03:44:125199 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105200 } else {
[email protected]1b0a6752012-02-22 03:44:125201 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105202 }
5203}
5204
5205void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125206 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365207 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125208 GLint real_location = -1;
5209 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525210 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5211 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105212 return;
5213 }
5214 if (type == GL_BOOL_VEC2) {
5215 GLsizei num_values = count * 2;
5216 scoped_array<GLint> temp(new GLint[num_values]);
5217 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535218 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105219 }
[email protected]1b0a6752012-02-22 03:44:125220 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105221 } else {
[email protected]1b0a6752012-02-22 03:44:125222 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105223 }
5224}
5225
5226void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125227 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365228 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125229 GLint real_location = -1;
5230 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525231 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5232 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105233 return;
5234 }
5235 if (type == GL_BOOL_VEC3) {
5236 GLsizei num_values = count * 3;
5237 scoped_array<GLint> temp(new GLint[num_values]);
5238 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535239 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105240 }
[email protected]1b0a6752012-02-22 03:44:125241 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105242 } else {
[email protected]1b0a6752012-02-22 03:44:125243 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105244 }
5245}
5246
5247void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125248 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365249 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125250 GLint real_location = -1;
5251 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525252 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5253 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105254 return;
5255 }
5256 if (type == GL_BOOL_VEC4) {
5257 GLsizei num_values = count * 4;
5258 scoped_array<GLint> temp(new GLint[num_values]);
5259 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535260 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105261 }
[email protected]1b0a6752012-02-22 03:44:125262 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105263 } else {
[email protected]1b0a6752012-02-22 03:44:125264 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105265 }
5266}
5267
[email protected]43c2f1f2011-03-25 18:35:365268void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125269 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365270 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125271 GLint real_location = -1;
5272 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525273 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5274 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365275 return;
5276 }
[email protected]1b0a6752012-02-22 03:44:125277 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365278}
5279
5280void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125281 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365282 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125283 GLint real_location = -1;
5284 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525285 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5286 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365287 return;
5288 }
[email protected]1b0a6752012-02-22 03:44:125289 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365290}
5291
5292void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125293 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365294 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125295 GLint real_location = -1;
5296 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525297 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5298 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365299 return;
5300 }
[email protected]1b0a6752012-02-22 03:44:125301 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365302}
5303
5304void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125305 GLint fake_location, GLsizei count, GLboolean transpose,
5306 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365307 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125308 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365309 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525310 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5311 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365312 return;
5313 }
[email protected]1b0a6752012-02-22 03:44:125314 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365315}
5316
5317void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125318 GLint fake_location, GLsizei count, GLboolean transpose,
5319 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365320 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125321 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365322 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525323 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5324 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365325 return;
5326 }
[email protected]1b0a6752012-02-22 03:44:125327 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365328}
5329
5330void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125331 GLint fake_location, GLsizei count, GLboolean transpose,
5332 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365333 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125334 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365335 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525336 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5337 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365338 return;
5339 }
[email protected]1b0a6752012-02-22 03:44:125340 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365341}
5342
[email protected]3916c97e2010-02-25 03:20:505343void GLES2DecoderImpl::DoUseProgram(GLuint program) {
[email protected]ae51d192010-04-27 00:48:035344 GLuint service_id = 0;
[email protected]3916c97e2010-02-25 03:20:505345 ProgramManager::ProgramInfo* info = NULL;
5346 if (program) {
[email protected]6b8cf1a2010-05-06 16:13:585347 info = GetProgramInfoNotShader(program, "glUseProgram");
[email protected]3916c97e2010-02-25 03:20:505348 if (!info) {
[email protected]ae51d192010-04-27 00:48:035349 return;
5350 }
5351 if (!info->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505352 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ad84a3a2012-06-08 21:42:435353 SetGLError(GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505354 return;
5355 }
[email protected]ae51d192010-04-27 00:48:035356 service_id = info->service_id();
[email protected]3916c97e2010-02-25 03:20:505357 }
[email protected]e259eb412012-10-13 05:47:245358 if (state_.current_program) {
5359 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
[email protected]ca488e12010-12-13 20:06:145360 }
[email protected]e259eb412012-10-13 05:47:245361 state_.current_program = info;
[email protected]cae20172012-12-07 00:06:195362 LogClientServiceMapping("glUseProgram", program, service_id);
[email protected]2df73892012-04-28 01:09:545363 glUseProgram(service_id);
[email protected]e259eb412012-10-13 05:47:245364 if (state_.current_program) {
5365 program_manager()->UseProgram(state_.current_program);
[email protected]ca488e12010-12-13 20:06:145366 }
[email protected]3916c97e2010-02-25 03:20:505367}
5368
[email protected]efcdd2362012-07-09 21:07:005369uint32 GLES2DecoderImpl::GetGLError() {
[email protected]96449d2c2009-11-25 00:01:325370 // Check the GL error first, then our wrapped error.
5371 GLenum error = glGetError();
5372 if (error == GL_NO_ERROR && error_bits_ != 0) {
[email protected]03f882a2010-01-08 20:46:375373 for (uint32 mask = 1; mask != 0; mask = mask << 1) {
[email protected]96449d2c2009-11-25 00:01:325374 if ((error_bits_ & mask) != 0) {
[email protected]ddd968b82010-03-02 00:44:295375 error = GLES2Util::GLErrorBitToGLError(mask);
[email protected]96449d2c2009-11-25 00:01:325376 break;
5377 }
5378 }
5379 }
5380
5381 if (error != GL_NO_ERROR) {
5382 // There was an error, clear the corresponding wrapped error.
[email protected]ddd968b82010-03-02 00:44:295383 error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
[email protected]96449d2c2009-11-25 00:01:325384 }
5385 return error;
5386}
5387
[email protected]1002c2d2011-06-28 22:39:045388GLenum GLES2DecoderImpl::PeekGLError() {
5389 GLenum error = glGetError();
5390 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435391 SetGLError(error, "", "");
[email protected]1002c2d2011-06-28 22:39:045392 }
5393 return error;
5394}
5395
[email protected]ad84a3a2012-06-08 21:42:435396void GLES2DecoderImpl::SetGLError(
5397 GLenum error, const char* function_name, const char* msg) {
[email protected]8eee29c2010-04-29 03:38:295398 if (msg) {
5399 last_error_ = msg;
[email protected]d2a0e1a2012-08-12 02:25:015400 LogMessage(GetLogPrefix() + ": " + std::string("GL ERROR :") +
[email protected]ad84a3a2012-06-08 21:42:435401 GLES2Util::GetStringEnum(error) + " : " +
5402 function_name + ": " + msg);
[email protected]8eee29c2010-04-29 03:38:295403 }
[email protected]ddd968b82010-03-02 00:44:295404 error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
[email protected]96449d2c2009-11-25 00:01:325405}
5406
[email protected]f80e6e12012-08-31 00:43:535407void GLES2DecoderImpl::SetGLErrorInvalidEnum(
5408 const char* function_name, GLenum value, const char* label) {
5409 SetGLError(GL_INVALID_ENUM, function_name,
5410 (std::string(label) + " was " +
5411 GLES2Util::GetStringEnum(value)).c_str());
5412}
5413
[email protected]445a8762012-12-06 15:43:215414void GLES2DecoderImpl::SetGLErrorInvalidParam(
5415 GLenum error,
5416 const char* function_name,
5417 GLenum pname,
5418 GLint param) {
5419 if (error == GL_INVALID_ENUM) {
5420 SetGLError(
5421 GL_INVALID_ENUM, function_name,
5422 (std::string("trying to set ") +
5423 GLES2Util::GetStringEnum(pname) + " to " +
5424 GLES2Util::GetStringEnum(param)).c_str());
5425 } else {
5426 SetGLError(
5427 error, function_name,
5428 (std::string("trying to set ") +
5429 GLES2Util::GetStringEnum(pname) + " to " +
5430 base::StringPrintf("%d", param)).c_str());
5431 }
5432}
5433
[email protected]d2a0e1a2012-08-12 02:25:015434const std::string& GLES2DecoderImpl::GetLogPrefix() const {
5435 const std::string& prefix(debug_marker_manager_.GetMarker());
5436 return prefix.empty() ? this_in_hex_ : prefix;
5437}
5438
[email protected]0f8afe82012-05-14 23:43:015439void GLES2DecoderImpl::LogMessage(const std::string& msg) {
5440 if (log_message_count_ < kMaxLogMessages ||
5441 CommandLine::ForCurrentProcess()->HasSwitch(
5442 switches::kDisableGLErrorLimit)) {
5443 ++log_message_count_;
5444 // LOG this unless logging is turned off as any chromium code that
5445 // generates these errors probably has a bug.
5446 if (log_synthesized_gl_errors()) {
[email protected]3f00df92012-06-19 00:44:585447 LOG(ERROR) << msg;
[email protected]0f8afe82012-05-14 23:43:015448 }
5449 if (!msg_callback_.is_null()) {
5450 msg_callback_.Run(0, msg);
5451 }
5452 } else {
5453 if (log_message_count_ == kMaxLogMessages) {
5454 ++log_message_count_;
5455 LOG(ERROR)
5456 << "Too many GL errors, not reporting any more for this context."
5457 << " use --disable-gl-error-limit to see all errors.";
5458 }
5459 }
5460}
5461
5462void GLES2DecoderImpl::RenderWarning(const std::string& msg) {
5463 LogMessage(std::string("RENDER WARNING: ") + msg);
5464}
5465
5466void GLES2DecoderImpl::PerformanceWarning(const std::string& msg) {
5467 LogMessage(std::string("PERFORMANCE WARNING: ") + msg);
5468}
5469
[email protected]c447acd2012-07-23 23:48:415470void GLES2DecoderImpl::ForceCompileShaderIfPending(
5471 ShaderManager::ShaderInfo* info) {
5472 if (info->compilation_status() ==
5473 ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE) {
[email protected]c447acd2012-07-23 23:48:415474 ShaderTranslator* translator = NULL;
5475 if (use_shader_translator_) {
5476 translator = info->shader_type() == GL_VERTEX_SHADER ?
5477 vertex_translator_.get() : fragment_translator_.get();
5478 }
5479 // We know there will be no errors, because we only defer compilation on
5480 // shaders that were previously compiled successfully.
5481 program_manager()->ForceCompileShader(info->deferred_compilation_source(),
5482 info,
5483 translator,
5484 feature_info_);
5485 }
5486}
5487
[email protected]07f54fcc2009-12-22 02:46:305488void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() {
5489 GLenum error;
5490 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435491 SetGLError(error, "", NULL);
[email protected]07f54fcc2009-12-22 02:46:305492 }
5493}
5494
[email protected]6217d392010-03-25 22:08:355495void GLES2DecoderImpl::ClearRealGLErrors() {
5496 GLenum error;
5497 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]3ed14d112011-12-13 22:05:515498 if (error != GL_OUT_OF_MEMORY) {
5499 // GL_OUT_OF_MEMORY can legally happen on lost device.
5500 NOTREACHED() << "GL error " << error << " was unhandled.";
5501 }
[email protected]6217d392010-03-25 22:08:355502 }
5503}
5504
[email protected]ef526492010-06-02 23:12:255505bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245506 DCHECK(state_.current_program);
[email protected]ef526492010-06-02 23:12:255507 // Only check if there are some unrenderable textures.
5508 if (!texture_manager()->HaveUnrenderableTextures()) {
5509 return false;
5510 }
5511 bool textures_set = false;
[email protected]3916c97e2010-02-25 03:20:505512 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245513 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505514 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5515 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245516 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505517 DCHECK(uniform_info);
5518 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5519 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025520 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245521 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]3916c97e2010-02-25 03:20:505522 TextureManager::TextureInfo* texture_info =
[email protected]61eeb33f2011-07-26 15:30:315523 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]80eb6b52012-01-19 00:14:415524 if (!texture_info || !texture_manager()->CanRender(texture_info)) {
[email protected]ef526492010-06-02 23:12:255525 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505526 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5527 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315528 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495529 texture_manager()->black_texture_id(uniform_info->type));
[email protected]0f8afe82012-05-14 23:43:015530 RenderWarning(
5531 std::string("texture bound to texture unit ") +
5532 base::IntToString(texture_unit_index) +
5533 " is not renderable. It maybe non-power-of-2 and have "
5534 " incompatible texture filtering or is not "
5535 "'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505536 }
5537 }
5538 // else: should this be an error?
5539 }
5540 }
[email protected]ef526492010-06-02 23:12:255541 return textures_set;
[email protected]3916c97e2010-02-25 03:20:505542}
5543
5544void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245545 DCHECK(state_.current_program);
[email protected]3916c97e2010-02-25 03:20:505546 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245547 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505548 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5549 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245550 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505551 DCHECK(uniform_info);
5552 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5553 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025554 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245555 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]3916c97e2010-02-25 03:20:505556 TextureManager::TextureInfo* texture_info =
5557 uniform_info->type == GL_SAMPLER_2D ?
5558 texture_unit.bound_texture_2d :
5559 texture_unit.bound_texture_cube_map;
[email protected]80eb6b52012-01-19 00:14:415560 if (!texture_info || !texture_manager()->CanRender(texture_info)) {
[email protected]3916c97e2010-02-25 03:20:505561 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5562 // Get the texture info that was previously bound here.
5563 texture_info = texture_unit.bind_target == GL_TEXTURE_2D ?
5564 texture_unit.bound_texture_2d :
5565 texture_unit.bound_texture_cube_map;
5566 glBindTexture(texture_unit.bind_target,
[email protected]ae51d192010-04-27 00:48:035567 texture_info ? texture_info->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505568 }
5569 }
5570 }
5571 }
5572 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245573 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305574}
5575
[email protected]0d6bfdc2011-11-02 01:32:205576bool GLES2DecoderImpl::ClearUnclearedTextures() {
5577 // Only check if there are some uncleared textures.
5578 if (!texture_manager()->HaveUnsafeTextures()) {
5579 return true;
5580 }
5581
5582 // 1: Check all textures we are about to render with.
[email protected]e259eb412012-10-13 05:47:245583 if (state_.current_program) {
[email protected]0d6bfdc2011-11-02 01:32:205584 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245585 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205586 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5587 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245588 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205589 DCHECK(uniform_info);
5590 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5591 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025592 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245593 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]0d6bfdc2011-11-02 01:32:205594 TextureManager::TextureInfo* texture_info =
5595 texture_unit.GetInfoForSamplerType(uniform_info->type);
5596 if (texture_info && !texture_info->SafeToRenderFrom()) {
5597 if (!texture_manager()->ClearRenderableLevels(this, texture_info)) {
5598 return false;
5599 }
5600 }
5601 }
5602 }
5603 }
5604 }
5605 return true;
5606}
5607
[email protected]c6aef902012-02-14 03:31:425608bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435609 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035610 // NOTE: We specifically do not check current_program->IsValid() because
5611 // it could never be invalid since glUseProgram would have failed. While
5612 // glLinkProgram could later mark the program as invalid the previous
5613 // valid program will still function if it is still the current program.
[email protected]e259eb412012-10-13 05:47:245614 if (!state_.current_program) {
[email protected]3916c97e2010-02-25 03:20:505615 // The program does not exist.
5616 // But GL says no ERROR.
[email protected]0f8afe82012-05-14 23:43:015617 RenderWarning("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505618 return false;
5619 }
[email protected]c6aef902012-02-14 03:31:425620
5621 // true if any enabled, used divisor is zero
5622 bool divisor0 = false;
[email protected]f39f4b3f2010-05-12 17:04:085623 // Validate all attribs currently enabled. If they are used by the current
5624 // program then check that they have enough elements to handle the draw call.
5625 // If they are not used by the current program check that they have a buffer
5626 // assigned.
5627 const VertexAttribManager::VertexAttribInfoList& infos =
[email protected]e259eb412012-10-13 05:47:245628 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos();
[email protected]f39f4b3f2010-05-12 17:04:085629 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
[email protected]8fbedc02010-11-18 18:43:405630 infos.begin(); it != infos.end(); ++it) {
[email protected]f39f4b3f2010-05-12 17:04:085631 const VertexAttribManager::VertexAttribInfo* info = *it;
5632 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245633 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]f39f4b3f2010-05-12 17:04:085634 if (attrib_info) {
[email protected]c6aef902012-02-14 03:31:425635 divisor0 |= (info->divisor() == 0);
5636 GLuint count = info->MaxVertexAccessed(primcount, max_vertex_accessed);
[email protected]f39f4b3f2010-05-12 17:04:085637 // This attrib is used in the current program.
[email protected]c6aef902012-02-14 03:31:425638 if (!info->CanAccess(count)) {
[email protected]0f8afe82012-05-14 23:43:015639 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435640 GL_INVALID_OPERATION, function_name,
[email protected]0f8afe82012-05-14 23:43:015641 (std::string(
[email protected]ad84a3a2012-06-08 21:42:435642 "attempt to access out of range vertices in attribute ") +
5643 base::IntToString(info->index())).c_str());
[email protected]f39f4b3f2010-05-12 17:04:085644 return false;
5645 }
5646 } else {
5647 // This attrib is not used in the current program.
[email protected]a0b78dc2011-11-11 10:43:105648 if (!info->buffer()) {
[email protected]f39f4b3f2010-05-12 17:04:085649 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435650 GL_INVALID_OPERATION, function_name,
[email protected]0f8afe82012-05-14 23:43:015651 (std::string(
[email protected]ad84a3a2012-06-08 21:42:435652 "attempt to render with no buffer attached to "
[email protected]0f8afe82012-05-14 23:43:015653 "enabled attribute ") +
5654 base::IntToString(info->index())).c_str());
[email protected]f39f4b3f2010-05-12 17:04:085655 return false;
5656 }
[email protected]1d32bc82010-01-13 22:06:465657 }
[email protected]07f54fcc2009-12-22 02:46:305658 }
[email protected]c6aef902012-02-14 03:31:425659
5660 if (primcount && !divisor0) {
5661 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435662 GL_INVALID_OPERATION, function_name,
5663 "attempt instanced render with all attributes having "
[email protected]c6aef902012-02-14 03:31:425664 "non-zero divisors");
5665 return false;
5666 }
5667
[email protected]3916c97e2010-02-25 03:20:505668 return true;
[email protected]b1122982010-05-17 23:04:245669}
5670
[email protected]c13e1da62011-09-09 21:48:305671bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435672 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305673 DCHECK(simulated);
5674 *simulated = false;
5675
[email protected]876f6fee2010-08-02 23:10:325676 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305677 return true;
[email protected]876f6fee2010-08-02 23:10:325678
[email protected]b1122982010-05-17 23:04:245679 const VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:245680 state_.vertex_attrib_manager->GetVertexAttribInfo(0);
[email protected]b1122982010-05-17 23:04:245681 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245682 bool attrib_0_used =
5683 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]fc753442011-02-04 19:49:495684 if (info->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305685 return true;
[email protected]b1122982010-05-17 23:04:245686 }
5687
[email protected]b1122982010-05-17 23:04:245688 // Make a buffer with a single repeated vec4 value enough to
5689 // simulate the constant value that is supposed to be here.
5690 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305691 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475692 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305693
5694 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475695 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305696 size_needed > 0x7FFFFFFFU) {
[email protected]ad84a3a2012-06-08 21:42:435697 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305698 return false;
5699 }
5700
[email protected]0f8afe82012-05-14 23:43:015701 PerformanceWarning(
5702 "Attribute 0 is disabled. This has signficant performance penalty");
5703
[email protected]c13e1da62011-09-09 21:48:305704 CopyRealGLErrorsToWrapper();
5705 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5706
[email protected]8f0b86c2f2012-04-10 05:48:285707 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5708 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495709 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305710 GLenum error = glGetError();
5711 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435712 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305713 return false;
5714 }
[email protected]fc753442011-02-04 19:49:495715 }
[email protected]af6380962012-11-29 23:24:135716
5717 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:285718 if (new_buffer ||
5719 (attrib_0_used &&
5720 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:135721 (value.v[0] != attrib_0_value_.v[0] ||
5722 value.v[1] != attrib_0_value_.v[1] ||
5723 value.v[2] != attrib_0_value_.v[2] ||
5724 value.v[3] != attrib_0_value_.v[3])))) {
5725 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:495726 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
5727 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:135728 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:245729 attrib_0_size_ = size_needed;
5730 }
5731
5732 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
5733
[email protected]c6aef902012-02-14 03:31:425734 if (info->divisor())
5735 glVertexAttribDivisorANGLE(0, 0);
5736
[email protected]c13e1da62011-09-09 21:48:305737 *simulated = true;
[email protected]b1122982010-05-17 23:04:245738 return true;
[email protected]b1122982010-05-17 23:04:245739}
5740
[email protected]43410e92012-04-20 17:06:285741void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib) {
[email protected]b1122982010-05-17 23:04:245742 const VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:245743 state_.vertex_attrib_manager->GetVertexAttribInfo(attrib);
[email protected]b1122982010-05-17 23:04:245744 const void* ptr = reinterpret_cast<const void*>(info->offset());
5745 BufferManager::BufferInfo* buffer_info = info->buffer();
5746 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0);
5747 glVertexAttribPointer(
[email protected]43410e92012-04-20 17:06:285748 attrib, info->size(), info->type(), info->normalized(), info->gl_stride(),
[email protected]b1122982010-05-17 23:04:245749 ptr);
[email protected]c6aef902012-02-14 03:31:425750 if (info->divisor())
[email protected]43410e92012-04-20 17:06:285751 glVertexAttribDivisorANGLE(attrib, info->divisor());
[email protected]e259eb412012-10-13 05:47:245752 glBindBuffer(
5753 GL_ARRAY_BUFFER,
5754 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:285755
[email protected]265f8992012-07-20 01:03:145756 // Never touch vertex attribute 0's state (in particular, never
5757 // disable it) when running on desktop GL because it will never be
5758 // re-enabled.
5759 if (attrib != 0 ||
5760 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
5761 if (info->enabled()) {
5762 glEnableVertexAttribArray(attrib);
5763 } else {
5764 glDisableVertexAttribArray(attrib);
5765 }
[email protected]43410e92012-04-20 17:06:285766 }
[email protected]b1122982010-05-17 23:04:245767}
[email protected]07f54fcc2009-12-22 02:46:305768
[email protected]8fbedc02010-11-18 18:43:405769bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:435770 const char* function_name,
[email protected]c6aef902012-02-14 03:31:425771 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:405772 DCHECK(simulated);
5773 *simulated = false;
5774 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
5775 return true;
5776
[email protected]e259eb412012-10-13 05:47:245777 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:405778 return true;
5779 }
5780
[email protected]0f8afe82012-05-14 23:43:015781 PerformanceWarning(
5782 "GL_FIXED attributes have a signficant performance penalty");
5783
[email protected]8fbedc02010-11-18 18:43:405784 // NOTE: we could be smart and try to check if a buffer is used
5785 // twice in 2 different attribs, find the overlapping parts and therefore
5786 // duplicate the minimum amount of data but this whole code path is not meant
5787 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
5788 // tests so we just add to the buffer attrib used.
5789
[email protected]c13e1da62011-09-09 21:48:305790 GLuint elements_needed = 0;
[email protected]8fbedc02010-11-18 18:43:405791 const VertexAttribManager::VertexAttribInfoList& infos =
[email protected]e259eb412012-10-13 05:47:245792 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos();
[email protected]8fbedc02010-11-18 18:43:405793 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
5794 infos.begin(); it != infos.end(); ++it) {
5795 const VertexAttribManager::VertexAttribInfo* info = *it;
5796 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245797 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]c6aef902012-02-14 03:31:425798 GLuint max_accessed = info->MaxVertexAccessed(primcount,
5799 max_vertex_accessed);
5800 GLuint num_vertices = max_accessed + 1;
5801 if (num_vertices == 0) {
[email protected]ad84a3a2012-06-08 21:42:435802 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425803 return false;
5804 }
[email protected]8fbedc02010-11-18 18:43:405805 if (attrib_info &&
[email protected]c6aef902012-02-14 03:31:425806 info->CanAccess(max_accessed) &&
[email protected]8fbedc02010-11-18 18:43:405807 info->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:475808 uint32 elements_used = 0;
5809 if (!SafeMultiplyUint32(num_vertices, info->size(), &elements_used) ||
5810 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ad84a3a2012-06-08 21:42:435811 SetGLError(
5812 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405813 return false;
5814 }
5815 }
5816 }
5817
[email protected]3aad1a32012-09-07 20:54:475818 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
5819 uint32 size_needed = 0;
5820 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305821 size_needed > 0x7FFFFFFFU) {
[email protected]ad84a3a2012-06-08 21:42:435822 SetGLError(GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405823 return false;
5824 }
5825
[email protected]c13e1da62011-09-09 21:48:305826 CopyRealGLErrorsToWrapper();
[email protected]8fbedc02010-11-18 18:43:405827
5828 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:305829 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:405830 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305831 GLenum error = glGetError();
5832 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435833 SetGLError(
5834 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:305835 return false;
5836 }
[email protected]8fbedc02010-11-18 18:43:405837 }
5838
5839 // Copy the elements and convert to float
5840 GLintptr offset = 0;
5841 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
5842 infos.begin(); it != infos.end(); ++it) {
5843 const VertexAttribManager::VertexAttribInfo* info = *it;
5844 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245845 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]c6aef902012-02-14 03:31:425846 GLuint max_accessed = info->MaxVertexAccessed(primcount,
5847 max_vertex_accessed);
5848 GLuint num_vertices = max_accessed + 1;
5849 if (num_vertices == 0) {
[email protected]ad84a3a2012-06-08 21:42:435850 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425851 return false;
5852 }
[email protected]8fbedc02010-11-18 18:43:405853 if (attrib_info &&
[email protected]c6aef902012-02-14 03:31:425854 info->CanAccess(max_accessed) &&
[email protected]8fbedc02010-11-18 18:43:405855 info->type() == GL_FIXED) {
5856 int num_elements = info->size() * kSizeOfFloat;
5857 int size = num_elements * num_vertices;
5858 scoped_array<float> data(new float[size]);
5859 const int32* src = reinterpret_cast<const int32 *>(
5860 info->buffer()->GetRange(info->offset(), size));
5861 const int32* end = src + num_elements;
5862 float* dst = data.get();
5863 while (src != end) {
5864 *dst++ = static_cast<float>(*src++) / 65536.0f;
5865 }
5866 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
5867 glVertexAttribPointer(
5868 info->index(), info->size(), GL_FLOAT, false, 0,
5869 reinterpret_cast<GLvoid*>(offset));
5870 offset += size;
5871 }
5872 }
5873 *simulated = true;
5874 return true;
5875}
5876
5877void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
5878 // There's no need to call glVertexAttribPointer because we shadow all the
5879 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:245880 glBindBuffer(
5881 GL_ARRAY_BUFFER,
5882 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]8fbedc02010-11-18 18:43:405883}
5884
[email protected]ad84a3a2012-06-08 21:42:435885error::Error GLES2DecoderImpl::DoDrawArrays(
5886 const char* function_name,
5887 bool instanced,
5888 GLenum mode,
5889 GLint first,
5890 GLsizei count,
5891 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:085892 if (ShouldDeferDraws())
5893 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:435894 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]f80e6e12012-08-31 00:43:535895 SetGLErrorInvalidEnum(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:435896 return error::kNoError;
5897 }
5898 if (count < 0) {
[email protected]ad84a3a2012-06-08 21:42:435899 SetGLError(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:435900 return error::kNoError;
5901 }
[email protected]c6aef902012-02-14 03:31:425902 if (primcount < 0) {
[email protected]ad84a3a2012-06-08 21:42:435903 SetGLError(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:425904 return error::kNoError;
5905 }
[email protected]ad84a3a2012-06-08 21:42:435906 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:435907 return error::kNoError;
5908 }
5909 // We have to check this here because the prototype for glDrawArrays
5910 // is GLint not GLsizei.
5911 if (first < 0) {
[email protected]ad84a3a2012-06-08 21:42:435912 SetGLError(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:435913 return error::kNoError;
5914 }
5915
[email protected]c6aef902012-02-14 03:31:425916 if (count == 0 || (instanced && primcount == 0)) {
[email protected]0f8afe82012-05-14 23:43:015917 RenderWarning("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:435918 return error::kNoError;
5919 }
5920
5921 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:435922 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:205923 if (!ClearUnclearedTextures()) {
[email protected]ad84a3a2012-06-08 21:42:435924 SetGLError(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:205925 return error::kNoError;
5926 }
[email protected]c13e1da62011-09-09 21:48:305927 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:435928 if (!SimulateAttrib0(
5929 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:305930 return error::kNoError;
5931 }
[email protected]38d139d2011-07-14 00:38:435932 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:435933 if (SimulateFixedAttribs(
5934 function_name, max_vertex_accessed, &simulated_fixed_attribs,
5935 primcount)) {
[email protected]38d139d2011-07-14 00:38:435936 bool textures_set = SetBlackTextureForNonRenderableTextures();
5937 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:425938 if (!instanced) {
5939 glDrawArrays(mode, first, count);
5940 } else {
5941 glDrawArraysInstancedANGLE(mode, first, count, primcount);
5942 }
[email protected]22e3f552012-03-13 01:54:195943 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:435944 if (textures_set) {
5945 RestoreStateForNonRenderableTextures();
5946 }
5947 if (simulated_fixed_attribs) {
5948 RestoreStateForSimulatedFixedAttribs();
5949 }
5950 }
5951 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:285952 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:435953 }
[email protected]38d139d2011-07-14 00:38:435954 }
5955 return error::kNoError;
5956}
5957
[email protected]c6aef902012-02-14 03:31:425958error::Error GLES2DecoderImpl::HandleDrawArrays(
5959 uint32 immediate_data_size, const gles2::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:435960 return DoDrawArrays("glDrawArrays",
5961 false,
[email protected]c6aef902012-02-14 03:31:425962 static_cast<GLenum>(c.mode),
5963 static_cast<GLint>(c.first),
5964 static_cast<GLsizei>(c.count),
5965 0);
5966}
5967
5968error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
5969 uint32 immediate_data_size, const gles2::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:155970 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:425971 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435972 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:425973 return error::kNoError;
5974 }
[email protected]ad84a3a2012-06-08 21:42:435975 return DoDrawArrays("glDrawArraysIntancedANGLE",
5976 true,
[email protected]c6aef902012-02-14 03:31:425977 static_cast<GLenum>(c.mode),
5978 static_cast<GLint>(c.first),
5979 static_cast<GLsizei>(c.count),
5980 static_cast<GLsizei>(c.primcount));
5981}
5982
[email protected]ad84a3a2012-06-08 21:42:435983error::Error GLES2DecoderImpl::DoDrawElements(
5984 const char* function_name,
5985 bool instanced,
5986 GLenum mode,
5987 GLsizei count,
5988 GLenum type,
5989 int32 offset,
5990 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:085991 if (ShouldDeferDraws())
5992 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:245993 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]8eee29c2010-04-29 03:38:295994 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435995 function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:295996 return error::kNoError;
5997 }
5998
[email protected]8eee29c2010-04-29 03:38:295999 if (count < 0) {
[email protected]ad84a3a2012-06-08 21:42:436000 SetGLError(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296001 return error::kNoError;
6002 }
6003 if (offset < 0) {
[email protected]ad84a3a2012-06-08 21:42:436004 SetGLError(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296005 return error::kNoError;
6006 }
[email protected]9438b012010-06-15 22:55:056007 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]f80e6e12012-08-31 00:43:536008 SetGLErrorInvalidEnum(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296009 return error::kNoError;
6010 }
[email protected]9438b012010-06-15 22:55:056011 if (!validators_->index_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536012 SetGLErrorInvalidEnum(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296013 return error::kNoError;
6014 }
[email protected]c6aef902012-02-14 03:31:426015 if (primcount < 0) {
[email protected]ad84a3a2012-06-08 21:42:436016 SetGLError(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426017 return error::kNoError;
6018 }
[email protected]8eee29c2010-04-29 03:38:296019
[email protected]ad84a3a2012-06-08 21:42:436020 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276021 return error::kNoError;
6022 }
6023
[email protected]c6aef902012-02-14 03:31:426024 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316025 return error::kNoError;
6026 }
6027
[email protected]8eee29c2010-04-29 03:38:296028 GLuint max_vertex_accessed;
[email protected]e259eb412012-10-13 05:47:246029 if (!state_.vertex_attrib_manager->element_array_buffer(
6030 )->GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) {
[email protected]8eee29c2010-04-29 03:38:296031 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436032 function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296033 return error::kNoError;
6034 }
6035
[email protected]ad84a3a2012-06-08 21:42:436036 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206037 if (!ClearUnclearedTextures()) {
[email protected]ad84a3a2012-06-08 21:42:436038 SetGLError(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206039 return error::kNoError;
6040 }
[email protected]c13e1da62011-09-09 21:48:306041 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436042 if (!SimulateAttrib0(
6043 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306044 return error::kNoError;
6045 }
[email protected]8fbedc02010-11-18 18:43:406046 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436047 if (SimulateFixedAttribs(
6048 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6049 primcount)) {
[email protected]8fbedc02010-11-18 18:43:406050 bool textures_set = SetBlackTextureForNonRenderableTextures();
[email protected]297ca1c2011-06-20 23:08:466051 ApplyDirtyState();
[email protected]8fbedc02010-11-18 18:43:406052 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]c6aef902012-02-14 03:31:426053 if (!instanced) {
6054 glDrawElements(mode, count, type, indices);
6055 } else {
6056 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6057 }
[email protected]22e3f552012-03-13 01:54:196058 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406059 if (textures_set) {
6060 RestoreStateForNonRenderableTextures();
6061 }
6062 if (simulated_fixed_attribs) {
6063 RestoreStateForSimulatedFixedAttribs();
6064 }
[email protected]ba3176a2009-12-16 18:19:466065 }
[email protected]b1122982010-05-17 23:04:246066 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286067 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246068 }
[email protected]96449d2c2009-11-25 00:01:326069 }
[email protected]f7a64ee2010-02-01 22:24:146070 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326071}
6072
[email protected]c6aef902012-02-14 03:31:426073error::Error GLES2DecoderImpl::HandleDrawElements(
6074 uint32 immediate_data_size, const gles2::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436075 return DoDrawElements("glDrawElements",
6076 false,
[email protected]c6aef902012-02-14 03:31:426077 static_cast<GLenum>(c.mode),
6078 static_cast<GLsizei>(c.count),
6079 static_cast<GLenum>(c.type),
6080 static_cast<int32>(c.index_offset),
6081 0);
6082}
6083
6084error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
6085 uint32 immediate_data_size, const gles2::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156086 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:426087 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436088 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426089 return error::kNoError;
6090 }
[email protected]ad84a3a2012-06-08 21:42:436091 return DoDrawElements("glDrawElementsInstancedANGLE",
6092 true,
[email protected]c6aef902012-02-14 03:31:426093 static_cast<GLenum>(c.mode),
6094 static_cast<GLsizei>(c.count),
6095 static_cast<GLenum>(c.type),
6096 static_cast<int32>(c.index_offset),
6097 static_cast<GLsizei>(c.primcount));
6098}
6099
[email protected]269200b12010-11-18 22:53:066100GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236101 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6102 GLuint max_vertex_accessed = 0;
6103 BufferManager::BufferInfo* info = GetBufferInfo(buffer_id);
[email protected]8eee29c2010-04-29 03:38:296104 if (!info) {
[email protected]ae51d192010-04-27 00:48:036105 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]8eee29c2010-04-29 03:38:296106 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436107 "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236108 } else {
6109 if (!info->GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036110 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]269200b12010-11-18 22:53:066111 SetGLError(
6112 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436113 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236114 }
6115 }
6116 return max_vertex_accessed;
6117}
6118
[email protected]96449d2c2009-11-25 00:01:326119// Calls glShaderSource for the various versions of the ShaderSource command.
6120// Assumes that data / data_size points to a piece of memory that is in range
6121// of whatever context it came from (shared memory, immediate memory, bucket
6122// memory.)
[email protected]45bf5152010-02-12 00:11:316123error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036124 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576125 std::string str(data, data + data_size);
[email protected]6b8cf1a2010-05-06 16:13:586126 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6127 client_id, "glShaderSource");
[email protected]45bf5152010-02-12 00:11:316128 if (!info) {
[email protected]45bf5152010-02-12 00:11:316129 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326130 }
[email protected]45bf5152010-02-12 00:11:316131 // Note: We don't actually call glShaderSource here. We wait until
6132 // the call to glCompileShader.
[email protected]258a3313f2011-10-18 20:13:576133 info->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146134 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326135}
6136
[email protected]f7a64ee2010-02-01 22:24:146137error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]b9849abf2009-11-25 19:13:196138 uint32 immediate_data_size, const gles2::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326139 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316140 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326141 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466142 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146143 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326144 }
[email protected]ae51d192010-04-27 00:48:036145 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326146}
6147
[email protected]f7a64ee2010-02-01 22:24:146148error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]b9849abf2009-11-25 19:13:196149 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:326150 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316151 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:306152 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:466153 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146154 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326155 }
[email protected]ae51d192010-04-27 00:48:036156 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:316157}
6158
[email protected]558847a2010-03-24 07:02:546159error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
6160 uint32 immediate_data_size, const gles2::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546161 Bucket* bucket = GetBucket(c.data_bucket_id);
6162 if (!bucket || bucket->size() == 0) {
6163 return error::kInvalidArguments;
6164 }
6165 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036166 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546167 bucket->size() - 1);
6168}
6169
[email protected]ae51d192010-04-27 00:48:036170void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386171 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]6b8cf1a2010-05-06 16:13:586172 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6173 client_id, "glCompileShader");
[email protected]45bf5152010-02-12 00:11:316174 if (!info) {
[email protected]45bf5152010-02-12 00:11:316175 return;
6176 }
[email protected]f57bb282010-11-12 00:51:346177 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186178 if (use_shader_translator_) {
[email protected]f57bb282010-11-12 00:51:346179 translator = info->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456180 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416181 }
[email protected]de17df392010-04-23 21:09:416182
[email protected]65dfc602012-07-23 20:39:396183 program_manager()->DoCompileShader(info, translator, feature_info_);
[email protected]45bf5152010-02-12 00:11:316184};
6185
[email protected]ddd968b82010-03-02 00:44:296186void GLES2DecoderImpl::DoGetShaderiv(
6187 GLuint shader, GLenum pname, GLint* params) {
[email protected]6b8cf1a2010-05-06 16:13:586188 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6189 shader, "glGetShaderiv");
[email protected]ddd968b82010-03-02 00:44:296190 if (!info) {
[email protected]ddd968b82010-03-02 00:44:296191 return;
6192 }
[email protected]8f1ccdac2010-05-19 21:01:486193 switch (pname) {
6194 case GL_SHADER_SOURCE_LENGTH:
[email protected]df6cf1ad2011-01-29 01:20:526195 *params = info->source() ? info->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486196 return;
6197 case GL_COMPILE_STATUS:
[email protected]062c38b2012-01-18 03:25:106198 *params = compile_shader_always_succeeds_ ? true : info->IsValid();
[email protected]e5186162010-06-14 18:54:416199 return;
[email protected]8f1ccdac2010-05-19 21:01:486200 case GL_INFO_LOG_LENGTH:
[email protected]df6cf1ad2011-01-29 01:20:526201 *params = info->log_info() ? info->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416202 return;
[email protected]d6a53e42011-10-05 00:09:366203 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]c447acd2012-07-23 23:48:416204 ForceCompileShaderIfPending(info);
[email protected]d6a53e42011-10-05 00:09:366205 *params = info->translated_source() ?
6206 info->translated_source()->size() + 1 : 0;
6207 return;
[email protected]8f1ccdac2010-05-19 21:01:486208 default:
6209 break;
[email protected]ddd968b82010-03-02 00:44:296210 }
[email protected]8f1ccdac2010-05-19 21:01:486211 glGetShaderiv(info->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296212}
6213
[email protected]ae51d192010-04-27 00:48:036214error::Error GLES2DecoderImpl::HandleGetShaderSource(
6215 uint32 immediate_data_size, const gles2::GetShaderSource& c) {
6216 GLuint shader = c.shader;
[email protected]ae51d192010-04-27 00:48:036217 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6218 Bucket* bucket = CreateBucket(bucket_id);
[email protected]6b8cf1a2010-05-06 16:13:586219 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6220 shader, "glGetShaderSource");
[email protected]df6cf1ad2011-01-29 01:20:526221 if (!info || !info->source()) {
[email protected]8eee29c2010-04-29 03:38:296222 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296223 return error::kNoError;
6224 }
[email protected]df6cf1ad2011-01-29 01:20:526225 bucket->SetFromString(info->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036226 return error::kNoError;
6227}
6228
[email protected]d6a53e42011-10-05 00:09:366229error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6230 uint32 immediate_data_size,
6231 const gles2::GetTranslatedShaderSourceANGLE& c) {
6232 GLuint shader = c.shader;
6233
6234 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6235 Bucket* bucket = CreateBucket(bucket_id);
6236 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6237 shader, "glTranslatedGetShaderSourceANGLE");
6238 if (!info) {
6239 bucket->SetSize(0);
6240 return error::kNoError;
6241 }
[email protected]c447acd2012-07-23 23:48:416242 ForceCompileShaderIfPending(info);
[email protected]d6a53e42011-10-05 00:09:366243
6244 bucket->SetFromString(info->translated_source() ?
6245 info->translated_source()->c_str() : NULL);
6246 return error::kNoError;
6247}
6248
[email protected]ae51d192010-04-27 00:48:036249error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
6250 uint32 immediate_data_size, const gles2::GetProgramInfoLog& c) {
6251 GLuint program = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586252 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6253 Bucket* bucket = CreateBucket(bucket_id);
6254 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6255 program, "glGetProgramInfoLog");
[email protected]df6cf1ad2011-01-29 01:20:526256 if (!info || !info->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466257 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036258 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316259 }
[email protected]df6cf1ad2011-01-29 01:20:526260 bucket->SetFromString(info->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036261 return error::kNoError;
6262}
6263
6264error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
6265 uint32 immediate_data_size, const gles2::GetShaderInfoLog& c) {
6266 GLuint shader = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586267 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6268 Bucket* bucket = CreateBucket(bucket_id);
6269 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6270 shader, "glGetShaderInfoLog");
[email protected]df6cf1ad2011-01-29 01:20:526271 if (!info || !info->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466272 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036273 return error::kNoError;
6274 }
[email protected]df6cf1ad2011-01-29 01:20:526275 bucket->SetFromString(info->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036276 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326277}
6278
[email protected]d058bca2012-11-26 10:27:266279bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6280 return state_.GetEnabled(cap);
6281}
6282
[email protected]1958e0e2010-04-22 05:17:156283bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106284 const BufferManager::BufferInfo* buffer = GetBufferInfo(client_id);
6285 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156286}
6287
6288bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106289 const FramebufferManager::FramebufferInfo* framebuffer =
[email protected]06c8b082011-01-05 18:00:366290 GetFramebufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:106291 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156292}
6293
6294bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366295 // IsProgram is true for programs as soon as they are created, until they are
6296 // deleted and no longer in use.
[email protected]a0b78dc2011-11-11 10:43:106297 const ProgramManager::ProgramInfo* program = GetProgramInfo(client_id);
6298 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156299}
6300
6301bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106302 const RenderbufferManager::RenderbufferInfo* renderbuffer =
[email protected]06c8b082011-01-05 18:00:366303 GetRenderbufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:106304 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156305}
6306
6307bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366308 // IsShader is true for shaders as soon as they are created, until they
6309 // are deleted and not attached to any programs.
[email protected]a0b78dc2011-11-11 10:43:106310 const ShaderManager::ShaderInfo* shader = GetShaderInfo(client_id);
6311 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156312}
6313
6314bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106315 const TextureManager::TextureInfo* texture = GetTextureInfo(client_id);
6316 return texture && texture->IsValid() && !texture->IsDeleted();
[email protected]ae51d192010-04-27 00:48:036317}
6318
6319void GLES2DecoderImpl::DoAttachShader(
6320 GLuint program_client_id, GLint shader_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:586321 ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader(
6322 program_client_id, "glAttachShader");
[email protected]ae51d192010-04-27 00:48:036323 if (!program_info) {
[email protected]ae51d192010-04-27 00:48:036324 return;
[email protected]1958e0e2010-04-22 05:17:156325 }
[email protected]6b8cf1a2010-05-06 16:13:586326 ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram(
6327 shader_client_id, "glAttachShader");
[email protected]ae51d192010-04-27 00:48:036328 if (!shader_info) {
[email protected]ae51d192010-04-27 00:48:036329 return;
6330 }
[email protected]ca488e12010-12-13 20:06:146331 if (!program_info->AttachShader(shader_manager(), shader_info)) {
[email protected]fb96c8e2010-08-12 04:10:316332 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436333 "glAttachShader", "can not attach more than"
[email protected]fb96c8e2010-08-12 04:10:316334 " one shader of the same type.");
6335 return;
6336 }
[email protected]ae51d192010-04-27 00:48:036337 glAttachShader(program_info->service_id(), shader_info->service_id());
6338}
6339
6340void GLES2DecoderImpl::DoDetachShader(
6341 GLuint program_client_id, GLint shader_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:586342 ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader(
6343 program_client_id, "glDetachShader");
[email protected]ae51d192010-04-27 00:48:036344 if (!program_info) {
[email protected]ae51d192010-04-27 00:48:036345 return;
6346 }
[email protected]6b8cf1a2010-05-06 16:13:586347 ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram(
6348 shader_client_id, "glDetachShader");
[email protected]ae51d192010-04-27 00:48:036349 if (!shader_info) {
[email protected]ae51d192010-04-27 00:48:036350 return;
6351 }
[email protected]9a0ccd42011-03-16 23:58:226352 if (!program_info->DetachShader(shader_manager(), shader_info)) {
6353 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436354 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226355 return;
6356 }
[email protected]ae51d192010-04-27 00:48:036357 glDetachShader(program_info->service_id(), shader_info->service_id());
6358}
6359
6360void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:586361 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6362 program_client_id, "glValidateProgram");
[email protected]ae51d192010-04-27 00:48:036363 if (!info) {
[email protected]ae51d192010-04-27 00:48:036364 return;
6365 }
[email protected]d685a682011-04-29 16:19:576366 info->Validate();
[email protected]1958e0e2010-04-22 05:17:156367}
6368
[email protected]b1122982010-05-17 23:04:246369void GLES2DecoderImpl::DoGetVertexAttribfv(
6370 GLuint index, GLenum pname, GLfloat* params) {
6371 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246372 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246373 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436374 SetGLError(GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]b1122982010-05-17 23:04:246375 return;
6376 }
6377 switch (pname) {
6378 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
6379 BufferManager::BufferInfo* buffer = info->buffer();
6380 if (buffer && !buffer->IsDeleted()) {
6381 GLuint client_id;
6382 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6383 *params = static_cast<GLfloat>(client_id);
6384 }
6385 break;
6386 }
6387 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
6388 *params = static_cast<GLfloat>(info->enabled());
6389 break;
6390 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
6391 *params = static_cast<GLfloat>(info->size());
6392 break;
6393 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
6394 *params = static_cast<GLfloat>(info->gl_stride());
6395 break;
6396 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
6397 *params = static_cast<GLfloat>(info->type());
6398 break;
6399 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
6400 *params = static_cast<GLfloat>(info->normalized());
6401 break;
[email protected]af6380962012-11-29 23:24:136402 case GL_CURRENT_VERTEX_ATTRIB: {
6403 const Vec4& value = state_.attrib_values[index];
6404 params[0] = value.v[0];
6405 params[1] = value.v[1];
6406 params[2] = value.v[2];
6407 params[3] = value.v[3];
[email protected]b1122982010-05-17 23:04:246408 break;
[email protected]af6380962012-11-29 23:24:136409 }
[email protected]c6aef902012-02-14 03:31:426410 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
6411 *params = static_cast<GLfloat>(info->divisor());
6412 break;
[email protected]b1122982010-05-17 23:04:246413 default:
6414 NOTREACHED();
6415 break;
6416 }
6417}
6418
6419void GLES2DecoderImpl::DoGetVertexAttribiv(
6420 GLuint index, GLenum pname, GLint* params) {
6421 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246422 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246423 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436424 SetGLError(GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]b1122982010-05-17 23:04:246425 return;
6426 }
6427 switch (pname) {
6428 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
6429 BufferManager::BufferInfo* buffer = info->buffer();
6430 if (buffer && !buffer->IsDeleted()) {
6431 GLuint client_id;
6432 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6433 *params = client_id;
6434 }
6435 break;
6436 }
6437 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
6438 *params = info->enabled();
6439 break;
6440 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
6441 *params = info->size();
6442 break;
6443 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
6444 *params = info->gl_stride();
6445 break;
6446 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
6447 *params = info->type();
6448 break;
6449 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
6450 *params = static_cast<GLint>(info->normalized());
6451 break;
[email protected]c6aef902012-02-14 03:31:426452 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
6453 *params = info->divisor();
6454 break;
[email protected]af6380962012-11-29 23:24:136455 case GL_CURRENT_VERTEX_ATTRIB: {
6456 const Vec4& value = state_.attrib_values[index];
6457 params[0] = static_cast<GLint>(value.v[0]);
6458 params[1] = static_cast<GLint>(value.v[1]);
6459 params[2] = static_cast<GLint>(value.v[2]);
6460 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246461 break;
[email protected]af6380962012-11-29 23:24:136462 }
[email protected]b1122982010-05-17 23:04:246463 default:
6464 NOTREACHED();
6465 break;
6466 }
6467}
6468
[email protected]af6380962012-11-29 23:24:136469bool GLES2DecoderImpl::SetVertexAttribValue(
6470 const char* function_name, GLuint index, const GLfloat* value) {
6471 if (index >= state_.attrib_values.size()) {
6472 SetGLError(GL_INVALID_VALUE, function_name, "index out of range");
6473 return false;
[email protected]b1122982010-05-17 23:04:246474 }
[email protected]af6380962012-11-29 23:24:136475 Vec4& v = state_.attrib_values[index];
6476 v.v[0] = value[0];
6477 v.v[1] = value[1];
6478 v.v[2] = value[2];
6479 v.v[3] = value[3];
6480 return true;
6481}
6482
6483void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6484 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6485 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6486 glVertexAttrib1f(index, v0);
6487 }
[email protected]b1122982010-05-17 23:04:246488}
6489
6490void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136491 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6492 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6493 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246494 }
[email protected]b1122982010-05-17 23:04:246495}
6496
6497void GLES2DecoderImpl::DoVertexAttrib3f(
6498 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136499 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6500 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6501 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246502 }
[email protected]b1122982010-05-17 23:04:246503}
6504
6505void GLES2DecoderImpl::DoVertexAttrib4f(
6506 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136507 GLfloat v[4] = { v0, v1, v2, v3, };
6508 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6509 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246510 }
[email protected]b1122982010-05-17 23:04:246511}
6512
6513void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136514 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6515 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6516 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246517 }
[email protected]b1122982010-05-17 23:04:246518}
6519
6520void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136521 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6522 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6523 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246524 }
[email protected]b1122982010-05-17 23:04:246525}
6526
6527void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136528 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6529 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6530 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246531 }
[email protected]b1122982010-05-17 23:04:246532}
6533
6534void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136535 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6536 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246537 }
[email protected]b1122982010-05-17 23:04:246538}
6539
[email protected]f7a64ee2010-02-01 22:24:146540error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]b9849abf2009-11-25 19:13:196541 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466542
[email protected]e259eb412012-10-13 05:47:246543 if (!state_.bound_array_buffer || state_.bound_array_buffer->IsDeleted()) {
6544 if (state_.vertex_attrib_manager == default_vertex_attrib_manager_) {
[email protected]944b62f32012-09-27 02:20:466545 SetGLError(GL_INVALID_VALUE,
6546 "glVertexAttribPointer", "no array buffer bound");
6547 return error::kNoError;
6548 } else if (c.offset != 0) {
6549 SetGLError(GL_INVALID_VALUE,
6550 "glVertexAttribPointer", "client side arrays are not allowed");
6551 return error::kNoError;
6552 }
[email protected]96449d2c2009-11-25 00:01:326553 }
[email protected]8eee29c2010-04-29 03:38:296554
6555 GLuint indx = c.indx;
6556 GLint size = c.size;
6557 GLenum type = c.type;
6558 GLboolean normalized = c.normalized;
6559 GLsizei stride = c.stride;
6560 GLsizei offset = c.offset;
6561 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056562 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536563 SetGLErrorInvalidEnum("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296564 return error::kNoError;
6565 }
[email protected]9438b012010-06-15 22:55:056566 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ff81c192011-01-07 23:04:316567 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436568 "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296569 return error::kNoError;
6570 }
6571 if (indx >= group_->max_vertex_attribs()) {
[email protected]ad84a3a2012-06-08 21:42:436572 SetGLError(GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296573 return error::kNoError;
6574 }
6575 if (stride < 0) {
6576 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436577 "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296578 return error::kNoError;
6579 }
6580 if (stride > 255) {
6581 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436582 "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296583 return error::kNoError;
6584 }
6585 if (offset < 0) {
6586 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436587 "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296588 return error::kNoError;
6589 }
6590 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316591 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296592 if (offset % component_size > 0) {
[email protected]ff81c192011-01-07 23:04:316593 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436594 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316595 return error::kNoError;
6596 }
6597 if (stride % component_size > 0) {
6598 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436599 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296600 return error::kNoError;
6601 }
[email protected]e259eb412012-10-13 05:47:246602 state_.vertex_attrib_manager->SetAttribInfo(
[email protected]8fbedc02010-11-18 18:43:406603 indx,
[email protected]e259eb412012-10-13 05:47:246604 state_.bound_array_buffer,
[email protected]8eee29c2010-04-29 03:38:296605 size,
6606 type,
[email protected]b1122982010-05-17 23:04:246607 normalized,
6608 stride,
6609 stride != 0 ? stride : component_size * size,
[email protected]8eee29c2010-04-29 03:38:296610 offset);
[email protected]8fbedc02010-11-18 18:43:406611 if (type != GL_FIXED) {
6612 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6613 }
[email protected]f7a64ee2010-02-01 22:24:146614 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326615}
6616
[email protected]43410e92012-04-20 17:06:286617void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6618 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246619 state_.viewport_x = x;
6620 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026621 state_.viewport_width = std::min(width, viewport_max_width_);
6622 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286623 glViewport(x, y, width, height);
6624}
6625
[email protected]c6aef902012-02-14 03:31:426626error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
6627 uint32 immediate_data_size, const gles2::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156628 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:426629 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436630 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426631 }
6632 GLuint index = c.index;
6633 GLuint divisor = c.divisor;
6634 if (index >= group_->max_vertex_attribs()) {
6635 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436636 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426637 return error::kNoError;
6638 }
6639
[email protected]e259eb412012-10-13 05:47:246640 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426641 index,
6642 divisor);
6643 glVertexAttribDivisorANGLE(index, divisor);
6644 return error::kNoError;
6645}
6646
[email protected]f7a64ee2010-02-01 22:24:146647error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]b9849abf2009-11-25 19:13:196648 uint32 immediate_data_size, const gles2::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:446649 if (ShouldDeferReads())
6650 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:316651 GLint x = c.x;
6652 GLint y = c.y;
6653 GLsizei width = c.width;
6654 GLsizei height = c.height;
6655 GLenum format = c.format;
6656 GLenum type = c.type;
[email protected]57f223832010-03-19 01:57:566657 if (width < 0 || height < 0) {
[email protected]ad84a3a2012-06-08 21:42:436658 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566659 return error::kNoError;
6660 }
[email protected]a51788e2010-02-24 21:54:256661 typedef gles2::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186662 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346663 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246664 width, height, format, type, state_.pack_alignment, &pixels_size,
6665 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186666 return error::kOutOfBounds;
6667 }
[email protected]612d2f82009-12-08 20:49:316668 void* pixels = GetSharedMemoryAs<void*>(
6669 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]a51788e2010-02-24 21:54:256670 Result* result = GetSharedMemoryAs<Result*>(
6671 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6672 if (!pixels || !result) {
[email protected]f7a64ee2010-02-01 22:24:146673 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466674 }
[email protected]a51788e2010-02-24 21:54:256675
[email protected]9438b012010-06-15 22:55:056676 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:536677 SetGLErrorInvalidEnum("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296678 return error::kNoError;
6679 }
[email protected]9438b012010-06-15 22:55:056680 if (!validators_->pixel_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536681 SetGLErrorInvalidEnum("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:126682 return error::kNoError;
6683 }
[email protected]57f223832010-03-19 01:57:566684 if (width == 0 || height == 0) {
6685 return error::kNoError;
6686 }
6687
[email protected]57f223832010-03-19 01:57:566688 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:306689 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:566690
[email protected]3aad1a32012-09-07 20:54:476691 int32 max_x;
6692 int32 max_y;
6693 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ad84a3a2012-06-08 21:42:436694 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:146695 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:316696 }
[email protected]57f223832010-03-19 01:57:566697
[email protected]0d6bfdc2011-11-02 01:32:206698 if (!CheckBoundFramebuffersValid("glReadPixels")) {
6699 return error::kNoError;
6700 }
6701
[email protected]a0b78dc2011-11-11 10:43:106702 CopyRealGLErrorsToWrapper();
6703
6704 ScopedResolvedFrameBufferBinder binder(this, false, true);
6705
[email protected]d37231fa2010-04-09 21:16:026706 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:566707 // The user requested an out of range area. Get the results 1 line
6708 // at a time.
6709 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346710 uint32 unpadded_row_size;
6711 uint32 padded_row_size;
6712 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246713 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346714 &unpadded_row_size, &padded_row_size)) {
[email protected]ad84a3a2012-06-08 21:42:436715 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566716 return error::kNoError;
6717 }
6718
6719 GLint dest_x_offset = std::max(-x, 0);
6720 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:346721 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246722 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
6723 NULL, NULL)) {
[email protected]ad84a3a2012-06-08 21:42:436724 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566725 return error::kNoError;
6726 }
6727
6728 // Copy each row into the larger dest rect.
6729 int8* dst = static_cast<int8*>(pixels);
6730 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:026731 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:566732 GLint read_width = read_end_x - read_x;
6733 for (GLint yy = 0; yy < height; ++yy) {
6734 GLint ry = y + yy;
6735
6736 // Clear the row.
6737 memset(dst, 0, unpadded_row_size);
6738
6739 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:026740 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:566741 glReadPixels(
6742 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6743 }
6744 dst += padded_row_size;
6745 }
6746 } else {
6747 glReadPixels(x, y, width, height, format, type, pixels);
6748 }
[email protected]1002c2d2011-06-28 22:39:046749 GLenum error = PeekGLError();
[email protected]a51788e2010-02-24 21:54:256750 if (error == GL_NO_ERROR) {
6751 *result = true;
[email protected]4848b9f82011-03-10 18:37:566752
6753 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6754 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
[email protected]84eb4252012-06-29 22:56:446755 if ((channels_exist & 0x0008) == 0 &&
[email protected]62e155e2012-10-23 22:43:156756 workarounds().clear_alpha_in_readpixels) {
[email protected]4848b9f82011-03-10 18:37:566757 // Set the alpha to 255 because some drivers are buggy in this regard.
6758 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346759
6760 uint32 unpadded_row_size;
6761 uint32 padded_row_size;
6762 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246763 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346764 &unpadded_row_size, &padded_row_size)) {
[email protected]ad84a3a2012-06-08 21:42:436765 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]4848b9f82011-03-10 18:37:566766 return error::kNoError;
6767 }
6768 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6769 // of this implementation.
6770 if (type != GL_UNSIGNED_BYTE) {
[email protected]ad84a3a2012-06-08 21:42:436771 SetGLError(
6772 GL_INVALID_OPERATION, "glReadPixels",
6773 "unsupported readPixel format");
[email protected]4848b9f82011-03-10 18:37:566774 return error::kNoError;
6775 }
6776 switch (format) {
6777 case GL_RGBA:
[email protected]297ca1c2011-06-20 23:08:466778 case GL_BGRA_EXT:
[email protected]4848b9f82011-03-10 18:37:566779 case GL_ALPHA: {
6780 int offset = (format == GL_ALPHA) ? 0 : 3;
6781 int step = (format == GL_ALPHA) ? 1 : 4;
6782 uint8* dst = static_cast<uint8*>(pixels) + offset;
6783 for (GLint yy = 0; yy < height; ++yy) {
6784 uint8* end = dst + unpadded_row_size;
6785 for (uint8* d = dst; d < end; d += step) {
6786 *d = 255;
6787 }
6788 dst += padded_row_size;
6789 }
6790 break;
6791 }
6792 default:
6793 break;
6794 }
6795 }
[email protected]a51788e2010-02-24 21:54:256796 }
[email protected]4848b9f82011-03-10 18:37:566797
[email protected]f7a64ee2010-02-01 22:24:146798 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326799}
6800
[email protected]f7a64ee2010-02-01 22:24:146801error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]b9849abf2009-11-25 19:13:196802 uint32 immediate_data_size, const gles2::PixelStorei& c) {
6803 GLenum pname = c.pname;
6804 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:056805 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]f80e6e12012-08-31 00:43:536806 SetGLErrorInvalidEnum("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:126807 return error::kNoError;
6808 }
[email protected]222471d2011-11-30 18:06:396809 switch (pname) {
6810 case GL_PACK_ALIGNMENT:
6811 case GL_UNPACK_ALIGNMENT:
6812 if (!validators_->pixel_store_alignment.IsValid(param)) {
6813 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436814 "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:396815 return error::kNoError;
6816 }
[email protected]164d6d52012-05-05 00:55:036817 break;
[email protected]0a1e9ad2012-05-04 21:13:036818 case GL_UNPACK_FLIP_Y_CHROMIUM:
6819 unpack_flip_y_ = (param != 0);
6820 return error::kNoError;
6821 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
6822 unpack_premultiply_alpha_ = (param != 0);
6823 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:176824 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
6825 unpack_unpremultiply_alpha_ = (param != 0);
6826 return error::kNoError;
[email protected]222471d2011-11-30 18:06:396827 default:
6828 break;
[email protected]b9849abf2009-11-25 19:13:196829 }
6830 glPixelStorei(pname, param);
6831 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:436832 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246833 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436834 break;
6835 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:426836 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:436837 break;
6838 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246839 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436840 break;
6841 default:
6842 // Validation should have prevented us from getting here.
6843 NOTREACHED();
6844 break;
[email protected]b9849abf2009-11-25 19:13:196845 }
[email protected]f7a64ee2010-02-01 22:24:146846 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196847}
6848
[email protected]1c75a3702011-11-11 14:15:286849error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
6850 uint32 immediate_data_size, const gles2::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:386851 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:456852 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]1c75a3702011-11-11 14:15:286853 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436854 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:286855 return error::kNoError;
6856 }
[email protected]7794d512012-04-17 20:36:496857 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:286858 return error::kNoError;
[email protected]7794d512012-04-17 20:36:496859 } else {
6860 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:286861 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:496862 }
[email protected]1c75a3702011-11-11 14:15:286863}
6864
[email protected]558847a2010-03-24 07:02:546865error::Error GLES2DecoderImpl::GetAttribLocationHelper(
6866 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6867 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576868 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ad84a3a2012-06-08 21:42:436869 SetGLError(GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576870 return error::kNoError;
6871 }
[email protected]6b8cf1a2010-05-06 16:13:586872 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6873 client_id, "glGetAttribLocation");
[email protected]ae51d192010-04-27 00:48:036874 if (!info) {
[email protected]f7a64ee2010-02-01 22:24:146875 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196876 }
[email protected]ae51d192010-04-27 00:48:036877 if (!info->IsValid()) {
[email protected]ad84a3a2012-06-08 21:42:436878 SetGLError(
6879 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256880 return error::kNoError;
6881 }
[email protected]b9849abf2009-11-25 19:13:196882 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:546883 location_shm_id, location_shm_offset, sizeof(GLint));
6884 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:146885 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196886 }
[email protected]558847a2010-03-24 07:02:546887 // Require the client to init this incase the context is lost and we are no
6888 // longer executing commands.
6889 if (*location != -1) {
6890 return error::kGenericError;
6891 }
[email protected]0bfd9882010-02-05 23:02:256892 *location = info->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:146893 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196894}
6895
[email protected]558847a2010-03-24 07:02:546896error::Error GLES2DecoderImpl::HandleGetAttribLocation(
6897 uint32 immediate_data_size, const gles2::GetAttribLocation& c) {
6898 uint32 name_size = c.data_size;
6899 const char* name = GetSharedMemoryAs<const char*>(
6900 c.name_shm_id, c.name_shm_offset, name_size);
6901 if (!name) {
6902 return error::kOutOfBounds;
6903 }
6904 String name_str(name, name_size);
6905 return GetAttribLocationHelper(
6906 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6907}
6908
[email protected]f7a64ee2010-02-01 22:24:146909error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]b9849abf2009-11-25 19:13:196910 uint32 immediate_data_size, const gles2::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:546911 uint32 name_size = c.data_size;
6912 const char* name = GetImmediateDataAs<const char*>(
6913 c, name_size, immediate_data_size);
6914 if (!name) {
6915 return error::kOutOfBounds;
6916 }
6917 String name_str(name, name_size);
6918 return GetAttribLocationHelper(
6919 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6920}
6921
6922error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
6923 uint32 immediate_data_size, const gles2::GetAttribLocationBucket& c) {
6924 Bucket* bucket = GetBucket(c.name_bucket_id);
6925 if (!bucket) {
6926 return error::kInvalidArguments;
6927 }
6928 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:186929 if (!bucket->GetAsString(&name_str)) {
6930 return error::kInvalidArguments;
6931 }
[email protected]558847a2010-03-24 07:02:546932 return GetAttribLocationHelper(
6933 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6934}
6935
6936error::Error GLES2DecoderImpl::GetUniformLocationHelper(
6937 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6938 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576939 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ad84a3a2012-06-08 21:42:436940 SetGLError(GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576941 return error::kNoError;
6942 }
[email protected]6b8cf1a2010-05-06 16:13:586943 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6944 client_id, "glUniformLocation");
[email protected]ae51d192010-04-27 00:48:036945 if (!info) {
[email protected]f7a64ee2010-02-01 22:24:146946 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196947 }
[email protected]ae51d192010-04-27 00:48:036948 if (!info->IsValid()) {
[email protected]ad84a3a2012-06-08 21:42:436949 SetGLError(
6950 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256951 return error::kNoError;
6952 }
[email protected]b9849abf2009-11-25 19:13:196953 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:546954 location_shm_id, location_shm_offset, sizeof(GLint));
6955 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:146956 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196957 }
[email protected]558847a2010-03-24 07:02:546958 // Require the client to init this incase the context is lost an we are no
6959 // longer executing commands.
6960 if (*location != -1) {
6961 return error::kGenericError;
6962 }
[email protected]2be6abf32012-06-26 00:28:336963 *location = info->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:146964 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196965}
6966
[email protected]f7a64ee2010-02-01 22:24:146967error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]b9849abf2009-11-25 19:13:196968 uint32 immediate_data_size, const gles2::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:196969 uint32 name_size = c.data_size;
6970 const char* name = GetSharedMemoryAs<const char*>(
6971 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:546972 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:146973 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196974 }
6975 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:546976 return GetUniformLocationHelper(
6977 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:196978}
6979
[email protected]f7a64ee2010-02-01 22:24:146980error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]b9849abf2009-11-25 19:13:196981 uint32 immediate_data_size, const gles2::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:196982 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:306983 const char* name = GetImmediateDataAs<const char*>(
6984 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:546985 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:146986 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196987 }
6988 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:546989 return GetUniformLocationHelper(
6990 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6991}
6992
6993error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
6994 uint32 immediate_data_size, const gles2::GetUniformLocationBucket& c) {
6995 Bucket* bucket = GetBucket(c.name_bucket_id);
6996 if (!bucket) {
6997 return error::kInvalidArguments;
6998 }
6999 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187000 if (!bucket->GetAsString(&name_str)) {
7001 return error::kInvalidArguments;
7002 }
[email protected]558847a2010-03-24 07:02:547003 return GetUniformLocationHelper(
7004 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197005}
7006
[email protected]ddd968b82010-03-02 00:44:297007error::Error GLES2DecoderImpl::HandleGetString(
7008 uint32 immediate_data_size, const gles2::GetString& c) {
7009 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057010 if (!validators_->string_type.IsValid(name)) {
[email protected]f80e6e12012-08-31 00:43:537011 SetGLErrorInvalidEnum("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297012 return error::kNoError;
7013 }
[email protected]1958e0e2010-04-22 05:17:157014 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
7015 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:047016 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157017 switch (name) {
7018 case GL_VERSION:
7019 str = "OpenGL ES 2.0 Chromium";
7020 break;
7021 case GL_SHADING_LANGUAGE_VERSION:
7022 str = "OpenGL ES GLSL ES 1.0 Chromium";
7023 break;
[email protected]32939602012-05-09 06:25:167024 case GL_RENDERER:
7025 str = "Chromium";
7026 break;
7027 case GL_VENDOR:
7028 str = "Chromium";
7029 break;
[email protected]1958e0e2010-04-22 05:17:157030 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047031 {
7032 // For WebGL contexts, strip out the OES derivatives extension if it has
7033 // not been enabled.
7034 if (force_webgl_glsl_validation_ &&
7035 !derivatives_explicitly_enabled_) {
7036 extensions = feature_info_->extensions();
7037 size_t offset = extensions.find(kOESDerivativeExtension);
7038 if (std::string::npos != offset) {
7039 extensions.replace(offset,
7040 offset + arraysize(kOESDerivativeExtension),
7041 std::string());
7042 }
[email protected]f0d74742011-10-03 16:31:047043 } else {
[email protected]6f5fac9d12012-06-26 21:02:457044 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047045 }
[email protected]6f5fac9d12012-06-26 21:02:457046 std::string surface_extensions = surface_->GetExtensions();
7047 if (!surface_extensions.empty())
7048 extensions += " " + surface_extensions;
7049 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047050 }
[email protected]1958e0e2010-04-22 05:17:157051 break;
7052 default:
7053 str = gl_str;
7054 break;
7055 }
[email protected]ddd968b82010-03-02 00:44:297056 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157057 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297058 return error::kNoError;
7059}
7060
[email protected]0c86dbf2010-03-05 08:14:117061void GLES2DecoderImpl::DoBufferData(
[email protected]b9363b22010-06-09 22:06:157062 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
[email protected]9438b012010-06-15 22:55:057063 if (!validators_->buffer_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:537064 SetGLErrorInvalidEnum("glBufferData", target, "target");
[email protected]8eee29c2010-04-29 03:38:297065 return;
7066 }
[email protected]9438b012010-06-15 22:55:057067 if (!validators_->buffer_usage.IsValid(usage)) {
[email protected]f80e6e12012-08-31 00:43:537068 SetGLErrorInvalidEnum("glBufferData", usage, "usage");
[email protected]0c86dbf2010-03-05 08:14:117069 return;
[email protected]3b6ec202010-03-05 05:16:237070 }
7071 if (size < 0) {
[email protected]ad84a3a2012-06-08 21:42:437072 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0");
[email protected]037896bd2010-04-21 19:07:287073 return;
[email protected]3b6ec202010-03-05 05:16:237074 }
7075 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target);
7076 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:437077 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287078 return;
[email protected]3b6ec202010-03-05 05:16:237079 }
7080 // Clear the buffer to 0 if no initial data was passed in.
7081 scoped_array<int8> zero;
7082 if (!data) {
7083 zero.reset(new int8[size]);
7084 memset(zero.get(), 0, size);
7085 data = zero.get();
7086 }
[email protected]473c01ccb2011-06-07 01:33:307087
[email protected]3b6ec202010-03-05 05:16:237088 CopyRealGLErrorsToWrapper();
7089 glBufferData(target, size, data, usage);
[email protected]1002c2d2011-06-28 22:39:047090 GLenum error = PeekGLError();
7091 if (error == GL_NO_ERROR) {
[email protected]473c01ccb2011-06-07 01:33:307092 buffer_manager()->SetInfo(info, size, usage);
[email protected]0c86dbf2010-03-05 08:14:117093 info->SetRange(0, size, data);
[email protected]a39370652012-09-25 21:52:137094 } else {
7095 buffer_manager()->SetInfo(info, 0, usage);
[email protected]3b6ec202010-03-05 05:16:237096 }
[email protected]0c86dbf2010-03-05 08:14:117097}
7098
7099error::Error GLES2DecoderImpl::HandleBufferData(
7100 uint32 immediate_data_size, const gles2::BufferData& c) {
7101 GLenum target = static_cast<GLenum>(c.target);
7102 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7103 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7104 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7105 GLenum usage = static_cast<GLenum>(c.usage);
7106 const void* data = NULL;
7107 if (data_shm_id != 0 || data_shm_offset != 0) {
7108 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7109 if (!data) {
7110 return error::kOutOfBounds;
7111 }
7112 }
7113 DoBufferData(target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147114 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197115}
7116
[email protected]f7a64ee2010-02-01 22:24:147117error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]b9849abf2009-11-25 19:13:197118 uint32 immediate_data_size, const gles2::BufferDataImmediate& c) {
7119 GLenum target = static_cast<GLenum>(c.target);
7120 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:307121 const void* data = GetImmediateDataAs<const void*>(
7122 c, size, immediate_data_size);
7123 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147124 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:307125 }
[email protected]b9849abf2009-11-25 19:13:197126 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0c86dbf2010-03-05 08:14:117127 DoBufferData(target, size, data, usage);
7128 return error::kNoError;
7129}
7130
7131void GLES2DecoderImpl::DoBufferSubData(
7132 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]3916c97e2010-02-25 03:20:507133 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477134 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:437135 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287136 return;
[email protected]a93bb842010-02-16 23:03:477137 }
[email protected]0c86dbf2010-03-05 08:14:117138 if (!info->SetRange(offset, size, data)) {
[email protected]ad84a3a2012-06-08 21:42:437139 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range");
[email protected]473c01ccb2011-06-07 01:33:307140 return;
[email protected]07f54fcc2009-12-22 02:46:307141 }
[email protected]473c01ccb2011-06-07 01:33:307142 glBufferSubData(target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197143}
7144
[email protected]0d6bfdc2011-11-02 01:32:207145bool GLES2DecoderImpl::ClearLevel(
7146 unsigned service_id,
7147 unsigned bind_target,
7148 unsigned target,
7149 int level,
7150 unsigned format,
7151 unsigned type,
7152 int width,
[email protected]4502e6492011-12-14 19:39:157153 int height,
7154 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007155 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7156 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7157 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7158 // on depth formats.
7159 GLuint fb = 0;
7160 glGenFramebuffersEXT(1, &fb);
7161 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7162
7163 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7164 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7165 GL_DEPTH_ATTACHMENT;
7166
7167 glFramebufferTexture2DEXT(
7168 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7169 // ANGLE promises a depth only attachment ok.
7170 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7171 GL_FRAMEBUFFER_COMPLETE) {
7172 return false;
7173 }
7174 glClearStencil(0);
7175 glStencilMask(-1);
7176 glClearDepth(1.0f);
7177 glDepthMask(true);
7178 glDisable(GL_SCISSOR_TEST);
7179 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7180
7181 RestoreClearState();
7182
7183 glDeleteFramebuffersEXT(1, &fb);
7184 FramebufferManager::FramebufferInfo* framebuffer =
7185 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7186 GLuint fb_service_id =
7187 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7188 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7189 return true;
7190 }
7191
[email protected]45d15a62012-04-18 14:33:177192 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7193
7194 uint32 size;
7195 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347196 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247197 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177198 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207199 return false;
7200 }
[email protected]45d15a62012-04-18 14:33:177201
[email protected]a5d3dad2012-05-26 04:34:447202 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7203
[email protected]45d15a62012-04-18 14:33:177204 int tile_height;
7205
7206 if (size > kMaxZeroSize) {
7207 if (kMaxZeroSize < padded_row_size) {
7208 // That'd be an awfully large texture.
7209 return false;
7210 }
7211 // We should never have a large total size with a zero row size.
7212 DCHECK_GT(padded_row_size, 0U);
7213 tile_height = kMaxZeroSize / padded_row_size;
7214 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247215 width, tile_height, format, type, state_.unpack_alignment, &size,
7216 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177217 return false;
7218 }
[email protected]4502e6492011-12-14 19:39:157219 } else {
[email protected]45d15a62012-04-18 14:33:177220 tile_height = height;
7221 }
7222
7223 // Assumes the size has already been checked.
7224 scoped_array<char> zero(new char[size]);
7225 memset(zero.get(), 0, size);
7226 glBindTexture(bind_target, service_id);
7227
7228 GLint y = 0;
7229 while (y < height) {
7230 GLint h = y + tile_height > height ? height - y : tile_height;
7231 if (is_texture_immutable || h != height) {
7232 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7233 } else {
7234 WrappedTexImage2D(
7235 target, level, format, width, h, 0, format, type, zero.get());
7236 }
7237 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157238 }
[email protected]0d6bfdc2011-11-02 01:32:207239 TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target);
7240 glBindTexture(bind_target, info ? info->service_id() : 0);
7241 return true;
7242}
7243
[email protected]ad84a3a2012-06-08 21:42:437244namespace {
7245
7246const int kS3TCBlockWidth = 4;
7247const int kS3TCBlockHeight = 4;
7248const int kS3TCDXT1BlockSize = 8;
7249const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077250const int kETC1BlockWidth = 4;
7251const int kETC1BlockHeight = 4;
7252const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437253
7254bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517255 return (size == 1) ||
7256 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437257}
7258
7259} // anonymous namespace.
7260
7261bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7262 const char* function_name,
7263 GLsizei width, GLsizei height, GLenum format, size_t size) {
7264 unsigned int bytes_required = 0;
7265
7266 switch (format) {
7267 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7268 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7269 int num_blocks_across =
7270 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7271 int num_blocks_down =
7272 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7273 int num_blocks = num_blocks_across * num_blocks_down;
7274 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7275 break;
7276 }
7277 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7278 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7279 int num_blocks_across =
7280 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7281 int num_blocks_down =
7282 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7283 int num_blocks = num_blocks_across * num_blocks_down;
7284 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7285 break;
7286 }
[email protected]2d3765b2012-10-03 00:31:077287 case GL_ETC1_RGB8_OES: {
7288 int num_blocks_across =
7289 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7290 int num_blocks_down =
7291 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7292 int num_blocks = num_blocks_across * num_blocks_down;
7293 bytes_required = num_blocks * kETC1BlockSize;
7294 break;
7295 }
[email protected]ad84a3a2012-06-08 21:42:437296 default:
[email protected]f80e6e12012-08-31 00:43:537297 SetGLErrorInvalidEnum(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437298 return false;
7299 }
7300
7301 if (size != bytes_required) {
7302 SetGLError(
7303 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7304 return false;
7305 }
7306
7307 return true;
7308}
7309
7310bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7311 const char* function_name,
7312 GLint level, GLsizei width, GLsizei height, GLenum format) {
7313 switch (format) {
7314 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7315 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7316 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7317 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7318 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
7319 SetGLError(
7320 GL_INVALID_OPERATION, function_name,
7321 "width or height invalid for level");
7322 return false;
7323 }
7324 return true;
7325 }
[email protected]2d3765b2012-10-03 00:31:077326 case GL_ETC1_RGB8_OES:
7327 if (width <= 0 || height <= 0) {
7328 SetGLError(
7329 GL_INVALID_OPERATION, function_name,
7330 "width or height invalid for level");
7331 return false;
7332 }
7333 return true;
[email protected]ad84a3a2012-06-08 21:42:437334 default:
7335 return false;
7336 }
7337}
7338
7339bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7340 const char* function_name,
7341 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7342 GLsizei width, GLsizei height, GLenum format,
7343 TextureManager::TextureInfo* texture) {
7344 if (xoffset < 0 || yoffset < 0) {
7345 SetGLError(
7346 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7347 return false;
7348 }
7349
7350 switch (format) {
7351 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7352 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7353 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7354 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7355 const int kBlockWidth = 4;
7356 const int kBlockHeight = 4;
7357 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
7358 SetGLError(
7359 GL_INVALID_OPERATION, function_name,
7360 "xoffset or yoffset not multiple of 4");
7361 return false;
7362 }
7363 GLsizei tex_width = 0;
7364 GLsizei tex_height = 0;
7365 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7366 width - xoffset > tex_width ||
7367 height - yoffset > tex_height) {
7368 SetGLError(
7369 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7370 return false;
7371 }
7372 return ValidateCompressedTexDimensions(
7373 function_name, level, width, height, format);
7374 }
[email protected]2d3765b2012-10-03 00:31:077375 case GL_ETC1_RGB8_OES: {
7376 SetGLError(
7377 GL_INVALID_OPERATION, function_name,
7378 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7379 return false;
7380 }
[email protected]ad84a3a2012-06-08 21:42:437381 default:
7382 return false;
7383 }
7384}
7385
[email protected]a93bb842010-02-16 23:03:477386error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7387 GLenum target,
7388 GLint level,
7389 GLenum internal_format,
7390 GLsizei width,
7391 GLsizei height,
7392 GLint border,
7393 GLsizei image_size,
7394 const void* data) {
[email protected]a93bb842010-02-16 23:03:477395 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057396 if (!validators_->texture_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:537397 SetGLErrorInvalidEnum("glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297398 return error::kNoError;
7399 }
[email protected]9438b012010-06-15 22:55:057400 if (!validators_->compressed_texture_format.IsValid(
7401 internal_format)) {
[email protected]f80e6e12012-08-31 00:43:537402 SetGLErrorInvalidEnum(
7403 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477404 return error::kNoError;
7405 }
[email protected]80eb6b52012-01-19 00:14:417406 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477407 border != 0) {
[email protected]8eee29c2010-04-29 03:38:297408 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437409 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477410 return error::kNoError;
7411 }
[email protected]3916c97e2010-02-25 03:20:507412 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477413 if (!info) {
[email protected]8eee29c2010-04-29 03:38:297414 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437415 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477416 return error::kNoError;
7417 }
[email protected]97dc7cbe2011-12-06 17:26:177418 if (info->IsImmutable()) {
7419 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437420 "glCompressedTexImage2D", "texture is immutable");
7421 return error::kNoError;
7422 }
7423
7424 if (!ValidateCompressedTexDimensions(
7425 "glCompressedTexImage2D", level, width, height, internal_format) ||
7426 !ValidateCompressedTexFuncData(
7427 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177428 return error::kNoError;
7429 }
[email protected]968351b2011-12-20 08:26:517430
7431 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427432 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517433 // TODO(gman): If textures tracked which framebuffers they were attached to
7434 // we could just mark those framebuffers as not complete.
7435 framebuffer_manager()->IncFramebufferStateChangeCount();
7436 }
7437
[email protected]a93bb842010-02-16 23:03:477438 scoped_array<int8> zero;
7439 if (!data) {
7440 zero.reset(new int8[image_size]);
7441 memset(zero.get(), 0, image_size);
7442 data = zero.get();
7443 }
[email protected]cadde4a2010-07-31 17:10:437444 CopyRealGLErrorsToWrapper();
[email protected]a93bb842010-02-16 23:03:477445 glCompressedTexImage2D(
7446 target, level, internal_format, width, height, border, image_size, data);
[email protected]1002c2d2011-06-28 22:39:047447 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437448 if (error == GL_NO_ERROR) {
7449 texture_manager()->SetLevelInfo(
[email protected]0d6bfdc2011-11-02 01:32:207450 info, target, level, internal_format, width, height, 1, border, 0, 0,
7451 true);
[email protected]cadde4a2010-07-31 17:10:437452 }
[email protected]a93bb842010-02-16 23:03:477453 return error::kNoError;
7454}
7455
[email protected]f7a64ee2010-02-01 22:24:147456error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197457 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) {
7458 GLenum target = static_cast<GLenum>(c.target);
7459 GLint level = static_cast<GLint>(c.level);
7460 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7461 GLsizei width = static_cast<GLsizei>(c.width);
7462 GLsizei height = static_cast<GLsizei>(c.height);
7463 GLint border = static_cast<GLint>(c.border);
7464 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7465 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7466 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7467 const void* data = NULL;
7468 if (data_shm_id != 0 || data_shm_offset != 0) {
7469 data = GetSharedMemoryAs<const void*>(
7470 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467471 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147472 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197473 }
7474 }
[email protected]a93bb842010-02-16 23:03:477475 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197476 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197477}
7478
[email protected]f7a64ee2010-02-01 22:24:147479error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]b9849abf2009-11-25 19:13:197480 uint32 immediate_data_size, const gles2::CompressedTexImage2DImmediate& c) {
7481 GLenum target = static_cast<GLenum>(c.target);
7482 GLint level = static_cast<GLint>(c.level);
7483 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7484 GLsizei width = static_cast<GLsizei>(c.width);
7485 GLsizei height = static_cast<GLsizei>(c.height);
7486 GLint border = static_cast<GLint>(c.border);
7487 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307488 const void* data = GetImmediateDataAs<const void*>(
7489 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467490 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147491 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467492 }
[email protected]a93bb842010-02-16 23:03:477493 return DoCompressedTexImage2D(
7494 target, level, internal_format, width, height, border, image_size, data);
7495}
7496
[email protected]b6140d02010-05-17 14:47:167497error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
7498 uint32 immediate_data_size, const gles2::CompressedTexImage2DBucket& c) {
7499 GLenum target = static_cast<GLenum>(c.target);
7500 GLint level = static_cast<GLint>(c.level);
7501 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7502 GLsizei width = static_cast<GLsizei>(c.width);
7503 GLsizei height = static_cast<GLsizei>(c.height);
7504 GLint border = static_cast<GLint>(c.border);
7505 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287506 if (!bucket) {
7507 return error::kInvalidArguments;
7508 }
7509 uint32 data_size = bucket->size();
7510 GLsizei imageSize = data_size;
7511 const void* data = bucket->GetData(0, data_size);
7512 if (!data) {
7513 return error::kInvalidArguments;
7514 }
[email protected]b6140d02010-05-17 14:47:167515 return DoCompressedTexImage2D(
7516 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287517 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167518}
7519
7520error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7521 uint32 immediate_data_size,
7522 const gles2::CompressedTexSubImage2DBucket& c) {
7523 GLenum target = static_cast<GLenum>(c.target);
7524 GLint level = static_cast<GLint>(c.level);
7525 GLint xoffset = static_cast<GLint>(c.xoffset);
7526 GLint yoffset = static_cast<GLint>(c.yoffset);
7527 GLsizei width = static_cast<GLsizei>(c.width);
7528 GLsizei height = static_cast<GLsizei>(c.height);
7529 GLenum format = static_cast<GLenum>(c.format);
7530 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287531 if (!bucket) {
7532 return error::kInvalidArguments;
7533 }
[email protected]b6140d02010-05-17 14:47:167534 uint32 data_size = bucket->size();
7535 GLsizei imageSize = data_size;
7536 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287537 if (!data) {
7538 return error::kInvalidArguments;
7539 }
[email protected]9438b012010-06-15 22:55:057540 if (!validators_->texture_target.IsValid(target)) {
[email protected]b6140d02010-05-17 14:47:167541 SetGLError(
[email protected]f80e6e12012-08-31 00:43:537542 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167543 return error::kNoError;
7544 }
[email protected]9438b012010-06-15 22:55:057545 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:537546 SetGLErrorInvalidEnum("glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057547 return error::kNoError;
7548 }
[email protected]b6140d02010-05-17 14:47:167549 if (width < 0) {
[email protected]ad84a3a2012-06-08 21:42:437550 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167551 return error::kNoError;
7552 }
7553 if (height < 0) {
[email protected]ad84a3a2012-06-08 21:42:437554 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167555 return error::kNoError;
7556 }
7557 if (imageSize < 0) {
[email protected]ad84a3a2012-06-08 21:42:437558 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167559 return error::kNoError;
7560 }
[email protected]cadde4a2010-07-31 17:10:437561 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167562 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7563 return error::kNoError;
7564}
7565
[email protected]81375742012-06-08 00:04:007566bool GLES2DecoderImpl::ValidateTextureParameters(
7567 const char* function_name,
7568 GLenum target, GLenum format, GLenum type, GLint level) {
7569 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
[email protected]ad84a3a2012-06-08 21:42:437570 SetGLError(GL_INVALID_OPERATION, function_name,
7571 (std::string("invalid type ") +
[email protected]81375742012-06-08 00:04:007572 GLES2Util::GetStringEnum(type) + " for format " +
7573 GLES2Util::GetStringEnum(format)).c_str());
7574 return false;
7575 }
7576
7577 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7578 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
[email protected]ad84a3a2012-06-08 21:42:437579 SetGLError(GL_INVALID_OPERATION, function_name,
7580 (std::string("invalid type ") +
[email protected]81375742012-06-08 00:04:007581 GLES2Util::GetStringEnum(type) + " for format " +
7582 GLES2Util::GetStringEnum(format)).c_str());
7583 return false;
7584 }
7585 return true;
7586}
7587
[email protected]f598f422012-12-07 08:30:037588bool GLES2DecoderImpl::ValidateTexImage2D(
7589 const char* function_name,
7590 GLenum target,
7591 GLint level,
7592 GLenum internal_format,
7593 GLsizei width,
7594 GLsizei height,
7595 GLint border,
7596 GLenum format,
7597 GLenum type,
7598 const void* pixels,
7599 uint32 pixels_size) {
[email protected]9438b012010-06-15 22:55:057600 if (!validators_->texture_target.IsValid(target)) {
[email protected]f598f422012-12-07 08:30:037601 SetGLErrorInvalidEnum(function_name, target, "target");
7602 return false;
[email protected]8eee29c2010-04-29 03:38:297603 }
[email protected]9438b012010-06-15 22:55:057604 if (!validators_->texture_format.IsValid(internal_format)) {
[email protected]f598f422012-12-07 08:30:037605 SetGLErrorInvalidEnum(function_name, internal_format, "internal_format");
7606 return false;
[email protected]8eee29c2010-04-29 03:38:297607 }
[email protected]9438b012010-06-15 22:55:057608 if (!validators_->texture_format.IsValid(format)) {
[email protected]f598f422012-12-07 08:30:037609 SetGLErrorInvalidEnum(function_name, format, "format");
7610 return false;
[email protected]8eee29c2010-04-29 03:38:297611 }
[email protected]9438b012010-06-15 22:55:057612 if (!validators_->pixel_type.IsValid(type)) {
[email protected]f598f422012-12-07 08:30:037613 SetGLErrorInvalidEnum(function_name, type, "type");
7614 return false;
[email protected]b9849abf2009-11-25 19:13:197615 }
[email protected]7b92c412010-07-20 17:48:257616 if (format != internal_format) {
[email protected]ad84a3a2012-06-08 21:42:437617 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037618 function_name, "format != internalFormat");
7619 return false;
[email protected]7b92c412010-07-20 17:48:257620 }
[email protected]f598f422012-12-07 08:30:037621 if (!ValidateTextureParameters(function_name, target, format, type, level)) {
7622 return false;
[email protected]81375742012-06-08 00:04:007623 }
[email protected]80eb6b52012-01-19 00:14:417624 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477625 border != 0) {
[email protected]f598f422012-12-07 08:30:037626 SetGLError(GL_INVALID_VALUE, function_name, "dimensions out of range");
7627 return false;
[email protected]a93bb842010-02-16 23:03:477628 }
[email protected]81375742012-06-08 00:04:007629 if ((GLES2Util::GetChannelsForFormat(format) &
7630 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
7631 SetGLError(
7632 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037633 function_name, "can not supply data for depth or stencil textures");
7634 return false;
[email protected]81375742012-06-08 00:04:007635 }
[email protected]3916c97e2010-02-25 03:20:507636 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477637 if (!info) {
[email protected]8eee29c2010-04-29 03:38:297638 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037639 function_name, "unknown texture for target");
7640 return false;
[email protected]a93bb842010-02-16 23:03:477641 }
[email protected]97dc7cbe2011-12-06 17:26:177642 if (info->IsImmutable()) {
7643 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037644 function_name, "texture is immutable");
7645 return false;
[email protected]97dc7cbe2011-12-06 17:26:177646 }
[email protected]f598f422012-12-07 08:30:037647 return true;
7648}
[email protected]97dc7cbe2011-12-06 17:26:177649
[email protected]f598f422012-12-07 08:30:037650void GLES2DecoderImpl::DoTexImage2D(
7651 GLenum target,
7652 GLint level,
7653 GLenum internal_format,
7654 GLsizei width,
7655 GLsizei height,
7656 GLint border,
7657 GLenum format,
7658 GLenum type,
7659 const void* pixels,
7660 uint32 pixels_size) {
7661 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format,
7662 width, height, border, format, type, pixels, pixels_size)) {
7663 return;
7664 }
7665 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]0226c112011-07-22 03:25:077666 GLsizei tex_width = 0;
7667 GLsizei tex_height = 0;
7668 GLenum tex_type = 0;
7669 GLenum tex_format = 0;
7670 bool level_is_same =
7671 info->GetLevelSize(target, level, &tex_width, &tex_height) &&
7672 info->GetLevelType(target, level, &tex_type, &tex_format) &&
7673 width == tex_width && height == tex_height &&
7674 type == tex_type && format == tex_format;
7675
7676 if (level_is_same && !pixels) {
[email protected]1bed6222011-12-21 11:21:397677 // Just set the level info but mark the texture as uncleared.
7678 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417679 info,
[email protected]1bed6222011-12-21 11:21:397680 target, level, internal_format, width, height, 1, border, format, type,
7681 false);
[email protected]ea72ed222011-08-17 18:58:437682 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037683 return;
[email protected]0226c112011-07-22 03:25:077684 }
7685
[email protected]297ca1c2011-06-20 23:08:467686 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427687 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517688 // TODO(gman): If textures tracked which framebuffers they were attached to
7689 // we could just mark those framebuffers as not complete.
7690 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:467691 }
7692
[email protected]1bed6222011-12-21 11:21:397693 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) {
[email protected]0226c112011-07-22 03:25:077694 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
[email protected]60f22d32012-12-12 00:31:587695 texture_manager()->SetLevelCleared(info, target, level, true);
[email protected]0226c112011-07-22 03:25:077696 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037697 return;
[email protected]7488d962010-07-16 02:41:587698 }
[email protected]876f6fee2010-08-02 23:10:327699
[email protected]cadde4a2010-07-31 17:10:437700 CopyRealGLErrorsToWrapper();
[email protected]473c01ccb2011-06-07 01:33:307701 WrappedTexImage2D(
7702 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477703 pixels);
[email protected]1002c2d2011-06-28 22:39:047704 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437705 if (error == GL_NO_ERROR) {
[email protected]0d6bfdc2011-11-02 01:32:207706 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417707 info,
[email protected]0d6bfdc2011-11-02 01:32:207708 target, level, internal_format, width, height, 1, border, format, type,
7709 pixels != NULL);
[email protected]b493ee622011-04-13 23:52:007710 tex_image_2d_failed_ = false;
[email protected]cadde4a2010-07-31 17:10:437711 }
[email protected]f598f422012-12-07 08:30:037712 return;
[email protected]b9849abf2009-11-25 19:13:197713}
7714
[email protected]f7a64ee2010-02-01 22:24:147715error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197716 uint32 immediate_data_size, const gles2::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387717 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]b493ee622011-04-13 23:52:007718 tex_image_2d_failed_ = true;
[email protected]b9849abf2009-11-25 19:13:197719 GLenum target = static_cast<GLenum>(c.target);
7720 GLint level = static_cast<GLint>(c.level);
7721 GLint internal_format = static_cast<GLint>(c.internalformat);
7722 GLsizei width = static_cast<GLsizei>(c.width);
7723 GLsizei height = static_cast<GLsizei>(c.height);
7724 GLint border = static_cast<GLint>(c.border);
7725 GLenum format = static_cast<GLenum>(c.format);
7726 GLenum type = static_cast<GLenum>(c.type);
7727 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7728 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187729 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347730 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247731 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347732 NULL)) {
[email protected]a76b0052010-03-05 00:33:187733 return error::kOutOfBounds;
7734 }
[email protected]b9849abf2009-11-25 19:13:197735 const void* pixels = NULL;
7736 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7737 pixels = GetSharedMemoryAs<const void*>(
7738 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467739 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147740 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197741 }
7742 }
[email protected]f598f422012-12-07 08:30:037743
7744 DoTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197745 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477746 pixels, pixels_size);
[email protected]f598f422012-12-07 08:30:037747 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197748}
7749
[email protected]f7a64ee2010-02-01 22:24:147750error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]b9849abf2009-11-25 19:13:197751 uint32 immediate_data_size, const gles2::TexImage2DImmediate& c) {
7752 GLenum target = static_cast<GLenum>(c.target);
7753 GLint level = static_cast<GLint>(c.level);
[email protected]ba3176a2009-12-16 18:19:467754 GLint internal_format = static_cast<GLint>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197755 GLsizei width = static_cast<GLsizei>(c.width);
7756 GLsizei height = static_cast<GLsizei>(c.height);
7757 GLint border = static_cast<GLint>(c.border);
7758 GLenum format = static_cast<GLenum>(c.format);
7759 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:187760 uint32 size;
[email protected]3458a64a2012-04-10 17:39:347761 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247762 width, height, format, type, state_.unpack_alignment, &size,
7763 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187764 return error::kOutOfBounds;
7765 }
[email protected]07f54fcc2009-12-22 02:46:307766 const void* pixels = GetImmediateDataAs<const void*>(
7767 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467768 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147769 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467770 }
[email protected]a93bb842010-02-16 23:03:477771 DoTexImage2D(
[email protected]ba3176a2009-12-16 18:19:467772 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477773 pixels, size);
[email protected]f7a64ee2010-02-01 22:24:147774 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327775}
7776
[email protected]cadde4a2010-07-31 17:10:437777void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7778 GLenum target,
7779 GLint level,
7780 GLint xoffset,
7781 GLint yoffset,
7782 GLsizei width,
7783 GLsizei height,
7784 GLenum format,
7785 GLsizei image_size,
7786 const void * data) {
7787 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7788 if (!info) {
7789 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437790 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437791 return;
7792 }
7793 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527794 GLenum internal_format = 0;
7795 if (!info->GetLevelType(target, level, &type, &internal_format)) {
7796 SetGLError(
7797 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437798 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527799 return;
7800 }
7801 if (internal_format != format) {
7802 SetGLError(
7803 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437804 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527805 return;
7806 }
7807 if (!info->ValidForTexture(
7808 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]cadde4a2010-07-31 17:10:437809 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437810 "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437811 return;
7812 }
[email protected]ad84a3a2012-06-08 21:42:437813
7814 if (!ValidateCompressedTexFuncData(
7815 "glCompressedTexSubImage2D", width, height, format, image_size) ||
7816 !ValidateCompressedTexSubDimensions(
7817 "glCompressedTexSubImage2D",
7818 target, level, xoffset, yoffset, width, height, format, info)) {
7819 return;
7820 }
7821
7822
[email protected]0d6bfdc2011-11-02 01:32:207823 // Note: There is no need to deal with texture cleared tracking here
7824 // because the validation above means you can only get here if the level
7825 // is already a matching compressed format and in that case
7826 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:437827 glCompressedTexSubImage2D(
7828 target, level, xoffset, yoffset, width, height, format, image_size, data);
7829}
7830
[email protected]6e288612010-12-21 20:45:037831static void Clip(
7832 GLint start, GLint range, GLint sourceRange,
7833 GLint* out_start, GLint* out_range) {
7834 DCHECK(out_start);
7835 DCHECK(out_range);
7836 if (start < 0) {
7837 range += start;
7838 start = 0;
7839 }
7840 GLint end = start + range;
7841 if (end > sourceRange) {
7842 range -= end - sourceRange;
7843 }
7844 *out_start = start;
7845 *out_range = range;
7846}
7847
[email protected]cadde4a2010-07-31 17:10:437848void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:447849 GLenum target,
7850 GLint level,
7851 GLenum internal_format,
7852 GLint x,
7853 GLint y,
7854 GLsizei width,
7855 GLsizei height,
7856 GLint border) {
[email protected]09e17272012-11-30 10:30:447857 DCHECK(!ShouldDeferReads());
[email protected]cadde4a2010-07-31 17:10:437858 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7859 if (!info) {
7860 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437861 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437862 return;
7863 }
[email protected]97dc7cbe2011-12-06 17:26:177864 if (info->IsImmutable()) {
7865 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437866 "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:177867 }
[email protected]80eb6b52012-01-19 00:14:417868 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:187869 border != 0) {
[email protected]ad84a3a2012-06-08 21:42:437870 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:187871 return;
7872 }
[email protected]81375742012-06-08 00:04:007873 if (!ValidateTextureParameters(
7874 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
7875 return;
7876 }
[email protected]f5719fb2010-08-04 18:27:187877
[email protected]9edc6b22010-12-23 02:00:267878 // Check we have compatible formats.
7879 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7880 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7881 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
7882
7883 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ad84a3a2012-06-08 21:42:437884 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:267885 return;
7886 }
7887
[email protected]81375742012-06-08 00:04:007888 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
7889 SetGLError(
7890 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437891 "glCopyImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:007892 return;
7893 }
7894
[email protected]a0b78dc2011-11-11 10:43:107895 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
7896 return;
7897 }
7898
[email protected]cadde4a2010-07-31 17:10:437899 CopyRealGLErrorsToWrapper();
[email protected]de26b3c2011-08-03 21:54:277900 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:037901 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:267902
[email protected]297ca1c2011-06-20 23:08:467903 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427904 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517905 // TODO(gman): If textures tracked which framebuffers they were attached to
7906 // we could just mark those framebuffers as not complete.
7907 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:467908 }
7909
[email protected]9edc6b22010-12-23 02:00:267910 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:037911 GLint copyX = 0;
7912 GLint copyY = 0;
7913 GLint copyWidth = 0;
7914 GLint copyHeight = 0;
7915 Clip(x, width, size.width(), &copyX, &copyWidth);
7916 Clip(y, height, size.height(), &copyY, &copyHeight);
7917
7918 if (copyX != x ||
7919 copyY != y ||
7920 copyWidth != width ||
7921 copyHeight != height) {
7922 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:207923 if (!ClearLevel(
7924 info->service_id(), info->target(),
[email protected]4502e6492011-12-14 19:39:157925 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
7926 info->IsImmutable())) {
[email protected]ad84a3a2012-06-08 21:42:437927 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:037928 return;
7929 }
[email protected]6e288612010-12-21 20:45:037930 if (copyHeight > 0 && copyWidth > 0) {
7931 GLint dx = copyX - x;
7932 GLint dy = copyY - y;
7933 GLint destX = dx;
7934 GLint destY = dy;
7935 glCopyTexSubImage2D(target, level,
7936 destX, destY, copyX, copyY,
7937 copyWidth, copyHeight);
7938 }
7939 } else {
7940 glCopyTexImage2D(target, level, internal_format,
7941 copyX, copyY, copyWidth, copyHeight, border);
7942 }
[email protected]1002c2d2011-06-28 22:39:047943 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437944 if (error == GL_NO_ERROR) {
7945 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417946 info, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:207947 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:437948 }
7949}
7950
7951void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:447952 GLenum target,
7953 GLint level,
7954 GLint xoffset,
7955 GLint yoffset,
7956 GLint x,
7957 GLint y,
7958 GLsizei width,
7959 GLsizei height) {
[email protected]09e17272012-11-30 10:30:447960 DCHECK(!ShouldDeferReads());
[email protected]cadde4a2010-07-31 17:10:437961 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7962 if (!info) {
7963 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437964 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437965 return;
7966 }
7967 GLenum type = 0;
7968 GLenum format = 0;
7969 if (!info->GetLevelType(target, level, &type, &format) ||
7970 !info->ValidForTexture(
7971 target, level, xoffset, yoffset, width, height, format, type)) {
7972 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437973 "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437974 return;
7975 }
[email protected]32145a92012-12-17 09:01:597976 if (info->AsyncTransferIsInProgress()) {
7977 SetGLError(GL_INVALID_OPERATION,
7978 "glCopyTexSubImage2D", "async upload pending for texture");
7979 return;
7980 }
[email protected]9edc6b22010-12-23 02:00:267981
7982 // Check we have compatible formats.
7983 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7984 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7985 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
7986
[email protected]2d3765b2012-10-03 00:31:077987 if (!channels_needed ||
7988 (channels_needed & channels_exist) != channels_needed) {
[email protected]9edc6b22010-12-23 02:00:267989 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:437990 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:267991 return;
7992 }
7993
[email protected]81375742012-06-08 00:04:007994 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
7995 SetGLError(
7996 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437997 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:007998 return;
7999 }
8000
[email protected]a0b78dc2011-11-11 10:43:108001 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8002 return;
8003 }
8004
[email protected]de26b3c2011-08-03 21:54:278005 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038006 gfx::Size size = GetBoundReadFrameBufferSize();
8007 GLint copyX = 0;
8008 GLint copyY = 0;
8009 GLint copyWidth = 0;
8010 GLint copyHeight = 0;
8011 Clip(x, width, size.width(), &copyX, &copyWidth);
8012 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208013
8014 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
[email protected]ad84a3a2012-06-08 21:42:438015 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208016 return;
8017 }
8018
[email protected]6e288612010-12-21 20:45:038019 if (copyX != x ||
8020 copyY != y ||
8021 copyWidth != width ||
8022 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208023 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038024 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348025 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248026 width, height, format, type, state_.unpack_alignment, &pixels_size,
8027 NULL, NULL)) {
[email protected]ad84a3a2012-06-08 21:42:438028 SetGLError(
8029 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038030 return;
8031 }
8032 scoped_array<char> zero(new char[pixels_size]);
8033 memset(zero.get(), 0, pixels_size);
8034 glTexSubImage2D(
8035 target, level, xoffset, yoffset, width, height,
8036 format, type, zero.get());
8037 }
[email protected]0d6bfdc2011-11-02 01:32:208038
[email protected]6e288612010-12-21 20:45:038039 if (copyHeight > 0 && copyWidth > 0) {
8040 GLint dx = copyX - x;
8041 GLint dy = copyY - y;
8042 GLint destX = xoffset + dx;
8043 GLint destY = yoffset + dy;
8044 glCopyTexSubImage2D(target, level,
8045 destX, destY, copyX, copyY,
8046 copyWidth, copyHeight);
8047 }
[email protected]cadde4a2010-07-31 17:10:438048}
8049
[email protected]f598f422012-12-07 08:30:038050bool GLES2DecoderImpl::ValidateTexSubImage2D(
8051 error::Error* error,
8052 const char* function_name,
8053 GLenum target,
8054 GLint level,
8055 GLint xoffset,
8056 GLint yoffset,
8057 GLsizei width,
8058 GLsizei height,
8059 GLenum format,
8060 GLenum type,
8061 const void * data) {
8062 (*error) = error::kNoError;
8063 if (!validators_->texture_target.IsValid(target)) {
8064 SetGLErrorInvalidEnum(function_name, target, "target");
8065 return false;
8066 }
8067 if (width < 0) {
8068 SetGLError(GL_INVALID_VALUE, function_name, "width < 0");
8069 return false;
8070 }
8071 if (height < 0) {
8072 SetGLError(GL_INVALID_VALUE, function_name, "height < 0");
8073 return false;
8074 }
8075 if (!validators_->texture_format.IsValid(format)) {
8076 SetGLErrorInvalidEnum(function_name, format, "format");
8077 return false;
8078 }
8079 if (!validators_->pixel_type.IsValid(type)) {
8080 SetGLErrorInvalidEnum(function_name, type, "type");
8081 return false;
8082 }
[email protected]cadde4a2010-07-31 17:10:438083 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
8084 if (!info) {
8085 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038086 function_name, "unknown texture for target");
8087 return false;
[email protected]cadde4a2010-07-31 17:10:438088 }
[email protected]df6cf1ad2011-01-29 01:20:528089 GLenum current_type = 0;
8090 GLenum internal_format = 0;
8091 if (!info->GetLevelType(target, level, &current_type, &internal_format)) {
8092 SetGLError(
[email protected]f598f422012-12-07 08:30:038093 GL_INVALID_OPERATION, function_name, "level does not exist.");
8094 return false;
[email protected]df6cf1ad2011-01-29 01:20:528095 }
8096 if (format != internal_format) {
8097 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038098 function_name, "format does not match internal format.");
8099 return false;
[email protected]df6cf1ad2011-01-29 01:20:528100 }
8101 if (type != current_type) {
8102 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038103 function_name, "type does not match type of texture.");
8104 return false;
[email protected]df6cf1ad2011-01-29 01:20:528105 }
[email protected]32145a92012-12-17 09:01:598106 if (info->AsyncTransferIsInProgress()) {
8107 SetGLError(GL_INVALID_OPERATION,
8108 function_name, "async upload pending for texture");
8109 return false;
8110 }
[email protected]cadde4a2010-07-31 17:10:438111 if (!info->ValidForTexture(
8112 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]f598f422012-12-07 08:30:038113 SetGLError(GL_INVALID_VALUE, function_name, "bad dimensions.");
8114 return false;
[email protected]cadde4a2010-07-31 17:10:438115 }
[email protected]81375742012-06-08 00:04:008116 if ((GLES2Util::GetChannelsForFormat(format) &
8117 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
8118 SetGLError(
8119 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038120 function_name, "can not supply data for depth or stencil textures");
8121 return false;
[email protected]81375742012-06-08 00:04:008122 }
[email protected]f598f422012-12-07 08:30:038123 if (data == NULL) {
8124 (*error) = error::kOutOfBounds;
8125 return false;
8126 }
8127 return true;
8128}
[email protected]81375742012-06-08 00:04:008129
[email protected]f598f422012-12-07 08:30:038130error::Error GLES2DecoderImpl::DoTexSubImage2D(
8131 GLenum target,
8132 GLint level,
8133 GLint xoffset,
8134 GLint yoffset,
8135 GLsizei width,
8136 GLsizei height,
8137 GLenum format,
8138 GLenum type,
8139 const void * data) {
8140 error::Error error = error::kNoError;
8141 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8142 xoffset, yoffset, width, height, format, type, data)) {
8143 return error;
8144 }
8145 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]4502e6492011-12-14 19:39:158146 GLsizei tex_width = 0;
8147 GLsizei tex_height = 0;
8148 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height);
8149 DCHECK(ok);
8150 if (xoffset != 0 || yoffset != 0 ||
8151 width != tex_width || height != tex_height) {
8152 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
[email protected]ad84a3a2012-06-08 21:42:438153 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038154 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308155 }
[email protected]63b465922012-09-06 02:04:528156 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158157 glTexSubImage2D(
8158 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038159 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208160 }
[email protected]4502e6492011-12-14 19:39:158161
8162 if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) {
[email protected]63b465922012-09-06 02:04:528163 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158164 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8165 // same as internal_foramt. If that changes we'll need to look them up.
8166 WrappedTexImage2D(
8167 target, level, format, width, height, 0, format, type, data);
8168 } else {
[email protected]63b465922012-09-06 02:04:528169 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158170 glTexSubImage2D(
8171 target, level, xoffset, yoffset, width, height, format, type, data);
8172 }
[email protected]60f22d32012-12-12 00:31:588173 texture_manager()->SetLevelCleared(info, target, level, true);
[email protected]f598f422012-12-07 08:30:038174 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438175}
8176
[email protected]b493ee622011-04-13 23:52:008177error::Error GLES2DecoderImpl::HandleTexSubImage2D(
8178 uint32 immediate_data_size, const gles2::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388179 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008180 GLboolean internal = static_cast<GLboolean>(c.internal);
8181 if (internal == GL_TRUE && tex_image_2d_failed_)
8182 return error::kNoError;
8183
8184 GLenum target = static_cast<GLenum>(c.target);
8185 GLint level = static_cast<GLint>(c.level);
8186 GLint xoffset = static_cast<GLint>(c.xoffset);
8187 GLint yoffset = static_cast<GLint>(c.yoffset);
8188 GLsizei width = static_cast<GLsizei>(c.width);
8189 GLsizei height = static_cast<GLsizei>(c.height);
8190 GLenum format = static_cast<GLenum>(c.format);
8191 GLenum type = static_cast<GLenum>(c.type);
8192 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348193 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248194 width, height, format, type, state_.unpack_alignment, &data_size,
8195 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008196 return error::kOutOfBounds;
8197 }
8198 const void* pixels = GetSharedMemoryAs<const void*>(
8199 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038200 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008201 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008202}
8203
8204error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
8205 uint32 immediate_data_size, const gles2::TexSubImage2DImmediate& c) {
8206 GLboolean internal = static_cast<GLboolean>(c.internal);
8207 if (internal == GL_TRUE && tex_image_2d_failed_)
8208 return error::kNoError;
8209
8210 GLenum target = static_cast<GLenum>(c.target);
8211 GLint level = static_cast<GLint>(c.level);
8212 GLint xoffset = static_cast<GLint>(c.xoffset);
8213 GLint yoffset = static_cast<GLint>(c.yoffset);
8214 GLsizei width = static_cast<GLsizei>(c.width);
8215 GLsizei height = static_cast<GLsizei>(c.height);
8216 GLenum format = static_cast<GLenum>(c.format);
8217 GLenum type = static_cast<GLenum>(c.type);
8218 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348219 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248220 width, height, format, type, state_.unpack_alignment, &data_size,
8221 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008222 return error::kOutOfBounds;
8223 }
8224 const void* pixels = GetImmediateDataAs<const void*>(
8225 c, data_size, immediate_data_size);
[email protected]f598f422012-12-07 08:30:038226 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008227 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008228}
8229
[email protected]f7a64ee2010-02-01 22:24:148230error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]b9849abf2009-11-25 19:13:198231 uint32 immediate_data_size, const gles2::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368232 GLuint index = static_cast<GLuint>(c.index);
8233 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]0bfd9882010-02-05 23:02:258234 typedef gles2::GetVertexAttribPointerv::Result Result;
8235 Result* result = GetSharedMemoryAs<Result*>(
8236 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368237 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148238 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368239 }
[email protected]07d0cc82010-02-17 04:51:408240 // Check that the client initialized the result.
8241 if (result->size != 0) {
8242 return error::kInvalidArguments;
8243 }
[email protected]9438b012010-06-15 22:55:058244 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]f80e6e12012-08-31 00:43:538245 SetGLErrorInvalidEnum("glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148246 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368247 }
[email protected]3916c97e2010-02-25 03:20:508248 if (index >= group_->max_vertex_attribs()) {
[email protected]8eee29c2010-04-29 03:38:298249 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438250 "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148251 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368252 }
[email protected]0bfd9882010-02-05 23:02:258253 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088254 *result->GetData() =
[email protected]e259eb412012-10-13 05:47:248255 state_.vertex_attrib_manager->GetVertexAttribInfo(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148256 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328257}
8258
[email protected]f7b85372010-02-03 01:11:378259bool GLES2DecoderImpl::GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128260 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378261 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128262 error::Error* error, GLint* real_location,
8263 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108264 DCHECK(error);
8265 DCHECK(service_id);
8266 DCHECK(result_pointer);
8267 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128268 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378269 *error = error::kNoError;
8270 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258271 SizedResult<GLint>* result;
8272 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8273 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8274 if (!result) {
[email protected]f7b85372010-02-03 01:11:378275 *error = error::kOutOfBounds;
8276 return false;
8277 }
[email protected]0bfd9882010-02-05 23:02:258278 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378279 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258280 result->SetNumResults(0);
[email protected]6b8cf1a2010-05-06 16:13:588281 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8282 program, "glGetUniform");
[email protected]f7b85372010-02-03 01:11:378283 if (!info) {
[email protected]ae51d192010-04-27 00:48:038284 return false;
8285 }
8286 if (!info->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378287 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ad84a3a2012-06-08 21:42:438288 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378289 return false;
8290 }
[email protected]ae51d192010-04-27 00:48:038291 *service_id = info->service_id();
[email protected]43c2f1f2011-03-25 18:35:368292 GLint array_index = -1;
8293 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]1b0a6752012-02-22 03:44:128294 info->GetUniformInfoByFakeLocation(
8295 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368296 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378297 // No such location.
[email protected]ad84a3a2012-06-08 21:42:438298 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378299 return false;
8300 }
[email protected]43c2f1f2011-03-25 18:35:368301 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508302 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378303 if (size == 0) {
[email protected]ad84a3a2012-06-08 21:42:438304 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378305 return false;
8306 }
[email protected]0bfd9882010-02-05 23:02:258307 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8308 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8309 if (!result) {
[email protected]f7b85372010-02-03 01:11:378310 *error = error::kOutOfBounds;
8311 return false;
8312 }
[email protected]0bfd9882010-02-05 23:02:258313 result->size = size;
[email protected]939e7362010-05-13 20:49:108314 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378315 return true;
8316}
8317
[email protected]f7a64ee2010-02-01 22:24:148318error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]b9849abf2009-11-25 19:13:198319 uint32 immediate_data_size, const gles2::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378320 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338321 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378322 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108323 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128324 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378325 Error error;
[email protected]0bfd9882010-02-05 23:02:258326 void* result;
[email protected]f7b85372010-02-03 01:11:378327 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128328 program, fake_location, c.params_shm_id, c.params_shm_offset,
8329 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258330 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128331 service_id, real_location,
[email protected]0bfd9882010-02-05 23:02:258332 static_cast<gles2::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378333 }
8334 return error;
[email protected]96449d2c2009-11-25 00:01:328335}
8336
[email protected]f7a64ee2010-02-01 22:24:148337error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]b9849abf2009-11-25 19:13:198338 uint32 immediate_data_size, const gles2::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378339 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338340 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378341 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128342 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378343 Error error;
[email protected]0bfd9882010-02-05 23:02:258344 typedef gles2::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108345 Result* result;
8346 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378347 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128348 program, fake_location, c.params_shm_id, c.params_shm_offset,
8349 &error, &real_location, &service_id,
8350 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108351 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8352 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8353 GLsizei num_values = result->GetNumResults();
8354 scoped_array<GLint> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128355 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108356 GLfloat* dst = result->GetData();
8357 for (GLsizei ii = 0; ii < num_values; ++ii) {
8358 dst[ii] = (temp[ii] != 0);
8359 }
8360 } else {
[email protected]1b0a6752012-02-22 03:44:128361 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108362 }
[email protected]f7b85372010-02-03 01:11:378363 }
8364 return error;
[email protected]96449d2c2009-11-25 00:01:328365}
8366
[email protected]f7a64ee2010-02-01 22:24:148367error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]b9849abf2009-11-25 19:13:198368 uint32 immediate_data_size, const gles2::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258369 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8370 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
8371 typedef gles2::GetShaderPrecisionFormat::Result Result;
8372 Result* result = GetSharedMemoryAs<Result*>(
8373 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8374 if (!result) {
8375 return error::kOutOfBounds;
8376 }
[email protected]07d0cc82010-02-17 04:51:408377 // Check that the client initialized the result.
8378 if (result->success != 0) {
8379 return error::kInvalidArguments;
8380 }
[email protected]9438b012010-06-15 22:55:058381 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]f80e6e12012-08-31 00:43:538382 SetGLErrorInvalidEnum(
8383 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298384 return error::kNoError;
8385 }
[email protected]9438b012010-06-15 22:55:058386 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]f80e6e12012-08-31 00:43:538387 SetGLErrorInvalidEnum(
8388 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298389 return error::kNoError;
8390 }
8391
8392 result->success = 1; // true
8393 switch (precision_type) {
8394 case GL_LOW_INT:
8395 case GL_MEDIUM_INT:
8396 case GL_HIGH_INT:
[email protected]0a34b582012-04-09 22:42:568397 // These values are for a 32-bit twos-complement integer format.
8398 result->min_range = 31;
8399 result->max_range = 30;
[email protected]8eee29c2010-04-29 03:38:298400 result->precision = 0;
[email protected]4e8a5b122010-05-08 22:00:108401 break;
[email protected]8eee29c2010-04-29 03:38:298402 case GL_LOW_FLOAT:
8403 case GL_MEDIUM_FLOAT:
8404 case GL_HIGH_FLOAT:
[email protected]0a34b582012-04-09 22:42:568405 // These values are for an IEEE single-precision floating-point format.
8406 result->min_range = 127;
8407 result->max_range = 127;
8408 result->precision = 23;
[email protected]8eee29c2010-04-29 03:38:298409 break;
8410 default:
8411 NOTREACHED();
8412 break;
[email protected]0bfd9882010-02-05 23:02:258413 }
[email protected]f7a64ee2010-02-01 22:24:148414 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328415}
8416
[email protected]f7a64ee2010-02-01 22:24:148417error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]b9849abf2009-11-25 19:13:198418 uint32 immediate_data_size, const gles2::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258419 uint32 result_size = c.result_size;
[email protected]6b8cf1a2010-05-06 16:13:588420 GLuint program = static_cast<GLuint>(c.program);
8421 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8422 program, "glGetAttachedShaders");
[email protected]ae51d192010-04-27 00:48:038423 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258424 return error::kNoError;
8425 }
8426 typedef gles2::GetAttachedShaders::Result Result;
8427 uint32 max_count = Result::ComputeMaxResults(result_size);
8428 Result* result = GetSharedMemoryAs<Result*>(
8429 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8430 if (!result) {
8431 return error::kOutOfBounds;
8432 }
[email protected]07d0cc82010-02-17 04:51:408433 // Check that the client initialized the result.
8434 if (result->size != 0) {
8435 return error::kInvalidArguments;
8436 }
[email protected]0bfd9882010-02-05 23:02:258437 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038438 glGetAttachedShaders(
8439 info->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258440 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038441 if (!shader_manager()->GetClientId(result->GetData()[ii],
8442 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258443 NOTREACHED();
8444 return error::kGenericError;
8445 }
8446 }
8447 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148448 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328449}
8450
[email protected]f7a64ee2010-02-01 22:24:148451error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]b9849abf2009-11-25 19:13:198452 uint32 immediate_data_size, const gles2::GetActiveUniform& c) {
[email protected]0bfd9882010-02-05 23:02:258453 GLuint program = c.program;
8454 GLuint index = c.index;
8455 uint32 name_bucket_id = c.name_bucket_id;
[email protected]0bfd9882010-02-05 23:02:258456 typedef gles2::GetActiveUniform::Result Result;
8457 Result* result = GetSharedMemoryAs<Result*>(
8458 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8459 if (!result) {
8460 return error::kOutOfBounds;
8461 }
[email protected]07d0cc82010-02-17 04:51:408462 // Check that the client initialized the result.
8463 if (result->success != 0) {
8464 return error::kInvalidArguments;
8465 }
[email protected]6b8cf1a2010-05-06 16:13:588466 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8467 program, "glGetActiveUniform");
[email protected]ae51d192010-04-27 00:48:038468 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258469 return error::kNoError;
8470 }
8471 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
8472 info->GetUniformInfo(index);
8473 if (!uniform_info) {
[email protected]ad84a3a2012-06-08 21:42:438474 SetGLError(GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258475 return error::kNoError;
8476 }
8477 result->success = 1; // true.
8478 result->size = uniform_info->size;
8479 result->type = uniform_info->type;
8480 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298481 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148482 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328483}
8484
[email protected]f7a64ee2010-02-01 22:24:148485error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]b9849abf2009-11-25 19:13:198486 uint32 immediate_data_size, const gles2::GetActiveAttrib& c) {
[email protected]0bfd9882010-02-05 23:02:258487 GLuint program = c.program;
8488 GLuint index = c.index;
8489 uint32 name_bucket_id = c.name_bucket_id;
[email protected]0bfd9882010-02-05 23:02:258490 typedef gles2::GetActiveAttrib::Result Result;
8491 Result* result = GetSharedMemoryAs<Result*>(
8492 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8493 if (!result) {
8494 return error::kOutOfBounds;
8495 }
[email protected]07d0cc82010-02-17 04:51:408496 // Check that the client initialized the result.
8497 if (result->success != 0) {
8498 return error::kInvalidArguments;
8499 }
[email protected]6b8cf1a2010-05-06 16:13:588500 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8501 program, "glGetActiveAttrib");
[email protected]ae51d192010-04-27 00:48:038502 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258503 return error::kNoError;
8504 }
8505 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
8506 info->GetAttribInfo(index);
8507 if (!attrib_info) {
[email protected]ad84a3a2012-06-08 21:42:438508 SetGLError(GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258509 return error::kNoError;
8510 }
8511 result->success = 1; // true.
8512 result->size = attrib_info->size;
8513 result->type = attrib_info->type;
8514 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298515 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148516 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328517}
8518
[email protected]b273e432010-04-12 17:23:588519error::Error GLES2DecoderImpl::HandleShaderBinary(
8520 uint32 immediate_data_size, const gles2::ShaderBinary& c) {
8521#if 1 // No binary shader support.
[email protected]ad84a3a2012-06-08 21:42:438522 SetGLError(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588523 return error::kNoError;
8524#else
8525 GLsizei n = static_cast<GLsizei>(c.n);
8526 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:438527 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588528 return error::kNoError;
8529 }
8530 GLsizei length = static_cast<GLsizei>(c.length);
8531 if (length < 0) {
[email protected]ad84a3a2012-06-08 21:42:438532 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588533 return error::kNoError;
8534 }
8535 uint32 data_size;
8536 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8537 return error::kOutOfBounds;
8538 }
8539 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8540 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8541 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8542 const void* binary = GetSharedMemoryAs<const void*>(
8543 c.binary_shm_id, c.binary_shm_offset, length);
8544 if (shaders == NULL || binary == NULL) {
8545 return error::kOutOfBounds;
8546 }
8547 scoped_array<GLuint> service_ids(new GLuint[n]);
8548 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ae51d192010-04-27 00:48:038549 ShaderManager::ShaderInfo* info = GetShaderInfo(shaders[ii]);
8550 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:438551 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588552 return error::kNoError;
8553 }
[email protected]ae51d192010-04-27 00:48:038554 service_ids[ii] = info->service_id();
[email protected]b273e432010-04-12 17:23:588555 }
8556 // TODO(gman): call glShaderBinary
8557 return error::kNoError;
8558#endif
8559}
8560
[email protected]6217d392010-03-25 22:08:358561error::Error GLES2DecoderImpl::HandleSwapBuffers(
8562 uint32 immediate_data_size, const gles2::SwapBuffers& c) {
[email protected]64ace852011-05-19 21:49:498563 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088564 if (!is_offscreen && surface_->DeferSwapBuffers()) {
8565 return error::kDeferCommandUntilLater;
8566 }
8567
[email protected]64ace852011-05-19 21:49:498568 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428569 // TRACE_EVENT for gpu tests:
8570 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
8571 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8572 "width", (is_offscreen ? offscreen_size_.width() :
8573 surface_->GetSize().width()));
[email protected]64ace852011-05-19 21:49:498574 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleSwapBuffers",
8575 "offscreen", is_offscreen,
8576 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358577 // If offscreen then don't actually SwapBuffers to the display. Just copy
8578 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498579 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318580 TRACE_EVENT2("gpu", "Offscreen",
8581 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538582 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8583 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8584 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8585 // fix this.
[email protected]62e155e2012-10-23 22:43:158586 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538587 offscreen_saved_frame_buffer_->Create();
8588 glFinish();
8589 }
8590
8591 // Allocate the offscreen saved color texture.
8592 DCHECK(offscreen_saved_color_format_);
8593 offscreen_saved_color_texture_->AllocateStorage(
8594 offscreen_size_, offscreen_saved_color_format_);
8595
8596 offscreen_saved_frame_buffer_->AttachRenderTexture(
8597 offscreen_saved_color_texture_.get());
8598 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8599 GL_FRAMEBUFFER_COMPLETE) {
8600 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8601 << "because offscreen saved FBO was incomplete.";
8602 return error::kLostContext;
8603 }
8604
[email protected]1fb8c482011-08-31 01:01:538605 // Clear the offscreen color texture.
8606 // TODO(piman): Is this still necessary?
8607 {
8608 ScopedFrameBufferBinder binder(this,
8609 offscreen_saved_frame_buffer_->id());
8610 glClearColor(0, 0, 0, 0);
8611 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8612 glDisable(GL_SCISSOR_TEST);
8613 glClear(GL_COLOR_BUFFER_BIT);
8614 RestoreClearState();
8615 }
8616
8617 UpdateParentTextureInfo();
8618 }
8619
[email protected]6217d392010-03-25 22:08:358620 ScopedGLErrorSuppressor suppressor(this);
8621
[email protected]34ff8b0c2010-10-01 20:06:028622 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138623 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278624 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]89d6ed02011-04-20 00:23:238625 return error::kNoError;
[email protected]b86b14982010-10-11 18:45:488626 } else {
[email protected]069944672012-04-25 20:52:238627 ScopedFrameBufferBinder binder(this,
8628 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138629
[email protected]069944672012-04-25 20:52:238630 if (offscreen_target_buffer_preserved_) {
8631 // Copy the target frame buffer to the saved offscreen texture.
8632 offscreen_saved_color_texture_->Copy(
8633 offscreen_saved_color_texture_->size(),
8634 offscreen_saved_color_format_);
8635 } else {
8636 // Flip the textures in the parent context via the texture manager.
8637 if (!!offscreen_saved_color_texture_info_.get())
8638 offscreen_saved_color_texture_info_->
8639 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568640
[email protected]069944672012-04-25 20:52:238641 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8642 offscreen_target_frame_buffer_->AttachRenderTexture(
8643 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488644 }
[email protected]069944672012-04-25 20:52:238645
8646 // Ensure the side effects of the copy are visible to the parent
8647 // context. There is no need to do this for ANGLE because it uses a
8648 // single D3D device for all contexts.
8649 if (!IsAngle())
8650 glFlush();
[email protected]89d6ed02011-04-20 00:23:238651 return error::kNoError;
[email protected]0c8c9d22010-06-25 17:36:398652 }
[email protected]6217d392010-03-25 22:08:358653 } else {
[email protected]111975c62012-09-06 01:37:318654 TRACE_EVENT2("gpu", "Onscreen",
8655 "width", surface_->GetSize().width(),
8656 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158657 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018658 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]5259ead82010-09-10 18:02:028659 return error::kLostContext;
[email protected]d0498742010-09-20 20:27:018660 }
[email protected]6217d392010-03-25 22:08:358661 }
8662
[email protected]89d6ed02011-04-20 00:23:238663 return error::kNoError;
[email protected]6217d392010-03-25 22:08:358664}
8665
[email protected]d4239852011-08-12 04:51:228666error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
8667 uint32 immediate_data_size, const gles2::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188668 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288669 if (!bucket || bucket->size() == 0) {
8670 return error::kInvalidArguments;
8671 }
[email protected]d4239852011-08-12 04:51:228672 typedef gles2::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188673 Result* result = GetSharedMemoryAs<Result*>(
8674 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8675 if (!result) {
8676 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108677 }
[email protected]b1d2dcb2010-05-17 19:24:188678 // Check that the client initialized the result.
8679 if (*result != 0) {
8680 return error::kInvalidArguments;
8681 }
8682 std::string feature_str;
8683 if (!bucket->GetAsString(&feature_str)) {
8684 return error::kInvalidArguments;
8685 }
8686
8687 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228688 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188689 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228690 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408691 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8692 // TODO(gman): decide how to remove the need for this const_cast.
8693 // I could make validators_ non const but that seems bad as this is the only
8694 // place it is needed. I could make some special friend class of validators
8695 // just to allow this to set them. That seems silly. I could refactor this
8696 // code to use the extension mechanism or the initialization attributes to
8697 // turn this feature on. Given that the only real point of this is to make
8698 // the conformance tests pass and given that there is lots of real work that
8699 // needs to be done it seems like refactoring for one to one of those
8700 // methods is a very low priority.
8701 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048702 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8703 force_webgl_glsl_validation_ = true;
8704 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188705 } else {
8706 return error::kNoError;
8707 }
8708
8709 *result = 1; // true.
8710 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108711}
8712
[email protected]c2f8c8402010-12-06 18:07:248713error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8714 uint32 immediate_data_size,
8715 const gles2::GetRequestableExtensionsCHROMIUM& c) {
8716 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]80eb6b52012-01-19 00:14:418717 FeatureInfo::Ref info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:298718 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:248719 bucket->SetFromString(info->extensions().c_str());
8720 return error::kNoError;
8721}
8722
8723error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
8724 uint32 immediate_data_size, const gles2::RequestExtensionCHROMIUM& c) {
8725 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288726 if (!bucket || bucket->size() == 0) {
8727 return error::kInvalidArguments;
8728 }
[email protected]c2f8c8402010-12-06 18:07:248729 std::string feature_str;
8730 if (!bucket->GetAsString(&feature_str)) {
8731 return error::kInvalidArguments;
8732 }
8733
[email protected]62e155e2012-10-23 22:43:158734 bool std_derivatives_enabled = features().oes_standard_derivatives;
8735 bool webglsl_enabled = features().chromium_webglsl;
[email protected]c2f8c8402010-12-06 18:07:248736
8737 feature_info_->AddFeatures(feature_str.c_str());
8738
[email protected]f0d74742011-10-03 16:31:048739 bool initialization_required = false;
8740 if (force_webgl_glsl_validation_ && !derivatives_explicitly_enabled_) {
8741 size_t derivatives_offset = feature_str.find(kOESDerivativeExtension);
8742 if (std::string::npos != derivatives_offset) {
8743 derivatives_explicitly_enabled_ = true;
8744 initialization_required = true;
8745 }
8746 }
8747
[email protected]c2f8c8402010-12-06 18:07:248748 // If we just enabled a feature which affects the shader translator,
8749 // we may need to re-initialize it.
[email protected]62e155e2012-10-23 22:43:158750 if (std_derivatives_enabled != features().oes_standard_derivatives ||
8751 webglsl_enabled != features().chromium_webglsl ||
[email protected]f0d74742011-10-03 16:31:048752 initialization_required) {
[email protected]c2f8c8402010-12-06 18:07:248753 InitializeShaderTranslator();
8754 }
8755
[email protected]302ce6d2011-07-07 23:28:118756 UpdateCapabilities();
8757
[email protected]c2f8c8402010-12-06 18:07:248758 return error::kNoError;
8759}
8760
[email protected]372e0412011-06-28 16:08:568761error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
8762 uint32 immediate_data_size, const gles2::GetMultipleIntegervCHROMIUM& c) {
8763 GLuint count = c.count;
8764 uint32 pnames_size;
8765 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8766 return error::kOutOfBounds;
8767 }
8768 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8769 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8770 if (pnames == NULL) {
8771 return error::kOutOfBounds;
8772 }
8773
8774 // We have to copy them since we use them twice so the client
8775 // can't change them between the time we validate them and the time we use
8776 // them.
8777 scoped_array<GLenum> enums(new GLenum[count]);
8778 memcpy(enums.get(), pnames, pnames_size);
8779
8780 // Count up the space needed for the result.
8781 uint32 num_results = 0;
8782 for (GLuint ii = 0; ii < count; ++ii) {
8783 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8784 if (num == 0) {
[email protected]f80e6e12012-08-31 00:43:538785 SetGLErrorInvalidEnum("glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568786 return error::kNoError;
8787 }
8788 // Num will never be more than 4.
8789 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478790 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568791 return error::kOutOfBounds;
8792 }
8793 }
8794
8795 uint32 result_size = 0;
8796 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8797 return error::kOutOfBounds;
8798 }
8799
8800 if (result_size != static_cast<uint32>(c.size)) {
8801 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438802 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:568803 return error::kNoError;
8804 }
8805
8806 GLint* results = GetSharedMemoryAs<GLint*>(
8807 c.results_shm_id, c.results_shm_offset, result_size);
8808 if (results == NULL) {
8809 return error::kOutOfBounds;
8810 }
8811
8812 // Check the results have been cleared in case the context was lost.
8813 for (uint32 ii = 0; ii < num_results; ++ii) {
8814 if (results[ii]) {
8815 return error::kInvalidArguments;
8816 }
8817 }
8818
8819 // Get each result.
8820 GLint* start = results;
8821 for (GLuint ii = 0; ii < count; ++ii) {
8822 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:268823 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:538824 !GetHelper(enums[ii], results, &num_written)) {
[email protected]372e0412011-06-28 16:08:568825 glGetIntegerv(enums[ii], results);
8826 }
8827 results += num_written;
8828 }
8829
8830 // Just to verify. Should this be a DCHECK?
8831 if (static_cast<uint32>(results - start) != num_results) {
8832 return error::kOutOfBounds;
8833 }
8834
8835 return error::kNoError;
8836}
8837
[email protected]2318d342011-07-11 22:27:428838error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
8839 uint32 immediate_data_size, const gles2::GetProgramInfoCHROMIUM& c) {
8840 GLuint program = static_cast<GLuint>(c.program);
8841 uint32 bucket_id = c.bucket_id;
8842 Bucket* bucket = CreateBucket(bucket_id);
8843 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
8844 ProgramManager::ProgramInfo* info = NULL;
[email protected]9a14ae612011-08-08 17:51:468845 info = GetProgramInfo(program);
8846 if (!info || !info->IsValid()) {
8847 return error::kNoError;
[email protected]2318d342011-07-11 22:27:428848 }
[email protected]5d4c6b22012-02-07 08:22:288849 info->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:428850 return error::kNoError;
8851}
8852
[email protected]38d139d2011-07-14 00:38:438853error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
8854 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:438855 case GL_NO_ERROR:
8856 // TODO(kbr): improve the precision of the error code in this case.
8857 // Consider delegating to context for error code if MakeCurrent fails.
8858 return error::kUnknown;
8859 case GL_GUILTY_CONTEXT_RESET_ARB:
8860 return error::kGuilty;
8861 case GL_INNOCENT_CONTEXT_RESET_ARB:
8862 return error::kInnocent;
8863 case GL_UNKNOWN_CONTEXT_RESET_ARB:
8864 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:438865 }
8866
8867 NOTREACHED();
8868 return error::kUnknown;
8869}
8870
8871bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:098872 if (reset_status_ != GL_NO_ERROR) {
8873 return true;
8874 }
[email protected]706b69f2012-07-27 04:59:308875 if (context_->WasAllocatedUsingRobustnessExtension()) {
8876 GLenum status = GL_NO_ERROR;
8877 if (has_robustness_extension_)
8878 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:438879 if (status != GL_NO_ERROR) {
8880 // The graphics card was reset. Signal a lost context to the application.
8881 reset_status_ = status;
8882 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:098883 << " context lost via ARB/EXT_robustness. Reset status = "
8884 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:438885 return true;
8886 }
8887 }
8888 return false;
8889}
8890
[email protected]c4485aad62012-12-17 10:19:098891void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
8892 // Only loses the context once.
8893 if (reset_status_ != GL_NO_ERROR) {
8894 return;
8895 }
8896
8897 // Marks this context as lost.
8898 reset_status_ = reset_status;
8899 current_decoder_error_ = error::kLostContext;
8900
8901 // Loses the parent's context.
8902 if (parent_) {
8903 parent_->LoseContext(reset_status);
8904 }
8905
8906 // Loses any child contexts.
8907 for (ChildList::iterator it = children_.begin();
8908 it != children_.end();
8909 ++it) {
8910 (*it)->LoseContext(reset_status);
8911 }
8912}
8913
8914error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
8915 uint32 immediate_data_size, const gles2::LoseContextCHROMIUM& c) {
8916 GLenum current = static_cast<GLenum>(c.current);
8917 GLenum other = static_cast<GLenum>(c.other);
8918 if (!validators_->reset_status.IsValid(current)) {
8919 SetGLErrorInvalidEnum("glLoseContextCHROMIUM", current, "current");
8920 }
8921 if (!validators_->reset_status.IsValid(other)) {
8922 SetGLErrorInvalidEnum("glLoseContextCHROMIUM", other, "other");
8923 }
8924 group_->LoseContexts(other);
8925 reset_status_ = current;
8926 current_decoder_error_ = error::kLostContext;
8927 return error::kLostContext;
8928}
8929
[email protected]882ba1e22012-03-08 19:02:538930bool GLES2DecoderImpl::GenQueriesEXTHelper(
8931 GLsizei n, const GLuint* client_ids) {
8932 for (GLsizei ii = 0; ii < n; ++ii) {
8933 if (query_manager_->GetQuery(client_ids[ii])) {
8934 return false;
8935 }
8936 }
[email protected]c45f1972012-03-14 07:27:368937 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:538938 return true;
8939}
8940
8941void GLES2DecoderImpl::DeleteQueriesEXTHelper(
8942 GLsizei n, const GLuint* client_ids) {
8943 for (GLsizei ii = 0; ii < n; ++ii) {
8944 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
8945 if (query && !query->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:248946 if (query == state_.current_query) {
8947 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:538948 }
[email protected]c45f1972012-03-14 07:27:368949 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:538950 query_manager_->RemoveQuery(client_ids[ii]);
8951 }
8952 }
8953}
8954
[email protected]22e3f552012-03-13 01:54:198955bool GLES2DecoderImpl::ProcessPendingQueries() {
8956 if (query_manager_.get() == NULL) {
8957 return false;
8958 }
[email protected]c45f1972012-03-14 07:27:368959 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:198960 current_decoder_error_ = error::kOutOfBounds;
8961 }
8962 return query_manager_->HavePendingQueries();
8963}
8964
[email protected]882ba1e22012-03-08 19:02:538965error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
8966 uint32 immediate_data_size, const gles2::BeginQueryEXT& c) {
8967 GLenum target = static_cast<GLenum>(c.target);
8968 GLuint client_id = static_cast<GLuint>(c.id);
8969 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
8970 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
8971
[email protected]c45f1972012-03-14 07:27:368972 switch (target) {
8973 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:558974 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]0713f43d2012-12-14 22:41:308975 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:368976 break;
8977 default:
[email protected]62e155e2012-10-23 22:43:158978 if (!features().occlusion_query_boolean) {
[email protected]ad84a3a2012-06-08 21:42:438979 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "not enabled");
[email protected]c45f1972012-03-14 07:27:368980 return error::kNoError;
8981 }
8982 break;
[email protected]882ba1e22012-03-08 19:02:538983 }
8984
[email protected]e259eb412012-10-13 05:47:248985 if (state_.current_query) {
[email protected]882ba1e22012-03-08 19:02:538986 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:438987 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:538988 return error::kNoError;
8989 }
8990
8991 if (client_id == 0) {
[email protected]ad84a3a2012-06-08 21:42:438992 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:538993 return error::kNoError;
8994 }
8995
8996 QueryManager::Query* query = query_manager_->GetQuery(client_id);
8997 if (!query) {
[email protected]c45f1972012-03-14 07:27:368998 // TODO(gman): Decide if we need this check.
8999 //
[email protected]882ba1e22012-03-08 19:02:539000 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369001 //
9002 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9003 // for all Query ids but from the POV of the command buffer service maybe
9004 // you don't.
9005 //
9006 // The client can enforce this. I don't think the service cares.
9007 //
9008 // IdAllocatorInterface* id_allocator =
9009 // group_->GetIdAllocator(id_namespaces::kQueries);
9010 // if (!id_allocator->InUse(client_id)) {
9011 // SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439012 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369013 // return error::kNoError;
9014 // }
9015 query = query_manager_->CreateQuery(
9016 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539017 }
9018
[email protected]c45f1972012-03-14 07:27:369019 if (query->target() != target) {
[email protected]ad84a3a2012-06-08 21:42:439020 SetGLError(
9021 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539022 return error::kNoError;
9023 } else if (query->shm_id() != sync_shm_id ||
9024 query->shm_offset() != sync_shm_offset) {
9025 DLOG(ERROR) << "Shared memory used by query not the same as before";
9026 return error::kInvalidArguments;
9027 }
9028
[email protected]c45f1972012-03-14 07:27:369029 if (!query_manager_->BeginQuery(query)) {
9030 return error::kOutOfBounds;
9031 }
[email protected]882ba1e22012-03-08 19:02:539032
[email protected]e259eb412012-10-13 05:47:249033 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539034 return error::kNoError;
9035}
9036
9037error::Error GLES2DecoderImpl::HandleEndQueryEXT(
9038 uint32 immediate_data_size, const gles2::EndQueryEXT& c) {
9039 GLenum target = static_cast<GLenum>(c.target);
9040 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9041
[email protected]e259eb412012-10-13 05:47:249042 if (!state_.current_query) {
[email protected]ad84a3a2012-06-08 21:42:439043 SetGLError(GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539044 return error::kNoError;
9045 }
[email protected]e259eb412012-10-13 05:47:249046 if (state_.current_query->target() != target) {
[email protected]882ba1e22012-03-08 19:02:539047 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439048 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539049 return error::kNoError;
9050 }
[email protected]882ba1e22012-03-08 19:02:539051
[email protected]e259eb412012-10-13 05:47:249052 if (!query_manager_->EndQuery(state_.current_query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369053 return error::kOutOfBounds;
9054 }
9055
[email protected]e259eb412012-10-13 05:47:249056 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539057 return error::kNoError;
9058}
9059
[email protected]944b62f32012-09-27 02:20:469060bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9061 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469062 for (GLsizei ii = 0; ii < n; ++ii) {
9063 if (GetVertexAttribManager(client_ids[ii])) {
9064 return false;
9065 }
9066 }
[email protected]ab4fd7282012-10-12 16:25:579067
[email protected]62e155e2012-10-23 22:43:159068 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579069 // Emulated VAO
9070 for (GLsizei ii = 0; ii < n; ++ii) {
9071 CreateVertexAttribManager(client_ids[ii], 0);
9072 }
9073 } else {
9074 scoped_array<GLuint> service_ids(new GLuint[n]);
9075
9076 glGenVertexArraysOES(n, service_ids.get());
9077 for (GLsizei ii = 0; ii < n; ++ii) {
9078 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9079 }
[email protected]944b62f32012-09-27 02:20:469080 }
[email protected]ab4fd7282012-10-12 16:25:579081
[email protected]944b62f32012-09-27 02:20:469082 return true;
9083}
9084
9085void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9086 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469087 for (GLsizei ii = 0; ii < n; ++ii) {
9088 VertexAttribManager* vao =
9089 GetVertexAttribManager(client_ids[ii]);
9090 if (vao && !vao->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249091 if (state_.vertex_attrib_manager == vao) {
9092 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469093 }
9094 RemoveVertexAttribManager(client_ids[ii]);
9095 }
9096 }
9097}
9098
9099void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469100 VertexAttribManager* vao = NULL;
9101 GLuint service_id = 0;
9102 if (client_id != 0) {
9103 vao = GetVertexAttribManager(client_id);
9104 if (!vao) {
9105 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9106 // only allows names that have been previously generated. As such, we do
9107 // not generate new names here.
9108 SetGLError(GL_INVALID_OPERATION,
9109 "glBindVertexArrayOES", ""
9110 "bad vertex array id.");
9111 current_decoder_error_ = error::kNoError;
9112 return;
9113 } else {
9114 service_id = vao->service_id();
9115 }
[email protected]944b62f32012-09-27 02:20:469116 } else {
[email protected]ab4fd7282012-10-12 16:25:579117 vao = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469118 }
9119
[email protected]ab4fd7282012-10-12 16:25:579120 // Only set the VAO state if it's changed
[email protected]e259eb412012-10-13 05:47:249121 if (state_.vertex_attrib_manager != vao) {
9122 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159123 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579124 EmulateVertexArrayState();
9125 } else {
9126 glBindVertexArrayOES(service_id);
9127 }
9128 }
9129}
9130
9131// Used when OES_vertex_array_object isn't natively supported
9132void GLES2DecoderImpl::EmulateVertexArrayState() {
9133 // Setup the Vertex attribute state
9134 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9135 RestoreStateForAttrib(vv);
9136 }
9137
9138 // Setup the element buffer
9139 BufferManager::BufferInfo* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249140 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579141 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9142 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469143}
9144
9145bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469146 const VertexAttribManager* vao =
9147 GetVertexAttribManager(client_id);
9148 return vao && vao->IsValid() && !vao->IsDeleted();
9149}
9150
[email protected]b0af4f52011-09-28 22:04:429151error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9152 uint32 immediate_data_size,
9153 const gles2::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159154 if (!features().chromium_stream_texture) {
[email protected]b0af4f52011-09-28 22:04:429155 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439156 "glOpenStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429157 "not supported.");
9158 return error::kNoError;
9159 }
9160
9161 uint32 client_id = c.client_id;
9162 typedef gles2::CreateStreamTextureCHROMIUM::Result Result;
9163 Result* result = GetSharedMemoryAs<Result*>(
9164 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9165
[email protected]e5081262012-01-05 23:09:039166 if (!result)
9167 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429168 *result = GL_ZERO;
9169 TextureManager::TextureInfo* info =
9170 texture_manager()->GetTextureInfo(client_id);
9171 if (!info) {
9172 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439173 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429174 "bad texture id.");
9175 return error::kNoError;
9176 }
9177
9178 if (info->IsStreamTexture()) {
9179 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439180 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429181 "is already a stream texture.");
9182 return error::kNoError;
9183 }
9184
9185 if (info->target() && info->target() != GL_TEXTURE_EXTERNAL_OES) {
9186 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439187 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429188 "is already bound to incompatible target.");
9189 return error::kNoError;
9190 }
9191
9192 if (!stream_texture_manager_)
9193 return error::kInvalidArguments;
9194
9195 GLuint object_id = stream_texture_manager_->CreateStreamTexture(
9196 info->service_id(), client_id);
9197
9198 if (object_id) {
9199 info->SetStreamTexture(true);
9200 } else {
9201 SetGLError(GL_OUT_OF_MEMORY,
[email protected]ad84a3a2012-06-08 21:42:439202 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429203 "failed to create platform texture.");
9204 }
9205
9206 *result = object_id;
9207 return error::kNoError;
9208}
9209
9210error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9211 uint32 immediate_data_size,
9212 const gles2::DestroyStreamTextureCHROMIUM& c) {
9213 GLuint client_id = c.texture;
9214 TextureManager::TextureInfo* info =
9215 texture_manager()->GetTextureInfo(client_id);
9216 if (info && info->IsStreamTexture()) {
9217 if (!stream_texture_manager_)
9218 return error::kInvalidArguments;
9219
9220 stream_texture_manager_->DestroyStreamTexture(info->service_id());
9221 info->SetStreamTexture(false);
[email protected]b0af4f52011-09-28 22:04:429222 } else {
9223 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439224 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429225 }
9226
9227 return error::kNoError;
9228}
9229
[email protected]e51bdf32011-11-23 22:21:469230#if defined(OS_MACOSX)
9231void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9232 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9233 texture_id);
9234 if (it != texture_to_io_surface_map_.end()) {
9235 // Found a previous IOSurface bound to this texture; release it.
9236 CFTypeRef surface = it->second;
9237 CFRelease(surface);
9238 texture_to_io_surface_map_.erase(it);
9239 }
9240}
9241#endif
9242
9243void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9244 GLenum target, GLsizei width, GLsizei height,
9245 GLuint io_surface_id, GLuint plane) {
9246#if defined(OS_MACOSX)
9247 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ad84a3a2012-06-08 21:42:439248 SetGLError(
9249 GL_INVALID_OPERATION,
9250 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469251 return;
9252 }
9253
9254 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9255 if (!surface_support) {
9256 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439257 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469258 return;
9259 }
9260
9261 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9262 // This might be supported in the future, and if we could require
9263 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9264 // could delete a lot of code. For now, perform strict validation so we
9265 // know what's going on.
9266 SetGLError(
9267 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439268 "glTexImageIOSurface2DCHROMIUM",
9269 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469270 return;
9271 }
9272
[email protected]09d50362012-10-18 20:54:379273 // Default target might be conceptually valid, but disallow it to avoid
9274 // accidents.
9275 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9276 target);
[email protected]e51bdf32011-11-23 22:21:469277 if (!info) {
9278 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439279 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469280 return;
9281 }
[email protected]e51bdf32011-11-23 22:21:469282
9283 // Look up the new IOSurface. Note that because of asynchrony
9284 // between processes this might fail; during live resizing the
9285 // plugin process might allocate and release an IOSurface before
9286 // this process gets a chance to look it up. Hold on to any old
9287 // IOSurface in this case.
9288 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9289 if (!surface) {
[email protected]ad84a3a2012-06-08 21:42:439290 SetGLError(
9291 GL_INVALID_OPERATION,
9292 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469293 return;
9294 }
9295
9296 // Release any IOSurface previously bound to this texture.
9297 ReleaseIOSurfaceForTexture(info->service_id());
9298
9299 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9300 texture_to_io_surface_map_.insert(
9301 std::make_pair(info->service_id(), surface));
9302
9303 CGLContextObj context =
9304 static_cast<CGLContextObj>(context_->GetHandle());
9305
9306 CGLError err = surface_support->CGLTexImageIOSurface2D(
9307 context,
9308 target,
9309 GL_RGBA,
9310 width,
9311 height,
9312 GL_BGRA,
9313 GL_UNSIGNED_INT_8_8_8_8_REV,
9314 surface,
9315 plane);
9316
9317 if (err != kCGLNoError) {
9318 SetGLError(
9319 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439320 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469321 return;
9322 }
9323
9324 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:419325 info, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469326 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9327
9328#else
9329 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439330 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469331#endif
9332}
9333
[email protected]97dc7cbe2011-12-06 17:26:179334static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9335 switch (internalformat) {
9336 case GL_RGB565:
9337 return GL_RGB;
9338 case GL_RGBA4:
9339 return GL_RGBA;
9340 case GL_RGB5_A1:
9341 return GL_RGBA;
9342 case GL_RGB8_OES:
9343 return GL_RGB;
9344 case GL_RGBA8_OES:
9345 return GL_RGBA;
9346 case GL_LUMINANCE8_ALPHA8_EXT:
9347 return GL_LUMINANCE_ALPHA;
9348 case GL_LUMINANCE8_EXT:
9349 return GL_LUMINANCE;
9350 case GL_ALPHA8_EXT:
9351 return GL_ALPHA;
9352 case GL_RGBA32F_EXT:
9353 return GL_RGBA;
9354 case GL_RGB32F_EXT:
9355 return GL_RGB;
9356 case GL_ALPHA32F_EXT:
9357 return GL_ALPHA;
9358 case GL_LUMINANCE32F_EXT:
9359 return GL_LUMINANCE;
9360 case GL_LUMINANCE_ALPHA32F_EXT:
9361 return GL_LUMINANCE_ALPHA;
9362 case GL_RGBA16F_EXT:
9363 return GL_RGBA;
9364 case GL_RGB16F_EXT:
9365 return GL_RGB;
9366 case GL_ALPHA16F_EXT:
9367 return GL_ALPHA;
9368 case GL_LUMINANCE16F_EXT:
9369 return GL_LUMINANCE;
9370 case GL_LUMINANCE_ALPHA16F_EXT:
9371 return GL_LUMINANCE_ALPHA;
9372 case GL_BGRA8_EXT:
9373 return GL_BGRA_EXT;
9374 default:
9375 return GL_NONE;
9376 }
9377}
9378
[email protected]43410e92012-04-20 17:06:289379void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039380 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
9381 GLenum internal_format) {
[email protected]43410e92012-04-20 17:06:289382 TextureManager::TextureInfo* dest_info = GetTextureInfo(dest_id);
9383 TextureManager::TextureInfo* source_info = GetTextureInfo(source_id);
9384
9385 if (!source_info || !dest_info) {
[email protected]ad84a3a2012-06-08 21:42:439386 SetGLError(GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289387 return;
9388 }
9389
9390 if (GL_TEXTURE_2D != target) {
9391 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439392 "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289393 return;
9394 }
9395
[email protected]0a1e9ad2012-05-04 21:13:039396 if (dest_info->target() != GL_TEXTURE_2D ||
9397 source_info->target() != GL_TEXTURE_2D) {
9398 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439399 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039400 return;
9401 }
9402
[email protected]43410e92012-04-20 17:06:289403 int source_width, source_height, dest_width, dest_height;
9404 if (!source_info->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
9405 &source_height)) {
9406 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439407 "glCopyTextureChromium", "source texture has no level 0");
[email protected]43410e92012-04-20 17:06:289408 return;
9409 }
9410
[email protected]43410e92012-04-20 17:06:289411 // Check that this type of texture is allowed.
9412 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
9413 source_height, 1)) {
9414 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439415 "glCopyTextureCHROMIUM", "Bad dimensions");
[email protected]43410e92012-04-20 17:06:289416 return;
9417 }
9418
[email protected]cf6b8f62012-05-25 21:43:379419 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9420 // needed because it takes 10s of milliseconds to initialize.
9421 if (!copy_texture_CHROMIUM_.get()) {
9422 CopyRealGLErrorsToWrapper();
9423 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
9424 copy_texture_CHROMIUM_->Initialize();
9425 RestoreCurrentFramebufferBindings();
9426 if (PeekGLError() != GL_NO_ERROR)
9427 return;
9428 }
9429
[email protected]0a1e9ad2012-05-04 21:13:039430 GLenum dest_type;
9431 GLenum dest_internal_format;
9432 bool dest_level_defined = dest_info->GetLevelSize(GL_TEXTURE_2D, level,
9433 &dest_width,
9434 &dest_height);
[email protected]43410e92012-04-20 17:06:289435
[email protected]0a1e9ad2012-05-04 21:13:039436 if (dest_level_defined) {
9437 dest_info->GetLevelType(GL_TEXTURE_2D, level, &dest_type,
9438 &dest_internal_format);
9439 } else {
9440 GLenum source_internal_format;
9441 source_info->GetLevelType(GL_TEXTURE_2D, 0, &dest_type,
9442 &source_internal_format);
9443 }
9444
9445 // Resize the destination texture to the dimensions of the source texture.
9446 if (!dest_level_defined || dest_width != source_width ||
9447 dest_height != source_height ||
9448 dest_internal_format != internal_format) {
[email protected]43410e92012-04-20 17:06:289449 // Ensure that the glTexImage2D succeeds.
9450 CopyRealGLErrorsToWrapper();
[email protected]0a1e9ad2012-05-04 21:13:039451 glBindTexture(GL_TEXTURE_2D, dest_info->service_id());
[email protected]43410e92012-04-20 17:06:289452 WrappedTexImage2D(
9453 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039454 0, internal_format, dest_type, NULL);
[email protected]43410e92012-04-20 17:06:289455 GLenum error = PeekGLError();
[email protected]0a1e9ad2012-05-04 21:13:039456 if (error != GL_NO_ERROR) {
9457 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289458 return;
[email protected]0a1e9ad2012-05-04 21:13:039459 }
[email protected]43410e92012-04-20 17:06:289460
9461 texture_manager()->SetLevelInfo(
9462 dest_info, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039463 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259464 } else {
[email protected]60f22d32012-12-12 00:31:589465 texture_manager()->SetLevelCleared(dest_info, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289466 }
9467
[email protected]88a61bf2012-10-27 13:00:429468 clear_state_dirty_ = true;
[email protected]0a1e9ad2012-05-04 21:13:039469 glViewport(0, 0, source_width, source_height);
[email protected]43410e92012-04-20 17:06:289470 copy_texture_CHROMIUM_->DoCopyTexture(target, source_info->service_id(),
9471 dest_info->service_id(), level,
9472 unpack_flip_y_,
[email protected]6c75c712012-06-19 15:43:179473 unpack_premultiply_alpha_,
9474 unpack_unpremultiply_alpha_);
[email protected]e259eb412012-10-13 05:47:249475 glViewport(
9476 state_.viewport_x, state_.viewport_y,
9477 state_.viewport_width, state_.viewport_height);
[email protected]43410e92012-04-20 17:06:289478
9479 // Restore all of the state touched by the extension.
[email protected]e259eb412012-10-13 05:47:249480 if (state_.current_program)
9481 glUseProgram(state_.current_program->service_id());
[email protected]43410e92012-04-20 17:06:289482 else
9483 glUseProgram(0);
9484
9485 RestoreCurrentFramebufferBindings();
9486 RestoreCurrentTexture2DBindings();
9487 RestoreStateForAttrib(
9488 CopyTextureCHROMIUMResourceManager::kVertexPositionAttrib);
9489 RestoreStateForAttrib(
9490 CopyTextureCHROMIUMResourceManager::kVertexTextureAttrib);
9491
9492 ApplyDirtyState();
9493}
9494
[email protected]97dc7cbe2011-12-06 17:26:179495static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9496 switch (internalformat) {
9497 case GL_RGB565:
9498 return GL_UNSIGNED_SHORT_5_6_5;
9499 case GL_RGBA4:
9500 return GL_UNSIGNED_SHORT_4_4_4_4;
9501 case GL_RGB5_A1:
9502 return GL_UNSIGNED_SHORT_5_5_5_1;
9503 case GL_RGB8_OES:
9504 return GL_UNSIGNED_BYTE;
9505 case GL_RGBA8_OES:
9506 return GL_UNSIGNED_BYTE;
9507 case GL_LUMINANCE8_ALPHA8_EXT:
9508 return GL_UNSIGNED_BYTE;
9509 case GL_LUMINANCE8_EXT:
9510 return GL_UNSIGNED_BYTE;
9511 case GL_ALPHA8_EXT:
9512 return GL_UNSIGNED_BYTE;
9513 case GL_RGBA32F_EXT:
9514 return GL_FLOAT;
9515 case GL_RGB32F_EXT:
9516 return GL_FLOAT;
9517 case GL_ALPHA32F_EXT:
9518 return GL_FLOAT;
9519 case GL_LUMINANCE32F_EXT:
9520 return GL_FLOAT;
9521 case GL_LUMINANCE_ALPHA32F_EXT:
9522 return GL_FLOAT;
9523 case GL_RGBA16F_EXT:
9524 return GL_HALF_FLOAT_OES;
9525 case GL_RGB16F_EXT:
9526 return GL_HALF_FLOAT_OES;
9527 case GL_ALPHA16F_EXT:
9528 return GL_HALF_FLOAT_OES;
9529 case GL_LUMINANCE16F_EXT:
9530 return GL_HALF_FLOAT_OES;
9531 case GL_LUMINANCE_ALPHA16F_EXT:
9532 return GL_HALF_FLOAT_OES;
9533 case GL_BGRA8_EXT:
9534 return GL_UNSIGNED_BYTE;
9535 default:
9536 return GL_NONE;
9537 }
9538}
9539
9540void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449541 GLenum target,
9542 GLint levels,
9543 GLenum internal_format,
9544 GLsizei width,
9545 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389546 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419547 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179548 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ad84a3a2012-06-08 21:42:439549 SetGLError(
9550 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179551 return;
9552 }
9553 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9554 if (!info) {
9555 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439556 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179557 return;
9558 }
9559 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:429560 clear_state_dirty_ = true;
[email protected]97dc7cbe2011-12-06 17:26:179561 }
9562 if (info->IsImmutable()) {
9563 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439564 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179565 return;
9566 }
9567 CopyRealGLErrorsToWrapper();
[email protected]f0e6a34f2012-01-04 20:53:409568 glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format),
9569 width, height);
[email protected]97dc7cbe2011-12-06 17:26:179570 GLenum error = PeekGLError();
9571 if (error == GL_NO_ERROR) {
9572 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9573 GLenum type = ExtractTypeFromStorageFormat(internal_format);
[email protected]4502e6492011-12-14 19:39:159574 GLsizei level_width = width;
9575 GLsizei level_height = height;
9576 for (int ii = 0; ii < levels; ++ii) {
9577 texture_manager()->SetLevelInfo(
[email protected]e071ea72012-11-26 22:29:599578 info, target, ii, format, level_width, level_height, 1, 0, format,
[email protected]80eb6b52012-01-19 00:14:419579 type, false);
[email protected]4502e6492011-12-14 19:39:159580 level_width = std::max(1, level_width >> 1);
9581 level_height = std::max(1, level_height >> 1);
9582 }
[email protected]97dc7cbe2011-12-06 17:26:179583 info->SetImmutable(true);
9584 }
[email protected]97dc7cbe2011-12-06 17:26:179585}
[email protected]e51bdf32011-11-23 22:21:469586
[email protected]78b514b2012-05-01 21:50:599587error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
9588 uint32 immediate_data_size, const gles2::GenMailboxCHROMIUM& c) {
9589 MailboxName name;
9590 mailbox_manager()->GenerateMailboxName(&name);
9591 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
9592 Bucket* bucket = CreateBucket(bucket_id);
9593
9594 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
9595 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
9596
9597 return error::kNoError;
9598}
9599
9600void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9601 const GLbyte* mailbox) {
9602 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9603 if (!info) {
9604 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439605 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599606 return;
9607 }
9608
9609 TextureDefinition* definition = texture_manager()->Save(info);
9610 if (!definition) {
9611 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439612 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599613 return;
9614 }
9615
9616 if (!group_->mailbox_manager()->ProduceTexture(
9617 target,
9618 *reinterpret_cast<const MailboxName*>(mailbox),
9619 definition,
9620 texture_manager())) {
9621 bool success = texture_manager()->Restore(info, definition);
9622 DCHECK(success);
9623 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439624 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599625 return;
9626 }
9627
9628 BindAndApplyTextureParameters(info);
9629}
9630
9631void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9632 const GLbyte* mailbox) {
9633 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9634 if (!info) {
9635 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439636 "glConsumeTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599637 return;
9638 }
9639
9640 scoped_ptr<TextureDefinition> definition(
9641 group_->mailbox_manager()->ConsumeTexture(
9642 target,
9643 *reinterpret_cast<const MailboxName*>(mailbox)));
9644 if (!definition.get()) {
9645 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439646 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599647 return;
9648 }
9649
9650 if (!texture_manager()->Restore(info, definition.release())) {
9651 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439652 "glConsumeTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599653 return;
9654 }
9655
9656 BindAndApplyTextureParameters(info);
9657}
9658
[email protected]d2a0e1a2012-08-12 02:25:019659void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9660 GLsizei length, const GLchar* marker) {
9661 if (!marker) {
9662 marker = "";
9663 }
9664 debug_marker_manager_.SetMarker(
9665 length ? std::string(marker, length) : std::string(marker));
9666}
9667
9668void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9669 GLsizei length, const GLchar* marker) {
9670 if (!marker) {
9671 marker = "";
9672 }
9673 debug_marker_manager_.PushGroup(
9674 length ? std::string(marker, length) : std::string(marker));
9675}
9676
9677void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9678 debug_marker_manager_.PopGroup();
9679}
9680
[email protected]09d50362012-10-18 20:54:379681void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9682 GLenum target, GLint image_id) {
9683 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9684 if (target != GL_TEXTURE_2D) {
9685 // This might be supported in the future.
9686 SetGLError(
9687 GL_INVALID_OPERATION,
9688 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9689 return;
9690 }
9691
9692 // Default target might be conceptually valid, but disallow it to avoid
9693 // accidents.
9694 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9695 target);
9696 if (!info) {
9697 SetGLError(GL_INVALID_OPERATION,
9698 "glBindTexImage2DCHROMIUM", "no texture bound");
9699 return;
9700 }
9701
9702 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9703 if (!gl_image) {
9704 SetGLError(GL_INVALID_OPERATION,
9705 "glBindTexImage2DCHROMIUM",
9706 "no image found with the given ID");
9707 return;
9708 }
9709
9710 if (!gl_image->BindTexImage()) {
9711 SetGLError(GL_INVALID_OPERATION,
9712 "glBindTexImage2DCHROMIUM",
9713 "fail to bind image with the given ID");
9714 return;
9715 }
9716
9717 gfx::Size size = gl_image->GetSize();
9718 texture_manager()->SetLevelInfo(
9719 info, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
9720 GL_RGBA, GL_UNSIGNED_BYTE, true);
9721 texture_manager()->SetLevelImage(info, target, 0, gl_image);
9722}
9723
9724void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
9725 GLenum target, GLint image_id) {
9726 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
9727 if (target != GL_TEXTURE_2D) {
9728 // This might be supported in the future.
9729 SetGLError(
9730 GL_INVALID_OPERATION,
9731 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9732 return;
9733 }
9734
9735 // Default target might be conceptually valid, but disallow it to avoid
9736 // accidents.
9737 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9738 target);
9739 if (!info) {
9740 SetGLError(GL_INVALID_OPERATION,
9741 "glReleaseTexImage2DCHROMIUM", "no texture bound");
9742 return;
9743 }
9744
9745 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9746 if (!gl_image) {
9747 SetGLError(GL_INVALID_OPERATION,
9748 "glReleaseTexImage2DCHROMIUM",
9749 "no image found with the given ID");
9750 return;
9751 }
9752
9753 // Do nothing when image is not currently bound.
9754 if (info->GetLevelImage(target, 0) != gl_image)
9755 return;
9756
9757 gl_image->ReleaseTexImage();
9758
9759 texture_manager()->SetLevelInfo(
9760 info, target, 0, GL_RGBA, 0, 0, 1, 0,
9761 GL_RGBA, GL_UNSIGNED_BYTE, false);
9762}
[email protected]d2a0e1a2012-08-12 02:25:019763
[email protected]94307712012-11-16 23:26:119764error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
9765 uint32 immediate_data_size, const gles2::TraceBeginCHROMIUM& c) {
9766 Bucket* bucket = GetBucket(c.bucket_id);
9767 if (!bucket || bucket->size() == 0) {
9768 return error::kInvalidArguments;
9769 }
9770 std::string command_name;
9771 if (!bucket->GetAsString(&command_name)) {
9772 return error::kInvalidArguments;
9773 }
9774
9775 linked_ptr<GPUTrace> trace(new GPUTrace(command_name));
9776 trace->EnableStartTrace();
9777 gpu_trace_stack_.push(trace);
9778
9779 return error::kNoError;
9780}
9781
9782void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
9783 if (gpu_trace_stack_.empty()) {
9784 SetGLError(GL_INVALID_OPERATION,
9785 "glTraceEndCHROMIUM", "no trace begin found");
9786 return;
9787 }
9788
9789 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top();
9790 trace->EnableEndTrace();
9791 gpu_trace_stack_.pop();
9792}
9793
[email protected]32145a92012-12-17 09:01:599794bool GLES2DecoderImpl::ValidateAsyncTransfer(
9795 const char* function_name,
9796 TextureManager::TextureInfo* info,
9797 GLenum target,
9798 GLint level,
9799 const void * data) {
9800 // We only support async uploads to 2D textures for now.
9801 if (GL_TEXTURE_2D != target) {
9802 SetGLErrorInvalidEnum(function_name, target, "target");
9803 return false;
9804 }
9805 // We only support uploads to level zero for now.
9806 if (level != 0) {
9807 SetGLError(GL_INVALID_VALUE, function_name, "level != 0");
9808 return false;
9809 }
9810 // A transfer buffer must be bound, even for asyncTexImage2D.
9811 if (data == NULL) {
9812 SetGLError(GL_INVALID_OPERATION, function_name, "buffer == 0");
9813 return false;
9814 }
9815 // We only support one async transfer in progress.
9816 if (!info || info->AsyncTransferIsInProgress()) {
9817 SetGLError(GL_INVALID_OPERATION,
9818 function_name, "transfer already in progress");
9819 return false;
9820 }
9821 return true;
9822}
9823
[email protected]69023942012-11-30 19:57:169824error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
9825 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) {
9826 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:169827 GLenum target = static_cast<GLenum>(c.target);
9828 GLint level = static_cast<GLint>(c.level);
9829 GLint internal_format = static_cast<GLint>(c.internalformat);
9830 GLsizei width = static_cast<GLsizei>(c.width);
9831 GLsizei height = static_cast<GLsizei>(c.height);
9832 GLint border = static_cast<GLint>(c.border);
9833 GLenum format = static_cast<GLenum>(c.format);
9834 GLenum type = static_cast<GLenum>(c.type);
9835 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9836 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
9837 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:599838
9839 // TODO(epenner): Move this and copies of this memory validation
9840 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:169841 if (!GLES2Util::ComputeImageDataSizes(
9842 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
9843 NULL)) {
9844 return error::kOutOfBounds;
9845 }
9846 const void* pixels = NULL;
9847 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9848 pixels = GetSharedMemoryAs<const void*>(
9849 pixels_shm_id, pixels_shm_offset, pixels_size);
9850 if (!pixels) {
9851 return error::kOutOfBounds;
9852 }
9853 }
9854
[email protected]32145a92012-12-17 09:01:599855 // All the normal glTexSubImage2D validation.
9856 if (!ValidateTexImage2D(
9857 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
9858 width, height, border, format, type, pixels, pixels_size)) {
9859 return error::kNoError;
9860 }
9861
9862 // Extra async validation.
9863 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9864 if (!ValidateAsyncTransfer(
9865 "glAsyncTexImage2DCHROMIUM", info, target, level, pixels))
9866 return error::kNoError;
9867
9868 // Don't allow async redefinition of a textures.
9869 if (info->IsDefined()) {
9870 SetGLError(GL_INVALID_OPERATION,
9871 "glAsyncTexImage2DCHROMIUM", "already defined");
9872 return error::kNoError;
9873 }
9874
9875 // We know the memory/size is safe, so get the real shared memory since
9876 // it might need to be duped to prevent use-after-free of the memory.
9877 Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
9878 base::SharedMemory* shared_memory = buffer.shared_memory;
9879 uint32 shm_size = buffer.size;
9880 uint32 shm_data_offset = c.pixels_shm_offset;
9881 uint32 shm_data_size = pixels_size;
9882
9883 // Set up the async state if needed, and make the texture
9884 // immutable so the async state stays valid. The level info
9885 // is set up lazily when the transfer completes.
9886 DCHECK(!info->GetAsyncTransferState());
9887 info->SetAsyncTransferState(
9888 async_pixel_transfer_delegate_->
9889 CreatePixelTransferState(info->service_id()));
9890 info->SetImmutable(true);
9891
9892 // Issue the async call and set up the texture.
9893 GLenum gl_internal_format =
9894 GetTexInternalFormat(internal_format, format, type);
9895 gfx::AsyncTexImage2DParams tex_params = {target, level, gl_internal_format,
9896 width, height, border, format, type};
9897 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
9898 shm_data_offset, shm_data_size};
9899
9900 // Add a pending transfer to the texture manager, which will bind the
9901 // transfer data to the texture and set the level info at the same time,
9902 // after the the transfer is complete.
9903 texture_manager()->AddPendingAsyncPixelTransfer(
9904 info->GetAsyncTransferState()->AsWeakPtr(), info);
9905
9906 async_pixel_transfer_delegate_->AsyncTexImage2D(
9907 info->GetAsyncTransferState(), tex_params, mem_params);
[email protected]f598f422012-12-07 08:30:039908 return error::kNoError;
[email protected]69023942012-11-30 19:57:169909}
9910
9911error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
9912 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) {
9913 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:169914 GLenum target = static_cast<GLenum>(c.target);
9915 GLint level = static_cast<GLint>(c.level);
9916 GLint xoffset = static_cast<GLint>(c.xoffset);
9917 GLint yoffset = static_cast<GLint>(c.yoffset);
9918 GLsizei width = static_cast<GLsizei>(c.width);
9919 GLsizei height = static_cast<GLsizei>(c.height);
9920 GLenum format = static_cast<GLenum>(c.format);
9921 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:599922
9923 // TODO(epenner): Move this and copies of this memory validation
9924 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:169925 uint32 data_size;
9926 if (!GLES2Util::ComputeImageDataSizes(
9927 width, height, format, type, state_.unpack_alignment, &data_size,
9928 NULL, NULL)) {
9929 return error::kOutOfBounds;
9930 }
9931 const void* pixels = GetSharedMemoryAs<const void*>(
9932 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:599933
9934 // All the normal glTexSubImage2D validation.
9935 error::Error error = error::kNoError;
9936 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
9937 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
9938 return error;
[email protected]69023942012-11-30 19:57:169939 }
9940
[email protected]32145a92012-12-17 09:01:599941 // Extra async validation.
9942 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9943 if (!ValidateAsyncTransfer(
9944 "glAsyncTexSubImage2DCHROMIUM", info, target, level, pixels))
9945 return error::kNoError;
9946
9947 // Guarantee async textures are always 'cleared' as follows:
9948 // - AsyncTexImage2D can not redefine an existing texture
9949 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
9950 // - AsyncTexSubImage2D clears synchronously if not already cleared.
9951 // - Textures become immutable after an async call.
9952 // This way we know in all cases that an async texture is always clear.
9953 if (!info->SafeToRenderFrom()) {
9954 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
9955 SetGLError(GL_OUT_OF_MEMORY,
9956 "glAsyncTexSubImage2DCHROMIUM","dimensions too big");
9957 return error::kNoError;
9958 }
9959 }
9960
9961 // We know the memory/size is safe, so get the real shared memory since
9962 // it might need to be duped to prevent use-after-free of the memory.
9963 Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
9964 base::SharedMemory* shared_memory = buffer.shared_memory;
9965 uint32 shm_size = buffer.size;
9966 uint32 shm_data_offset = c.data_shm_offset;
9967 uint32 shm_data_size = data_size;
9968
9969 if (!info->GetAsyncTransferState()) {
9970 // Set up the async state if needed, and make the texture
9971 // immutable so the async state stays valid.
9972 info->SetAsyncTransferState(
9973 async_pixel_transfer_delegate_->
9974 CreatePixelTransferState(info->service_id()));
9975 info->SetImmutable(true);
9976 }
9977
9978 gfx::AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
9979 width, height, format, type};
9980 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
9981 shm_data_offset, shm_data_size};
9982 async_pixel_transfer_delegate_->AsyncTexSubImage2D(
9983 info->GetAsyncTransferState(), tex_params, mem_params);
9984 return error::kNoError;
[email protected]69023942012-11-30 19:57:169985}
9986
[email protected]96449d2c2009-11-25 00:01:329987// Include the auto-generated part of this file. We split this because it means
9988// we can easily edit the non-auto generated parts right here in this file
9989// instead of having to edit some template or the code generator.
9990#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
9991
9992} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:259993} // namespace gpu