blob: 29b92c393ee16b63468b49d51c033a8fa629fbe6 [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"
25#include "base/memory/weak_ptr.h"
[email protected]0f8afe82012-05-14 23:43:0126#include "base/string_number_conversions.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]c9e2cbbb2012-05-12 21:17:2759#include "ui/gl/gl_context.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]297ca1c2011-06-20 23:08:46197static void WrappedTexImage2D(
[email protected]473c01ccb2011-06-07 01:33:30198 GLenum target,
199 GLint level,
200 GLenum internal_format,
201 GLsizei width,
202 GLsizei height,
203 GLint border,
204 GLenum format,
205 GLenum type,
206 const void* pixels) {
[email protected]f0e6a34f2012-01-04 20:53:40207 GLenum gl_internal_format = GetTexInternalFormat(internal_format);
[email protected]473c01ccb2011-06-07 01:33:30208 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
[email protected]f0e6a34f2012-01-04 20:53:40209 if (type == GL_FLOAT) {
[email protected]58b75f92012-03-20 21:15:43210 switch (format) {
211 case GL_RGBA:
212 gl_internal_format = GL_RGBA32F_ARB;
213 break;
214 case GL_RGB:
215 gl_internal_format = GL_RGB32F_ARB;
216 break;
217 case GL_LUMINANCE_ALPHA:
218 gl_internal_format = GL_LUMINANCE_ALPHA32F_ARB;
219 break;
220 case GL_LUMINANCE:
221 gl_internal_format = GL_LUMINANCE32F_ARB;
222 break;
223 case GL_ALPHA:
224 gl_internal_format = GL_ALPHA32F_ARB;
225 break;
226 default:
227 NOTREACHED();
228 break;
[email protected]473c01ccb2011-06-07 01:33:30229 }
230 } else if (type == GL_HALF_FLOAT_OES) {
[email protected]58b75f92012-03-20 21:15:43231 switch (format) {
232 case GL_RGBA:
233 gl_internal_format = GL_RGBA16F_ARB;
234 break;
235 case GL_RGB:
236 gl_internal_format = GL_RGB16F_ARB;
237 break;
238 case GL_LUMINANCE_ALPHA:
239 gl_internal_format = GL_LUMINANCE_ALPHA16F_ARB;
240 break;
241 case GL_LUMINANCE:
242 gl_internal_format = GL_LUMINANCE16F_ARB;
243 break;
244 case GL_ALPHA:
245 gl_internal_format = GL_ALPHA16F_ARB;
246 break;
247 default:
248 NOTREACHED();
249 break;
[email protected]473c01ccb2011-06-07 01:33:30250 }
251 }
252 }
253 glTexImage2D(
254 target, level, gl_internal_format, width, height, border, format, type,
255 pixels);
256}
257
[email protected]297ca1c2011-06-20 23:08:46258// Wrapper for glEnable/glDisable that doesn't suck.
259static void EnableDisable(GLenum pname, bool enable) {
260 if (enable) {
261 glEnable(pname);
262 } else {
263 glDisable(pname);
264 }
265}
266
[email protected]6217d392010-03-25 22:08:35267// This class prevents any GL errors that occur when it is in scope from
268// being reported to the client.
269class ScopedGLErrorSuppressor {
270 public:
271 explicit ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder);
272 ~ScopedGLErrorSuppressor();
273 private:
274 GLES2DecoderImpl* decoder_;
275 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
276};
277
278// Temporarily changes a decoder's bound 2D texture and restore it when this
279// object goes out of scope. Also temporarily switches to using active texture
280// unit zero in case the client has changed that to something invalid.
281class ScopedTexture2DBinder {
282 public:
283 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
284 ~ScopedTexture2DBinder();
285
286 private:
287 GLES2DecoderImpl* decoder_;
288 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
289};
290
291// Temporarily changes a decoder's bound render buffer and restore it when this
292// object goes out of scope.
293class ScopedRenderBufferBinder {
294 public:
295 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
296 ~ScopedRenderBufferBinder();
297
298 private:
299 GLES2DecoderImpl* decoder_;
300 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
301};
302
303// Temporarily changes a decoder's bound frame buffer and restore it when this
304// object goes out of scope.
305class ScopedFrameBufferBinder {
306 public:
307 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
308 ~ScopedFrameBufferBinder();
309
310 private:
311 GLES2DecoderImpl* decoder_;
312 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
313};
314
[email protected]34ff8b0c2010-10-01 20:06:02315// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52316// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27317// if it is bound or enforce_internal_framebuffer is true. If internal is
318// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02319class ScopedResolvedFrameBufferBinder {
320 public:
[email protected]e7e38032011-07-26 17:25:25321 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27322 bool enforce_internal_framebuffer,
323 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02324 ~ScopedResolvedFrameBufferBinder();
325
326 private:
327 GLES2DecoderImpl* decoder_;
328 bool resolve_and_bind_;
329 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
330};
331
[email protected]63b465922012-09-06 02:04:52332// This class records texture upload time when in scope.
333class ScopedTextureUploadTimer {
334 public:
335 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder);
336 ~ScopedTextureUploadTimer();
337
338 private:
339 GLES2DecoderImpl* decoder_;
340 base::TimeTicks begin_time_;
341 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer);
342};
343
[email protected]6217d392010-03-25 22:08:35344// Encapsulates an OpenGL texture.
345class Texture {
346 public:
347 explicit Texture(GLES2DecoderImpl* decoder);
348 ~Texture();
349
350 // Create a new render texture.
351 void Create();
352
353 // Set the initial size and format of a render texture or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02354 bool AllocateStorage(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35355
356 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58357 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35358
359 // Destroy the render texture. This must be explicitly called before
360 // destroying this object.
361 void Destroy();
362
[email protected]97872062010-11-03 19:07:05363 // Invalidate the texture. This can be used when a context is lost and it is
364 // not possible to make it current in order to free the resource.
365 void Invalidate();
366
[email protected]6217d392010-03-25 22:08:35367 GLuint id() const {
368 return id_;
369 }
370
[email protected]d37231fa2010-04-09 21:16:02371 gfx::Size size() const {
372 return size_;
373 }
374
[email protected]1078f912011-12-23 13:12:14375 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25376 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14377 }
378
[email protected]6217d392010-03-25 22:08:35379 private:
380 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25381 MemoryTypeTracker memory_tracker_;
[email protected]6217d392010-03-25 22:08:35382 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02383 gfx::Size size_;
[email protected]6217d392010-03-25 22:08:35384 DISALLOW_COPY_AND_ASSIGN(Texture);
385};
386
387// Encapsulates an OpenGL render buffer of any format.
388class RenderBuffer {
389 public:
390 explicit RenderBuffer(GLES2DecoderImpl* decoder);
391 ~RenderBuffer();
392
393 // Create a new render buffer.
394 void Create();
395
396 // Set the initial size and format of a render buffer or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02397 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
[email protected]6217d392010-03-25 22:08:35398
399 // Destroy the render buffer. This must be explicitly called before destroying
400 // this object.
401 void Destroy();
402
[email protected]97872062010-11-03 19:07:05403 // Invalidate the render buffer. This can be used when a context is lost and
404 // it is not possible to make it current in order to free the resource.
405 void Invalidate();
406
[email protected]6217d392010-03-25 22:08:35407 GLuint id() const {
408 return id_;
409 }
410
[email protected]1078f912011-12-23 13:12:14411 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25412 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14413 }
414
[email protected]6217d392010-03-25 22:08:35415 private:
416 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25417 MemoryTypeTracker memory_tracker_;
[email protected]6217d392010-03-25 22:08:35418 GLuint id_;
419 DISALLOW_COPY_AND_ASSIGN(RenderBuffer);
420};
421
422// Encapsulates an OpenGL frame buffer.
423class FrameBuffer {
424 public:
425 explicit FrameBuffer(GLES2DecoderImpl* decoder);
426 ~FrameBuffer();
427
428 // Create a new frame buffer.
429 void Create();
430
431 // Attach a color render buffer to a frame buffer.
432 void AttachRenderTexture(Texture* texture);
433
[email protected]b9363b22010-06-09 22:06:15434 // Attach a render buffer to a frame buffer. Note that this unbinds any
435 // currently bound frame buffer.
436 void AttachRenderBuffer(GLenum target, RenderBuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35437
[email protected]6217d392010-03-25 22:08:35438 // Destroy the frame buffer. This must be explicitly called before destroying
439 // this object.
440 void Destroy();
441
[email protected]97872062010-11-03 19:07:05442 // Invalidate the frame buffer. This can be used when a context is lost and it
443 // is not possible to make it current in order to free the resource.
444 void Invalidate();
445
[email protected]6217d392010-03-25 22:08:35446 // See glCheckFramebufferStatusEXT.
447 GLenum CheckStatus();
448
449 GLuint id() const {
450 return id_;
451 }
452
453 private:
454 GLES2DecoderImpl* decoder_;
455 GLuint id_;
456 DISALLOW_COPY_AND_ASSIGN(FrameBuffer);
457};
[email protected]34ff8b0c2010-10-01 20:06:02458
[email protected]43f28f832010-02-03 02:28:48459// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32460
[email protected]ddb1e5a2010-12-13 20:10:45461bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
462 uint32* service_texture_id) {
463 return false;
464}
465
[email protected]a3ded6d2010-10-19 06:44:39466GLES2Decoder::GLES2Decoder()
[email protected]e844ae22012-01-14 03:36:26467 : debug_(false),
[email protected]b5d647c2012-02-10 01:41:32468 log_commands_(false),
469 log_synthesized_gl_errors_(true) {
[email protected]96449d2c2009-11-25 00:01:32470}
471
[email protected]3916c97e2010-02-25 03:20:50472GLES2Decoder::~GLES2Decoder() {
473}
474
[email protected]57edfdad2012-02-07 04:57:15475bool GLES2Decoder::testing_force_is_angle_;
476
477void GLES2Decoder::set_testing_force_is_angle(bool force) {
478 testing_force_is_angle_ = force;
479}
480
481bool GLES2Decoder::IsAngle() {
482#if defined(OS_WIN)
483 return testing_force_is_angle_ ||
484 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
485#else
486 return testing_force_is_angle_;
487#endif
488}
489
[email protected]f39f4b3f2010-05-12 17:04:08490// This class implements GLES2Decoder so we don't have to expose all the GLES2
491// cmd stuff to outside this class.
492class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
493 public GLES2Decoder {
494 public:
[email protected]0f8afe82012-05-14 23:43:01495 static const int kMaxLogMessages = 256;
[email protected]fa20ec82012-05-04 04:02:48496
[email protected]aa7666122011-09-02 19:45:52497 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00498 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08499
[email protected]96449d2c2009-11-25 00:01:32500 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14501 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50502 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00503 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32504
505 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00506 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32507
508 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38509 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
510 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23511 bool offscreen,
[email protected]6217d392010-03-25 22:08:35512 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29513 const DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39514 const char* allowed_extensions,
[email protected]b8e97b62012-09-30 15:09:00515 const std::vector<int32>& attribs) OVERRIDE;
516 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38517 virtual void SetSurface(
518 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]3c644d82011-06-20 19:58:24519 virtual bool SetParent(GLES2Decoder* parent_decoder,
[email protected]b8e97b62012-09-30 15:09:00520 uint32 parent_texture_id) OVERRIDE;
521 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39522 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00523 virtual bool MakeCurrent() OVERRIDE;
524 virtual void ReleaseCurrent() OVERRIDE;
525 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
526 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
527 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]1868a342012-11-07 15:56:02528 virtual void RestoreState() const OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00529 virtual QueryManager* GetQueryManager() OVERRIDE {
530 return query_manager_.get();
531 }
532 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46533 return vertex_array_manager_.get();
534 }
[email protected]b8e97b62012-09-30 15:09:00535 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48536
[email protected]b8e97b62012-09-30 15:09:00537 virtual void SetGLError(GLenum error,
538 const char* function_name,
539 const char* msg);
540 virtual void SetGLErrorInvalidEnum(const char* function_name,
541 GLenum value,
542 const char* label);
[email protected]9d37f062011-11-22 01:24:52543 virtual void SetResizeCallback(
[email protected]b8e97b62012-09-30 15:09:00544 const base::Callback<void(gfx::Size)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00545
[email protected]b8e97b62012-09-30 15:09:00546 virtual void SetMsgCallback(const MsgCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00547
[email protected]b8e97b62012-09-30 15:09:00548 virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE;
[email protected]1318e922010-09-17 22:03:16549 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00550 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48551
[email protected]efcdd2362012-07-09 21:07:00552 virtual uint32 GetGLError() OVERRIDE;
553
[email protected]63b465922012-09-06 02:04:52554 virtual uint32 GetTextureUploadCount() OVERRIDE;
555 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
556 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30557 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52558
[email protected]8e3e0662010-08-23 18:46:30559 // Restores the current state to the user's settings.
560 void RestoreCurrentFramebufferBindings();
561 void RestoreCurrentRenderbufferBindings();
562 void RestoreCurrentTexture2DBindings();
563
[email protected]297ca1c2011-06-20 23:08:46564 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
565 void ApplyDirtyState();
566
[email protected]78b514b2012-05-01 21:50:59567 // Reapply the texture parameters to the given texture.
568 void BindAndApplyTextureParameters(TextureManager::TextureInfo* info);
569
[email protected]297ca1c2011-06-20 23:08:46570 // These check the state of the currently bound framebuffer or the
571 // backbuffer if no framebuffer is bound.
572 bool BoundFramebufferHasColorAttachmentWithAlpha();
573 bool BoundFramebufferHasDepthAttachment();
574 bool BoundFramebufferHasStencilAttachment();
575
[email protected]b8e97b62012-09-30 15:09:00576 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43577
[email protected]96449d2c2009-11-25 00:01:32578 private:
[email protected]6217d392010-03-25 22:08:35579 friend class ScopedGLErrorSuppressor;
[email protected]34ff8b0c2010-10-01 20:06:02580 friend class ScopedResolvedFrameBufferBinder;
[email protected]63b465922012-09-06 02:04:52581 friend class ScopedTextureUploadTimer;
[email protected]1078f912011-12-23 13:12:14582 friend class Texture;
[email protected]6217d392010-03-25 22:08:35583 friend class RenderBuffer;
584 friend class FrameBuffer;
585
[email protected]c2f8c8402010-12-06 18:07:24586 // Initialize or re-initialize the shader translator.
587 bool InitializeShaderTranslator();
588
[email protected]302ce6d2011-07-07 23:28:11589 void UpdateCapabilities();
590
[email protected]ae51d192010-04-27 00:48:03591 // Helpers for the glGen and glDelete functions.
592 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
593 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
594 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
595 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
596 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
597 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
598 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
599 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53600 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
601 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46602 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
603 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47604
[email protected]3916c97e2010-02-25 03:20:50605 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50606 BufferManager* buffer_manager() {
607 return group_->buffer_manager();
608 }
609
[email protected]a25fa872010-03-25 02:57:58610 RenderbufferManager* renderbuffer_manager() {
611 return group_->renderbuffer_manager();
612 }
613
614 FramebufferManager* framebuffer_manager() {
615 return group_->framebuffer_manager();
616 }
617
[email protected]3916c97e2010-02-25 03:20:50618 ProgramManager* program_manager() {
619 return group_->program_manager();
620 }
621
622 ShaderManager* shader_manager() {
623 return group_->shader_manager();
624 }
625
626 TextureManager* texture_manager() {
627 return group_->texture_manager();
628 }
629
[email protected]78b514b2012-05-01 21:50:59630 MailboxManager* mailbox_manager() {
631 return group_->mailbox_manager();
632 }
633
[email protected]09d50362012-10-18 20:54:37634 ImageManager* image_manager() {
635 return group_->image_manager();
636 }
637
[email protected]944b62f32012-09-27 02:20:46638 VertexArrayManager* vertex_array_manager() {
639 return vertex_array_manager_.get();
640 }
641
[email protected]34ff8b0c2010-10-01 20:06:02642 bool IsOffscreenBufferMultisampled() const {
643 return offscreen_target_samples_ > 1;
644 }
645
[email protected]a93bb842010-02-16 23:03:47646 // Creates a TextureInfo for the given texture.
[email protected]ae51d192010-04-27 00:48:03647 TextureManager::TextureInfo* CreateTextureInfo(
648 GLuint client_id, GLuint service_id) {
[email protected]80eb6b52012-01-19 00:14:41649 return texture_manager()->CreateTextureInfo(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47650 }
651
652 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]ae51d192010-04-27 00:48:03653 TextureManager::TextureInfo* GetTextureInfo(GLuint client_id) {
[email protected]3916c97e2010-02-25 03:20:50654 TextureManager::TextureInfo* info =
[email protected]ae51d192010-04-27 00:48:03655 texture_manager()->GetTextureInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10656 return info;
[email protected]a93bb842010-02-16 23:03:47657 }
658
659 // Deletes the texture info for the given texture.
[email protected]ae51d192010-04-27 00:48:03660 void RemoveTextureInfo(GLuint client_id) {
[email protected]80eb6b52012-01-19 00:14:41661 texture_manager()->RemoveTextureInfo(client_id);
[email protected]3916c97e2010-02-25 03:20:50662 }
[email protected]a93bb842010-02-16 23:03:47663
[email protected]d37231fa2010-04-09 21:16:02664 // Get the size (in pixels) of the currently bound frame buffer (either FBO
665 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30666 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02667
[email protected]9edc6b22010-12-23 02:00:26668 // Get the format of the currently bound frame buffer (either FBO or regular
669 // back buffer)
670 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46671 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26672
[email protected]a93bb842010-02-16 23:03:47673 // Wrapper for CompressedTexImage2D commands.
674 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37675 GLenum target,
676 GLint level,
677 GLenum internal_format,
678 GLsizei width,
679 GLsizei height,
680 GLint border,
681 GLsizei image_size,
682 const void* data);
[email protected]a93bb842010-02-16 23:03:47683
[email protected]cadde4a2010-07-31 17:10:43684 // Wrapper for CompressedTexSubImage2D.
685 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37686 GLenum target,
687 GLint level,
688 GLint xoffset,
689 GLint yoffset,
690 GLsizei width,
691 GLsizei height,
692 GLenum format,
693 GLsizei imageSize,
694 const void * data);
[email protected]cadde4a2010-07-31 17:10:43695
696 // Wrapper for CopyTexImage2D.
697 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37698 GLenum target,
699 GLint level,
700 GLenum internal_format,
701 GLint x,
702 GLint y,
703 GLsizei width,
704 GLsizei height,
705 GLint border);
[email protected]cadde4a2010-07-31 17:10:43706
707 // Wrapper for CopyTexSubImage2D.
708 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37709 GLenum target,
710 GLint level,
711 GLint xoffset,
712 GLint yoffset,
713 GLint x,
714 GLint y,
715 GLsizei width,
716 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43717
[email protected]a93bb842010-02-16 23:03:47718 // Wrapper for TexImage2D commands.
719 error::Error DoTexImage2D(
[email protected]09d50362012-10-18 20:54:37720 GLenum target,
721 GLint level,
722 GLenum internal_format,
723 GLsizei width,
724 GLsizei height,
725 GLint border,
726 GLenum format,
727 GLenum type,
728 const void* pixels,
729 uint32 pixels_size);
[email protected]a93bb842010-02-16 23:03:47730
[email protected]cadde4a2010-07-31 17:10:43731 // Wrapper for TexSubImage2D.
732 void DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37733 GLenum target,
734 GLint level,
735 GLint xoffset,
736 GLint yoffset,
737 GLsizei width,
738 GLsizei height,
739 GLenum format,
740 GLenum type,
741 const void * data);
[email protected]cadde4a2010-07-31 17:10:43742
[email protected]e51bdf32011-11-23 22:21:46743 // Wrapper for TexImageIOSurface2DCHROMIUM.
744 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37745 GLenum target,
746 GLsizei width,
747 GLsizei height,
748 GLuint io_surface_id,
749 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46750
[email protected]43410e92012-04-20 17:06:28751 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37752 GLenum target,
753 GLuint source_id,
754 GLuint target_id,
755 GLint level,
756 GLenum internal_format);
[email protected]43410e92012-04-20 17:06:28757
[email protected]97dc7cbe2011-12-06 17:26:17758 // Wrapper for TexStorage2DEXT.
759 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37760 GLenum target,
761 GLint levels,
762 GLenum internal_format,
763 GLsizei width,
764 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17765
[email protected]78b514b2012-05-01 21:50:59766 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
767 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
768
[email protected]09d50362012-10-18 20:54:37769 void DoBindTexImage2DCHROMIUM(
770 GLenum target,
771 GLint image_id);
772 void DoReleaseTexImage2DCHROMIUM(
773 GLenum target,
774 GLint image_id);
775
[email protected]94307712012-11-16 23:26:11776 void DoTraceEndCHROMIUM(void);
777
[email protected]a93bb842010-02-16 23:03:47778 // Creates a ProgramInfo for the given program.
[email protected]d685a682011-04-29 16:19:57779 ProgramManager::ProgramInfo* CreateProgramInfo(
780 GLuint client_id, GLuint service_id) {
781 return program_manager()->CreateProgramInfo(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47782 }
783
[email protected]07f54fcc2009-12-22 02:46:30784 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ae51d192010-04-27 00:48:03785 ProgramManager::ProgramInfo* GetProgramInfo(GLuint client_id) {
[email protected]ca488e12010-12-13 20:06:14786 return program_manager()->GetProgramInfo(client_id);
[email protected]1d32bc82010-01-13 22:06:46787 }
[email protected]07f54fcc2009-12-22 02:46:30788
[email protected]6b8cf1a2010-05-06 16:13:58789 // Gets the program info for the given program. If it's not a program
790 // generates a GL error. Returns NULL if not program.
791 ProgramManager::ProgramInfo* GetProgramInfoNotShader(
792 GLuint client_id, const char* function_name) {
793 ProgramManager::ProgramInfo* info = GetProgramInfo(client_id);
794 if (!info) {
795 if (GetShaderInfo(client_id)) {
[email protected]ad84a3a2012-06-08 21:42:43796 SetGLError(
797 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58798 } else {
[email protected]ad84a3a2012-06-08 21:42:43799 SetGLError(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58800 }
801 }
802 return info;
803 }
804
805
[email protected]45bf5152010-02-12 00:11:31806 // Creates a ShaderInfo for the given shader.
[email protected]d685a682011-04-29 16:19:57807 ShaderManager::ShaderInfo* CreateShaderInfo(
808 GLuint client_id,
809 GLuint service_id,
810 GLenum shader_type) {
811 return shader_manager()->CreateShaderInfo(
812 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31813 }
814
815 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ae51d192010-04-27 00:48:03816 ShaderManager::ShaderInfo* GetShaderInfo(GLuint client_id) {
[email protected]ca488e12010-12-13 20:06:14817 return shader_manager()->GetShaderInfo(client_id);
[email protected]45bf5152010-02-12 00:11:31818 }
819
[email protected]6b8cf1a2010-05-06 16:13:58820 // Gets the shader info for the given shader. If it's not a shader generates a
821 // GL error. Returns NULL if not shader.
822 ShaderManager::ShaderInfo* GetShaderInfoNotProgram(
823 GLuint client_id, const char* function_name) {
824 ShaderManager::ShaderInfo* info = GetShaderInfo(client_id);
825 if (!info) {
826 if (GetProgramInfo(client_id)) {
827 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:43828 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58829 } else {
[email protected]ad84a3a2012-06-08 21:42:43830 SetGLError(
831 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58832 }
833 }
834 return info;
835 }
836
[email protected]a93bb842010-02-16 23:03:47837 // Creates a buffer info for the given buffer.
[email protected]ae51d192010-04-27 00:48:03838 void CreateBufferInfo(GLuint client_id, GLuint service_id) {
839 return buffer_manager()->CreateBufferInfo(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47840 }
841
[email protected]07f54fcc2009-12-22 02:46:30842 // Gets the buffer info for the given buffer.
[email protected]ae51d192010-04-27 00:48:03843 BufferManager::BufferInfo* GetBufferInfo(GLuint client_id) {
844 BufferManager::BufferInfo* info =
845 buffer_manager()->GetBufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10846 return info;
[email protected]1d32bc82010-01-13 22:06:46847 }
[email protected]07f54fcc2009-12-22 02:46:30848
[email protected]a93bb842010-02-16 23:03:47849 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
850 // on glDeleteBuffers so we can make sure the user does not try to render
851 // with deleted buffers.
[email protected]ae51d192010-04-27 00:48:03852 void RemoveBufferInfo(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:47853
[email protected]a25fa872010-03-25 02:57:58854 // Creates a framebuffer info for the given framebuffer.
[email protected]ae51d192010-04-27 00:48:03855 void CreateFramebufferInfo(GLuint client_id, GLuint service_id) {
856 return framebuffer_manager()->CreateFramebufferInfo(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58857 }
858
859 // Gets the framebuffer info for the given framebuffer.
860 FramebufferManager::FramebufferInfo* GetFramebufferInfo(
[email protected]ae51d192010-04-27 00:48:03861 GLuint client_id) {
[email protected]a25fa872010-03-25 02:57:58862 FramebufferManager::FramebufferInfo* info =
[email protected]ae51d192010-04-27 00:48:03863 framebuffer_manager()->GetFramebufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10864 return info;
[email protected]a25fa872010-03-25 02:57:58865 }
866
867 // Removes the framebuffer info for the given framebuffer.
[email protected]ae51d192010-04-27 00:48:03868 void RemoveFramebufferInfo(GLuint client_id) {
869 framebuffer_manager()->RemoveFramebufferInfo(client_id);
[email protected]a25fa872010-03-25 02:57:58870 }
871
872 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ae51d192010-04-27 00:48:03873 void CreateRenderbufferInfo(GLuint client_id, GLuint service_id) {
874 return renderbuffer_manager()->CreateRenderbufferInfo(
875 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58876 }
877
878 // Gets the renderbuffer info for the given renderbuffer.
879 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfo(
[email protected]ae51d192010-04-27 00:48:03880 GLuint client_id) {
[email protected]a25fa872010-03-25 02:57:58881 RenderbufferManager::RenderbufferInfo* info =
[email protected]ae51d192010-04-27 00:48:03882 renderbuffer_manager()->GetRenderbufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10883 return info;
[email protected]a25fa872010-03-25 02:57:58884 }
885
886 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ae51d192010-04-27 00:48:03887 void RemoveRenderbufferInfo(GLuint client_id) {
888 renderbuffer_manager()->RemoveRenderbufferInfo(client_id);
[email protected]a25fa872010-03-25 02:57:58889 }
890
[email protected]944b62f32012-09-27 02:20:46891 // Gets the vertex attrib manager for the given vertex array.
892 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
893 VertexAttribManager* info =
894 vertex_array_manager()->GetVertexAttribManager(client_id);
895 return info;
896 }
897
898 // Removes the vertex attrib manager for the given vertex array.
899 void RemoveVertexAttribManager(GLuint client_id) {
900 vertex_array_manager()->RemoveVertexAttribManager(client_id);
901 }
902
903 // Creates a vertex attrib manager for the given vertex array.
904 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
905 return vertex_array_manager()->CreateVertexAttribManager(
906 client_id, service_id, group_->max_vertex_attribs());
907 }
908
[email protected]258a3313f2011-10-18 20:13:57909 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:33910 void DoBindUniformLocationCHROMIUM(
911 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:57912
[email protected]558847a2010-03-24 07:02:54913 error::Error GetAttribLocationHelper(
914 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
915 const std::string& name_str);
916
917 error::Error GetUniformLocationHelper(
918 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
919 const std::string& name_str);
920
[email protected]3916c97e2010-02-25 03:20:50921 // Helper for glShaderSource.
922 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:03923 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:30924
[email protected]0d6bfdc2011-11-02 01:32:20925 // Clear any textures used by the current program.
926 bool ClearUnclearedTextures();
927
928 // Clear any uncleared level in texture.
929 // Returns false if there was a generated GL error.
930 bool ClearTexture(TextureManager::TextureInfo* info);
931
932 // Clears any uncleared attachments attached to the given frame buffer.
933 // Returns false if there was a generated GL error.
934 void ClearUnclearedAttachments(
[email protected]8e3e0662010-08-23 18:46:30935 GLenum target, FramebufferManager::FramebufferInfo* info);
[email protected]3a2e7c7b2010-08-06 01:12:28936
[email protected]0d6bfdc2011-11-02 01:32:20937 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:00938 virtual bool ClearLevel(unsigned service_id,
939 unsigned bind_target,
940 unsigned target,
941 int level,
942 unsigned format,
943 unsigned type,
944 int width,
945 int height,
946 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:20947
[email protected]c007aa02010-09-02 22:22:40948 // Restore all GL state that affects clearing.
949 void RestoreClearState();
950
[email protected]3a2e7c7b2010-08-06 01:12:28951 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:46952 // Returns: true if glEnable/glDisable should actually be called.
953 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:28954
[email protected]0d6bfdc2011-11-02 01:32:20955 // Check that the currently bound framebuffers are valid.
956 // Generates GL error if not.
957 bool CheckBoundFramebuffersValid(const char* func_name);
958
959 // Check if a framebuffer meets our requirements.
960 bool CheckFramebufferValid(
961 FramebufferManager::FramebufferInfo* framebuffer,
962 GLenum target,
963 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:27964
[email protected]939e7362010-05-13 20:49:10965 // Checks if the current program exists and is valid. If not generates the
966 // appropriate GL error. Returns true if the current program is in a usable
967 // state.
968 bool CheckCurrentProgram(const char* function_name);
969
970 // Checks if the current program exists and is valid and that location is not
971 // -1. If the current program is not valid generates the appropriate GL
972 // error. Returns true if the current program is in a usable state and
973 // location is not -1.
974 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
975
976 // Gets the type of a uniform for a location in the current program. Sets GL
977 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:36978 // program is valid and the location exists. Adjusts count so it
979 // does not overflow the uniform.
980 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:12981 GLint fake_location, const char* function_name,
982 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:10983
[email protected]b177ae22011-11-01 03:29:11984 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:02985 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:11986
[email protected]b273e432010-04-12 17:23:58987 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
988 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
[email protected]b273e432010-04-12 17:23:58989
[email protected]96449d2c2009-11-25 00:01:32990 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:03991 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:32992
993 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:03994 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:32995
[email protected]3916c97e2010-02-25 03:20:50996 // Wrapper for glActiveTexture
997 void DoActiveTexture(GLenum texture_unit);
998
[email protected]ae51d192010-04-27 00:48:03999 // Wrapper for glAttachShader
1000 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1001
[email protected]96449d2c2009-11-25 00:01:321002 // Wrapper for glBindBuffer since we need to track the current targets.
1003 void DoBindBuffer(GLenum target, GLuint buffer);
1004
[email protected]86093972010-03-11 00:13:561005 // Wrapper for glBindFramebuffer since we need to track the current targets.
1006 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1007
1008 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1009 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1010
[email protected]a93bb842010-02-16 23:03:471011 // Wrapper for glBindTexture since we need to track the current targets.
1012 void DoBindTexture(GLenum target, GLuint texture);
1013
[email protected]944b62f32012-09-27 02:20:461014 // Wrapper for glBindVertexArrayOES
1015 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571016 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461017
[email protected]8e3e0662010-08-23 18:46:301018 // Wrapper for glBlitFramebufferEXT.
1019 void DoBlitFramebufferEXT(
1020 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1021 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1022 GLbitfield mask, GLenum filter);
1023
[email protected]36cef8ce2010-03-16 07:34:451024 // Wrapper for glBufferData.
[email protected]0c86dbf2010-03-05 08:14:111025 void DoBufferData(
1026 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
1027
[email protected]36cef8ce2010-03-16 07:34:451028 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111029 void DoBufferSubData(
1030 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1031
[email protected]36cef8ce2010-03-16 07:34:451032 // Wrapper for glCheckFramebufferStatus
1033 GLenum DoCheckFramebufferStatus(GLenum target);
1034
[email protected]3a03a8f2011-03-19 00:51:271035 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081036 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271037
[email protected]88a61bf2012-10-27 13:00:421038 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421039 void DoDepthRangef(GLclampf znear, GLclampf zfar);
1040 void DoHint(GLenum target, GLenum mode);
1041 void DoSampleCoverage (GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281042
[email protected]45bf5152010-02-12 00:11:311043 // Wrapper for glCompileShader.
1044 void DoCompileShader(GLuint shader);
1045
[email protected]269200b12010-11-18 22:53:061046 // Helper for DeleteSharedIdsCHROMIUM commands.
1047 void DoDeleteSharedIdsCHROMIUM(
1048 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101049
[email protected]ae51d192010-04-27 00:48:031050 // Wrapper for glDetachShader
1051 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1052
[email protected]3a2e7c7b2010-08-06 01:12:281053 // Wrapper for glDisable
1054 void DoDisable(GLenum cap);
1055
[email protected]07f54fcc2009-12-22 02:46:301056 // Wrapper for glDisableVertexAttribArray.
1057 void DoDisableVertexAttribArray(GLuint index);
1058
[email protected]3a2e7c7b2010-08-06 01:12:281059 // Wrapper for glEnable
1060 void DoEnable(GLenum cap);
1061
[email protected]07f54fcc2009-12-22 02:46:301062 // Wrapper for glEnableVertexAttribArray.
1063 void DoEnableVertexAttribArray(GLuint index);
1064
[email protected]882ba1e22012-03-08 19:02:531065 // Wrapper for glFinish.
1066 void DoFinish();
1067
1068 // Wrapper for glFlush.
1069 void DoFlush();
1070
[email protected]36cef8ce2010-03-16 07:34:451071 // Wrapper for glFramebufferRenderbufffer.
1072 void DoFramebufferRenderbuffer(
1073 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1074 GLuint renderbuffer);
1075
1076 // Wrapper for glFramebufferTexture2D.
1077 void DoFramebufferTexture2D(
1078 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1079 GLint level);
1080
[email protected]a93bb842010-02-16 23:03:471081 // Wrapper for glGenerateMipmap
1082 void DoGenerateMipmap(GLenum target);
1083
[email protected]269200b12010-11-18 22:53:061084 // Helper for GenSharedIdsCHROMIUM commands.
1085 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101086 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1087
[email protected]b273e432010-04-12 17:23:581088 // Wrapper for DoGetBooleanv.
1089 void DoGetBooleanv(GLenum pname, GLboolean* params);
1090
1091 // Wrapper for DoGetFloatv.
1092 void DoGetFloatv(GLenum pname, GLfloat* params);
1093
[email protected]36cef8ce2010-03-16 07:34:451094 // Wrapper for glGetFramebufferAttachmentParameteriv.
1095 void DoGetFramebufferAttachmentParameteriv(
1096 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1097
[email protected]a0c3e972010-04-21 00:49:131098 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581099 void DoGetIntegerv(GLenum pname, GLint* params);
1100
[email protected]29a9eb52010-04-13 09:04:231101 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061102 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231103 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1104
[email protected]a0c3e972010-04-21 00:49:131105 // Wrapper for glGetProgramiv.
1106 void DoGetProgramiv(
1107 GLuint program_id, GLenum pname, GLint* params);
1108
[email protected]36cef8ce2010-03-16 07:34:451109 // Wrapper for glRenderbufferParameteriv.
1110 void DoGetRenderbufferParameteriv(
1111 GLenum target, GLenum pname, GLint* params);
1112
[email protected]ddd968b82010-03-02 00:44:291113 // Wrapper for glGetShaderiv
1114 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1115
[email protected]b1122982010-05-17 23:04:241116 // Wrappers for glGetVertexAttrib.
1117 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1118 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1119
[email protected]1958e0e2010-04-22 05:17:151120 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241121 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151122 bool DoIsBuffer(GLuint client_id);
1123 bool DoIsFramebuffer(GLuint client_id);
1124 bool DoIsProgram(GLuint client_id);
1125 bool DoIsRenderbuffer(GLuint client_id);
1126 bool DoIsShader(GLuint client_id);
1127 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461128 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151129
[email protected]07f54fcc2009-12-22 02:46:301130 // Wrapper for glLinkProgram
1131 void DoLinkProgram(GLuint program);
1132
[email protected]269200b12010-11-18 22:53:061133 // Helper for RegisterSharedIdsCHROMIUM.
1134 void DoRegisterSharedIdsCHROMIUM(
1135 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101136
[email protected]36cef8ce2010-03-16 07:34:451137 // Wrapper for glRenderbufferStorage.
1138 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031139 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451140
[email protected]8e3e0662010-08-23 18:46:301141 // Wrapper for glRenderbufferStorageMultisampleEXT.
1142 void DoRenderbufferStorageMultisample(
1143 GLenum target, GLsizei samples, GLenum internalformat,
1144 GLsizei width, GLsizei height);
1145
[email protected]b273e432010-04-12 17:23:581146 // Wrapper for glReleaseShaderCompiler.
1147 void DoReleaseShaderCompiler() { }
1148
[email protected]3916c97e2010-02-25 03:20:501149 // Wrappers for glTexParameter functions.
1150 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1151 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1152 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1153 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1154
1155 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1156 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121157 void DoUniform1i(GLint fake_location, GLint v0);
1158 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1159 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1160 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1161 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101162
1163 // Wrappers for glUniformfv because some drivers don't correctly accept
1164 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121165 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1166 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1167 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1168 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501169
[email protected]43c2f1f2011-03-25 18:35:361170 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121171 GLint fake_location, GLsizei count, GLboolean transpose,
1172 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361173 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121174 GLint fake_location, GLsizei count, GLboolean transpose,
1175 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361176 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121177 GLint fake_location, GLsizei count, GLboolean transpose,
1178 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361179
[email protected]b1122982010-05-17 23:04:241180 // Wrappers for glVertexAttrib??
1181 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1182 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1183 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1184 void DoVertexAttrib4f(
1185 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1186 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1187 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1188 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1189 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1190
[email protected]43410e92012-04-20 17:06:281191 // Wrapper for glViewport
1192 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1193
[email protected]07f54fcc2009-12-22 02:46:301194 // Wrapper for glUseProgram
1195 void DoUseProgram(GLuint program);
1196
[email protected]ae51d192010-04-27 00:48:031197 // Wrapper for glValidateProgram.
1198 void DoValidateProgram(GLuint program_client_id);
1199
[email protected]d2a0e1a2012-08-12 02:25:011200 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1201 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1202 void DoPopGroupMarkerEXT(void);
1203
[email protected]4e8a5b122010-05-08 22:00:101204 // Gets the number of values that will be returned by glGetXXX. Returns
1205 // false if pname is unknown.
1206 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1207
[email protected]1002c2d2011-06-28 22:39:041208 // Gets the GLError and stores it in our wrapper. Effectively
1209 // this lets us peek at the error without losing it.
1210 GLenum PeekGLError();
1211
[email protected]07f54fcc2009-12-22 02:46:301212 // Copies the real GL errors to the wrapper. This is so we can
1213 // make sure there are no native GL errors before calling some GL function
1214 // so that on return we know any error generated was for that specific
1215 // command.
1216 void CopyRealGLErrorsToWrapper();
1217
[email protected]6217d392010-03-25 22:08:351218 // Clear all real GL errors. This is to prevent the client from seeing any
1219 // errors caused by GL calls that it was not responsible for issuing.
1220 void ClearRealGLErrors();
1221
[email protected]07f54fcc2009-12-22 02:46:301222 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431223 bool IsDrawValid(
1224 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301225
[email protected]c13e1da62011-09-09 21:48:301226 // Returns true if successful, simulated will be true if attrib0 was
1227 // simulated.
[email protected]c6aef902012-02-14 03:31:421228 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431229 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281230 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241231
[email protected]ef526492010-06-02 23:12:251232 // Returns true if textures were set.
1233 bool SetBlackTextureForNonRenderableTextures();
[email protected]3916c97e2010-02-25 03:20:501234 void RestoreStateForNonRenderableTextures();
1235
[email protected]8fbedc02010-11-18 18:43:401236 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421237 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431238 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421239 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401240 void RestoreStateForSimulatedFixedAttribs();
1241
[email protected]c6aef902012-02-14 03:31:421242 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1243 // cases (primcount is 0 for non-instanced).
1244 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431245 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421246 bool instanced, GLenum mode, GLint first, GLsizei count,
1247 GLsizei primcount);
1248 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431249 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421250 bool instanced, GLenum mode, GLsizei count, GLenum type,
1251 int32 offset, GLsizei primcount);
1252
[email protected]07f54fcc2009-12-22 02:46:301253 // Gets the buffer id for a given target.
[email protected]3916c97e2010-02-25 03:20:501254 BufferManager::BufferInfo* GetBufferInfoForTarget(GLenum target) {
[email protected]07f54fcc2009-12-22 02:46:301255 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
[email protected]944b62f32012-09-27 02:20:461256 if (target == GL_ARRAY_BUFFER) {
[email protected]e259eb412012-10-13 05:47:241257 return state_.bound_array_buffer;
[email protected]944b62f32012-09-27 02:20:461258 } else {
[email protected]e259eb412012-10-13 05:47:241259 return state_.vertex_attrib_manager->element_array_buffer();
[email protected]944b62f32012-09-27 02:20:461260 }
[email protected]07f54fcc2009-12-22 02:46:301261 }
1262
[email protected]a93bb842010-02-16 23:03:471263 // Gets the texture id for a given target.
[email protected]3916c97e2010-02-25 03:20:501264 TextureManager::TextureInfo* GetTextureInfoForTarget(GLenum target) {
[email protected]e259eb412012-10-13 05:47:241265 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:501266 TextureManager::TextureInfo* info = NULL;
[email protected]a93bb842010-02-16 23:03:471267 switch (target) {
1268 case GL_TEXTURE_2D:
[email protected]3916c97e2010-02-25 03:20:501269 info = unit.bound_texture_2d;
1270 break;
[email protected]a93bb842010-02-16 23:03:471271 case GL_TEXTURE_CUBE_MAP:
1272 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1273 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1274 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1275 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1276 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1277 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
[email protected]3916c97e2010-02-25 03:20:501278 info = unit.bound_texture_cube_map;
1279 break;
[email protected]61eeb33f2011-07-26 15:30:311280 case GL_TEXTURE_EXTERNAL_OES:
1281 info = unit.bound_texture_external_oes;
1282 break;
[email protected]e51bdf32011-11-23 22:21:461283 case GL_TEXTURE_RECTANGLE_ARB:
1284 info = unit.bound_texture_rectangle_arb;
1285 break;
[email protected]a93bb842010-02-16 23:03:471286 default:
1287 NOTREACHED();
[email protected]3916c97e2010-02-25 03:20:501288 return NULL;
[email protected]a93bb842010-02-16 23:03:471289 }
[email protected]a0b78dc2011-11-11 10:43:101290 return info;
[email protected]a93bb842010-02-16 23:03:471291 }
1292
[email protected]09d50362012-10-18 20:54:371293 TextureManager::TextureInfo* GetTextureInfoForTargetUnlessDefault(
1294 GLenum target) {
1295 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
1296 if (!info)
1297 return NULL;
1298 if (info == texture_manager()->GetDefaultTextureInfo(target))
1299 return NULL;
1300 return info;
1301 }
1302
[email protected]61eeb33f2011-07-26 15:30:311303 GLenum GetBindTargetForSamplerType(GLenum type) {
1304 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461305 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1306 switch (type) {
1307 case GL_SAMPLER_2D:
1308 return GL_TEXTURE_2D;
1309 case GL_SAMPLER_CUBE:
1310 return GL_TEXTURE_CUBE_MAP;
1311 case GL_SAMPLER_EXTERNAL_OES:
1312 return GL_TEXTURE_EXTERNAL_OES;
1313 case GL_SAMPLER_2D_RECT_ARB:
1314 return GL_TEXTURE_RECTANGLE_ARB;
1315 }
1316
1317 NOTREACHED();
1318 return 0;
[email protected]61eeb33f2011-07-26 15:30:311319 }
1320
[email protected]8e3e0662010-08-23 18:46:301321 // Gets the framebuffer info for a particular target.
1322 FramebufferManager::FramebufferInfo* GetFramebufferInfoForTarget(
1323 GLenum target) {
1324 FramebufferManager::FramebufferInfo* info = NULL;
1325 switch (target) {
1326 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451327 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]e259eb412012-10-13 05:47:241328 info = state_.bound_draw_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301329 break;
[email protected]ebfb73c2012-08-15 02:37:451330 case GL_READ_FRAMEBUFFER_EXT:
[email protected]e259eb412012-10-13 05:47:241331 info = state_.bound_read_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301332 break;
1333 default:
1334 NOTREACHED();
1335 break;
1336 }
[email protected]a0b78dc2011-11-11 10:43:101337 return info;
[email protected]8e3e0662010-08-23 18:46:301338 }
1339
[email protected]0d6bfdc2011-11-02 01:32:201340 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfoForTarget(
1341 GLenum target) {
1342 RenderbufferManager::RenderbufferInfo* info = NULL;
1343 switch (target) {
1344 case GL_RENDERBUFFER:
[email protected]e259eb412012-10-13 05:47:241345 info = state_.bound_renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201346 break;
1347 default:
1348 NOTREACHED();
1349 break;
1350 }
[email protected]a0b78dc2011-11-11 10:43:101351 return info;
[email protected]0d6bfdc2011-11-02 01:32:201352 }
1353
[email protected]f7b85372010-02-03 01:11:371354 // Validates the program and location for a glGetUniform call and returns
1355 // a SizeResult setup to receive the result. Returns true if glGetUniform
1356 // should be called.
1357 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121358 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371359 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121360 error::Error* error, GLint* real_location, GLuint* service_id,
1361 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371362
[email protected]1078f912011-12-23 13:12:141363 // Computes the estimated memory used for the backbuffer and passes it to
1364 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531365 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141366
[email protected]38d139d2011-07-14 00:38:431367 // Returns true if the context was just lost due to e.g. GL_ARB_robustness.
1368 bool WasContextLost();
1369
[email protected]e51bdf32011-11-23 22:21:461370#if defined(OS_MACOSX)
1371 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1372#endif
1373
[email protected]81375742012-06-08 00:04:001374 // Validates the combination of texture parameters. For example validates that
1375 // for a given format the specific type, level and targets are valid.
1376 // Synthesizes the correct GL error if invalid. Returns true if valid.
1377 bool ValidateTextureParameters(
1378 const char* function_name,
1379 GLenum target, GLenum format, GLenum type, GLint level);
1380
[email protected]ad84a3a2012-06-08 21:42:431381 bool ValidateCompressedTexDimensions(
1382 const char* function_name,
1383 GLint level, GLsizei width, GLsizei height, GLenum format);
1384 bool ValidateCompressedTexFuncData(
1385 const char* function_name,
1386 GLsizei width, GLsizei height, GLenum format, size_t size);
1387 bool ValidateCompressedTexSubDimensions(
1388 const char* function_name,
1389 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1390 GLsizei width, GLsizei height, GLenum format,
1391 TextureManager::TextureInfo* texture);
1392
[email protected]0f8afe82012-05-14 23:43:011393 void LogMessage(const std::string& msg);
1394 void RenderWarning(const std::string& msg);
1395 void PerformanceWarning(const std::string& msg);
[email protected]d2a0e1a2012-08-12 02:25:011396 const std::string& GetLogPrefix() const;
[email protected]0f8afe82012-05-14 23:43:011397
[email protected]62e155e2012-10-23 22:43:151398 const FeatureInfo::FeatureFlags& features() const {
1399 return feature_info_->feature_flags();
1400 }
1401
1402 const FeatureInfo::Workarounds& workarounds() const {
1403 return feature_info_->workarounds();
1404 }
1405
[email protected]a7266a92012-06-28 02:11:081406 bool ShouldDeferDraws() {
1407 return !offscreen_target_frame_buffer_.get() &&
[email protected]e259eb412012-10-13 05:47:241408 state_.bound_draw_framebuffer == NULL &&
[email protected]a7266a92012-06-28 02:11:081409 surface_->DeferDraws();
1410 }
1411
[email protected]c447acd2012-07-23 23:48:411412 void ForceCompileShaderIfPending(ShaderManager::ShaderInfo* info);
1413
[email protected]96449d2c2009-11-25 00:01:321414 // Generate a member function prototype for each command in an automated and
1415 // typesafe way.
1416 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141417 Error Handle ## name( \
[email protected]b9849abf2009-11-25 19:13:191418 uint32 immediate_data_size, \
[email protected]96449d2c2009-11-25 00:01:321419 const gles2::name& args); \
1420
1421 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1422
1423 #undef GLES2_CMD_OP
1424
[email protected]2f2d7042010-04-14 21:45:581425 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381426 scoped_refptr<gfx::GLSurface> surface_;
1427 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021428
[email protected]a3ded6d2010-10-19 06:44:391429 // The ContextGroup for this decoder uses to track resources.
1430 ContextGroup::Ref group_;
1431
[email protected]e259eb412012-10-13 05:47:241432 // All the state for this context.
1433 ContextState state_;
1434
[email protected]6217d392010-03-25 22:08:351435 // A parent decoder can access this decoders saved offscreen frame buffer.
1436 // The parent pointer is reset if the parent is destroyed.
1437 base::WeakPtr<GLES2DecoderImpl> parent_;
1438
[email protected]34ff8b0c2010-10-01 20:06:021439 // Current width and height of the offscreen frame buffer.
1440 gfx::Size offscreen_size_;
1441
[email protected]96449d2c2009-11-25 00:01:321442 // Current GL error bits.
1443 uint32 error_bits_;
1444
[email protected]96449d2c2009-11-25 00:01:321445 // Util to help with GL.
1446 GLES2Util util_;
1447
[email protected]43410e92012-04-20 17:06:281448 // unpack flip y as last set by glPixelStorei
1449 bool unpack_flip_y_;
1450
[email protected]6c75c712012-06-19 15:43:171451 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281452 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171453 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281454
[email protected]944b62f32012-09-27 02:20:461455 // Default vertex attribs manager, used when no VAOs are bound.
1456 VertexAttribManager::Ref default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301457
[email protected]b1122982010-05-17 23:04:241458 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1459 GLuint attrib_0_buffer_id_;
1460
1461 // The value currently in attrib_0.
1462 VertexAttribManager::VertexAttribInfo::Vec4 attrib_0_value_;
1463
[email protected]fc753442011-02-04 19:49:491464 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1465 bool attrib_0_buffer_matches_value_;
1466
[email protected]b1122982010-05-17 23:04:241467 // The size of attrib 0.
1468 GLsizei attrib_0_size_;
1469
[email protected]8fbedc02010-11-18 18:43:401470 // The buffer used to simulate GL_FIXED attribs.
1471 GLuint fixed_attrib_buffer_id_;
1472
1473 // The size of fiixed attrib buffer.
1474 GLsizei fixed_attrib_buffer_size_;
1475
[email protected]3a2e7c7b2010-08-06 01:12:281476 // state saved for clearing so we can clear render buffers and then
1477 // restore to these values.
[email protected]88a61bf2012-10-27 13:00:421478 bool clear_state_dirty_;
[email protected]3a2e7c7b2010-08-06 01:12:281479
[email protected]b9363b22010-06-09 22:06:151480 // The offscreen frame buffer that the client renders to. With EGL, the
1481 // depth and stencil buffers are separate. With regular GL there is a single
1482 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1483 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]6217d392010-03-25 22:08:351484 scoped_ptr<FrameBuffer> offscreen_target_frame_buffer_;
1485 scoped_ptr<Texture> offscreen_target_color_texture_;
[email protected]34ff8b0c2010-10-01 20:06:021486 scoped_ptr<RenderBuffer> offscreen_target_color_render_buffer_;
[email protected]b9363b22010-06-09 22:06:151487 scoped_ptr<RenderBuffer> offscreen_target_depth_render_buffer_;
1488 scoped_ptr<RenderBuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021489 GLenum offscreen_target_color_format_;
1490 GLenum offscreen_target_depth_format_;
1491 GLenum offscreen_target_stencil_format_;
1492 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561493 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351494
[email protected]de26b3c2011-08-03 21:54:271495 // The copy that is saved when SwapBuffers is called.
[email protected]34ff8b0c2010-10-01 20:06:021496 scoped_ptr<FrameBuffer> offscreen_saved_frame_buffer_;
[email protected]6217d392010-03-25 22:08:351497 scoped_ptr<Texture> offscreen_saved_color_texture_;
[email protected]8a61d872012-01-20 12:43:561498 TextureManager::TextureInfo::Ref offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271499
1500 // The copy that is used as the destination for multi-sample resolves.
1501 scoped_ptr<FrameBuffer> offscreen_resolved_frame_buffer_;
1502 scoped_ptr<Texture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051503 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351504
[email protected]882ba1e22012-03-08 19:02:531505 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531506
[email protected]944b62f32012-09-27 02:20:461507 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1508
[email protected]9d37f062011-11-22 01:24:521509 base::Callback<void(gfx::Size)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001510
[email protected]6b6e7ee2011-12-13 08:04:521511 MsgCallback msg_callback_;
[email protected]43f28f832010-02-03 02:28:481512
[email protected]b0af4f52011-09-28 22:04:421513 StreamTextureManager* stream_texture_manager_;
1514
[email protected]32fe9aa2011-01-21 23:47:131515 // The format of the back buffer_
1516 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461517 bool back_buffer_has_depth_;
1518 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131519
[email protected]473c01ccb2011-06-07 01:33:301520 bool teximage2d_faster_than_texsubimage2d_;
[email protected]473c01ccb2011-06-07 01:33:301521
[email protected]8eee29c2010-04-29 03:38:291522 // The last error message set.
1523 std::string last_error_;
1524
[email protected]0f8afe82012-05-14 23:43:011525 int log_message_count_;
[email protected]fa20ec82012-05-04 04:02:481526
[email protected]a3a93e7b2010-08-28 00:48:561527 // The current decoder error.
1528 error::Error current_decoder_error_;
1529
[email protected]d2a0e1a2012-08-12 02:25:011530 DebugMarkerManager debug_marker_manager_;
1531 std::string this_in_hex_;
1532
[email protected]b1d2dcb2010-05-17 19:24:181533 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041534 scoped_refptr<ShaderTranslator> vertex_translator_;
1535 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181536
[email protected]e82fb792011-09-22 00:33:291537 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411538
[email protected]915a59a12010-09-30 21:29:111539 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051540 const Validators* validators_;
[email protected]80eb6b52012-01-19 00:14:411541 FeatureInfo::Ref feature_info_;
[email protected]9438b012010-06-15 22:55:051542
[email protected]b493ee622011-04-13 23:52:001543 // This indicates all the following texSubImage2D calls that are part of the
1544 // failed texImage2D call should be ignored.
1545 bool tex_image_2d_failed_;
1546
[email protected]65225772011-05-12 21:10:241547 int frame_number_;
1548
[email protected]706b69f2012-07-27 04:59:301549 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431550 GLenum reset_status_;
1551
[email protected]f0d74742011-10-03 16:31:041552 // These flags are used to override the state of the shared feature_info_
1553 // member. Because the same FeatureInfo instance may be shared among many
1554 // contexts, the assumptions on the availablity of extensions in WebGL
1555 // contexts may be broken. These flags override the shared state to preserve
1556 // WebGL semantics.
1557 bool force_webgl_glsl_validation_;
1558 bool derivatives_explicitly_enabled_;
1559
[email protected]062c38b2012-01-18 03:25:101560 bool compile_shader_always_succeeds_;
1561
[email protected]e51bdf32011-11-23 22:21:461562#if defined(OS_MACOSX)
1563 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1564 TextureToIOSurfaceMap texture_to_io_surface_map_;
1565#endif
1566
[email protected]c826d732012-02-09 04:40:261567 typedef std::vector<GLES2DecoderImpl*> ChildList;
1568 ChildList children_;
1569
[email protected]43410e92012-04-20 17:06:281570 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1571
[email protected]1868a342012-11-07 15:56:021572 // Cached values of the currently assigned viewport dimensions.
1573 GLsizei viewport_max_width_;
1574 GLsizei viewport_max_height_;
1575
[email protected]63b465922012-09-06 02:04:521576 // Command buffer stats.
1577 int texture_upload_count_;
1578 base::TimeDelta total_texture_upload_time_;
1579 base::TimeDelta total_processing_commands_time_;
1580
[email protected]94307712012-11-16 23:26:111581 std::stack<linked_ptr<GPUTrace> > gpu_trace_stack_;
1582
[email protected]96449d2c2009-11-25 00:01:321583 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1584};
1585
[email protected]6217d392010-03-25 22:08:351586ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder)
1587 : decoder_(decoder) {
1588 decoder_->CopyRealGLErrorsToWrapper();
1589}
1590
1591ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
1592 decoder_->ClearRealGLErrors();
1593}
1594
1595ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1596 GLuint id)
1597 : decoder_(decoder) {
1598 ScopedGLErrorSuppressor suppressor(decoder_);
1599
1600 // TODO(apatrick): Check if there are any other states that need to be reset
1601 // before binding a new texture.
1602 glActiveTexture(GL_TEXTURE0);
1603 glBindTexture(GL_TEXTURE_2D, id);
1604}
1605
1606ScopedTexture2DBinder::~ScopedTexture2DBinder() {
1607 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301608 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351609}
1610
1611ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1612 GLuint id)
1613 : decoder_(decoder) {
1614 ScopedGLErrorSuppressor suppressor(decoder_);
1615 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1616}
1617
1618ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
1619 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301620 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351621}
1622
1623ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1624 GLuint id)
1625 : decoder_(decoder) {
1626 ScopedGLErrorSuppressor suppressor(decoder_);
1627 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
1628}
1629
1630ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
1631 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301632 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351633}
1634
[email protected]34ff8b0c2010-10-01 20:06:021635ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271636 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521637 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021638 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1639 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241640 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521641 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021642 if (!resolve_and_bind_)
1643 return;
1644
1645 ScopedGLErrorSuppressor suppressor(decoder_);
1646 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1647 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271648 GLuint targetid;
1649 if (internal) {
1650 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1651 decoder_->offscreen_resolved_frame_buffer_.reset(
1652 new FrameBuffer(decoder_));
1653 decoder_->offscreen_resolved_frame_buffer_->Create();
1654 decoder_->offscreen_resolved_color_texture_.reset(new Texture(decoder_));
1655 decoder_->offscreen_resolved_color_texture_->Create();
1656
1657 DCHECK(decoder_->offscreen_saved_color_format_);
1658 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
1659 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_);
[email protected]de26b3c2011-08-03 21:54:271660 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1661 decoder_->offscreen_resolved_color_texture_.get());
1662 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1663 GL_FRAMEBUFFER_COMPLETE) {
1664 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1665 << "because offscreen resolved FBO was incomplete.";
1666 return;
1667 }
1668 }
1669 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1670 } else {
1671 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1672 }
1673 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021674 const int width = decoder_->offscreen_size_.width();
1675 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181676 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151677 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021678 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1679 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1680 } else {
1681 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1682 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1683 }
[email protected]de26b3c2011-08-03 21:54:271684 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021685}
1686
1687ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1688 if (!resolve_and_bind_)
1689 return;
1690
1691 ScopedGLErrorSuppressor suppressor(decoder_);
1692 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221693 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181694 glEnable(GL_SCISSOR_TEST);
1695 }
[email protected]34ff8b0c2010-10-01 20:06:021696}
1697
[email protected]63b465922012-09-06 02:04:521698ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder)
1699 : decoder_(decoder),
1700 begin_time_(base::TimeTicks::HighResNow()) {
1701}
1702
1703ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1704 decoder_->texture_upload_count_++;
1705 decoder_->total_texture_upload_time_ +=
1706 base::TimeTicks::HighResNow() - begin_time_;
1707}
1708
[email protected]6217d392010-03-25 22:08:351709Texture::Texture(GLES2DecoderImpl* decoder)
1710 : decoder_(decoder),
[email protected]3e7951c2012-09-17 03:16:281711 memory_tracker_(decoder->GetContextGroup()->memory_tracker()),
[email protected]ff6493f2012-07-31 19:52:251712 id_(0) {
[email protected]6217d392010-03-25 22:08:351713}
1714
1715Texture::~Texture() {
1716 // This does not destroy the render texture because that would require that
1717 // the associated GL context was current. Just check that it was explicitly
1718 // destroyed.
1719 DCHECK_EQ(id_, 0u);
1720}
1721
1722void Texture::Create() {
1723 ScopedGLErrorSuppressor suppressor(decoder_);
1724 Destroy();
1725 glGenTextures(1, &id_);
[email protected]3a4d0c52011-06-29 23:11:581726 ScopedTexture2DBinder binder(decoder_, id_);
1727 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1728 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1729 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1730 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161731
1732 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1733 // never called on an offscreen context, no data will ever be uploaded to the
1734 // saved offscreen color texture (it is deferred until to when SwapBuffers
1735 // is called). My idea is that some nvidia drivers might have a bug where
1736 // deleting a texture that has never been populated might cause a
1737 // crash.
1738 glTexImage2D(
1739 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]ff6493f2012-07-31 19:52:251740 memory_tracker_.UpdateMemRepresented(16u * 16u * 4u);
[email protected]6217d392010-03-25 22:08:351741}
1742
[email protected]34ff8b0c2010-10-01 20:06:021743bool Texture::AllocateStorage(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351744 DCHECK_NE(id_, 0u);
1745 ScopedGLErrorSuppressor suppressor(decoder_);
1746 ScopedTexture2DBinder binder(decoder_, id_);
[email protected]6217d392010-03-25 22:08:351747
[email protected]f0e6a34f2012-01-04 20:53:401748 WrappedTexImage2D(GL_TEXTURE_2D,
1749 0, // mip level
1750 format,
1751 size.width(),
1752 size.height(),
1753 0, // border
1754 format,
1755 GL_UNSIGNED_BYTE,
1756 NULL);
[email protected]6217d392010-03-25 22:08:351757
[email protected]d37231fa2010-04-09 21:16:021758 size_ = size;
1759
[email protected]1078f912011-12-23 13:12:141760 bool success = glGetError() == GL_NO_ERROR;
1761 if (success) {
1762 uint32 image_size = 0;
[email protected]3458a64a2012-04-10 17:39:341763 GLES2Util::ComputeImageDataSizes(
1764 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 4, &image_size,
1765 NULL, NULL);
[email protected]ff6493f2012-07-31 19:52:251766 memory_tracker_.UpdateMemRepresented(image_size);
[email protected]1078f912011-12-23 13:12:141767 }
1768 return success;
[email protected]6217d392010-03-25 22:08:351769}
1770
[email protected]3a4d0c52011-06-29 23:11:581771void Texture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351772 DCHECK_NE(id_, 0u);
1773 ScopedGLErrorSuppressor suppressor(decoder_);
1774 ScopedTexture2DBinder binder(decoder_, id_);
1775 glCopyTexImage2D(GL_TEXTURE_2D,
1776 0, // level
[email protected]3a4d0c52011-06-29 23:11:581777 format,
[email protected]6217d392010-03-25 22:08:351778 0, 0,
1779 size.width(),
1780 size.height(),
1781 0); // border
1782}
1783
1784void Texture::Destroy() {
1785 if (id_ != 0) {
1786 ScopedGLErrorSuppressor suppressor(decoder_);
1787 glDeleteTextures(1, &id_);
1788 id_ = 0;
[email protected]ff6493f2012-07-31 19:52:251789 memory_tracker_.UpdateMemRepresented(0);
[email protected]6217d392010-03-25 22:08:351790 }
1791}
1792
[email protected]97872062010-11-03 19:07:051793void Texture::Invalidate() {
1794 id_ = 0;
1795}
1796
[email protected]6217d392010-03-25 22:08:351797RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder)
1798 : decoder_(decoder),
[email protected]3e7951c2012-09-17 03:16:281799 memory_tracker_(decoder->GetContextGroup()->memory_tracker()),
[email protected]ff6493f2012-07-31 19:52:251800 id_(0) {
[email protected]6217d392010-03-25 22:08:351801}
1802
1803RenderBuffer::~RenderBuffer() {
1804 // This does not destroy the render buffer because that would require that
1805 // the associated GL context was current. Just check that it was explicitly
1806 // destroyed.
1807 DCHECK_EQ(id_, 0u);
1808}
1809
1810void RenderBuffer::Create() {
1811 ScopedGLErrorSuppressor suppressor(decoder_);
1812 Destroy();
1813 glGenRenderbuffersEXT(1, &id_);
1814}
1815
[email protected]34ff8b0c2010-10-01 20:06:021816bool RenderBuffer::AllocateStorage(const gfx::Size& size, GLenum format,
1817 GLsizei samples) {
[email protected]6217d392010-03-25 22:08:351818 ScopedGLErrorSuppressor suppressor(decoder_);
1819 ScopedRenderBufferBinder binder(decoder_, id_);
[email protected]34ff8b0c2010-10-01 20:06:021820 if (samples <= 1) {
1821 glRenderbufferStorageEXT(GL_RENDERBUFFER,
1822 format,
1823 size.width(),
1824 size.height());
1825 } else {
[email protected]57edfdad2012-02-07 04:57:151826 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021827 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
1828 samples,
1829 format,
1830 size.width(),
1831 size.height());
1832 } else {
1833 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
1834 samples,
1835 format,
1836 size.width(),
1837 size.height());
1838 }
1839 }
[email protected]1078f912011-12-23 13:12:141840 bool success = glGetError() == GL_NO_ERROR;
1841 if (success) {
[email protected]ff6493f2012-07-31 19:52:251842 memory_tracker_.UpdateMemRepresented(
1843 size.width() * size.height() * samples *
1844 GLES2Util::RenderbufferBytesPerPixel(format));
[email protected]1078f912011-12-23 13:12:141845 }
1846 return success;
[email protected]6217d392010-03-25 22:08:351847}
1848
1849void RenderBuffer::Destroy() {
1850 if (id_ != 0) {
1851 ScopedGLErrorSuppressor suppressor(decoder_);
1852 glDeleteRenderbuffersEXT(1, &id_);
1853 id_ = 0;
[email protected]ff6493f2012-07-31 19:52:251854 memory_tracker_.UpdateMemRepresented(0);
[email protected]6217d392010-03-25 22:08:351855 }
1856}
1857
[email protected]97872062010-11-03 19:07:051858void RenderBuffer::Invalidate() {
1859 id_ = 0;
1860}
1861
[email protected]6217d392010-03-25 22:08:351862FrameBuffer::FrameBuffer(GLES2DecoderImpl* decoder)
1863 : decoder_(decoder),
1864 id_(0) {
1865}
1866
1867FrameBuffer::~FrameBuffer() {
1868 // This does not destroy the frame buffer because that would require that
1869 // the associated GL context was current. Just check that it was explicitly
1870 // destroyed.
1871 DCHECK_EQ(id_, 0u);
1872}
1873
1874void FrameBuffer::Create() {
1875 ScopedGLErrorSuppressor suppressor(decoder_);
1876 Destroy();
1877 glGenFramebuffersEXT(1, &id_);
1878}
1879
1880void FrameBuffer::AttachRenderTexture(Texture* texture) {
1881 DCHECK_NE(id_, 0u);
1882 ScopedGLErrorSuppressor suppressor(decoder_);
1883 ScopedFrameBufferBinder binder(decoder_, id_);
1884 GLuint attach_id = texture ? texture->id() : 0;
1885 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
1886 GL_COLOR_ATTACHMENT0,
1887 GL_TEXTURE_2D,
1888 attach_id,
1889 0);
1890}
1891
[email protected]b9363b22010-06-09 22:06:151892void FrameBuffer::AttachRenderBuffer(GLenum target,
1893 RenderBuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:351894 DCHECK_NE(id_, 0u);
1895 ScopedGLErrorSuppressor suppressor(decoder_);
1896 ScopedFrameBufferBinder binder(decoder_, id_);
1897 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
1898 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:151899 target,
[email protected]6217d392010-03-25 22:08:351900 GL_RENDERBUFFER,
1901 attach_id);
1902}
1903
[email protected]6217d392010-03-25 22:08:351904void FrameBuffer::Destroy() {
1905 if (id_ != 0) {
1906 ScopedGLErrorSuppressor suppressor(decoder_);
1907 glDeleteFramebuffersEXT(1, &id_);
1908 id_ = 0;
1909 }
1910}
1911
[email protected]97872062010-11-03 19:07:051912void FrameBuffer::Invalidate() {
1913 id_ = 0;
1914}
1915
[email protected]6217d392010-03-25 22:08:351916GLenum FrameBuffer::CheckStatus() {
1917 DCHECK_NE(id_, 0u);
1918 ScopedGLErrorSuppressor suppressor(decoder_);
1919 ScopedFrameBufferBinder binder(decoder_, id_);
1920 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
1921}
1922
[email protected]aa7666122011-09-02 19:45:521923GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
1924 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:321925}
1926
[email protected]aa7666122011-09-02 19:45:521927GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:391928 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:571929 group_(group),
[email protected]96449d2c2009-11-25 00:01:321930 error_bits_(0),
[email protected]43410e92012-04-20 17:06:281931 unpack_flip_y_(false),
1932 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:171933 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:241934 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:491935 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:241936 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:401937 fixed_attrib_buffer_id_(0),
1938 fixed_attrib_buffer_size_(0),
[email protected]88a61bf2012-10-27 13:00:421939 clear_state_dirty_(true),
[email protected]34ff8b0c2010-10-01 20:06:021940 offscreen_target_color_format_(0),
1941 offscreen_target_depth_format_(0),
1942 offscreen_target_stencil_format_(0),
1943 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:561944 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:051945 offscreen_saved_color_format_(0),
[email protected]b0af4f52011-09-28 22:04:421946 stream_texture_manager_(NULL),
[email protected]32fe9aa2011-01-21 23:47:131947 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:461948 back_buffer_has_depth_(false),
1949 back_buffer_has_stencil_(false),
[email protected]473c01ccb2011-06-07 01:33:301950 teximage2d_faster_than_texsubimage2d_(true),
[email protected]0f8afe82012-05-14 23:43:011951 log_message_count_(0),
[email protected]a3a93e7b2010-08-28 00:48:561952 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:051953 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:111954 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:001955 feature_info_(group_->feature_info()),
[email protected]65225772011-05-12 21:10:241956 tex_image_2d_failed_(false),
[email protected]38d139d2011-07-14 00:38:431957 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:301958 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:511959 reset_status_(GL_NO_ERROR),
[email protected]f0d74742011-10-03 16:31:041960 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:101961 derivatives_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:281962 compile_shader_always_succeeds_(false),
[email protected]1868a342012-11-07 15:56:021963 viewport_max_width_(0),
1964 viewport_max_height_(0),
[email protected]63b465922012-09-06 02:04:521965 texture_upload_count_(0) {
[email protected]3b1ecc262011-08-03 22:49:571966 DCHECK(group);
1967
[email protected]d2a0e1a2012-08-12 02:25:011968 GLES2DecoderImpl* this_temp = this;
1969 this_in_hex_ = HexEncode(&this_temp, sizeof(this_temp));
1970
[email protected]b1122982010-05-17 23:04:241971 attrib_0_value_.v[0] = 0.0f;
1972 attrib_0_value_.v[1] = 0.0f;
1973 attrib_0_value_.v[2] = 0.0f;
1974 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:151975
[email protected]c2f8c8402010-12-06 18:07:241976 // The shader translator is used for WebGL even when running on EGL
1977 // because additional restrictions are needed (like only enabling
1978 // GL_OES_standard_derivatives on demand). It is used for the unit
1979 // tests because
1980 // GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes the
1981 // empty string to CompileShader and this is not a valid shader.
1982 // TODO(apatrick): fix this test.
1983 if ((gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
[email protected]62e155e2012-10-23 22:43:151984 !features().chromium_webglsl && !force_webgl_glsl_validation_) ||
[email protected]39ba4f02012-03-26 01:16:001985 gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
1986 CommandLine::ForCurrentProcess()->HasSwitch(
1987 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:151988 use_shader_translator_ = false;
1989 }
[email protected]473c01ccb2011-06-07 01:33:301990
[email protected]a39370652012-09-25 21:52:131991 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:301992 if (IsAngle()) {
1993 teximage2d_faster_than_texsubimage2d_ = false;
[email protected]473c01ccb2011-06-07 01:33:301994 }
[email protected]96449d2c2009-11-25 00:01:321995}
1996
[email protected]80eb6b52012-01-19 00:14:411997GLES2DecoderImpl::~GLES2DecoderImpl() {
1998}
1999
[email protected]c410da802011-03-14 19:17:412000bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382001 const scoped_refptr<gfx::GLSurface>& surface,
2002 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232003 bool offscreen,
[email protected]c410da802011-03-14 19:17:412004 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292005 const DisallowedFeatures& disallowed_features,
[email protected]c410da802011-03-14 19:17:412006 const char* allowed_extensions,
[email protected]3c644d82011-06-20 19:58:242007 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322008 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382009 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302010 DCHECK(!context_.get());
2011
[email protected]e844ae22012-01-14 03:36:262012 if (CommandLine::ForCurrentProcess()->HasSwitch(
2013 switches::kEnableGPUDebugging)) {
2014 set_debug(true);
2015 }
2016
[email protected]39ba4f02012-03-26 01:16:002017 if (CommandLine::ForCurrentProcess()->HasSwitch(
2018 switches::kEnableGPUCommandLogging)) {
2019 set_log_commands(true);
2020 }
2021
[email protected]062c38b2012-01-18 03:25:102022 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2023 switches::kCompileShaderAlwaysSucceeds);
2024
[email protected]f62a5ab2011-05-23 20:34:152025
[email protected]63c9b052012-05-17 18:27:382026 // Take ownership of the context and surface. The surface can be replaced with
2027 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382028 context_ = context;
[email protected]63c9b052012-05-17 18:27:382029 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182030
[email protected]e82fb792011-09-22 00:33:292031 if (!group_->Initialize(disallowed_features, allowed_extensions)) {
[email protected]09ddb91f2011-04-14 23:16:222032 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392033 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422034 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382035 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032036 return false;
[email protected]a3ded6d2010-10-19 06:44:392037 }
[email protected]b64c24952012-04-19 03:20:272038 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282039
[email protected]e82fb792011-09-22 00:33:292040 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502041
[email protected]944b62f32012-09-27 02:20:462042 default_vertex_attrib_manager_ = new VertexAttribManager();
2043 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2044
[email protected]ab4fd7282012-10-12 16:25:572045 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2046 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322047
[email protected]d6ca4792012-05-14 19:24:132048 query_manager_.reset(new QueryManager(this, feature_info_));
[email protected]944b62f32012-09-27 02:20:462049 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532050
[email protected]302ce6d2011-07-07 23:28:112051 util_.set_num_compressed_texture_formats(
2052 validators_->compressed_texture_format.GetValues().size());
2053
[email protected]1071e572011-02-09 20:00:122054 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2055 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2056 // OpenGL ES 2.0 does not have this issue.
2057 glEnableVertexAttribArray(0);
2058 }
[email protected]b1122982010-05-17 23:04:242059 glGenBuffersARB(1, &attrib_0_buffer_id_);
2060 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2061 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2062 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402063 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082064
[email protected]1868a342012-11-07 15:56:022065 state_.texture_units.resize(group_->max_texture_units());
2066 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492067 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312068 // We want the last bind to be 2D.
2069 TextureManager::TextureInfo* info;
[email protected]62e155e2012-10-23 22:43:152070 if (features().oes_egl_image_external) {
[email protected]61eeb33f2011-07-26 15:30:312071 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_EXTERNAL_OES);
[email protected]e259eb412012-10-13 05:47:242072 state_.texture_units[tt].bound_texture_external_oes = info;
[email protected]61eeb33f2011-07-26 15:30:312073 glBindTexture(GL_TEXTURE_EXTERNAL_OES, info->service_id());
2074 }
[email protected]62e155e2012-10-23 22:43:152075 if (features().arb_texture_rectangle) {
[email protected]e51bdf32011-11-23 22:21:462076 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_RECTANGLE_ARB);
[email protected]e259eb412012-10-13 05:47:242077 state_.texture_units[tt].bound_texture_rectangle_arb = info;
[email protected]e51bdf32011-11-23 22:21:462078 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, info->service_id());
2079 }
[email protected]61eeb33f2011-07-26 15:30:312080 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
[email protected]e259eb412012-10-13 05:47:242081 state_.texture_units[tt].bound_texture_cube_map = info;
[email protected]00f893d2010-08-24 18:55:492082 glBindTexture(GL_TEXTURE_CUBE_MAP, info->service_id());
2083 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
[email protected]e259eb412012-10-13 05:47:242084 state_.texture_units[tt].bound_texture_2d = info;
[email protected]00f893d2010-08-24 18:55:492085 glBindTexture(GL_TEXTURE_2D, info->service_id());
[email protected]1958e0e2010-04-22 05:17:152086 }
[email protected]00f893d2010-08-24 18:55:492087 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502088 CHECK_GL_ERROR();
2089
[email protected]297ca1c2011-06-20 23:08:462090 ContextCreationAttribParser attrib_parser;
2091 if (!attrib_parser.Parse(attribs))
2092 return false;
[email protected]41c56362011-06-14 16:47:432093
[email protected]297ca1c2011-06-20 23:08:462094 // These are NOT if the back buffer has these proprorties. They are
2095 // if we want the command buffer to enforce them regardless of what
2096 // the real backbuffer is assuming the real back buffer gives us more than
2097 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2098 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2099 // can't do anything about that.
2100
2101 GLint v = 0;
2102 glGetIntegerv(GL_ALPHA_BITS, &v);
2103 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2104 // user requested RGB then RGB. If the user did not specify a preference than
2105 // use whatever we were given. Same for DEPTH and STENCIL.
2106 back_buffer_color_format_ =
2107 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2108 glGetIntegerv(GL_DEPTH_BITS, &v);
2109 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2110 glGetIntegerv(GL_STENCIL_BITS, &v);
2111 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
2112
[email protected]069944672012-04-25 20:52:232113 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022114 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]53862ed2010-10-25 19:22:542115 (context_->HasExtension("GL_EXT_framebuffer_multisample") ||
[email protected]34ff8b0c2010-10-01 20:06:022116 context_->HasExtension("GL_ANGLE_framebuffer_multisample"))) {
2117 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432118 // max_sample_count must be initialized to a sane value. If
2119 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2120 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022121 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2122 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2123 max_sample_count);
2124 } else {
2125 offscreen_target_samples_ = 1;
2126 }
[email protected]8a61d872012-01-20 12:43:562127 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022128
2129 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2130 const bool rgb8_supported =
2131 context_->HasExtension("GL_OES_rgb8_rgba8");
2132 // The only available default render buffer formats in GLES2 have very
2133 // little precision. Don't enable multisampling unless 8-bit render
2134 // buffer formats are available--instead fall back to 8-bit textures.
2135 if (rgb8_supported && offscreen_target_samples_ > 1) {
2136 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2137 GL_RGBA8 : GL_RGB8;
2138 } else {
2139 offscreen_target_samples_ = 1;
2140 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2141 GL_RGBA : GL_RGB;
2142 }
2143
2144 // ANGLE only supports packed depth/stencil formats, so use it if it is
2145 // available.
2146 const bool depth24_stencil8_supported =
2147 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272148 VLOG(1) << "GL_OES_packed_depth_stencil "
2149 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002150 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2151 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022152 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2153 offscreen_target_stencil_format_ = 0;
2154 } else {
2155 // It may be the case that this depth/stencil combination is not
2156 // supported, but this will be checked later by CheckFramebufferStatus.
2157 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2158 GL_DEPTH_COMPONENT16 : 0;
2159 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2160 GL_STENCIL_INDEX8 : 0;
2161 }
2162 } else {
2163 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2164 GL_RGBA : GL_RGB;
2165
2166 // If depth is requested at all, use the packed depth stencil format if
2167 // it's available, as some desktop GL drivers don't support any non-packed
2168 // formats for depth attachments.
2169 const bool depth24_stencil8_supported =
2170 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272171 VLOG(1) << "GL_EXT_packed_depth_stencil "
2172 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022173
[email protected]71ee3642010-10-14 18:08:002174 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2175 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022176 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2177 offscreen_target_stencil_format_ = 0;
2178 } else {
2179 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2180 GL_DEPTH_COMPONENT : 0;
2181 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2182 GL_STENCIL_INDEX : 0;
2183 }
2184 }
2185
[email protected]97872062010-11-03 19:07:052186 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2187 GL_RGBA : GL_RGB;
2188
[email protected]6217d392010-03-25 22:08:352189 // Create the target frame buffer. This is the one that the client renders
2190 // directly to.
2191 offscreen_target_frame_buffer_.reset(new FrameBuffer(this));
2192 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022193 // Due to GLES2 format limitations, either the color texture (for
2194 // non-multisampling) or the color render buffer (for multisampling) will be
2195 // attached to the offscreen frame buffer. The render buffer has more
2196 // limited formats available to it, but the texture can't do multisampling.
2197 if (IsOffscreenBufferMultisampled()) {
2198 offscreen_target_color_render_buffer_.reset(new RenderBuffer(this));
2199 offscreen_target_color_render_buffer_->Create();
2200 } else {
2201 offscreen_target_color_texture_.reset(new Texture(this));
2202 offscreen_target_color_texture_->Create();
2203 }
2204 offscreen_target_depth_render_buffer_.reset(new RenderBuffer(this));
[email protected]b9363b22010-06-09 22:06:152205 offscreen_target_depth_render_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022206 offscreen_target_stencil_render_buffer_.reset(new RenderBuffer(this));
[email protected]b9363b22010-06-09 22:06:152207 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352208
2209 // Create the saved offscreen texture. The target frame buffer is copied
2210 // here when SwapBuffers is called.
[email protected]34ff8b0c2010-10-01 20:06:022211 offscreen_saved_frame_buffer_.reset(new FrameBuffer(this));
2212 offscreen_saved_frame_buffer_->Create();
2213 //
[email protected]6217d392010-03-25 22:08:352214 offscreen_saved_color_texture_.reset(new Texture(this));
2215 offscreen_saved_color_texture_->Create();
2216
[email protected]6217d392010-03-25 22:08:352217 // Allocate the render buffers at their initial size and check the status
2218 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592219 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012220 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382221 Destroy(true);
[email protected]6217d392010-03-25 22:08:352222 return false;
2223 }
2224
2225 // Bind to the new default frame buffer (the offscreen target frame buffer).
2226 // This should now be associated with ID zero.
2227 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2228 }
2229
[email protected]295faf4b2012-01-25 23:31:412230 // Clear the backbuffer.
2231 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2232
[email protected]76a0ee102010-04-07 21:03:042233 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2234 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2235 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372236 // mailing list archives. It also implicitly enables the desktop GL
2237 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2238 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152239 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2240 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372241 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152242 }
[email protected]de17df392010-04-23 21:09:412243
[email protected]706b69f2012-07-27 04:59:302244 has_robustness_extension_ =
2245 context->HasExtension("GL_ARB_robustness") ||
2246 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432247
[email protected]c2f8c8402010-12-06 18:07:242248 if (!InitializeShaderTranslator()) {
2249 return false;
[email protected]de17df392010-04-23 21:09:412250 }
[email protected]76a0ee102010-04-07 21:03:042251
[email protected]e259eb412012-10-13 05:47:242252 state_.viewport_width = size.width();
2253 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282254
[email protected]5904806b2012-05-08 18:10:222255 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282256 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022257 viewport_max_width_ = viewport_params[0];
2258 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282259
[email protected]88a61bf2012-10-27 13:00:422260 state_.scissor_width = state_.viewport_width;
2261 state_.scissor_height = state_.viewport_height;
2262
[email protected]11f3e702012-06-19 19:00:012263 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222264 state_.InitCapabilities();
2265 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242266 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]88a61bf2012-10-27 13:00:422267 glHint(GL_GENERATE_MIPMAP_HINT, state_.hint_generate_mipmap);
[email protected]e259eb412012-10-13 05:47:242268 glPixelStorei(GL_PACK_ALIGNMENT, state_.pack_alignment);
[email protected]e259eb412012-10-13 05:47:242269 glPixelStorei(GL_UNPACK_ALIGNMENT, state_.unpack_alignment);
[email protected]11f3e702012-06-19 19:00:012270
2271 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2272 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2273 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2274 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2275
[email protected]6d9374e2012-07-17 03:31:242276 // AMD and Intel drivers on Mac OS apparently get gl_PointCoord
2277 // backward from the spec and this setting makes them work
2278 // correctly. rdar://problem/11883495
[email protected]62e155e2012-10-23 22:43:152279 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462280 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2281 }
[email protected]dd289a5d62012-06-30 22:05:462282
[email protected]246a70452010-03-05 21:53:502283 return true;
[email protected]96449d2c2009-11-25 00:01:322284}
2285
[email protected]302ce6d2011-07-07 23:28:112286void GLES2DecoderImpl::UpdateCapabilities() {
2287 util_.set_num_compressed_texture_formats(
2288 validators_->compressed_texture_format.GetValues().size());
2289 util_.set_num_shader_binary_formats(
2290 validators_->shader_binary_format.GetValues().size());
2291}
2292
[email protected]c2f8c8402010-12-06 18:07:242293bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442294 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2295
[email protected]c2f8c8402010-12-06 18:07:242296 // Re-check the state of use_shader_translator_ each time this is called.
2297 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
[email protected]62e155e2012-10-23 22:43:152298 (features().chromium_webglsl || force_webgl_glsl_validation_) &&
[email protected]c2f8c8402010-12-06 18:07:242299 !use_shader_translator_) {
2300 use_shader_translator_ = true;
2301 }
2302 if (!use_shader_translator_) {
2303 return true;
2304 }
2305 ShBuiltInResources resources;
2306 ShInitBuiltInResources(&resources);
2307 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2308 resources.MaxVertexUniformVectors =
2309 group_->max_vertex_uniform_vectors();
2310 resources.MaxVaryingVectors = group_->max_varying_vectors();
2311 resources.MaxVertexTextureImageUnits =
2312 group_->max_vertex_texture_image_units();
2313 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2314 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2315 resources.MaxFragmentUniformVectors =
2316 group_->max_fragment_uniform_vectors();
2317 resources.MaxDrawBuffers = 1;
[email protected]f0d74742011-10-03 16:31:042318
2319 if (force_webgl_glsl_validation_) {
2320 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
2321 } else {
2322 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152323 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462324 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152325 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062326 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152327 features().oes_egl_image_external ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042328 }
2329
[email protected]693ca512012-11-13 18:09:132330 if (features().enable_shader_name_hashing)
2331 resources.HashFunction = &CityHashForAngle;
2332
[email protected]f0d74742011-10-03 16:31:042333 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ||
[email protected]62e155e2012-10-23 22:43:152334 features().chromium_webglsl ? SH_WEBGL_SPEC : SH_GLES2_SPEC;
[email protected]a2a0fe762011-09-20 00:59:122335 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2336 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2337 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2338 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
[email protected]62e155e2012-10-23 22:43:152339 workarounds().needs_glsl_built_in_function_emulation ?
[email protected]a2a0fe762011-09-20 00:59:122340 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
2341 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
[email protected]87fb6ab2012-06-13 22:28:042342
2343 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2344 vertex_translator_ = cache->GetTranslator(
2345 SH_VERTEX_SHADER, shader_spec, &resources,
2346 implementation_type, function_behavior);
2347 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242348 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382349 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242350 return false;
2351 }
[email protected]87fb6ab2012-06-13 22:28:042352
2353 fragment_translator_ = cache->GetTranslator(
2354 SH_FRAGMENT_SHADER, shader_spec, &resources,
2355 implementation_type, function_behavior);
2356 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242357 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382358 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242359 return false;
2360 }
2361 return true;
2362}
2363
[email protected]ae51d192010-04-27 00:48:032364bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472365 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ae51d192010-04-27 00:48:032366 if (GetBufferInfo(client_ids[ii])) {
2367 return false;
2368 }
2369 }
2370 scoped_array<GLuint> service_ids(new GLuint[n]);
2371 glGenBuffersARB(n, service_ids.get());
2372 for (GLsizei ii = 0; ii < n; ++ii) {
2373 CreateBufferInfo(client_ids[ii], service_ids[ii]);
2374 }
2375 return true;
2376}
2377
2378bool GLES2DecoderImpl::GenFramebuffersHelper(
2379 GLsizei n, const GLuint* client_ids) {
2380 for (GLsizei ii = 0; ii < n; ++ii) {
2381 if (GetFramebufferInfo(client_ids[ii])) {
2382 return false;
2383 }
2384 }
2385 scoped_array<GLuint> service_ids(new GLuint[n]);
2386 glGenFramebuffersEXT(n, service_ids.get());
2387 for (GLsizei ii = 0; ii < n; ++ii) {
2388 CreateFramebufferInfo(client_ids[ii], service_ids[ii]);
2389 }
2390 return true;
2391}
2392
2393bool GLES2DecoderImpl::GenRenderbuffersHelper(
2394 GLsizei n, const GLuint* client_ids) {
2395 for (GLsizei ii = 0; ii < n; ++ii) {
2396 if (GetRenderbufferInfo(client_ids[ii])) {
2397 return false;
2398 }
2399 }
2400 scoped_array<GLuint> service_ids(new GLuint[n]);
2401 glGenRenderbuffersEXT(n, service_ids.get());
2402 for (GLsizei ii = 0; ii < n; ++ii) {
2403 CreateRenderbufferInfo(client_ids[ii], service_ids[ii]);
2404 }
2405 return true;
2406}
2407
2408bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2409 for (GLsizei ii = 0; ii < n; ++ii) {
2410 if (GetTextureInfo(client_ids[ii])) {
2411 return false;
2412 }
2413 }
2414 scoped_array<GLuint> service_ids(new GLuint[n]);
2415 glGenTextures(n, service_ids.get());
2416 for (GLsizei ii = 0; ii < n; ++ii) {
2417 CreateTextureInfo(client_ids[ii], service_ids[ii]);
2418 }
2419 return true;
2420}
2421
2422void GLES2DecoderImpl::DeleteBuffersHelper(
2423 GLsizei n, const GLuint* client_ids) {
2424 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102425 BufferManager::BufferInfo* buffer = GetBufferInfo(client_ids[ii]);
2426 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242427 state_.vertex_attrib_manager->Unbind(buffer);
2428 if (state_.bound_array_buffer == buffer) {
2429 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102430 }
[email protected]ae51d192010-04-27 00:48:032431 RemoveBufferInfo(client_ids[ii]);
2432 }
[email protected]a93bb842010-02-16 23:03:472433 }
[email protected]07f54fcc2009-12-22 02:46:302434}
2435
[email protected]ae51d192010-04-27 00:48:032436void GLES2DecoderImpl::DeleteFramebuffersHelper(
2437 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452438 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152439 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112440
[email protected]a25fa872010-03-25 02:57:582441 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102442 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ae51d192010-04-27 00:48:032443 GetFramebufferInfo(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102444 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242445 if (framebuffer == state_.bound_draw_framebuffer) {
2446 state_.bound_draw_framebuffer = NULL;
[email protected]88a61bf2012-10-27 13:00:422447 clear_state_dirty_ = true;
[email protected]ebfb73c2012-08-15 02:37:452448 GLenum target = supports_separate_framebuffer_binds ?
2449 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112450 glBindFramebufferEXT(target, GetBackbufferServiceId());
2451 }
[email protected]e259eb412012-10-13 05:47:242452 if (framebuffer == state_.bound_read_framebuffer) {
2453 state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452454 GLenum target = supports_separate_framebuffer_binds ?
2455 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112456 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462457 }
[email protected]ae51d192010-04-27 00:48:032458 RemoveFramebufferInfo(client_ids[ii]);
2459 }
[email protected]a25fa872010-03-25 02:57:582460 }
[email protected]07f54fcc2009-12-22 02:46:302461}
2462
[email protected]ae51d192010-04-27 00:48:032463void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2464 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452465 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152466 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582467 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102468 RenderbufferManager::RenderbufferInfo* renderbuffer =
[email protected]ae51d192010-04-27 00:48:032469 GetRenderbufferInfo(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102470 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242471 if (state_.bound_renderbuffer == renderbuffer) {
2472 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102473 }
2474 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452475 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242476 if (state_.bound_read_framebuffer) {
2477 state_.bound_read_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452478 GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102479 }
[email protected]e259eb412012-10-13 05:47:242480 if (state_.bound_draw_framebuffer) {
2481 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452482 GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102483 }
2484 } else {
[email protected]e259eb412012-10-13 05:47:242485 if (state_.bound_draw_framebuffer) {
2486 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]a0b78dc2011-11-11 10:43:102487 GL_FRAMEBUFFER, renderbuffer);
2488 }
2489 }
[email protected]88a61bf2012-10-27 13:00:422490 clear_state_dirty_ = true;
[email protected]ae51d192010-04-27 00:48:032491 RemoveRenderbufferInfo(client_ids[ii]);
2492 }
[email protected]a25fa872010-03-25 02:57:582493 }
[email protected]07f54fcc2009-12-22 02:46:302494}
2495
[email protected]ae51d192010-04-27 00:48:032496void GLES2DecoderImpl::DeleteTexturesHelper(
2497 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452498 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152499 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472500 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102501 TextureManager::TextureInfo* texture = GetTextureInfo(client_ids[ii]);
2502 if (texture && !texture->IsDeleted()) {
2503 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:422504 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462505 }
[email protected]a0b78dc2011-11-11 10:43:102506 // Unbind texture from texture units.
[email protected]1868a342012-11-07 15:56:022507 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]e259eb412012-10-13 05:47:242508 state_.texture_units[jj].Unbind(texture);
[email protected]a0b78dc2011-11-11 10:43:102509 }
2510 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452511 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242512 if (state_.bound_read_framebuffer) {
2513 state_.bound_read_framebuffer->UnbindTexture(
[email protected]ebfb73c2012-08-15 02:37:452514 GL_READ_FRAMEBUFFER_EXT, texture);
[email protected]a0b78dc2011-11-11 10:43:102515 }
[email protected]e259eb412012-10-13 05:47:242516 if (state_.bound_draw_framebuffer) {
2517 state_.bound_draw_framebuffer->UnbindTexture(
[email protected]ebfb73c2012-08-15 02:37:452518 GL_DRAW_FRAMEBUFFER_EXT, texture);
[email protected]a0b78dc2011-11-11 10:43:102519 }
2520 } else {
[email protected]e259eb412012-10-13 05:47:242521 if (state_.bound_draw_framebuffer) {
2522 state_.bound_draw_framebuffer->UnbindTexture(GL_FRAMEBUFFER, texture);
[email protected]a0b78dc2011-11-11 10:43:102523 }
2524 }
2525 GLuint service_id = texture->service_id();
2526 if (texture->IsStreamTexture() && stream_texture_manager_) {
[email protected]b0af4f52011-09-28 22:04:422527 stream_texture_manager_->DestroyStreamTexture(service_id);
2528 }
[email protected]e51bdf32011-11-23 22:21:462529#if defined(OS_MACOSX)
2530 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2531 ReleaseIOSurfaceForTexture(service_id);
2532 }
2533#endif
[email protected]ae51d192010-04-27 00:48:032534 RemoveTextureInfo(client_ids[ii]);
2535 }
[email protected]a93bb842010-02-16 23:03:472536 }
[email protected]07f54fcc2009-12-22 02:46:302537}
2538
[email protected]43f28f832010-02-03 02:28:482539// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322540
[email protected]eb54a562010-01-20 21:55:182541bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382542 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2543 return false;
2544
2545 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432546 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]63c9b052012-05-17 18:27:382547 return false;
[email protected]38d139d2011-07-14 00:38:432548 }
2549
[email protected]63c9b052012-05-17 18:27:382550 return true;
[email protected]eb54a562010-01-20 21:55:182551}
2552
[email protected]a96a6022011-11-04 00:58:122553void GLES2DecoderImpl::ReleaseCurrent() {
2554 if (context_.get())
2555 context_->ReleaseCurrent(surface_.get());
2556}
2557
[email protected]8e3e0662010-08-23 18:46:302558void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
[email protected]0d6bfdc2011-11-02 01:32:202559 RenderbufferManager::RenderbufferInfo* renderbuffer =
2560 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
[email protected]8e3e0662010-08-23 18:46:302561 glBindRenderbufferEXT(
[email protected]0d6bfdc2011-11-02 01:32:202562 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
[email protected]8e3e0662010-08-23 18:46:302563}
2564
2565static void RebindCurrentFramebuffer(
2566 GLenum target,
2567 FramebufferManager::FramebufferInfo* info,
[email protected]a3783712012-01-20 22:18:242568 GLuint back_buffer_service_id) {
[email protected]8e3e0662010-08-23 18:46:302569 GLuint framebuffer_id = info ? info->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462570
[email protected]a3783712012-01-20 22:18:242571 if (framebuffer_id == 0) {
2572 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302573 }
[email protected]297ca1c2011-06-20 23:08:462574
[email protected]8e3e0662010-08-23 18:46:302575 glBindFramebufferEXT(target, framebuffer_id);
2576}
2577
2578void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]88a61bf2012-10-27 13:00:422579 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462580
[email protected]62e155e2012-10-23 22:43:152581 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302582 RebindCurrentFramebuffer(
2583 GL_FRAMEBUFFER,
[email protected]e259eb412012-10-13 05:47:242584 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242585 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302586 } else {
2587 RebindCurrentFramebuffer(
2588 GL_READ_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242589 state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242590 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302591 RebindCurrentFramebuffer(
2592 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242593 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242594 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302595 }
2596}
2597
2598void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
[email protected]e259eb412012-10-13 05:47:242599 TextureUnit& info = state_.texture_units[0];
[email protected]8e3e0662010-08-23 18:46:302600 GLuint last_id;
2601 if (info.bound_texture_2d) {
2602 last_id = info.bound_texture_2d->service_id();
2603 } else {
2604 last_id = 0;
2605 }
2606
2607 glBindTexture(GL_TEXTURE_2D, last_id);
[email protected]e259eb412012-10-13 05:47:242608 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]8e3e0662010-08-23 18:46:302609}
2610
[email protected]0d6bfdc2011-11-02 01:32:202611bool GLES2DecoderImpl::CheckFramebufferValid(
2612 FramebufferManager::FramebufferInfo* framebuffer,
2613 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102614 if (!framebuffer) {
[email protected]0d6bfdc2011-11-02 01:32:202615 return true;
2616 }
2617
[email protected]968351b2011-12-20 08:26:512618 if (framebuffer_manager()->IsComplete(framebuffer)) {
2619 return true;
2620 }
2621
[email protected]0d6bfdc2011-11-02 01:32:202622 GLenum completeness = framebuffer->IsPossiblyComplete();
2623 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
2624 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:432625 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272626 return false;
2627 }
[email protected]0d6bfdc2011-11-02 01:32:202628
2629 // Are all the attachments cleared?
2630 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2631 texture_manager()->HaveUnclearedMips()) {
2632 if (!framebuffer->IsCleared()) {
2633 // Can we clear them?
[email protected]73276522012-11-09 05:50:202634 if (framebuffer->GetStatus(texture_manager(), target) !=
2635 GL_FRAMEBUFFER_COMPLETE) {
[email protected]0d6bfdc2011-11-02 01:32:202636 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:432637 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2638 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202639 return false;
2640 }
2641 ClearUnclearedAttachments(target, framebuffer);
2642 }
2643 }
2644
[email protected]968351b2011-12-20 08:26:512645 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202646 if (framebuffer->GetStatus(texture_manager(), target) !=
2647 GL_FRAMEBUFFER_COMPLETE) {
[email protected]968351b2011-12-20 08:26:512648 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:432649 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2650 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512651 return false;
2652 }
2653 framebuffer_manager()->MarkAsComplete(framebuffer);
2654 }
2655
[email protected]0d6bfdc2011-11-02 01:32:202656 // NOTE: At this point we don't know if the framebuffer is complete but
2657 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272658 return true;
2659}
2660
[email protected]0d6bfdc2011-11-02 01:32:202661bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:152662 if (!features().chromium_framebuffer_multisample) {
[email protected]0d6bfdc2011-11-02 01:32:202663 return CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242664 state_.bound_draw_framebuffer, GL_FRAMEBUFFER_EXT, func_name);
[email protected]0d6bfdc2011-11-02 01:32:202665 }
2666 return CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242667 state_.bound_draw_framebuffer,
2668 GL_DRAW_FRAMEBUFFER_EXT, func_name) &&
[email protected]0d6bfdc2011-11-02 01:32:202669 CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242670 state_.bound_read_framebuffer,
2671 GL_READ_FRAMEBUFFER_EXT, func_name);
[email protected]0d6bfdc2011-11-02 01:32:202672}
2673
[email protected]8e3e0662010-08-23 18:46:302674gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]0d6bfdc2011-11-02 01:32:202675 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452676 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202677 if (framebuffer != NULL) {
[email protected]9edc6b22010-12-23 02:00:262678 const FramebufferManager::FramebufferInfo::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:202679 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:262680 if (attachment) {
2681 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:502682 }
[email protected]9edc6b22010-12-23 02:00:262683 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:022684 } else if (offscreen_target_frame_buffer_.get()) {
2685 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:352686 } else {
[email protected]f62a5ab2011-05-23 20:34:152687 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:022688 }
[email protected]246a70452010-03-05 21:53:502689}
2690
[email protected]9edc6b22010-12-23 02:00:262691GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]0d6bfdc2011-11-02 01:32:202692 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452693 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202694 if (framebuffer != NULL) {
2695 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:462696 } else if (offscreen_target_frame_buffer_.get()) {
2697 return offscreen_target_color_format_;
2698 } else {
2699 return back_buffer_color_format_;
2700 }
2701}
2702
2703GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]0d6bfdc2011-11-02 01:32:202704 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452705 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202706 if (framebuffer != NULL) {
2707 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:262708 } else if (offscreen_target_frame_buffer_.get()) {
2709 return offscreen_target_color_format_;
2710 } else {
[email protected]32fe9aa2011-01-21 23:47:132711 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:262712 }
2713}
2714
[email protected]9a5afa432011-07-22 18:16:392715void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]34ff8b0c2010-10-01 20:06:022716 if (parent_) {
[email protected]2f2d7042010-04-14 21:45:582717 // Update the info about the offscreen saved color texture in the parent.
2718 // The reference to the parent is a weak pointer and will become null if the
2719 // parent is later destroyed.
[email protected]262d7aa2010-12-03 22:07:292720 TextureManager* parent_texture_manager = parent_->texture_manager();
[email protected]262d7aa2010-12-03 22:07:292721 parent_texture_manager->SetLevelInfo(
[email protected]8a61d872012-01-20 12:43:562722 offscreen_saved_color_texture_info_,
[email protected]ef526492010-06-02 23:12:252723 GL_TEXTURE_2D,
2724 0, // level
2725 GL_RGBA,
[email protected]799b4b22011-08-22 17:09:592726 offscreen_size_.width(),
2727 offscreen_size_.height(),
[email protected]ef526492010-06-02 23:12:252728 1, // depth
2729 0, // border
2730 GL_RGBA,
[email protected]0d6bfdc2011-11-02 01:32:202731 GL_UNSIGNED_BYTE,
2732 true);
[email protected]262d7aa2010-12-03 22:07:292733 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562734 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042735 GL_TEXTURE_MAG_FILTER,
2736 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:292737 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562738 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042739 GL_TEXTURE_MIN_FILTER,
2740 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:292741 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562742 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042743 GL_TEXTURE_WRAP_S,
2744 GL_CLAMP_TO_EDGE);
[email protected]262d7aa2010-12-03 22:07:292745 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562746 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042747 GL_TEXTURE_WRAP_T,
2748 GL_CLAMP_TO_EDGE);
[email protected]8a61d872012-01-20 12:43:562749 } else {
2750 offscreen_saved_color_texture_info_ = NULL;
[email protected]0c8c9d22010-06-25 17:36:392751 }
[email protected]6217d392010-03-25 22:08:352752}
2753
[email protected]799b4b22011-08-22 17:09:592754void GLES2DecoderImpl::SetResizeCallback(
[email protected]9d37f062011-11-22 01:24:522755 const base::Callback<void(gfx::Size)>& callback) {
2756 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:002757}
2758
[email protected]6b6e7ee2011-12-13 08:04:522759void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) {
2760 msg_callback_ = callback;
2761}
2762
[email protected]b0af4f52011-09-28 22:04:422763void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) {
2764 stream_texture_manager_ = manager;
2765}
2766
[email protected]1318e922010-09-17 22:03:162767bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
2768 uint32* service_texture_id) {
2769 TextureManager::TextureInfo* texture =
2770 texture_manager()->GetTextureInfo(client_texture_id);
2771 if (texture) {
2772 *service_texture_id = texture->service_id();
2773 return true;
2774 }
2775 return false;
2776}
2777
[email protected]63b465922012-09-06 02:04:522778uint32 GLES2DecoderImpl::GetTextureUploadCount() {
2779 return texture_upload_count_;
2780}
2781
2782base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
2783 return total_texture_upload_time_;
2784}
2785
2786base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
2787 return total_processing_commands_time_;
2788}
2789
[email protected]dc25dda2012-09-27 21:36:302790void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
2791 total_processing_commands_time_ += time;
2792}
2793
[email protected]63c9b052012-05-17 18:27:382794void GLES2DecoderImpl::Destroy(bool have_context) {
2795 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:052796
[email protected]c826d732012-02-09 04:40:262797 ChildList children = children_;
2798 for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
2799 (*it)->SetParent(NULL, 0);
2800 DCHECK(children_.empty());
[email protected]3c644d82011-06-20 19:58:242801 SetParent(NULL, 0);
2802
[email protected]80eb6b52012-01-19 00:14:412803 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:242804 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:462805 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:022806 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:242807 state_.bound_array_buffer = NULL;
2808 state_.current_query = NULL;
2809 state_.current_program = NULL;
2810 state_.bound_read_framebuffer = NULL;
2811 state_.bound_draw_framebuffer = NULL;
2812 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:412813
[email protected]eadc96792010-10-27 19:39:392814 if (have_context) {
[email protected]c322e882012-05-23 18:06:182815 if (copy_texture_CHROMIUM_.get()) {
2816 copy_texture_CHROMIUM_->Destroy();
2817 copy_texture_CHROMIUM_.reset();
2818 }
[email protected]43410e92012-04-20 17:06:282819
[email protected]e259eb412012-10-13 05:47:242820 if (state_.current_program) {
2821 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
2822 state_.current_program = NULL;
[email protected]ca488e12010-12-13 20:06:142823 }
2824
[email protected]b1122982010-05-17 23:04:242825 if (attrib_0_buffer_id_) {
2826 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
2827 }
[email protected]8fbedc02010-11-18 18:43:402828 if (fixed_attrib_buffer_id_) {
2829 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
2830 }
[email protected]b1122982010-05-17 23:04:242831
[email protected]97872062010-11-03 19:07:052832 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:542833 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:052834 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:542835 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:052836 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:022837 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:052838 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:152839 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:052840 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:152841 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:052842 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:022843 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:052844 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:542845 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:272846 if (offscreen_resolved_frame_buffer_.get())
2847 offscreen_resolved_frame_buffer_->Destroy();
2848 if (offscreen_resolved_color_texture_.get())
2849 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:052850 } else {
2851 if (offscreen_target_frame_buffer_.get())
2852 offscreen_target_frame_buffer_->Invalidate();
2853 if (offscreen_target_color_texture_.get())
2854 offscreen_target_color_texture_->Invalidate();
2855 if (offscreen_target_color_render_buffer_.get())
2856 offscreen_target_color_render_buffer_->Invalidate();
2857 if (offscreen_target_depth_render_buffer_.get())
2858 offscreen_target_depth_render_buffer_->Invalidate();
2859 if (offscreen_target_stencil_render_buffer_.get())
2860 offscreen_target_stencil_render_buffer_->Invalidate();
2861 if (offscreen_saved_frame_buffer_.get())
2862 offscreen_saved_frame_buffer_->Invalidate();
2863 if (offscreen_saved_color_texture_.get())
2864 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:272865 if (offscreen_resolved_frame_buffer_.get())
2866 offscreen_resolved_frame_buffer_->Invalidate();
2867 if (offscreen_resolved_color_texture_.get())
2868 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:022869 }
[email protected]43410e92012-04-20 17:06:282870 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:052871
[email protected]882ba1e22012-03-08 19:02:532872 if (query_manager_.get()) {
2873 query_manager_->Destroy(have_context);
2874 query_manager_.reset();
2875 }
2876
[email protected]944b62f32012-09-27 02:20:462877 if (vertex_array_manager_ .get()) {
2878 vertex_array_manager_->Destroy(have_context);
2879 vertex_array_manager_.reset();
2880 }
2881
[email protected]1871a092011-10-10 21:46:422882 if (group_) {
2883 group_->Destroy(have_context);
2884 group_ = NULL;
2885 }
[email protected]3ae019382011-10-05 19:42:412886
[email protected]fe871662011-06-16 20:43:052887 if (context_.get()) {
2888 context_->ReleaseCurrent(NULL);
[email protected]79311e82011-09-20 00:40:502889 context_ = NULL;
[email protected]fe871662011-06-16 20:43:052890 }
[email protected]0fc35742011-04-13 17:57:542891
[email protected]97872062010-11-03 19:07:052892 offscreen_target_frame_buffer_.reset();
2893 offscreen_target_color_texture_.reset();
2894 offscreen_target_color_render_buffer_.reset();
2895 offscreen_target_depth_render_buffer_.reset();
2896 offscreen_target_stencil_render_buffer_.reset();
2897 offscreen_saved_frame_buffer_.reset();
2898 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:272899 offscreen_resolved_frame_buffer_.reset();
2900 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:462901
2902#if defined(OS_MACOSX)
2903 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
2904 it != texture_to_io_surface_map_.end(); ++it) {
2905 CFRelease(it->second);
2906 }
2907 texture_to_io_surface_map_.clear();
2908#endif
[email protected]96449d2c2009-11-25 00:01:322909}
2910
[email protected]63c9b052012-05-17 18:27:382911void GLES2DecoderImpl::SetSurface(
2912 const scoped_refptr<gfx::GLSurface>& surface) {
2913 DCHECK(context_->IsCurrent(NULL));
2914 DCHECK(surface_.get());
2915 surface_ = surface;
2916 RestoreCurrentFramebufferBindings();
2917}
2918
[email protected]3c644d82011-06-20 19:58:242919bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent,
2920 uint32 new_parent_texture_id) {
[email protected]9a5afa432011-07-22 18:16:392921 if (!offscreen_saved_color_texture_.get())
2922 return false;
2923
[email protected]3c644d82011-06-20 19:58:242924 // Remove the saved frame buffer mapping from the parent decoder. The
2925 // parent pointer is a weak pointer so it will be null if the parent has
2926 // already been destroyed.
2927 if (parent_) {
[email protected]c826d732012-02-09 04:40:262928 ChildList::iterator it = std::find(
2929 parent_->children_.begin(),
2930 parent_->children_.end(),
2931 this);
2932 DCHECK(it != parent_->children_.end());
2933 parent_->children_.erase(it);
[email protected]3c644d82011-06-20 19:58:242934 // First check the texture has been mapped into the parent. This might not
2935 // be the case if initialization failed midway through.
2936 GLuint service_id = offscreen_saved_color_texture_->id();
2937 GLuint client_id = 0;
2938 if (parent_->texture_manager()->GetClientId(service_id, &client_id)) {
[email protected]80eb6b52012-01-19 00:14:412939 parent_->texture_manager()->RemoveTextureInfo(client_id);
[email protected]3c644d82011-06-20 19:58:242940 }
2941 }
2942
2943 GLES2DecoderImpl* new_parent_impl = static_cast<GLES2DecoderImpl*>(
2944 new_parent);
2945 if (new_parent_impl) {
[email protected]c826d732012-02-09 04:40:262946#ifndef NDEBUG
2947 ChildList::iterator it = std::find(
2948 new_parent_impl->children_.begin(),
2949 new_parent_impl->children_.end(),
2950 this);
2951 DCHECK(it == new_parent_impl->children_.end());
2952#endif
2953 new_parent_impl->children_.push_back(this);
[email protected]3c644d82011-06-20 19:58:242954 // Map the ID of the saved offscreen texture into the parent so that
2955 // it can reference it.
2956 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]98687862011-07-11 23:31:302957
2958 // Replace texture info when ID is already in use by parent.
2959 if (new_parent_impl->texture_manager()->GetTextureInfo(
[email protected]80eb6b52012-01-19 00:14:412960 new_parent_texture_id))
[email protected]98687862011-07-11 23:31:302961 new_parent_impl->texture_manager()->RemoveTextureInfo(
[email protected]80eb6b52012-01-19 00:14:412962 new_parent_texture_id);
[email protected]98687862011-07-11 23:31:302963
[email protected]8a61d872012-01-20 12:43:562964 offscreen_saved_color_texture_info_ =
[email protected]5f4f2a732011-07-30 00:47:552965 new_parent_impl->CreateTextureInfo(new_parent_texture_id, service_id);
[email protected]8a61d872012-01-20 12:43:562966 offscreen_saved_color_texture_info_->SetNotOwned();
2967 new_parent_impl->texture_manager()->
2968 SetInfoTarget(offscreen_saved_color_texture_info_, GL_TEXTURE_2D);
[email protected]3c644d82011-06-20 19:58:242969
2970 parent_ = new_parent_impl->AsWeakPtr();
[email protected]9a5afa432011-07-22 18:16:392971
2972 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:242973 } else {
2974 parent_.reset();
[email protected]8a61d872012-01-20 12:43:562975 offscreen_saved_color_texture_info_ = NULL;
[email protected]3c644d82011-06-20 19:58:242976 }
2977
2978 return true;
2979}
2980
[email protected]260ddc4e2012-06-28 00:01:532981size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:142982 size_t total = 0;
2983 if (offscreen_target_frame_buffer_.get()) {
2984 if (offscreen_target_color_texture_.get()) {
2985 total += offscreen_target_color_texture_->estimated_size();
2986 }
2987 if (offscreen_target_color_render_buffer_.get()) {
2988 total += offscreen_target_color_render_buffer_->estimated_size();
2989 }
2990 if (offscreen_target_depth_render_buffer_.get()) {
2991 total += offscreen_target_depth_render_buffer_->estimated_size();
2992 }
2993 if (offscreen_target_stencil_render_buffer_.get()) {
2994 total += offscreen_target_stencil_render_buffer_->estimated_size();
2995 }
2996 if (offscreen_saved_color_texture_.get()) {
2997 total += offscreen_saved_color_texture_->estimated_size();
2998 }
2999 if (offscreen_resolved_color_texture_.get()) {
3000 total += offscreen_resolved_color_texture_->estimated_size();
3001 }
3002 } else {
3003 gfx::Size size = surface_->GetSize();
3004 total += size.width() * size.height() *
3005 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3006 }
[email protected]260ddc4e2012-06-28 00:01:533007 return total;
[email protected]1078f912011-12-23 13:12:143008}
3009
[email protected]799b4b22011-08-22 17:09:593010bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3011 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3012 if (!is_offscreen) {
3013 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3014 << " with an onscreen framebuffer.";
3015 return false;
3016 }
3017
3018 if (offscreen_size_ == size)
3019 return true;
3020
3021 offscreen_size_ = size;
3022 int w = offscreen_size_.width();
3023 int h = offscreen_size_.height();
3024 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3025 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3026 << "to allocate storage due to excessive dimensions.";
3027 return false;
3028 }
3029
3030 // Reallocate the offscreen target buffers.
3031 DCHECK(offscreen_target_color_format_);
3032 if (IsOffscreenBufferMultisampled()) {
3033 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3034 offscreen_size_, offscreen_target_color_format_,
3035 offscreen_target_samples_)) {
3036 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3037 << "to allocate storage for offscreen target color buffer.";
3038 return false;
3039 }
3040 } else {
3041 if (!offscreen_target_color_texture_->AllocateStorage(
3042 offscreen_size_, offscreen_target_color_format_)) {
3043 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3044 << "to allocate storage for offscreen target color texture.";
3045 return false;
3046 }
3047 }
3048 if (offscreen_target_depth_format_ &&
3049 !offscreen_target_depth_render_buffer_->AllocateStorage(
3050 offscreen_size_, offscreen_target_depth_format_,
3051 offscreen_target_samples_)) {
3052 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3053 << "to allocate storage for offscreen target depth buffer.";
3054 return false;
3055 }
3056 if (offscreen_target_stencil_format_ &&
3057 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3058 offscreen_size_, offscreen_target_stencil_format_,
3059 offscreen_target_samples_)) {
3060 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3061 << "to allocate storage for offscreen target stencil buffer.";
3062 return false;
3063 }
3064
3065 // Attach the offscreen target buffers to the target frame buffer.
3066 if (IsOffscreenBufferMultisampled()) {
3067 offscreen_target_frame_buffer_->AttachRenderBuffer(
3068 GL_COLOR_ATTACHMENT0,
3069 offscreen_target_color_render_buffer_.get());
3070 } else {
3071 offscreen_target_frame_buffer_->AttachRenderTexture(
3072 offscreen_target_color_texture_.get());
3073 }
3074 if (offscreen_target_depth_format_) {
3075 offscreen_target_frame_buffer_->AttachRenderBuffer(
3076 GL_DEPTH_ATTACHMENT,
3077 offscreen_target_depth_render_buffer_.get());
3078 }
3079 const bool packed_depth_stencil =
3080 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3081 if (packed_depth_stencil) {
3082 offscreen_target_frame_buffer_->AttachRenderBuffer(
3083 GL_STENCIL_ATTACHMENT,
3084 offscreen_target_depth_render_buffer_.get());
3085 } else if (offscreen_target_stencil_format_) {
3086 offscreen_target_frame_buffer_->AttachRenderBuffer(
3087 GL_STENCIL_ATTACHMENT,
3088 offscreen_target_stencil_render_buffer_.get());
3089 }
3090
3091 if (offscreen_target_frame_buffer_->CheckStatus() !=
3092 GL_FRAMEBUFFER_COMPLETE) {
3093 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3094 << "because offscreen FBO was incomplete.";
3095 return false;
3096 }
3097
3098 // Clear the target frame buffer.
3099 {
3100 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3101 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3102 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3103 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3104 glClearStencil(0);
3105 glStencilMaskSeparate(GL_FRONT, -1);
3106 glStencilMaskSeparate(GL_BACK, -1);
3107 glClearDepth(0);
3108 glDepthMask(GL_TRUE);
3109 glDisable(GL_SCISSOR_TEST);
3110 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3111 RestoreClearState();
3112 }
[email protected]d85ef76d2011-09-08 22:21:433113
3114 // Destroy the offscreen resolved framebuffers.
3115 if (offscreen_resolved_frame_buffer_.get())
3116 offscreen_resolved_frame_buffer_->Destroy();
3117 if (offscreen_resolved_color_texture_.get())
3118 offscreen_resolved_color_texture_->Destroy();
3119 offscreen_resolved_color_texture_.reset();
3120 offscreen_resolved_frame_buffer_.reset();
3121
[email protected]799b4b22011-08-22 17:09:593122 return true;
[email protected]6217d392010-03-25 22:08:353123}
3124
[email protected]799b4b22011-08-22 17:09:593125error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
3126 uint32 immediate_data_size, const gles2::ResizeCHROMIUM& c) {
[email protected]452120872012-09-27 15:21:023127 if (ShouldDeferDraws())
3128 return error::kDeferCommandUntilLater;
3129
[email protected]799b4b22011-08-22 17:09:593130 GLuint width = static_cast<GLuint>(c.width);
3131 GLuint height = static_cast<GLuint>(c.height);
3132 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]a0d989162011-11-22 13:15:073133#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3134 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003135 // Make sure that we are done drawing to the back buffer before resizing.
3136 glFinish();
3137#endif
[email protected]799b4b22011-08-22 17:09:593138 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3139 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493140 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3141 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3142 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593143 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493144 }
[email protected]7ff86b92010-11-25 17:50:003145 }
[email protected]799b4b22011-08-22 17:09:593146
[email protected]9d37f062011-11-22 01:24:523147 if (!resize_callback_.is_null()) {
3148 resize_callback_.Run(gfx::Size(width, height));
[email protected]c777de52011-09-09 23:08:563149 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493150 if (!context_->IsCurrent(surface_.get())) {
3151 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3152 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053153 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493154 }
[email protected]658f7562011-09-09 05:24:053155 }
[email protected]799b4b22011-08-22 17:09:593156
3157 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393158}
3159
[email protected]96449d2c2009-11-25 00:01:323160const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3161 if (command_id > kStartPoint && command_id < kNumCommands) {
3162 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3163 }
3164 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3165}
3166
3167// Decode command with its arguments, and call the corresponding GL function.
3168// Note: args is a pointer to the command buffer. As such, it could be changed
3169// by a (malicious) client at any time, so if validation has to happen, it
3170// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143171error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323172 unsigned int command,
3173 unsigned int arg_count,
3174 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143175 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263176 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003177 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3178 // LOG(INFO), tried VLOG(1), no luck.
[email protected]d2a0e1a2012-08-12 02:25:013179 LOG(ERROR) << "[" << GetLogPrefix() << "]" << "cmd: "
3180 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193181 }
[email protected]96449d2c2009-11-25 00:01:323182 unsigned int command_index = command - kStartPoint - 1;
3183 if (command_index < arraysize(g_command_info)) {
3184 const CommandInfo& info = g_command_info[command_index];
3185 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3186 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3187 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193188 uint32 immediate_data_size =
3189 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323190 switch (command) {
3191 #define GLES2_CMD_OP(name) \
3192 case name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193193 result = Handle ## name( \
3194 immediate_data_size, \
[email protected]96449d2c2009-11-25 00:01:323195 *static_cast<const name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193196 break; \
[email protected]96449d2c2009-11-25 00:01:323197
3198 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323199 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383200 }
3201 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303202 GLenum error;
3203 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]d2a0e1a2012-08-12 02:25:013204 LOG(ERROR) << "[" << GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003205 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3206 << GetCommandName(command);
[email protected]ad84a3a2012-06-08 21:42:433207 SetGLError(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193208 }
[email protected]96449d2c2009-11-25 00:01:323209 }
3210 } else {
[email protected]f7a64ee2010-02-01 22:24:143211 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323212 }
[email protected]b9849abf2009-11-25 19:13:193213 } else {
3214 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323215 }
[email protected]a3a93e7b2010-08-28 00:48:563216 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3217 result = current_decoder_error_;
3218 current_decoder_error_ = error::kNoError;
3219 }
[email protected]b9849abf2009-11-25 19:13:193220 return result;
[email protected]96449d2c2009-11-25 00:01:323221}
3222
[email protected]ae51d192010-04-27 00:48:033223void GLES2DecoderImpl::RemoveBufferInfo(GLuint client_id) {
3224 buffer_manager()->RemoveBufferInfo(client_id);
[email protected]3916c97e2010-02-25 03:20:503225}
3226
[email protected]ae51d192010-04-27 00:48:033227bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
3228 if (GetProgramInfo(client_id)) {
3229 return false;
3230 }
[email protected]96449d2c2009-11-25 00:01:323231 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033232 if (service_id != 0) {
3233 CreateProgramInfo(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323234 }
[email protected]ae51d192010-04-27 00:48:033235 return true;
[email protected]96449d2c2009-11-25 00:01:323236}
3237
[email protected]ae51d192010-04-27 00:48:033238bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
3239 if (GetShaderInfo(client_id)) {
3240 return false;
[email protected]96449d2c2009-11-25 00:01:323241 }
[email protected]ae51d192010-04-27 00:48:033242 GLuint service_id = glCreateShader(type);
3243 if (service_id != 0) {
[email protected]7cea56d92010-04-28 17:21:383244 CreateShaderInfo(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033245 }
3246 return true;
[email protected]96449d2c2009-11-25 00:01:323247}
3248
[email protected]882ba1e22012-03-08 19:02:533249void GLES2DecoderImpl::DoFinish() {
3250 glFinish();
[email protected]22e3f552012-03-13 01:54:193251 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533252}
3253
3254void GLES2DecoderImpl::DoFlush() {
3255 glFlush();
[email protected]22e3f552012-03-13 01:54:193256 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533257}
3258
[email protected]3916c97e2010-02-25 03:20:503259void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453260 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023261 if (texture_index >= state_.texture_units.size()) {
[email protected]f80e6e12012-08-31 00:43:533262 SetGLErrorInvalidEnum(
3263 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503264 return;
3265 }
[email protected]e259eb412012-10-13 05:47:243266 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453267 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503268}
3269
[email protected]051b1372010-04-12 02:42:083270void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]3916c97e2010-02-25 03:20:503271 BufferManager::BufferInfo* info = NULL;
[email protected]051b1372010-04-12 02:42:083272 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033273 if (client_id != 0) {
3274 info = GetBufferInfo(client_id);
3275 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353276 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153277 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3278 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353279 return;
3280 }
3281
[email protected]ae51d192010-04-27 00:48:033282 // It's a new id so make a buffer info for it.
3283 glGenBuffersARB(1, &service_id);
3284 CreateBufferInfo(client_id, service_id);
3285 info = GetBufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573286 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103287 group_->GetIdAllocator(id_namespaces::kBuffers);
3288 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033289 }
[email protected]051b1372010-04-12 02:42:083290 }
[email protected]ae51d192010-04-27 00:48:033291 if (info) {
[email protected]4e8a5b122010-05-08 22:00:103292 if (!buffer_manager()->SetTarget(info, target)) {
[email protected]8eee29c2010-04-29 03:38:293293 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433294 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473295 return;
3296 }
[email protected]ae51d192010-04-27 00:48:033297 service_id = info->service_id();
[email protected]a93bb842010-02-16 23:03:473298 }
[email protected]96449d2c2009-11-25 00:01:323299 switch (target) {
3300 case GL_ARRAY_BUFFER:
[email protected]e259eb412012-10-13 05:47:243301 state_.bound_array_buffer = info;
[email protected]96449d2c2009-11-25 00:01:323302 break;
3303 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]e259eb412012-10-13 05:47:243304 state_.vertex_attrib_manager->SetElementArrayBuffer(info);
[email protected]96449d2c2009-11-25 00:01:323305 break;
3306 default:
[email protected]a93bb842010-02-16 23:03:473307 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323308 break;
3309 }
[email protected]051b1372010-04-12 02:42:083310 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323311}
3312
[email protected]297ca1c2011-06-20 23:08:463313bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
3314 return (GLES2Util::GetChannelsForFormat(
3315 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3316}
3317
3318bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]0d6bfdc2011-11-02 01:32:203319 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453320 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203321 if (framebuffer) {
3322 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463323 }
3324 if (offscreen_target_frame_buffer_.get()) {
3325 return offscreen_target_depth_format_ != 0;
3326 }
3327 return back_buffer_has_depth_;
3328}
3329
3330bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]0d6bfdc2011-11-02 01:32:203331 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453332 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203333 if (framebuffer) {
3334 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463335 }
3336 if (offscreen_target_frame_buffer_.get()) {
3337 return offscreen_target_stencil_format_ != 0 ||
3338 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3339 }
3340 return back_buffer_has_stencil_;
3341}
3342
3343void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]88a61bf2012-10-27 13:00:423344 if (clear_state_dirty_) {
[email protected]297ca1c2011-06-20 23:08:463345 glColorMask(
[email protected]e259eb412012-10-13 05:47:243346 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3347 state_.color_mask_alpha &&
3348 BoundFramebufferHasColorAttachmentWithAlpha());
[email protected]297ca1c2011-06-20 23:08:463349 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243350 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223351 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463352 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243353 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423354 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243355 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423356 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223357 EnableDisable(
3358 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3359 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3360 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3361 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]88a61bf2012-10-27 13:00:423362 clear_state_dirty_ = false;
[email protected]297ca1c2011-06-20 23:08:463363 }
3364}
3365
[email protected]78b514b2012-05-01 21:50:593366void GLES2DecoderImpl::BindAndApplyTextureParameters(
3367 TextureManager::TextureInfo* info) {
3368 glBindTexture(info->target(), info->service_id());
3369 glTexParameteri(info->target(), GL_TEXTURE_MIN_FILTER, info->min_filter());
3370 glTexParameteri(info->target(), GL_TEXTURE_MAG_FILTER, info->mag_filter());
3371 glTexParameteri(info->target(), GL_TEXTURE_WRAP_S, info->wrap_s());
3372 glTexParameteri(info->target(), GL_TEXTURE_WRAP_T, info->wrap_t());
3373}
3374
[email protected]1868a342012-11-07 15:56:023375GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]b177ae22011-11-01 03:29:113376 return (offscreen_target_frame_buffer_.get()) ?
3377 offscreen_target_frame_buffer_->id() :
[email protected]1868a342012-11-07 15:56:023378 (surface_ ? surface_->GetBackingFrameBufferObject() : 0);
3379}
3380
3381void GLES2DecoderImpl::RestoreState() const {
3382 state_.RestoreState();
3383
3384 // TODO: Restore multisample bindings
3385 GLuint service_id = state_.bound_draw_framebuffer ?
3386 state_.bound_draw_framebuffer->service_id() :
3387 GetBackbufferServiceId();
3388 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
[email protected]b177ae22011-11-01 03:29:113389}
3390
[email protected]051b1372010-04-12 02:42:083391void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
3392 FramebufferManager::FramebufferInfo* info = NULL;
3393 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033394 if (client_id != 0) {
3395 info = GetFramebufferInfo(client_id);
[email protected]051b1372010-04-12 02:42:083396 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353397 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153398 LOG(ERROR)
3399 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3400 current_decoder_error_ = error::kGenericError;
3401 return;
[email protected]bf5a8d132011-08-16 08:39:353402 }
3403
[email protected]ae51d192010-04-27 00:48:033404 // It's a new id so make a framebuffer info for it.
3405 glGenFramebuffersEXT(1, &service_id);
3406 CreateFramebufferInfo(client_id, service_id);
3407 info = GetFramebufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573408 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103409 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3410 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033411 } else {
3412 service_id = info->service_id();
[email protected]051b1372010-04-12 02:42:083413 }
[email protected]06c8b082011-01-05 18:00:363414 info->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083415 }
[email protected]8e3e0662010-08-23 18:46:303416
3417 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]e259eb412012-10-13 05:47:243418 state_.bound_draw_framebuffer = info;
[email protected]8e3e0662010-08-23 18:46:303419 }
3420 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]e259eb412012-10-13 05:47:243421 state_.bound_read_framebuffer = info;
[email protected]8e3e0662010-08-23 18:46:303422 }
[email protected]6217d392010-03-25 22:08:353423
[email protected]88a61bf2012-10-27 13:00:423424 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:463425
[email protected]b177ae22011-11-01 03:29:113426 // If we are rendering to the backbuffer get the FBO id for any simulated
3427 // backbuffer.
3428 if (info == NULL) {
3429 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463430 }
[email protected]6217d392010-03-25 22:08:353431
[email protected]051b1372010-04-12 02:42:083432 glBindFramebufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563433}
3434
[email protected]051b1372010-04-12 02:42:083435void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
3436 RenderbufferManager::RenderbufferInfo* info = NULL;
3437 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033438 if (client_id != 0) {
3439 info = GetRenderbufferInfo(client_id);
[email protected]051b1372010-04-12 02:42:083440 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353441 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153442 LOG(ERROR)
3443 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3444 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353445 return;
3446 }
3447
[email protected]ae51d192010-04-27 00:48:033448 // It's a new id so make a renderbuffer info for it.
3449 glGenRenderbuffersEXT(1, &service_id);
3450 CreateRenderbufferInfo(client_id, service_id);
[email protected]066849e32010-05-03 19:14:103451 info = GetRenderbufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573452 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103453 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3454 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033455 } else {
3456 service_id = info->service_id();
[email protected]051b1372010-04-12 02:42:083457 }
[email protected]06c8b082011-01-05 18:00:363458 info->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083459 }
[email protected]e259eb412012-10-13 05:47:243460 state_.bound_renderbuffer = info;
[email protected]051b1372010-04-12 02:42:083461 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563462}
3463
[email protected]051b1372010-04-12 02:42:083464void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]ae51d192010-04-27 00:48:033465 TextureManager::TextureInfo* info = NULL;
[email protected]051b1372010-04-12 02:42:083466 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033467 if (client_id != 0) {
3468 info = GetTextureInfo(client_id);
3469 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353470 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153471 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3472 current_decoder_error_ = error::kGenericError;
3473 return;
[email protected]bf5a8d132011-08-16 08:39:353474 }
3475
[email protected]ae51d192010-04-27 00:48:033476 // It's a new id so make a texture info for it.
3477 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413478 DCHECK_NE(0u, service_id);
[email protected]ae51d192010-04-27 00:48:033479 CreateTextureInfo(client_id, service_id);
3480 info = GetTextureInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573481 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103482 group_->GetIdAllocator(id_namespaces::kTextures);
3483 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033484 }
3485 } else {
3486 info = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083487 }
[email protected]ae51d192010-04-27 00:48:033488
[email protected]1958e0e2010-04-22 05:17:153489 // Check the texture exists
3490 // Check that we are not trying to bind it to a different target.
[email protected]ae51d192010-04-27 00:48:033491 if (info->target() != 0 && info->target() != target) {
[email protected]8eee29c2010-04-29 03:38:293492 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433493 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153494 return;
3495 }
[email protected]b0af4f52011-09-28 22:04:423496 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
3497 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433498 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423499 return;
3500 }
[email protected]1958e0e2010-04-22 05:17:153501 if (info->target() == 0) {
[email protected]80eb6b52012-01-19 00:14:413502 texture_manager()->SetInfoTarget(info, target);
[email protected]a93bb842010-02-16 23:03:473503 }
[email protected]ae51d192010-04-27 00:48:033504 glBindTexture(target, info->service_id());
[email protected]e259eb412012-10-13 05:47:243505 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503506 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473507 switch (target) {
3508 case GL_TEXTURE_2D:
[email protected]3916c97e2010-02-25 03:20:503509 unit.bound_texture_2d = info;
[email protected]a93bb842010-02-16 23:03:473510 break;
3511 case GL_TEXTURE_CUBE_MAP:
[email protected]3916c97e2010-02-25 03:20:503512 unit.bound_texture_cube_map = info;
[email protected]a93bb842010-02-16 23:03:473513 break;
[email protected]61eeb33f2011-07-26 15:30:313514 case GL_TEXTURE_EXTERNAL_OES:
3515 unit.bound_texture_external_oes = info;
[email protected]b0af4f52011-09-28 22:04:423516 if (info->IsStreamTexture()) {
3517 DCHECK(stream_texture_manager_);
3518 StreamTexture* stream_tex =
3519 stream_texture_manager_->LookupStreamTexture(info->service_id());
3520 if (stream_tex)
3521 stream_tex->Update();
3522 }
[email protected]61eeb33f2011-07-26 15:30:313523 break;
[email protected]e51bdf32011-11-23 22:21:463524 case GL_TEXTURE_RECTANGLE_ARB:
3525 unit.bound_texture_rectangle_arb = info;
3526 break;
[email protected]a93bb842010-02-16 23:03:473527 default:
3528 NOTREACHED(); // Validation should prevent us getting here.
3529 break;
3530 }
3531}
3532
[email protected]07f54fcc2009-12-22 02:46:303533void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243534 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123535 if (index != 0 ||
3536 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243537 glDisableVertexAttribArray(index);
3538 }
[email protected]07f54fcc2009-12-22 02:46:303539 } else {
[email protected]8eee29c2010-04-29 03:38:293540 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:433541 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303542 }
3543}
3544
3545void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243546 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:303547 glEnableVertexAttribArray(index);
3548 } else {
[email protected]8eee29c2010-04-29 03:38:293549 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:433550 "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303551 }
3552}
3553
[email protected]a93bb842010-02-16 23:03:473554void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]3916c97e2010-02-25 03:20:503555 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]97dc7cbe2011-12-06 17:26:173556 if (!info ||
[email protected]38c0a972012-05-12 00:48:023557 !texture_manager()->CanGenerateMipmaps(info)) {
[email protected]8eee29c2010-04-29 03:38:293558 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433559 "glGenerateMipmaps", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:473560 return;
3561 }
[email protected]38c0a972012-05-12 00:48:023562
[email protected]7687479c2012-05-14 23:54:043563 if (!texture_manager()->ClearTextureLevel(this, info, target, 0)) {
[email protected]ad84a3a2012-06-08 21:42:433564 SetGLError(GL_OUT_OF_MEMORY, "glGenerateMipmaps", "dimensions too big");
[email protected]7687479c2012-05-14 23:54:043565 return;
3566 }
3567
[email protected]38c0a972012-05-12 00:48:023568 CopyRealGLErrorsToWrapper();
[email protected]59f3ca02011-03-26 22:24:193569 // Workaround for Mac driver bug. In the large scheme of things setting
3570 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:563571 // hit so there's probably no need to make this conditional. The bug appears
3572 // to be that if the filtering mode is set to something that doesn't require
3573 // mipmaps for rendering, or is never set to something other than the default,
3574 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:153575 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193576 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3577 }
[email protected]a93bb842010-02-16 23:03:473578 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:153579 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193580 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, info->min_filter());
3581 }
[email protected]38c0a972012-05-12 00:48:023582 GLenum error = PeekGLError();
3583 if (error == GL_NO_ERROR) {
3584 texture_manager()->MarkMipmapsGenerated(info);
3585 }
[email protected]a93bb842010-02-16 23:03:473586}
3587
[email protected]b273e432010-04-12 17:23:583588bool GLES2DecoderImpl::GetHelper(
3589 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:583590 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:153591 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
3592 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:433593 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3594 *num_written = 1;
3595 if (params) {
3596 *params = GL_RGBA; // We don't support other formats.
3597 }
3598 return true;
3599 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3600 *num_written = 1;
3601 if (params) {
3602 *params = GL_UNSIGNED_BYTE; // We don't support other types.
3603 }
3604 return true;
3605 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
3606 *num_written = 1;
3607 if (params) {
3608 *params = group_->max_fragment_uniform_vectors();
3609 }
3610 return true;
3611 case GL_MAX_VARYING_VECTORS:
3612 *num_written = 1;
3613 if (params) {
3614 *params = group_->max_varying_vectors();
3615 }
3616 return true;
3617 case GL_MAX_VERTEX_UNIFORM_VECTORS:
3618 *num_written = 1;
3619 if (params) {
3620 *params = group_->max_vertex_uniform_vectors();
3621 }
3622 return true;
[email protected]4e8a5b122010-05-08 22:00:103623 }
[email protected]5cb735d2011-10-13 01:37:233624 }
3625 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:243626 case GL_MAX_VIEWPORT_DIMS:
3627 if (offscreen_target_frame_buffer_.get()) {
3628 *num_written = 2;
3629 if (params) {
3630 params[0] = renderbuffer_manager()->max_renderbuffer_size();
3631 params[1] = renderbuffer_manager()->max_renderbuffer_size();
3632 }
3633 return true;
3634 }
[email protected]5cb735d2011-10-13 01:37:233635 return false;
[email protected]84afefa2011-10-19 21:45:533636 case GL_MAX_SAMPLES:
3637 *num_written = 1;
3638 if (params) {
3639 params[0] = renderbuffer_manager()->max_samples();
3640 }
3641 return true;
3642 case GL_MAX_RENDERBUFFER_SIZE:
3643 *num_written = 1;
3644 if (params) {
3645 params[0] = renderbuffer_manager()->max_renderbuffer_size();
3646 }
3647 return true;
[email protected]5cb735d2011-10-13 01:37:233648 case GL_MAX_TEXTURE_SIZE:
3649 *num_written = 1;
3650 if (params) {
3651 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
3652 }
3653 return true;
3654 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
3655 *num_written = 1;
3656 if (params) {
3657 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
3658 }
3659 return true;
[email protected]297ca1c2011-06-20 23:08:463660 case GL_ALPHA_BITS:
3661 *num_written = 1;
3662 if (params) {
3663 GLint v = 0;
3664 glGetIntegerv(GL_ALPHA_BITS, &v);
3665 params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0;
3666 }
3667 return true;
3668 case GL_DEPTH_BITS:
3669 *num_written = 1;
3670 if (params) {
3671 GLint v = 0;
3672 glGetIntegerv(GL_DEPTH_BITS, &v);
3673 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
3674 }
3675 return true;
3676 case GL_STENCIL_BITS:
3677 *num_written = 1;
3678 if (params) {
3679 GLint v = 0;
3680 glGetIntegerv(GL_STENCIL_BITS, &v);
3681 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
3682 }
3683 return true;
[email protected]656dcaad2010-05-07 17:18:373684 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:113685 *num_written = validators_->compressed_texture_format.GetValues().size();
3686 if (params) {
3687 for (GLint ii = 0; ii < *num_written; ++ii) {
3688 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
3689 }
3690 }
[email protected]656dcaad2010-05-07 17:18:373691 return true;
[email protected]b273e432010-04-12 17:23:583692 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
3693 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103694 if (params) {
[email protected]302ce6d2011-07-07 23:28:113695 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:103696 }
[email protected]b273e432010-04-12 17:23:583697 return true;
3698 case GL_NUM_SHADER_BINARY_FORMATS:
3699 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103700 if (params) {
[email protected]302ce6d2011-07-07 23:28:113701 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:103702 }
[email protected]b273e432010-04-12 17:23:583703 return true;
3704 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:113705 *num_written = validators_->shader_binary_format.GetValues().size();
3706 if (params) {
3707 for (GLint ii = 0; ii < *num_written; ++ii) {
3708 params[ii] = validators_->shader_binary_format.GetValues()[ii];
3709 }
3710 }
3711 return true;
[email protected]b273e432010-04-12 17:23:583712 case GL_SHADER_COMPILER:
3713 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103714 if (params) {
3715 *params = GL_TRUE;
3716 }
[email protected]b273e432010-04-12 17:23:583717 return true;
[email protected]6b8cf1a2010-05-06 16:13:583718 case GL_ARRAY_BUFFER_BINDING:
3719 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103720 if (params) {
[email protected]e259eb412012-10-13 05:47:243721 if (state_.bound_array_buffer) {
[email protected]4e8a5b122010-05-08 22:00:103722 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:243723 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:103724 &client_id);
3725 *params = client_id;
3726 } else {
3727 *params = 0;
3728 }
[email protected]6b8cf1a2010-05-06 16:13:583729 }
3730 return true;
3731 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
3732 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103733 if (params) {
[email protected]e259eb412012-10-13 05:47:243734 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:103735 GLuint client_id = 0;
3736 buffer_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:243737 state_.vertex_attrib_manager->element_array_buffer(
3738 )->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:103739 *params = client_id;
3740 } else {
3741 *params = 0;
3742 }
[email protected]6b8cf1a2010-05-06 16:13:583743 }
3744 return true;
3745 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:303746 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:583747 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103748 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:203749 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453750 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:203751 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:103752 GLuint client_id = 0;
3753 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:203754 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:303755 *params = client_id;
3756 } else {
3757 *params = 0;
3758 }
3759 }
3760 return true;
[email protected]ebfb73c2012-08-15 02:37:453761 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:303762 *num_written = 1;
3763 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:203764 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453765 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203766 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:303767 GLuint client_id = 0;
3768 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:203769 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:103770 *params = client_id;
3771 } else {
3772 *params = 0;
3773 }
[email protected]6b8cf1a2010-05-06 16:13:583774 }
3775 return true;
3776 case GL_RENDERBUFFER_BINDING:
3777 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103778 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:203779 RenderbufferManager::RenderbufferInfo* renderbuffer =
3780 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
3781 if (renderbuffer) {
[email protected]4e8a5b122010-05-08 22:00:103782 GLuint client_id = 0;
3783 renderbuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:203784 renderbuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:103785 *params = client_id;
3786 } else {
3787 *params = 0;
3788 }
[email protected]6b8cf1a2010-05-06 16:13:583789 }
3790 return true;
3791 case GL_CURRENT_PROGRAM:
3792 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103793 if (params) {
[email protected]e259eb412012-10-13 05:47:243794 if (state_.current_program) {
[email protected]4e8a5b122010-05-08 22:00:103795 GLuint client_id = 0;
3796 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:243797 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:103798 *params = client_id;
3799 } else {
3800 *params = 0;
3801 }
[email protected]6b8cf1a2010-05-06 16:13:583802 }
3803 return true;
[email protected]bf835842012-11-19 15:21:513804 case GL_VERTEX_ARRAY_BINDING_OES:
3805 *num_written = 1;
3806 if (params) {
3807 if (state_.vertex_attrib_manager != default_vertex_attrib_manager_) {
3808 GLuint client_id = 0;
3809 vertex_array_manager_->GetClientId(
3810 state_.vertex_attrib_manager->service_id(), &client_id);
3811 *params = client_id;
3812 } else {
3813 *params = 0;
3814 }
3815 }
3816 return true;
[email protected]4e8a5b122010-05-08 22:00:103817 case GL_TEXTURE_BINDING_2D:
3818 *num_written = 1;
3819 if (params) {
[email protected]e259eb412012-10-13 05:47:243820 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:583821 if (unit.bound_texture_2d) {
3822 GLuint client_id = 0;
3823 texture_manager()->GetClientId(
3824 unit.bound_texture_2d->service_id(), &client_id);
3825 *params = client_id;
3826 } else {
3827 *params = 0;
3828 }
[email protected]6b8cf1a2010-05-06 16:13:583829 }
[email protected]4e8a5b122010-05-08 22:00:103830 return true;
3831 case GL_TEXTURE_BINDING_CUBE_MAP:
3832 *num_written = 1;
3833 if (params) {
[email protected]e259eb412012-10-13 05:47:243834 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:583835 if (unit.bound_texture_cube_map) {
3836 GLuint client_id = 0;
3837 texture_manager()->GetClientId(
3838 unit.bound_texture_cube_map->service_id(), &client_id);
3839 *params = client_id;
3840 } else {
3841 *params = 0;
3842 }
[email protected]6b8cf1a2010-05-06 16:13:583843 }
[email protected]4e8a5b122010-05-08 22:00:103844 return true;
[email protected]61eeb33f2011-07-26 15:30:313845 case GL_TEXTURE_BINDING_EXTERNAL_OES:
3846 *num_written = 1;
3847 if (params) {
[email protected]e259eb412012-10-13 05:47:243848 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]61eeb33f2011-07-26 15:30:313849 if (unit.bound_texture_external_oes) {
3850 GLuint client_id = 0;
3851 texture_manager()->GetClientId(
3852 unit.bound_texture_external_oes->service_id(), &client_id);
3853 *params = client_id;
3854 } else {
3855 *params = 0;
3856 }
3857 }
3858 return true;
[email protected]e51bdf32011-11-23 22:21:463859 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
3860 *num_written = 1;
3861 if (params) {
[email protected]e259eb412012-10-13 05:47:243862 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]e51bdf32011-11-23 22:21:463863 if (unit.bound_texture_rectangle_arb) {
3864 GLuint client_id = 0;
3865 texture_manager()->GetClientId(
3866 unit.bound_texture_rectangle_arb->service_id(), &client_id);
3867 *params = client_id;
3868 } else {
3869 *params = 0;
3870 }
3871 }
3872 return true;
[email protected]6c75c712012-06-19 15:43:173873 case GL_UNPACK_FLIP_Y_CHROMIUM:
3874 *num_written = 1;
3875 if (params) {
3876 params[0] = unpack_flip_y_;
3877 }
3878 return true;
3879 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
3880 *num_written = 1;
3881 if (params) {
3882 params[0] = unpack_premultiply_alpha_;
3883 }
3884 return true;
3885 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
3886 *num_written = 1;
3887 if (params) {
3888 params[0] = unpack_unpremultiply_alpha_;
3889 }
3890 return true;
[email protected]b273e432010-04-12 17:23:583891 default:
[email protected]4e8a5b122010-05-08 22:00:103892 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:533893 return false;
[email protected]b273e432010-04-12 17:23:583894 }
3895}
3896
[email protected]4e8a5b122010-05-08 22:00:103897bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
3898 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:263899 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:533900 return true;
3901 }
[email protected]4e8a5b122010-05-08 22:00:103902 return GetHelper(pname, NULL, num_values);
3903}
3904
[email protected]b273e432010-04-12 17:23:583905void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
3906 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:103907 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:533908 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]4e8a5b122010-05-08 22:00:103909 scoped_array<GLint> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:263910 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:533911 GetHelper(pname, values.get(), &num_written);
3912 }
[email protected]b273e432010-04-12 17:23:583913 for (GLsizei ii = 0; ii < num_written; ++ii) {
3914 params[ii] = static_cast<GLboolean>(values[ii]);
3915 }
3916 } else {
3917 glGetBooleanv(pname, params);
3918 }
3919}
3920
3921void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
3922 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:103923 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:263924 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:533925 if (GetHelper(pname, NULL, &num_written)) {
3926 scoped_array<GLint> values(new GLint[num_written]);
3927 GetHelper(pname, values.get(), &num_written);
3928 for (GLsizei ii = 0; ii < num_written; ++ii) {
3929 params[ii] = static_cast<GLfloat>(values[ii]);
3930 }
3931 } else {
3932 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:583933 }
[email protected]b273e432010-04-12 17:23:583934 }
3935}
3936
3937void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
3938 DCHECK(params);
3939 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:263940 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:533941 !GetHelper(pname, params, &num_written)) {
[email protected]b273e432010-04-12 17:23:583942 glGetIntegerv(pname, params);
3943 }
3944}
3945
[email protected]a0c3e972010-04-21 00:49:133946void GLES2DecoderImpl::DoGetProgramiv(
3947 GLuint program_id, GLenum pname, GLint* params) {
[email protected]6b8cf1a2010-05-06 16:13:583948 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
3949 program_id, "glGetProgramiv");
[email protected]a0c3e972010-04-21 00:49:133950 if (!info) {
[email protected]a0c3e972010-04-21 00:49:133951 return;
3952 }
3953 info->GetProgramiv(pname, params);
3954}
3955
[email protected]258a3313f2011-10-18 20:13:573956void GLES2DecoderImpl::DoBindAttribLocation(
3957 GLuint program, GLuint index, const char* name) {
3958 if (!StringIsValidForGLES(name)) {
[email protected]ad84a3a2012-06-08 21:42:433959 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:573960 return;
3961 }
[email protected]68dcb1f2012-04-07 00:14:563962 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ad84a3a2012-06-08 21:42:433963 SetGLError(GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:563964 return;
3965 }
3966 if (index >= group_->max_vertex_attribs()) {
[email protected]ad84a3a2012-06-08 21:42:433967 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:563968 return;
3969 }
[email protected]6b8cf1a2010-05-06 16:13:583970 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
3971 program, "glBindAttribLocation");
[email protected]ae51d192010-04-27 00:48:033972 if (!info) {
[email protected]258a3313f2011-10-18 20:13:573973 return;
[email protected]558847a2010-03-24 07:02:543974 }
[email protected]c3e4c4e2012-03-02 19:23:243975 info->SetAttribLocationBinding(name, static_cast<GLint>(index));
[email protected]258a3313f2011-10-18 20:13:573976 glBindAttribLocation(info->service_id(), index, name);
3977}
3978
3979error::Error GLES2DecoderImpl::HandleBindAttribLocation(
3980 uint32 immediate_data_size, const gles2::BindAttribLocation& c) {
3981 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:543982 GLuint index = static_cast<GLuint>(c.index);
3983 uint32 name_size = c.data_size;
3984 const char* name = GetSharedMemoryAs<const char*>(
3985 c.name_shm_id, c.name_shm_offset, name_size);
3986 if (name == NULL) {
3987 return error::kOutOfBounds;
3988 }
3989 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:573990 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:543991 return error::kNoError;
3992}
3993
3994error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate(
3995 uint32 immediate_data_size, const gles2::BindAttribLocationImmediate& c) {
[email protected]6b8cf1a2010-05-06 16:13:583996 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:543997 GLuint index = static_cast<GLuint>(c.index);
3998 uint32 name_size = c.data_size;
3999 const char* name = GetImmediateDataAs<const char*>(
4000 c, name_size, immediate_data_size);
4001 if (name == NULL) {
4002 return error::kOutOfBounds;
4003 }
4004 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574005 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544006 return error::kNoError;
4007}
4008
4009error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
4010 uint32 immediate_data_size, const gles2::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584011 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544012 GLuint index = static_cast<GLuint>(c.index);
4013 Bucket* bucket = GetBucket(c.name_bucket_id);
4014 if (!bucket || bucket->size() == 0) {
4015 return error::kInvalidArguments;
4016 }
4017 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184018 if (!bucket->GetAsString(&name_str)) {
4019 return error::kInvalidArguments;
4020 }
[email protected]258a3313f2011-10-18 20:13:574021 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544022 return error::kNoError;
4023}
4024
[email protected]2be6abf32012-06-26 00:28:334025void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
4026 GLuint program, GLint location, const char* name) {
4027 if (!StringIsValidForGLES(name)) {
4028 SetGLError(GL_INVALID_VALUE,
4029 "glBindUniformLocationCHROMIUM", "Invalid character");
4030 return;
4031 }
4032 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
4033 SetGLError(GL_INVALID_OPERATION,
4034 "glBindUniformLocationCHROMIUM", "reserved prefix");
4035 return;
4036 }
4037 if (location < 0 || static_cast<uint32>(location) >=
4038 (group_->max_fragment_uniform_vectors() +
4039 group_->max_vertex_uniform_vectors()) * 4) {
4040 SetGLError(GL_INVALID_VALUE,
4041 "glBindUniformLocationCHROMIUM", "location out of range");
4042 return;
4043 }
4044 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4045 program, "glBindUniformLocationCHROMIUM");
4046 if (!info) {
4047 return;
4048 }
4049 if (!info->SetUniformLocationBinding(name, location)) {
4050 SetGLError(GL_INVALID_VALUE,
4051 "glBindUniformLocationCHROMIUM", "location out of range");
4052 }
4053}
4054
4055error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
4056 uint32 immediate_data_size, const gles2::BindUniformLocationCHROMIUM& c) {
4057 GLuint program = static_cast<GLuint>(c.program);
4058 GLint location = static_cast<GLint>(c.location);
4059 uint32 name_size = c.data_size;
4060 const char* name = GetSharedMemoryAs<const char*>(
4061 c.name_shm_id, c.name_shm_offset, name_size);
4062 if (name == NULL) {
4063 return error::kOutOfBounds;
4064 }
4065 String name_str(name, name_size);
4066 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4067 return error::kNoError;
4068}
4069
4070error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4071 uint32 immediate_data_size,
4072 const gles2::BindUniformLocationCHROMIUMImmediate& c) {
4073 GLuint program = static_cast<GLuint>(c.program);
4074 GLint location = static_cast<GLint>(c.location);
4075 uint32 name_size = c.data_size;
4076 const char* name = GetImmediateDataAs<const char*>(
4077 c, name_size, immediate_data_size);
4078 if (name == NULL) {
4079 return error::kOutOfBounds;
4080 }
4081 String name_str(name, name_size);
4082 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4083 return error::kNoError;
4084}
4085
4086error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4087 uint32 immediate_data_size,
4088 const gles2::BindUniformLocationCHROMIUMBucket& c) {
4089 GLuint program = static_cast<GLuint>(c.program);
4090 GLint location = static_cast<GLint>(c.location);
4091 Bucket* bucket = GetBucket(c.name_bucket_id);
4092 if (!bucket || bucket->size() == 0) {
4093 return error::kInvalidArguments;
4094 }
4095 std::string name_str;
4096 if (!bucket->GetAsString(&name_str)) {
4097 return error::kInvalidArguments;
4098 }
4099 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4100 return error::kNoError;
4101}
4102
[email protected]f7a64ee2010-02-01 22:24:144103error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ba3176a2009-12-16 18:19:464104 uint32 immediate_data_size, const gles2::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034105 GLuint client_id = c.shader;
4106 if (client_id) {
4107 ShaderManager::ShaderInfo* info = GetShaderInfo(client_id);
4108 if (info) {
[email protected]ca488e12010-12-13 20:06:144109 if (!info->IsDeleted()) {
4110 glDeleteShader(info->service_id());
4111 shader_manager()->MarkAsDeleted(info);
4112 }
[email protected]ae51d192010-04-27 00:48:034113 } else {
[email protected]ad84a3a2012-06-08 21:42:434114 SetGLError(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034115 }
[email protected]96449d2c2009-11-25 00:01:324116 }
[email protected]f7a64ee2010-02-01 22:24:144117 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324118}
4119
[email protected]f7a64ee2010-02-01 22:24:144120error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ba3176a2009-12-16 18:19:464121 uint32 immediate_data_size, const gles2::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034122 GLuint client_id = c.program;
4123 if (client_id) {
4124 ProgramManager::ProgramInfo* info = GetProgramInfo(client_id);
4125 if (info) {
[email protected]ca488e12010-12-13 20:06:144126 if (!info->IsDeleted()) {
[email protected]ca488e12010-12-13 20:06:144127 program_manager()->MarkAsDeleted(shader_manager(), info);
4128 }
[email protected]ae51d192010-04-27 00:48:034129 } else {
[email protected]ad84a3a2012-06-08 21:42:434130 SetGLError(GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034131 }
[email protected]96449d2c2009-11-25 00:01:324132 }
[email protected]f7a64ee2010-02-01 22:24:144133 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324134}
4135
[email protected]269200b12010-11-18 22:53:064136void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104137 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574138 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104139 for (GLsizei ii = 0; ii < n; ++ii) {
4140 id_allocator->FreeID(ids[ii]);
4141 }
4142}
4143
[email protected]269200b12010-11-18 22:53:064144error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
4145 uint32 immediate_data_size, const gles2::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104146 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4147 GLsizei n = static_cast<GLsizei>(c.n);
4148 uint32 data_size;
4149 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4150 return error::kOutOfBounds;
4151 }
4152 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4153 c.ids_shm_id, c.ids_shm_offset, data_size);
4154 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434155 SetGLError(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104156 return error::kNoError;
4157 }
4158 if (ids == NULL) {
4159 return error::kOutOfBounds;
4160 }
[email protected]269200b12010-11-18 22:53:064161 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104162 return error::kNoError;
4163}
4164
[email protected]269200b12010-11-18 22:53:064165void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104166 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574167 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104168 if (id_offset == 0) {
4169 for (GLsizei ii = 0; ii < n; ++ii) {
4170 ids[ii] = id_allocator->AllocateID();
4171 }
4172 } else {
4173 for (GLsizei ii = 0; ii < n; ++ii) {
4174 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4175 id_offset = ids[ii] + 1;
4176 }
4177 }
4178}
4179
[email protected]269200b12010-11-18 22:53:064180error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
4181 uint32 immediate_data_size, const gles2::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104182 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4183 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4184 GLsizei n = static_cast<GLsizei>(c.n);
4185 uint32 data_size;
4186 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4187 return error::kOutOfBounds;
4188 }
4189 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4190 c.ids_shm_id, c.ids_shm_offset, data_size);
4191 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434192 SetGLError(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104193 return error::kNoError;
4194 }
4195 if (ids == NULL) {
4196 return error::kOutOfBounds;
4197 }
[email protected]269200b12010-11-18 22:53:064198 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104199 return error::kNoError;
4200}
4201
[email protected]269200b12010-11-18 22:53:064202void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104203 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574204 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104205 for (GLsizei ii = 0; ii < n; ++ii) {
4206 if (!id_allocator->MarkAsUsed(ids[ii])) {
4207 for (GLsizei jj = 0; jj < ii; ++jj) {
4208 id_allocator->FreeID(ids[jj]);
4209 }
4210 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:434211 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4212 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104213 return;
4214 }
4215 }
4216}
4217
[email protected]269200b12010-11-18 22:53:064218error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
4219 uint32 immediate_data_size, const gles2::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104220 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4221 GLsizei n = static_cast<GLsizei>(c.n);
4222 uint32 data_size;
4223 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4224 return error::kOutOfBounds;
4225 }
4226 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4227 c.ids_shm_id, c.ids_shm_offset, data_size);
4228 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434229 SetGLError(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104230 return error::kNoError;
4231 }
4232 if (ids == NULL) {
4233 return error::kOutOfBounds;
4234 }
[email protected]269200b12010-11-18 22:53:064235 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104236 return error::kNoError;
4237}
4238
[email protected]a7266a92012-06-28 02:11:084239error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
4240 if (ShouldDeferDraws())
4241 return error::kDeferCommandUntilLater;
[email protected]0d6bfdc2011-11-02 01:32:204242 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]e259eb412012-10-13 05:47:244243 UNSHIPPED_TRACE_EVENT_INSTANT2(
4244 "test_gpu", "DoClear",
4245 "red", state_.color_clear_red,
4246 "green", state_.color_clear_green);
[email protected]297ca1c2011-06-20 23:08:464247 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274248 glClear(mask);
4249 }
[email protected]a7266a92012-06-28 02:11:084250 return error::kNoError;
4251}
4252
4253error::Error GLES2DecoderImpl::HandleClear(
4254 uint32 immediate_data_size, const gles2::Clear& c) {
4255 GLbitfield mask = static_cast<GLbitfield>(c.mask);
4256 return DoClear(mask);
[email protected]3a03a8f2011-03-19 00:51:274257}
4258
[email protected]36cef8ce2010-03-16 07:34:454259void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4260 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034261 GLuint client_renderbuffer_id) {
[email protected]8e3e0662010-08-23 18:46:304262 FramebufferManager::FramebufferInfo* framebuffer_info =
4263 GetFramebufferInfoForTarget(target);
4264 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294265 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434266 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454267 return;
4268 }
[email protected]ae51d192010-04-27 00:48:034269 GLuint service_id = 0;
[email protected]3a2e7c7b2010-08-06 01:12:284270 RenderbufferManager::RenderbufferInfo* info = NULL;
[email protected]ae51d192010-04-27 00:48:034271 if (client_renderbuffer_id) {
[email protected]3a2e7c7b2010-08-06 01:12:284272 info = GetRenderbufferInfo(client_renderbuffer_id);
[email protected]ae51d192010-04-27 00:48:034273 if (!info) {
[email protected]8eee29c2010-04-29 03:38:294274 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434275 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034276 return;
4277 }
4278 service_id = info->service_id();
4279 }
[email protected]9edc6b22010-12-23 02:00:264280 CopyRealGLErrorsToWrapper();
[email protected]ae51d192010-04-27 00:48:034281 glFramebufferRenderbufferEXT(
4282 target, attachment, renderbuffertarget, service_id);
[email protected]1002c2d2011-06-28 22:39:044283 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264284 if (error == GL_NO_ERROR) {
[email protected]8e3e0662010-08-23 18:46:304285 framebuffer_info->AttachRenderbuffer(attachment, info);
[email protected]3a2e7c7b2010-08-06 01:12:284286 }
[email protected]e259eb412012-10-13 05:47:244287 if (framebuffer_info == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424288 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464289 }
[email protected]3a2e7c7b2010-08-06 01:12:284290}
4291
[email protected]3a2e7c7b2010-08-06 01:12:284292void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464293 if (SetCapabilityState(cap, false)) {
4294 glDisable(cap);
4295 }
[email protected]3a2e7c7b2010-08-06 01:12:284296}
4297
4298void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464299 if (SetCapabilityState(cap, true)) {
4300 glEnable(cap);
4301 }
[email protected]3a2e7c7b2010-08-06 01:12:284302}
4303
[email protected]88a61bf2012-10-27 13:00:424304void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4305 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4306 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4307 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284308}
4309
[email protected]88a61bf2012-10-27 13:00:424310void GLES2DecoderImpl::DoHint(GLenum target, GLenum mode) {
4311 switch (target) {
4312 case GL_GENERATE_MIPMAP_HINT:
4313 state_.hint_generate_mipmap = mode;
4314 break;
4315 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4316 state_.hint_fragment_shader_derivative = mode;
4317 break;
4318 default:
4319 NOTREACHED();
4320 }
4321 glHint(target, mode);
4322}
4323
4324void GLES2DecoderImpl::DoSampleCoverage (GLclampf value, GLboolean invert) {
4325 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4326 state_.sample_coverage_invert = (invert != 0);
4327 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284328}
4329
[email protected]0d6bfdc2011-11-02 01:32:204330// Assumes framebuffer is complete.
4331void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]8e3e0662010-08-23 18:46:304332 GLenum target, FramebufferManager::FramebufferInfo* info) {
4333 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204334 // bind this to the DRAW point, clear then bind back to READ
4335 // TODO(gman): I don't think there is any guarantee that an FBO that
4336 // is complete on the READ attachment will be complete as a DRAW
4337 // attachment.
4338 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
4339 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, info->service_id());
[email protected]8e3e0662010-08-23 18:46:304340 }
[email protected]3a2e7c7b2010-08-06 01:12:284341 GLbitfield clear_bits = 0;
4342 if (info->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464343 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204344 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464345 (GLES2Util::GetChannelsForFormat(
[email protected]0d6bfdc2011-11-02 01:32:204346 info->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f : 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284347 glColorMask(true, true, true, true);
4348 clear_bits |= GL_COLOR_BUFFER_BIT;
4349 }
4350
4351 if (info->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4352 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
4353 glClearStencil(0);
4354 glStencilMask(-1);
4355 clear_bits |= GL_STENCIL_BUFFER_BIT;
4356 }
4357
4358 if (info->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4359 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
4360 glClearDepth(1.0f);
4361 glDepthMask(true);
4362 clear_bits |= GL_DEPTH_BUFFER_BIT;
4363 }
4364
4365 glDisable(GL_SCISSOR_TEST);
4366 glClear(clear_bits);
4367
[email protected]968351b2011-12-20 08:26:514368 framebuffer_manager()->MarkAttachmentsAsCleared(
4369 info, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284370
[email protected]c007aa02010-09-02 22:22:404371 RestoreClearState();
4372
4373 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204374 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, info->service_id());
[email protected]87d1a3fe2011-12-01 04:25:484375 FramebufferManager::FramebufferInfo* framebuffer =
4376 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4377 GLuint service_id =
4378 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
4379 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404380 }
4381}
4382
4383void GLES2DecoderImpl::RestoreClearState() {
[email protected]88a61bf2012-10-27 13:00:424384 clear_state_dirty_ = true;
[email protected]e259eb412012-10-13 05:47:244385 glClearColor(
4386 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4387 state_.color_clear_alpha);
4388 glClearStencil(state_.stencil_clear);
4389 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224390 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284391 glEnable(GL_SCISSOR_TEST);
4392 }
[email protected]36cef8ce2010-03-16 07:34:454393}
4394
4395GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]0d6bfdc2011-11-02 01:32:204396 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304397 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204398 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454399 return GL_FRAMEBUFFER_COMPLETE;
4400 }
[email protected]0d6bfdc2011-11-02 01:32:204401 GLenum completeness = framebuffer->IsPossiblyComplete();
4402 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4403 return completeness;
4404 }
[email protected]73276522012-11-09 05:50:204405 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454406}
4407
4408void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034409 GLenum target, GLenum attachment, GLenum textarget,
4410 GLuint client_texture_id, GLint level) {
[email protected]8e3e0662010-08-23 18:46:304411 FramebufferManager::FramebufferInfo* framebuffer_info =
4412 GetFramebufferInfoForTarget(target);
4413 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294414 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434415 "glFramebufferTexture2D", "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454416 return;
4417 }
[email protected]ae51d192010-04-27 00:48:034418 GLuint service_id = 0;
[email protected]3a2e7c7b2010-08-06 01:12:284419 TextureManager::TextureInfo* info = NULL;
[email protected]ae51d192010-04-27 00:48:034420 if (client_texture_id) {
[email protected]3a2e7c7b2010-08-06 01:12:284421 info = GetTextureInfo(client_texture_id);
[email protected]ae51d192010-04-27 00:48:034422 if (!info) {
[email protected]8eee29c2010-04-29 03:38:294423 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434424 "glFramebufferTexture2D", "unknown texture");
[email protected]ae51d192010-04-27 00:48:034425 return;
4426 }
4427 service_id = info->service_id();
4428 }
[email protected]0d6bfdc2011-11-02 01:32:204429
[email protected]80eb6b52012-01-19 00:14:414430 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]0d6bfdc2011-11-02 01:32:204431 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434432 "glFramebufferTexture2D", "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204433 return;
4434 }
4435
[email protected]9edc6b22010-12-23 02:00:264436 CopyRealGLErrorsToWrapper();
[email protected]ae51d192010-04-27 00:48:034437 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
[email protected]1002c2d2011-06-28 22:39:044438 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264439 if (error == GL_NO_ERROR) {
4440 framebuffer_info->AttachTexture(attachment, info, textarget, level);
[email protected]3a2e7c7b2010-08-06 01:12:284441 }
[email protected]e259eb412012-10-13 05:47:244442 if (framebuffer_info == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424443 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464444 }
[email protected]36cef8ce2010-03-16 07:34:454445}
4446
4447void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4448 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]8e3e0662010-08-23 18:46:304449 FramebufferManager::FramebufferInfo* framebuffer_info =
4450 GetFramebufferInfoForTarget(target);
4451 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294452 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434453 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454454 return;
4455 }
4456 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:574457 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
4458 GLint type = 0;
4459 GLuint client_id = 0;
4460 glGetFramebufferAttachmentParameterivEXT(
4461 target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
4462 switch (type) {
4463 case GL_RENDERBUFFER: {
4464 renderbuffer_manager()->GetClientId(*params, &client_id);
4465 break;
4466 }
4467 case GL_TEXTURE: {
4468 texture_manager()->GetClientId(*params, &client_id);
4469 break;
4470 }
4471 default:
4472 break;
4473 }
4474 *params = client_id;
4475 }
[email protected]36cef8ce2010-03-16 07:34:454476}
4477
4478void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
4479 GLenum target, GLenum pname, GLint* params) {
[email protected]0d6bfdc2011-11-02 01:32:204480 RenderbufferManager::RenderbufferInfo* renderbuffer =
4481 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4482 if (!renderbuffer) {
[email protected]8eee29c2010-04-29 03:38:294483 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434484 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454485 return;
4486 }
[email protected]3a03a8f2011-03-19 00:51:274487 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434488 case GL_RENDERBUFFER_INTERNAL_FORMAT:
4489 *params = renderbuffer->internal_format();
4490 break;
4491 case GL_RENDERBUFFER_WIDTH:
4492 *params = renderbuffer->width();
4493 break;
4494 case GL_RENDERBUFFER_HEIGHT:
4495 *params = renderbuffer->height();
4496 break;
4497 default:
4498 glGetRenderbufferParameterivEXT(target, pname, params);
4499 break;
[email protected]b71f52c2010-06-18 22:20:204500 }
[email protected]36cef8ce2010-03-16 07:34:454501}
4502
[email protected]8e3e0662010-08-23 18:46:304503void GLES2DecoderImpl::DoBlitFramebufferEXT(
4504 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4505 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4506 GLbitfield mask, GLenum filter) {
[email protected]62e155e2012-10-23 22:43:154507 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:304508 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434509 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304510 }
[email protected]d058bca2012-11-26 10:27:264511 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:244512 if (IsAngle()) {
4513 glBlitFramebufferANGLE(
4514 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4515 } else {
4516 glBlitFramebufferEXT(
4517 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4518 }
[email protected]d058bca2012-11-26 10:27:264519 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]529c6672012-01-04 02:18:264520 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", "width", srcX1 - srcX0);
[email protected]8e3e0662010-08-23 18:46:304521}
4522
4523void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
4524 GLenum target, GLsizei samples, GLenum internalformat,
4525 GLsizei width, GLsizei height) {
[email protected]62e155e2012-10-23 22:43:154526 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:304527 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434528 "glRenderbufferStorageMultisampleEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304529 return;
4530 }
[email protected]8e3e0662010-08-23 18:46:304531
[email protected]0d6bfdc2011-11-02 01:32:204532 RenderbufferManager::RenderbufferInfo* renderbuffer =
4533 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4534 if (!renderbuffer) {
4535 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434536 "glGetRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:204537 return;
4538 }
4539
[email protected]84afefa2011-10-19 21:45:534540 if (samples > renderbuffer_manager()->max_samples()) {
4541 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434542 "glGetRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:534543 return;
4544 }
4545
4546 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
4547 height > renderbuffer_manager()->max_renderbuffer_size()) {
4548 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434549 "glGetRenderbufferStorageMultisample", "size too large");
[email protected]84afefa2011-10-19 21:45:534550 return;
4551 }
4552
[email protected]9edc6b22010-12-23 02:00:264553 GLenum impl_format = internalformat;
[email protected]8e3e0662010-08-23 18:46:304554 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
[email protected]9edc6b22010-12-23 02:00:264555 switch (impl_format) {
[email protected]8e3e0662010-08-23 18:46:304556 case GL_DEPTH_COMPONENT16:
[email protected]9edc6b22010-12-23 02:00:264557 impl_format = GL_DEPTH_COMPONENT;
[email protected]8e3e0662010-08-23 18:46:304558 break;
4559 case GL_RGBA4:
4560 case GL_RGB5_A1:
[email protected]9edc6b22010-12-23 02:00:264561 impl_format = GL_RGBA;
[email protected]8e3e0662010-08-23 18:46:304562 break;
4563 case GL_RGB565:
[email protected]9edc6b22010-12-23 02:00:264564 impl_format = GL_RGB;
[email protected]8e3e0662010-08-23 18:46:304565 break;
4566 }
4567 }
4568
[email protected]9edc6b22010-12-23 02:00:264569 CopyRealGLErrorsToWrapper();
[email protected]866b91c52011-03-23 14:38:084570 if (IsAngle()) {
4571 glRenderbufferStorageMultisampleANGLE(
4572 target, samples, impl_format, width, height);
4573 } else {
4574 glRenderbufferStorageMultisampleEXT(
4575 target, samples, impl_format, width, height);
4576 }
[email protected]1002c2d2011-06-28 22:39:044577 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264578 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:514579 // TODO(gman): If renderbuffers tracked which framebuffers they were
4580 // attached to we could just mark those framebuffers as not complete.
4581 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:204582 renderbuffer_manager()->SetInfo(
4583 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:264584 }
[email protected]8e3e0662010-08-23 18:46:304585}
4586
[email protected]36cef8ce2010-03-16 07:34:454587void GLES2DecoderImpl::DoRenderbufferStorage(
4588 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]0d6bfdc2011-11-02 01:32:204589 RenderbufferManager::RenderbufferInfo* renderbuffer =
4590 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4591 if (!renderbuffer) {
[email protected]8eee29c2010-04-29 03:38:294592 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434593 "glGetRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454594 return;
4595 }
[email protected]876f6fee2010-08-02 23:10:324596
[email protected]84afefa2011-10-19 21:45:534597 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
4598 height > renderbuffer_manager()->max_renderbuffer_size()) {
4599 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434600 "glGetRenderbufferStorage", "size too large");
[email protected]84afefa2011-10-19 21:45:534601 return;
4602 }
4603
[email protected]9edc6b22010-12-23 02:00:264604 GLenum impl_format = internalformat;
[email protected]876f6fee2010-08-02 23:10:324605 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
[email protected]9edc6b22010-12-23 02:00:264606 switch (impl_format) {
[email protected]876f6fee2010-08-02 23:10:324607 case GL_DEPTH_COMPONENT16:
[email protected]9edc6b22010-12-23 02:00:264608 impl_format = GL_DEPTH_COMPONENT;
[email protected]876f6fee2010-08-02 23:10:324609 break;
4610 case GL_RGBA4:
4611 case GL_RGB5_A1:
[email protected]9edc6b22010-12-23 02:00:264612 impl_format = GL_RGBA;
[email protected]876f6fee2010-08-02 23:10:324613 break;
4614 case GL_RGB565:
[email protected]9edc6b22010-12-23 02:00:264615 impl_format = GL_RGB;
[email protected]876f6fee2010-08-02 23:10:324616 break;
4617 }
[email protected]b71f52c2010-06-18 22:20:204618 }
[email protected]876f6fee2010-08-02 23:10:324619
[email protected]9edc6b22010-12-23 02:00:264620 CopyRealGLErrorsToWrapper();
4621 glRenderbufferStorageEXT(target, impl_format, width, height);
[email protected]1002c2d2011-06-28 22:39:044622 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264623 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:514624 // TODO(gman): If tetxures tracked which framebuffers they were attached to
4625 // we could just mark those framebuffers as not complete.
4626 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:204627 renderbuffer_manager()->SetInfo(
4628 renderbuffer, 0, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:264629 }
[email protected]36cef8ce2010-03-16 07:34:454630}
4631
[email protected]07f54fcc2009-12-22 02:46:304632void GLES2DecoderImpl::DoLinkProgram(GLuint program) {
[email protected]43ed3a72012-05-30 22:55:384633 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]6b8cf1a2010-05-06 16:13:584634 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4635 program, "glLinkProgram");
[email protected]a93bb842010-02-16 23:03:474636 if (!info) {
[email protected]a93bb842010-02-16 23:03:474637 return;
4638 }
[email protected]05afda12011-01-20 00:17:344639
[email protected]65dfc602012-07-23 20:39:394640 ShaderTranslator* vertex_translator = NULL;
4641 ShaderTranslator* fragment_translator = NULL;
4642 if (use_shader_translator_) {
4643 vertex_translator = vertex_translator_;
4644 fragment_translator = fragment_translator_;
4645 }
4646 if (info->Link(shader_manager(),
4647 vertex_translator,
4648 fragment_translator,
4649 feature_info_)) {
[email protected]e259eb412012-10-13 05:47:244650 if (info == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:154651 if (workarounds().use_current_program_after_successful_link) {
4652 glUseProgram(info->service_id());
[email protected]c2a3caf12012-10-23 19:32:004653 }
[email protected]62e155e2012-10-23 22:43:154654 program_manager()->ClearUniforms(info);
[email protected]2df73892012-04-28 01:09:544655 }
4656 }
[email protected]07f54fcc2009-12-22 02:46:304657};
4658
[email protected]3916c97e2010-02-25 03:20:504659void GLES2DecoderImpl::DoTexParameterf(
4660 GLenum target, GLenum pname, GLfloat param) {
4661 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]07f54fcc2009-12-22 02:46:304662 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434663 SetGLError(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244664 return;
[email protected]07f54fcc2009-12-22 02:46:304665 }
[email protected]cbb22e42011-05-12 23:36:244666
4667 if (!texture_manager()->SetParameter(
[email protected]80eb6b52012-01-19 00:14:414668 info, pname, static_cast<GLint>(param))) {
[email protected]f80e6e12012-08-31 00:43:534669 SetGLErrorInvalidEnum("glTexParameterf", pname, "pname");
[email protected]cbb22e42011-05-12 23:36:244670 return;
4671 }
4672 glTexParameterf(target, pname, param);
[email protected]07f54fcc2009-12-22 02:46:304673}
4674
[email protected]3916c97e2010-02-25 03:20:504675void GLES2DecoderImpl::DoTexParameteri(
4676 GLenum target, GLenum pname, GLint param) {
4677 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4678 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434679 SetGLError(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244680 return;
[email protected]3916c97e2010-02-25 03:20:504681 }
[email protected]cbb22e42011-05-12 23:36:244682
[email protected]80eb6b52012-01-19 00:14:414683 if (!texture_manager()->SetParameter(info, pname, param)) {
[email protected]f80e6e12012-08-31 00:43:534684 SetGLErrorInvalidEnum("glTexParameteri", pname, "pname");
[email protected]cbb22e42011-05-12 23:36:244685 return;
4686 }
4687 glTexParameteri(target, pname, param);
[email protected]3916c97e2010-02-25 03:20:504688}
4689
4690void GLES2DecoderImpl::DoTexParameterfv(
4691 GLenum target, GLenum pname, const GLfloat* params) {
4692 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4693 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434694 SetGLError(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244695 return;
[email protected]3916c97e2010-02-25 03:20:504696 }
[email protected]cbb22e42011-05-12 23:36:244697
4698 if (!texture_manager()->SetParameter(
[email protected]80eb6b52012-01-19 00:14:414699 info, pname, static_cast<GLint>(params[0]))) {
[email protected]f80e6e12012-08-31 00:43:534700 SetGLErrorInvalidEnum("glTexParameterfv", pname, "pname");
[email protected]cbb22e42011-05-12 23:36:244701 return;
4702 }
4703 glTexParameterfv(target, pname, params);
[email protected]3916c97e2010-02-25 03:20:504704}
4705
4706void GLES2DecoderImpl::DoTexParameteriv(
4707 GLenum target, GLenum pname, const GLint* params) {
4708 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4709 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434710 SetGLError(GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244711 return;
[email protected]3916c97e2010-02-25 03:20:504712 }
[email protected]cbb22e42011-05-12 23:36:244713
[email protected]80eb6b52012-01-19 00:14:414714 if (!texture_manager()->SetParameter(info, pname, *params)) {
[email protected]f80e6e12012-08-31 00:43:534715 SetGLErrorInvalidEnum("glTexParameteriv", pname, "pname");
[email protected]cbb22e42011-05-12 23:36:244716 return;
4717 }
4718 glTexParameteriv(target, pname, params);
[email protected]3916c97e2010-02-25 03:20:504719}
4720
[email protected]939e7362010-05-13 20:49:104721bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]e259eb412012-10-13 05:47:244722 if (!state_.current_program) {
[email protected]ad84a3a2012-06-08 21:42:434723 // The program does not exist.
4724 SetGLError(GL_INVALID_OPERATION, function_name, "no program in use");
4725 return false;
[email protected]939e7362010-05-13 20:49:104726 }
[email protected]e259eb412012-10-13 05:47:244727 if (!state_.current_program->InUse()) {
[email protected]ad84a3a2012-06-08 21:42:434728 SetGLError(GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:104729 return false;
4730 }
4731 return true;
4732}
4733
4734bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
4735 GLint location, const char* function_name) {
4736 if (!CheckCurrentProgram(function_name)) {
4737 return false;
4738 }
4739 return location != -1;
4740}
4741
[email protected]43c2f1f2011-03-25 18:35:364742bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:124743 GLint fake_location, const char* function_name,
4744 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:364745 DCHECK(type);
4746 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:124747 DCHECK(real_location);
4748 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:104749 return false;
4750 }
[email protected]43c2f1f2011-03-25 18:35:364751 GLint array_index = -1;
4752 const ProgramManager::ProgramInfo::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:244753 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:124754 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:364755 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434756 SetGLError(GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:104757 return false;
4758 }
[email protected]43c2f1f2011-03-25 18:35:364759 if (*count > 1 && !info->is_array) {
4760 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:434761 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:364762 return false;
4763 }
4764 *count = std::min(info->size - array_index, *count);
4765 if (*count <= 0) {
4766 return false;
4767 }
4768 *type = info->type;
[email protected]939e7362010-05-13 20:49:104769 return true;
4770}
4771
[email protected]1b0a6752012-02-22 03:44:124772void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
4773 GLenum type = 0;
4774 GLsizei count = 1;
4775 GLint real_location = -1;
4776 if (!PrepForSetUniformByLocation(
4777 fake_location, "glUniform1iv", &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:504778 return;
4779 }
[email protected]e259eb412012-10-13 05:47:244780 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:024781 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ad84a3a2012-06-08 21:42:434782 SetGLError(GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:464783 return;
4784 }
[email protected]1b0a6752012-02-22 03:44:124785 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:504786}
4787
4788void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:124789 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:364790 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124791 GLint real_location = -1;
4792 if (!PrepForSetUniformByLocation(
4793 fake_location, "glUniform1iv", &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:364794 return;
4795 }
[email protected]74727112012-06-13 21:18:084796 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
4797 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:244798 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:024799 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ad84a3a2012-06-08 21:42:434800 SetGLError(GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:464801 return;
4802 }
[email protected]43c2f1f2011-03-25 18:35:364803 }
[email protected]1b0a6752012-02-22 03:44:124804 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:504805}
4806
[email protected]939e7362010-05-13 20:49:104807void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:124808 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:364809 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124810 GLint real_location = -1;
4811 if (!PrepForSetUniformByLocation(
4812 fake_location, "glUniform1fv", &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:104813 return;
4814 }
4815 if (type == GL_BOOL) {
4816 scoped_array<GLint> temp(new GLint[count]);
4817 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:534818 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:104819 }
[email protected]1b0a6752012-02-22 03:44:124820 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:104821 } else {
[email protected]1b0a6752012-02-22 03:44:124822 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:104823 }
4824}
4825
4826void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:124827 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:364828 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124829 GLint real_location = -1;
4830 if (!PrepForSetUniformByLocation(
4831 fake_location, "glUniform2fv", &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:104832 return;
4833 }
4834 if (type == GL_BOOL_VEC2) {
4835 GLsizei num_values = count * 2;
4836 scoped_array<GLint> temp(new GLint[num_values]);
4837 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:534838 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:104839 }
[email protected]1b0a6752012-02-22 03:44:124840 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:104841 } else {
[email protected]1b0a6752012-02-22 03:44:124842 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:104843 }
4844}
4845
4846void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:124847 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:364848 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124849 GLint real_location = -1;
4850 if (!PrepForSetUniformByLocation(
4851 fake_location, "glUniform3fv", &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:104852 return;
4853 }
4854 if (type == GL_BOOL_VEC3) {
4855 GLsizei num_values = count * 3;
4856 scoped_array<GLint> temp(new GLint[num_values]);
4857 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:534858 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:104859 }
[email protected]1b0a6752012-02-22 03:44:124860 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:104861 } else {
[email protected]1b0a6752012-02-22 03:44:124862 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:104863 }
4864}
4865
4866void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:124867 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:364868 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124869 GLint real_location = -1;
4870 if (!PrepForSetUniformByLocation(
4871 fake_location, "glUniform4fv", &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:104872 return;
4873 }
4874 if (type == GL_BOOL_VEC4) {
4875 GLsizei num_values = count * 4;
4876 scoped_array<GLint> temp(new GLint[num_values]);
4877 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:534878 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:104879 }
[email protected]1b0a6752012-02-22 03:44:124880 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:104881 } else {
[email protected]1b0a6752012-02-22 03:44:124882 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:104883 }
4884}
4885
[email protected]43c2f1f2011-03-25 18:35:364886void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:124887 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:364888 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124889 GLint real_location = -1;
4890 if (!PrepForSetUniformByLocation(
4891 fake_location, "glUniform2iv", &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:364892 return;
4893 }
[email protected]1b0a6752012-02-22 03:44:124894 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:364895}
4896
4897void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:124898 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:364899 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124900 GLint real_location = -1;
4901 if (!PrepForSetUniformByLocation(
4902 fake_location, "glUniform3iv", &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:364903 return;
4904 }
[email protected]1b0a6752012-02-22 03:44:124905 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:364906}
4907
4908void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:124909 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:364910 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124911 GLint real_location = -1;
4912 if (!PrepForSetUniformByLocation(
4913 fake_location, "glUniform4iv", &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:364914 return;
4915 }
[email protected]1b0a6752012-02-22 03:44:124916 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:364917}
4918
4919void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:124920 GLint fake_location, GLsizei count, GLboolean transpose,
4921 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:364922 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124923 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:364924 if (!PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:124925 fake_location, "glUniformMatrix2fv", &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:364926 return;
4927 }
[email protected]1b0a6752012-02-22 03:44:124928 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:364929}
4930
4931void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:124932 GLint fake_location, GLsizei count, GLboolean transpose,
4933 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:364934 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124935 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:364936 if (!PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:124937 fake_location, "glUniformMatrix3fv", &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:364938 return;
4939 }
[email protected]1b0a6752012-02-22 03:44:124940 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:364941}
4942
4943void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:124944 GLint fake_location, GLsizei count, GLboolean transpose,
4945 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:364946 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:124947 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:364948 if (!PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:124949 fake_location, "glUniformMatrix4fv", &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:364950 return;
4951 }
[email protected]1b0a6752012-02-22 03:44:124952 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:364953}
4954
[email protected]3916c97e2010-02-25 03:20:504955void GLES2DecoderImpl::DoUseProgram(GLuint program) {
[email protected]ae51d192010-04-27 00:48:034956 GLuint service_id = 0;
[email protected]3916c97e2010-02-25 03:20:504957 ProgramManager::ProgramInfo* info = NULL;
4958 if (program) {
[email protected]6b8cf1a2010-05-06 16:13:584959 info = GetProgramInfoNotShader(program, "glUseProgram");
[email protected]3916c97e2010-02-25 03:20:504960 if (!info) {
[email protected]ae51d192010-04-27 00:48:034961 return;
4962 }
4963 if (!info->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:504964 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ad84a3a2012-06-08 21:42:434965 SetGLError(GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:504966 return;
4967 }
[email protected]ae51d192010-04-27 00:48:034968 service_id = info->service_id();
[email protected]3916c97e2010-02-25 03:20:504969 }
[email protected]e259eb412012-10-13 05:47:244970 if (state_.current_program) {
4971 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
[email protected]ca488e12010-12-13 20:06:144972 }
[email protected]e259eb412012-10-13 05:47:244973 state_.current_program = info;
[email protected]2df73892012-04-28 01:09:544974 glUseProgram(service_id);
[email protected]e259eb412012-10-13 05:47:244975 if (state_.current_program) {
4976 program_manager()->UseProgram(state_.current_program);
[email protected]ca488e12010-12-13 20:06:144977 }
[email protected]3916c97e2010-02-25 03:20:504978}
4979
[email protected]efcdd2362012-07-09 21:07:004980uint32 GLES2DecoderImpl::GetGLError() {
[email protected]96449d2c2009-11-25 00:01:324981 // Check the GL error first, then our wrapped error.
4982 GLenum error = glGetError();
4983 if (error == GL_NO_ERROR && error_bits_ != 0) {
[email protected]03f882a2010-01-08 20:46:374984 for (uint32 mask = 1; mask != 0; mask = mask << 1) {
[email protected]96449d2c2009-11-25 00:01:324985 if ((error_bits_ & mask) != 0) {
[email protected]ddd968b82010-03-02 00:44:294986 error = GLES2Util::GLErrorBitToGLError(mask);
[email protected]96449d2c2009-11-25 00:01:324987 break;
4988 }
4989 }
4990 }
4991
4992 if (error != GL_NO_ERROR) {
4993 // There was an error, clear the corresponding wrapped error.
[email protected]ddd968b82010-03-02 00:44:294994 error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
[email protected]96449d2c2009-11-25 00:01:324995 }
4996 return error;
4997}
4998
[email protected]1002c2d2011-06-28 22:39:044999GLenum GLES2DecoderImpl::PeekGLError() {
5000 GLenum error = glGetError();
5001 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435002 SetGLError(error, "", "");
[email protected]1002c2d2011-06-28 22:39:045003 }
5004 return error;
5005}
5006
[email protected]ad84a3a2012-06-08 21:42:435007void GLES2DecoderImpl::SetGLError(
5008 GLenum error, const char* function_name, const char* msg) {
[email protected]8eee29c2010-04-29 03:38:295009 if (msg) {
5010 last_error_ = msg;
[email protected]d2a0e1a2012-08-12 02:25:015011 LogMessage(GetLogPrefix() + ": " + std::string("GL ERROR :") +
[email protected]ad84a3a2012-06-08 21:42:435012 GLES2Util::GetStringEnum(error) + " : " +
5013 function_name + ": " + msg);
[email protected]8eee29c2010-04-29 03:38:295014 }
[email protected]ddd968b82010-03-02 00:44:295015 error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
[email protected]96449d2c2009-11-25 00:01:325016}
5017
[email protected]f80e6e12012-08-31 00:43:535018void GLES2DecoderImpl::SetGLErrorInvalidEnum(
5019 const char* function_name, GLenum value, const char* label) {
5020 SetGLError(GL_INVALID_ENUM, function_name,
5021 (std::string(label) + " was " +
5022 GLES2Util::GetStringEnum(value)).c_str());
5023}
5024
[email protected]d2a0e1a2012-08-12 02:25:015025const std::string& GLES2DecoderImpl::GetLogPrefix() const {
5026 const std::string& prefix(debug_marker_manager_.GetMarker());
5027 return prefix.empty() ? this_in_hex_ : prefix;
5028}
5029
[email protected]0f8afe82012-05-14 23:43:015030void GLES2DecoderImpl::LogMessage(const std::string& msg) {
5031 if (log_message_count_ < kMaxLogMessages ||
5032 CommandLine::ForCurrentProcess()->HasSwitch(
5033 switches::kDisableGLErrorLimit)) {
5034 ++log_message_count_;
5035 // LOG this unless logging is turned off as any chromium code that
5036 // generates these errors probably has a bug.
5037 if (log_synthesized_gl_errors()) {
[email protected]3f00df92012-06-19 00:44:585038 LOG(ERROR) << msg;
[email protected]0f8afe82012-05-14 23:43:015039 }
5040 if (!msg_callback_.is_null()) {
5041 msg_callback_.Run(0, msg);
5042 }
5043 } else {
5044 if (log_message_count_ == kMaxLogMessages) {
5045 ++log_message_count_;
5046 LOG(ERROR)
5047 << "Too many GL errors, not reporting any more for this context."
5048 << " use --disable-gl-error-limit to see all errors.";
5049 }
5050 }
5051}
5052
5053void GLES2DecoderImpl::RenderWarning(const std::string& msg) {
5054 LogMessage(std::string("RENDER WARNING: ") + msg);
5055}
5056
5057void GLES2DecoderImpl::PerformanceWarning(const std::string& msg) {
5058 LogMessage(std::string("PERFORMANCE WARNING: ") + msg);
5059}
5060
[email protected]c447acd2012-07-23 23:48:415061void GLES2DecoderImpl::ForceCompileShaderIfPending(
5062 ShaderManager::ShaderInfo* info) {
5063 if (info->compilation_status() ==
5064 ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE) {
[email protected]c447acd2012-07-23 23:48:415065 ShaderTranslator* translator = NULL;
5066 if (use_shader_translator_) {
5067 translator = info->shader_type() == GL_VERTEX_SHADER ?
5068 vertex_translator_.get() : fragment_translator_.get();
5069 }
5070 // We know there will be no errors, because we only defer compilation on
5071 // shaders that were previously compiled successfully.
5072 program_manager()->ForceCompileShader(info->deferred_compilation_source(),
5073 info,
5074 translator,
5075 feature_info_);
5076 }
5077}
5078
[email protected]07f54fcc2009-12-22 02:46:305079void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() {
5080 GLenum error;
5081 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435082 SetGLError(error, "", NULL);
[email protected]07f54fcc2009-12-22 02:46:305083 }
5084}
5085
[email protected]6217d392010-03-25 22:08:355086void GLES2DecoderImpl::ClearRealGLErrors() {
5087 GLenum error;
5088 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]3ed14d112011-12-13 22:05:515089 if (error != GL_OUT_OF_MEMORY) {
5090 // GL_OUT_OF_MEMORY can legally happen on lost device.
5091 NOTREACHED() << "GL error " << error << " was unhandled.";
5092 }
[email protected]6217d392010-03-25 22:08:355093 }
5094}
5095
[email protected]ef526492010-06-02 23:12:255096bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245097 DCHECK(state_.current_program);
[email protected]ef526492010-06-02 23:12:255098 // Only check if there are some unrenderable textures.
5099 if (!texture_manager()->HaveUnrenderableTextures()) {
5100 return false;
5101 }
5102 bool textures_set = false;
[email protected]3916c97e2010-02-25 03:20:505103 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245104 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505105 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5106 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245107 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505108 DCHECK(uniform_info);
5109 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5110 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025111 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245112 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]3916c97e2010-02-25 03:20:505113 TextureManager::TextureInfo* texture_info =
[email protected]61eeb33f2011-07-26 15:30:315114 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]80eb6b52012-01-19 00:14:415115 if (!texture_info || !texture_manager()->CanRender(texture_info)) {
[email protected]ef526492010-06-02 23:12:255116 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505117 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5118 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315119 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495120 texture_manager()->black_texture_id(uniform_info->type));
[email protected]0f8afe82012-05-14 23:43:015121 RenderWarning(
5122 std::string("texture bound to texture unit ") +
5123 base::IntToString(texture_unit_index) +
5124 " is not renderable. It maybe non-power-of-2 and have "
5125 " incompatible texture filtering or is not "
5126 "'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505127 }
5128 }
5129 // else: should this be an error?
5130 }
5131 }
[email protected]ef526492010-06-02 23:12:255132 return textures_set;
[email protected]3916c97e2010-02-25 03:20:505133}
5134
5135void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245136 DCHECK(state_.current_program);
[email protected]3916c97e2010-02-25 03:20:505137 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245138 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505139 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5140 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245141 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505142 DCHECK(uniform_info);
5143 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5144 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025145 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245146 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]3916c97e2010-02-25 03:20:505147 TextureManager::TextureInfo* texture_info =
5148 uniform_info->type == GL_SAMPLER_2D ?
5149 texture_unit.bound_texture_2d :
5150 texture_unit.bound_texture_cube_map;
[email protected]80eb6b52012-01-19 00:14:415151 if (!texture_info || !texture_manager()->CanRender(texture_info)) {
[email protected]3916c97e2010-02-25 03:20:505152 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5153 // Get the texture info that was previously bound here.
5154 texture_info = texture_unit.bind_target == GL_TEXTURE_2D ?
5155 texture_unit.bound_texture_2d :
5156 texture_unit.bound_texture_cube_map;
5157 glBindTexture(texture_unit.bind_target,
[email protected]ae51d192010-04-27 00:48:035158 texture_info ? texture_info->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505159 }
5160 }
5161 }
5162 }
5163 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245164 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305165}
5166
[email protected]0d6bfdc2011-11-02 01:32:205167bool GLES2DecoderImpl::ClearUnclearedTextures() {
5168 // Only check if there are some uncleared textures.
5169 if (!texture_manager()->HaveUnsafeTextures()) {
5170 return true;
5171 }
5172
5173 // 1: Check all textures we are about to render with.
[email protected]e259eb412012-10-13 05:47:245174 if (state_.current_program) {
[email protected]0d6bfdc2011-11-02 01:32:205175 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245176 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205177 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5178 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245179 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205180 DCHECK(uniform_info);
5181 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5182 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025183 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245184 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]0d6bfdc2011-11-02 01:32:205185 TextureManager::TextureInfo* texture_info =
5186 texture_unit.GetInfoForSamplerType(uniform_info->type);
5187 if (texture_info && !texture_info->SafeToRenderFrom()) {
5188 if (!texture_manager()->ClearRenderableLevels(this, texture_info)) {
5189 return false;
5190 }
5191 }
5192 }
5193 }
5194 }
5195 }
5196 return true;
5197}
5198
[email protected]c6aef902012-02-14 03:31:425199bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435200 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035201 // NOTE: We specifically do not check current_program->IsValid() because
5202 // it could never be invalid since glUseProgram would have failed. While
5203 // glLinkProgram could later mark the program as invalid the previous
5204 // valid program will still function if it is still the current program.
[email protected]e259eb412012-10-13 05:47:245205 if (!state_.current_program) {
[email protected]3916c97e2010-02-25 03:20:505206 // The program does not exist.
5207 // But GL says no ERROR.
[email protected]0f8afe82012-05-14 23:43:015208 RenderWarning("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505209 return false;
5210 }
[email protected]c6aef902012-02-14 03:31:425211
5212 // true if any enabled, used divisor is zero
5213 bool divisor0 = false;
[email protected]f39f4b3f2010-05-12 17:04:085214 // Validate all attribs currently enabled. If they are used by the current
5215 // program then check that they have enough elements to handle the draw call.
5216 // If they are not used by the current program check that they have a buffer
5217 // assigned.
5218 const VertexAttribManager::VertexAttribInfoList& infos =
[email protected]e259eb412012-10-13 05:47:245219 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos();
[email protected]f39f4b3f2010-05-12 17:04:085220 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
[email protected]8fbedc02010-11-18 18:43:405221 infos.begin(); it != infos.end(); ++it) {
[email protected]f39f4b3f2010-05-12 17:04:085222 const VertexAttribManager::VertexAttribInfo* info = *it;
5223 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245224 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]f39f4b3f2010-05-12 17:04:085225 if (attrib_info) {
[email protected]c6aef902012-02-14 03:31:425226 divisor0 |= (info->divisor() == 0);
5227 GLuint count = info->MaxVertexAccessed(primcount, max_vertex_accessed);
[email protected]f39f4b3f2010-05-12 17:04:085228 // This attrib is used in the current program.
[email protected]c6aef902012-02-14 03:31:425229 if (!info->CanAccess(count)) {
[email protected]0f8afe82012-05-14 23:43:015230 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435231 GL_INVALID_OPERATION, function_name,
[email protected]0f8afe82012-05-14 23:43:015232 (std::string(
[email protected]ad84a3a2012-06-08 21:42:435233 "attempt to access out of range vertices in attribute ") +
5234 base::IntToString(info->index())).c_str());
[email protected]f39f4b3f2010-05-12 17:04:085235 return false;
5236 }
5237 } else {
5238 // This attrib is not used in the current program.
[email protected]a0b78dc2011-11-11 10:43:105239 if (!info->buffer()) {
[email protected]f39f4b3f2010-05-12 17:04:085240 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435241 GL_INVALID_OPERATION, function_name,
[email protected]0f8afe82012-05-14 23:43:015242 (std::string(
[email protected]ad84a3a2012-06-08 21:42:435243 "attempt to render with no buffer attached to "
[email protected]0f8afe82012-05-14 23:43:015244 "enabled attribute ") +
5245 base::IntToString(info->index())).c_str());
[email protected]f39f4b3f2010-05-12 17:04:085246 return false;
5247 }
[email protected]1d32bc82010-01-13 22:06:465248 }
[email protected]07f54fcc2009-12-22 02:46:305249 }
[email protected]c6aef902012-02-14 03:31:425250
5251 if (primcount && !divisor0) {
5252 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435253 GL_INVALID_OPERATION, function_name,
5254 "attempt instanced render with all attributes having "
[email protected]c6aef902012-02-14 03:31:425255 "non-zero divisors");
5256 return false;
5257 }
5258
[email protected]3916c97e2010-02-25 03:20:505259 return true;
[email protected]b1122982010-05-17 23:04:245260}
5261
[email protected]c13e1da62011-09-09 21:48:305262bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435263 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305264 DCHECK(simulated);
5265 *simulated = false;
5266
[email protected]876f6fee2010-08-02 23:10:325267 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305268 return true;
[email protected]876f6fee2010-08-02 23:10:325269
[email protected]b1122982010-05-17 23:04:245270 const VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:245271 state_.vertex_attrib_manager->GetVertexAttribInfo(0);
[email protected]b1122982010-05-17 23:04:245272 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245273 bool attrib_0_used =
5274 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]fc753442011-02-04 19:49:495275 if (info->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305276 return true;
[email protected]b1122982010-05-17 23:04:245277 }
5278
[email protected]b1122982010-05-17 23:04:245279 // Make a buffer with a single repeated vec4 value enough to
5280 // simulate the constant value that is supposed to be here.
5281 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305282 typedef VertexAttribManager::VertexAttribInfo::Vec4 Vec4;
5283
5284 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475285 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305286
5287 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475288 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305289 size_needed > 0x7FFFFFFFU) {
[email protected]ad84a3a2012-06-08 21:42:435290 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305291 return false;
5292 }
5293
[email protected]0f8afe82012-05-14 23:43:015294 PerformanceWarning(
5295 "Attribute 0 is disabled. This has signficant performance penalty");
5296
[email protected]c13e1da62011-09-09 21:48:305297 CopyRealGLErrorsToWrapper();
5298 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5299
[email protected]8f0b86c2f2012-04-10 05:48:285300 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5301 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495302 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305303 GLenum error = glGetError();
5304 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435305 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305306 return false;
5307 }
[email protected]fc753442011-02-04 19:49:495308 }
[email protected]8f0b86c2f2012-04-10 05:48:285309 if (new_buffer ||
5310 (attrib_0_used &&
5311 (!attrib_0_buffer_matches_value_ ||
5312 (info->value().v[0] != attrib_0_value_.v[0] ||
5313 info->value().v[1] != attrib_0_value_.v[1] ||
5314 info->value().v[2] != attrib_0_value_.v[2] ||
5315 info->value().v[3] != attrib_0_value_.v[3])))) {
[email protected]fc753442011-02-04 19:49:495316 std::vector<Vec4> temp(num_vertices, info->value());
5317 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
5318 attrib_0_buffer_matches_value_ = true;
[email protected]b1122982010-05-17 23:04:245319 attrib_0_value_ = info->value();
5320 attrib_0_size_ = size_needed;
5321 }
5322
5323 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
5324
[email protected]c6aef902012-02-14 03:31:425325 if (info->divisor())
5326 glVertexAttribDivisorANGLE(0, 0);
5327
[email protected]c13e1da62011-09-09 21:48:305328 *simulated = true;
[email protected]b1122982010-05-17 23:04:245329 return true;
[email protected]b1122982010-05-17 23:04:245330}
5331
[email protected]43410e92012-04-20 17:06:285332void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib) {
[email protected]b1122982010-05-17 23:04:245333 const VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:245334 state_.vertex_attrib_manager->GetVertexAttribInfo(attrib);
[email protected]b1122982010-05-17 23:04:245335 const void* ptr = reinterpret_cast<const void*>(info->offset());
5336 BufferManager::BufferInfo* buffer_info = info->buffer();
5337 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0);
5338 glVertexAttribPointer(
[email protected]43410e92012-04-20 17:06:285339 attrib, info->size(), info->type(), info->normalized(), info->gl_stride(),
[email protected]b1122982010-05-17 23:04:245340 ptr);
[email protected]c6aef902012-02-14 03:31:425341 if (info->divisor())
[email protected]43410e92012-04-20 17:06:285342 glVertexAttribDivisorANGLE(attrib, info->divisor());
[email protected]e259eb412012-10-13 05:47:245343 glBindBuffer(
5344 GL_ARRAY_BUFFER,
5345 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:285346
[email protected]265f8992012-07-20 01:03:145347 // Never touch vertex attribute 0's state (in particular, never
5348 // disable it) when running on desktop GL because it will never be
5349 // re-enabled.
5350 if (attrib != 0 ||
5351 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
5352 if (info->enabled()) {
5353 glEnableVertexAttribArray(attrib);
5354 } else {
5355 glDisableVertexAttribArray(attrib);
5356 }
[email protected]43410e92012-04-20 17:06:285357 }
[email protected]b1122982010-05-17 23:04:245358}
[email protected]07f54fcc2009-12-22 02:46:305359
[email protected]8fbedc02010-11-18 18:43:405360bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:435361 const char* function_name,
[email protected]c6aef902012-02-14 03:31:425362 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:405363 DCHECK(simulated);
5364 *simulated = false;
5365 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
5366 return true;
5367
[email protected]e259eb412012-10-13 05:47:245368 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:405369 return true;
5370 }
5371
[email protected]0f8afe82012-05-14 23:43:015372 PerformanceWarning(
5373 "GL_FIXED attributes have a signficant performance penalty");
5374
[email protected]8fbedc02010-11-18 18:43:405375 // NOTE: we could be smart and try to check if a buffer is used
5376 // twice in 2 different attribs, find the overlapping parts and therefore
5377 // duplicate the minimum amount of data but this whole code path is not meant
5378 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
5379 // tests so we just add to the buffer attrib used.
5380
[email protected]c13e1da62011-09-09 21:48:305381 GLuint elements_needed = 0;
[email protected]8fbedc02010-11-18 18:43:405382 const VertexAttribManager::VertexAttribInfoList& infos =
[email protected]e259eb412012-10-13 05:47:245383 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos();
[email protected]8fbedc02010-11-18 18:43:405384 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
5385 infos.begin(); it != infos.end(); ++it) {
5386 const VertexAttribManager::VertexAttribInfo* info = *it;
5387 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245388 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]c6aef902012-02-14 03:31:425389 GLuint max_accessed = info->MaxVertexAccessed(primcount,
5390 max_vertex_accessed);
5391 GLuint num_vertices = max_accessed + 1;
5392 if (num_vertices == 0) {
[email protected]ad84a3a2012-06-08 21:42:435393 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425394 return false;
5395 }
[email protected]8fbedc02010-11-18 18:43:405396 if (attrib_info &&
[email protected]c6aef902012-02-14 03:31:425397 info->CanAccess(max_accessed) &&
[email protected]8fbedc02010-11-18 18:43:405398 info->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:475399 uint32 elements_used = 0;
5400 if (!SafeMultiplyUint32(num_vertices, info->size(), &elements_used) ||
5401 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ad84a3a2012-06-08 21:42:435402 SetGLError(
5403 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405404 return false;
5405 }
5406 }
5407 }
5408
[email protected]3aad1a32012-09-07 20:54:475409 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
5410 uint32 size_needed = 0;
5411 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305412 size_needed > 0x7FFFFFFFU) {
[email protected]ad84a3a2012-06-08 21:42:435413 SetGLError(GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405414 return false;
5415 }
5416
[email protected]c13e1da62011-09-09 21:48:305417 CopyRealGLErrorsToWrapper();
[email protected]8fbedc02010-11-18 18:43:405418
5419 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:305420 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:405421 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305422 GLenum error = glGetError();
5423 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435424 SetGLError(
5425 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:305426 return false;
5427 }
[email protected]8fbedc02010-11-18 18:43:405428 }
5429
5430 // Copy the elements and convert to float
5431 GLintptr offset = 0;
5432 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
5433 infos.begin(); it != infos.end(); ++it) {
5434 const VertexAttribManager::VertexAttribInfo* info = *it;
5435 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245436 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]c6aef902012-02-14 03:31:425437 GLuint max_accessed = info->MaxVertexAccessed(primcount,
5438 max_vertex_accessed);
5439 GLuint num_vertices = max_accessed + 1;
5440 if (num_vertices == 0) {
[email protected]ad84a3a2012-06-08 21:42:435441 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425442 return false;
5443 }
[email protected]8fbedc02010-11-18 18:43:405444 if (attrib_info &&
[email protected]c6aef902012-02-14 03:31:425445 info->CanAccess(max_accessed) &&
[email protected]8fbedc02010-11-18 18:43:405446 info->type() == GL_FIXED) {
5447 int num_elements = info->size() * kSizeOfFloat;
5448 int size = num_elements * num_vertices;
5449 scoped_array<float> data(new float[size]);
5450 const int32* src = reinterpret_cast<const int32 *>(
5451 info->buffer()->GetRange(info->offset(), size));
5452 const int32* end = src + num_elements;
5453 float* dst = data.get();
5454 while (src != end) {
5455 *dst++ = static_cast<float>(*src++) / 65536.0f;
5456 }
5457 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
5458 glVertexAttribPointer(
5459 info->index(), info->size(), GL_FLOAT, false, 0,
5460 reinterpret_cast<GLvoid*>(offset));
5461 offset += size;
5462 }
5463 }
5464 *simulated = true;
5465 return true;
5466}
5467
5468void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
5469 // There's no need to call glVertexAttribPointer because we shadow all the
5470 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:245471 glBindBuffer(
5472 GL_ARRAY_BUFFER,
5473 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]8fbedc02010-11-18 18:43:405474}
5475
[email protected]ad84a3a2012-06-08 21:42:435476error::Error GLES2DecoderImpl::DoDrawArrays(
5477 const char* function_name,
5478 bool instanced,
5479 GLenum mode,
5480 GLint first,
5481 GLsizei count,
5482 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:085483 if (ShouldDeferDraws())
5484 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:435485 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]f80e6e12012-08-31 00:43:535486 SetGLErrorInvalidEnum(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:435487 return error::kNoError;
5488 }
5489 if (count < 0) {
[email protected]ad84a3a2012-06-08 21:42:435490 SetGLError(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:435491 return error::kNoError;
5492 }
[email protected]c6aef902012-02-14 03:31:425493 if (primcount < 0) {
[email protected]ad84a3a2012-06-08 21:42:435494 SetGLError(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:425495 return error::kNoError;
5496 }
[email protected]ad84a3a2012-06-08 21:42:435497 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:435498 return error::kNoError;
5499 }
5500 // We have to check this here because the prototype for glDrawArrays
5501 // is GLint not GLsizei.
5502 if (first < 0) {
[email protected]ad84a3a2012-06-08 21:42:435503 SetGLError(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:435504 return error::kNoError;
5505 }
5506
[email protected]c6aef902012-02-14 03:31:425507 if (count == 0 || (instanced && primcount == 0)) {
[email protected]0f8afe82012-05-14 23:43:015508 RenderWarning("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:435509 return error::kNoError;
5510 }
5511
5512 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:435513 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:205514 if (!ClearUnclearedTextures()) {
[email protected]ad84a3a2012-06-08 21:42:435515 SetGLError(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:205516 return error::kNoError;
5517 }
[email protected]c13e1da62011-09-09 21:48:305518 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:435519 if (!SimulateAttrib0(
5520 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:305521 return error::kNoError;
5522 }
[email protected]38d139d2011-07-14 00:38:435523 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:435524 if (SimulateFixedAttribs(
5525 function_name, max_vertex_accessed, &simulated_fixed_attribs,
5526 primcount)) {
[email protected]38d139d2011-07-14 00:38:435527 bool textures_set = SetBlackTextureForNonRenderableTextures();
5528 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:425529 if (!instanced) {
5530 glDrawArrays(mode, first, count);
5531 } else {
5532 glDrawArraysInstancedANGLE(mode, first, count, primcount);
5533 }
[email protected]22e3f552012-03-13 01:54:195534 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:435535 if (textures_set) {
5536 RestoreStateForNonRenderableTextures();
5537 }
5538 if (simulated_fixed_attribs) {
5539 RestoreStateForSimulatedFixedAttribs();
5540 }
5541 }
5542 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:285543 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:435544 }
5545 if (WasContextLost()) {
5546 LOG(ERROR) << " GLES2DecoderImpl: Context lost during DrawArrays.";
5547 return error::kLostContext;
5548 }
5549 }
5550 return error::kNoError;
5551}
5552
[email protected]c6aef902012-02-14 03:31:425553error::Error GLES2DecoderImpl::HandleDrawArrays(
5554 uint32 immediate_data_size, const gles2::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:435555 return DoDrawArrays("glDrawArrays",
5556 false,
[email protected]c6aef902012-02-14 03:31:425557 static_cast<GLenum>(c.mode),
5558 static_cast<GLint>(c.first),
5559 static_cast<GLsizei>(c.count),
5560 0);
5561}
5562
5563error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
5564 uint32 immediate_data_size, const gles2::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:155565 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:425566 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435567 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:425568 return error::kNoError;
5569 }
[email protected]ad84a3a2012-06-08 21:42:435570 return DoDrawArrays("glDrawArraysIntancedANGLE",
5571 true,
[email protected]c6aef902012-02-14 03:31:425572 static_cast<GLenum>(c.mode),
5573 static_cast<GLint>(c.first),
5574 static_cast<GLsizei>(c.count),
5575 static_cast<GLsizei>(c.primcount));
5576}
5577
[email protected]ad84a3a2012-06-08 21:42:435578error::Error GLES2DecoderImpl::DoDrawElements(
5579 const char* function_name,
5580 bool instanced,
5581 GLenum mode,
5582 GLsizei count,
5583 GLenum type,
5584 int32 offset,
5585 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:085586 if (ShouldDeferDraws())
5587 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:245588 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]8eee29c2010-04-29 03:38:295589 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435590 function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:295591 return error::kNoError;
5592 }
5593
[email protected]8eee29c2010-04-29 03:38:295594 if (count < 0) {
[email protected]ad84a3a2012-06-08 21:42:435595 SetGLError(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:295596 return error::kNoError;
5597 }
5598 if (offset < 0) {
[email protected]ad84a3a2012-06-08 21:42:435599 SetGLError(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:295600 return error::kNoError;
5601 }
[email protected]9438b012010-06-15 22:55:055602 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]f80e6e12012-08-31 00:43:535603 SetGLErrorInvalidEnum(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:295604 return error::kNoError;
5605 }
[email protected]9438b012010-06-15 22:55:055606 if (!validators_->index_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:535607 SetGLErrorInvalidEnum(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:295608 return error::kNoError;
5609 }
[email protected]c6aef902012-02-14 03:31:425610 if (primcount < 0) {
[email protected]ad84a3a2012-06-08 21:42:435611 SetGLError(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:425612 return error::kNoError;
5613 }
[email protected]8eee29c2010-04-29 03:38:295614
[email protected]ad84a3a2012-06-08 21:42:435615 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:275616 return error::kNoError;
5617 }
5618
[email protected]c6aef902012-02-14 03:31:425619 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:315620 return error::kNoError;
5621 }
5622
[email protected]8eee29c2010-04-29 03:38:295623 GLuint max_vertex_accessed;
[email protected]e259eb412012-10-13 05:47:245624 if (!state_.vertex_attrib_manager->element_array_buffer(
5625 )->GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) {
[email protected]8eee29c2010-04-29 03:38:295626 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435627 function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:295628 return error::kNoError;
5629 }
5630
[email protected]ad84a3a2012-06-08 21:42:435631 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:205632 if (!ClearUnclearedTextures()) {
[email protected]ad84a3a2012-06-08 21:42:435633 SetGLError(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:205634 return error::kNoError;
5635 }
[email protected]c13e1da62011-09-09 21:48:305636 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:435637 if (!SimulateAttrib0(
5638 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:305639 return error::kNoError;
5640 }
[email protected]8fbedc02010-11-18 18:43:405641 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:435642 if (SimulateFixedAttribs(
5643 function_name, max_vertex_accessed, &simulated_fixed_attribs,
5644 primcount)) {
[email protected]8fbedc02010-11-18 18:43:405645 bool textures_set = SetBlackTextureForNonRenderableTextures();
[email protected]297ca1c2011-06-20 23:08:465646 ApplyDirtyState();
[email protected]8fbedc02010-11-18 18:43:405647 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]c6aef902012-02-14 03:31:425648 if (!instanced) {
5649 glDrawElements(mode, count, type, indices);
5650 } else {
5651 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
5652 }
[email protected]22e3f552012-03-13 01:54:195653 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:405654 if (textures_set) {
5655 RestoreStateForNonRenderableTextures();
5656 }
5657 if (simulated_fixed_attribs) {
5658 RestoreStateForSimulatedFixedAttribs();
5659 }
[email protected]ba3176a2009-12-16 18:19:465660 }
[email protected]b1122982010-05-17 23:04:245661 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:285662 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:245663 }
[email protected]38d139d2011-07-14 00:38:435664 if (WasContextLost()) {
5665 LOG(ERROR) << " GLES2DecoderImpl: Context lost during DrawElements.";
5666 return error::kLostContext;
5667 }
[email protected]96449d2c2009-11-25 00:01:325668 }
[email protected]f7a64ee2010-02-01 22:24:145669 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325670}
5671
[email protected]c6aef902012-02-14 03:31:425672error::Error GLES2DecoderImpl::HandleDrawElements(
5673 uint32 immediate_data_size, const gles2::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:435674 return DoDrawElements("glDrawElements",
5675 false,
[email protected]c6aef902012-02-14 03:31:425676 static_cast<GLenum>(c.mode),
5677 static_cast<GLsizei>(c.count),
5678 static_cast<GLenum>(c.type),
5679 static_cast<int32>(c.index_offset),
5680 0);
5681}
5682
5683error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
5684 uint32 immediate_data_size, const gles2::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:155685 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:425686 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435687 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:425688 return error::kNoError;
5689 }
[email protected]ad84a3a2012-06-08 21:42:435690 return DoDrawElements("glDrawElementsInstancedANGLE",
5691 true,
[email protected]c6aef902012-02-14 03:31:425692 static_cast<GLenum>(c.mode),
5693 static_cast<GLsizei>(c.count),
5694 static_cast<GLenum>(c.type),
5695 static_cast<int32>(c.index_offset),
5696 static_cast<GLsizei>(c.primcount));
5697}
5698
[email protected]269200b12010-11-18 22:53:065699GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:235700 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
5701 GLuint max_vertex_accessed = 0;
5702 BufferManager::BufferInfo* info = GetBufferInfo(buffer_id);
[email protected]8eee29c2010-04-29 03:38:295703 if (!info) {
[email protected]ae51d192010-04-27 00:48:035704 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]8eee29c2010-04-29 03:38:295705 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:435706 "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:235707 } else {
5708 if (!info->GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:035709 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]269200b12010-11-18 22:53:065710 SetGLError(
5711 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435712 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:235713 }
5714 }
5715 return max_vertex_accessed;
5716}
5717
[email protected]96449d2c2009-11-25 00:01:325718// Calls glShaderSource for the various versions of the ShaderSource command.
5719// Assumes that data / data_size points to a piece of memory that is in range
5720// of whatever context it came from (shared memory, immediate memory, bucket
5721// memory.)
[email protected]45bf5152010-02-12 00:11:315722error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:035723 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:575724 std::string str(data, data + data_size);
[email protected]6b8cf1a2010-05-06 16:13:585725 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
5726 client_id, "glShaderSource");
[email protected]45bf5152010-02-12 00:11:315727 if (!info) {
[email protected]45bf5152010-02-12 00:11:315728 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325729 }
[email protected]45bf5152010-02-12 00:11:315730 // Note: We don't actually call glShaderSource here. We wait until
5731 // the call to glCompileShader.
[email protected]258a3313f2011-10-18 20:13:575732 info->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:145733 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325734}
5735
[email protected]f7a64ee2010-02-01 22:24:145736error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]b9849abf2009-11-25 19:13:195737 uint32 immediate_data_size, const gles2::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:325738 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:315739 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:325740 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:465741 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:145742 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:325743 }
[email protected]ae51d192010-04-27 00:48:035744 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:325745}
5746
[email protected]f7a64ee2010-02-01 22:24:145747error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]b9849abf2009-11-25 19:13:195748 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:325749 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:315750 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:305751 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:465752 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:145753 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:325754 }
[email protected]ae51d192010-04-27 00:48:035755 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:315756}
5757
[email protected]558847a2010-03-24 07:02:545758error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
5759 uint32 immediate_data_size, const gles2::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:545760 Bucket* bucket = GetBucket(c.data_bucket_id);
5761 if (!bucket || bucket->size() == 0) {
5762 return error::kInvalidArguments;
5763 }
5764 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:035765 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:545766 bucket->size() - 1);
5767}
5768
[email protected]ae51d192010-04-27 00:48:035769void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:385770 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]6b8cf1a2010-05-06 16:13:585771 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
5772 client_id, "glCompileShader");
[email protected]45bf5152010-02-12 00:11:315773 if (!info) {
[email protected]45bf5152010-02-12 00:11:315774 return;
5775 }
[email protected]f57bb282010-11-12 00:51:345776 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:185777 if (use_shader_translator_) {
[email protected]f57bb282010-11-12 00:51:345778 translator = info->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:455779 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:415780 }
[email protected]de17df392010-04-23 21:09:415781
[email protected]65dfc602012-07-23 20:39:395782 program_manager()->DoCompileShader(info, translator, feature_info_);
[email protected]45bf5152010-02-12 00:11:315783};
5784
[email protected]ddd968b82010-03-02 00:44:295785void GLES2DecoderImpl::DoGetShaderiv(
5786 GLuint shader, GLenum pname, GLint* params) {
[email protected]6b8cf1a2010-05-06 16:13:585787 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
5788 shader, "glGetShaderiv");
[email protected]ddd968b82010-03-02 00:44:295789 if (!info) {
[email protected]ddd968b82010-03-02 00:44:295790 return;
5791 }
[email protected]8f1ccdac2010-05-19 21:01:485792 switch (pname) {
5793 case GL_SHADER_SOURCE_LENGTH:
[email protected]df6cf1ad2011-01-29 01:20:525794 *params = info->source() ? info->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:485795 return;
5796 case GL_COMPILE_STATUS:
[email protected]062c38b2012-01-18 03:25:105797 *params = compile_shader_always_succeeds_ ? true : info->IsValid();
[email protected]e5186162010-06-14 18:54:415798 return;
[email protected]8f1ccdac2010-05-19 21:01:485799 case GL_INFO_LOG_LENGTH:
[email protected]df6cf1ad2011-01-29 01:20:525800 *params = info->log_info() ? info->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:415801 return;
[email protected]d6a53e42011-10-05 00:09:365802 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]c447acd2012-07-23 23:48:415803 ForceCompileShaderIfPending(info);
[email protected]d6a53e42011-10-05 00:09:365804 *params = info->translated_source() ?
5805 info->translated_source()->size() + 1 : 0;
5806 return;
[email protected]8f1ccdac2010-05-19 21:01:485807 default:
5808 break;
[email protected]ddd968b82010-03-02 00:44:295809 }
[email protected]8f1ccdac2010-05-19 21:01:485810 glGetShaderiv(info->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:295811}
5812
[email protected]ae51d192010-04-27 00:48:035813error::Error GLES2DecoderImpl::HandleGetShaderSource(
5814 uint32 immediate_data_size, const gles2::GetShaderSource& c) {
5815 GLuint shader = c.shader;
[email protected]ae51d192010-04-27 00:48:035816 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
5817 Bucket* bucket = CreateBucket(bucket_id);
[email protected]6b8cf1a2010-05-06 16:13:585818 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
5819 shader, "glGetShaderSource");
[email protected]df6cf1ad2011-01-29 01:20:525820 if (!info || !info->source()) {
[email protected]8eee29c2010-04-29 03:38:295821 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:295822 return error::kNoError;
5823 }
[email protected]df6cf1ad2011-01-29 01:20:525824 bucket->SetFromString(info->source()->c_str());
[email protected]ae51d192010-04-27 00:48:035825 return error::kNoError;
5826}
5827
[email protected]d6a53e42011-10-05 00:09:365828error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
5829 uint32 immediate_data_size,
5830 const gles2::GetTranslatedShaderSourceANGLE& c) {
5831 GLuint shader = c.shader;
5832
5833 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
5834 Bucket* bucket = CreateBucket(bucket_id);
5835 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
5836 shader, "glTranslatedGetShaderSourceANGLE");
5837 if (!info) {
5838 bucket->SetSize(0);
5839 return error::kNoError;
5840 }
[email protected]c447acd2012-07-23 23:48:415841 ForceCompileShaderIfPending(info);
[email protected]d6a53e42011-10-05 00:09:365842
5843 bucket->SetFromString(info->translated_source() ?
5844 info->translated_source()->c_str() : NULL);
5845 return error::kNoError;
5846}
5847
[email protected]ae51d192010-04-27 00:48:035848error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
5849 uint32 immediate_data_size, const gles2::GetProgramInfoLog& c) {
5850 GLuint program = c.program;
[email protected]6b8cf1a2010-05-06 16:13:585851 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
5852 Bucket* bucket = CreateBucket(bucket_id);
5853 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
5854 program, "glGetProgramInfoLog");
[email protected]df6cf1ad2011-01-29 01:20:525855 if (!info || !info->log_info()) {
[email protected]9a14ae612011-08-08 17:51:465856 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:035857 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:315858 }
[email protected]df6cf1ad2011-01-29 01:20:525859 bucket->SetFromString(info->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:035860 return error::kNoError;
5861}
5862
5863error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
5864 uint32 immediate_data_size, const gles2::GetShaderInfoLog& c) {
5865 GLuint shader = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:585866 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
5867 Bucket* bucket = CreateBucket(bucket_id);
5868 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
5869 shader, "glGetShaderInfoLog");
[email protected]df6cf1ad2011-01-29 01:20:525870 if (!info || !info->log_info()) {
[email protected]9a14ae612011-08-08 17:51:465871 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:035872 return error::kNoError;
5873 }
[email protected]df6cf1ad2011-01-29 01:20:525874 bucket->SetFromString(info->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:035875 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325876}
5877
[email protected]d058bca2012-11-26 10:27:265878bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
5879 return state_.GetEnabled(cap);
5880}
5881
[email protected]1958e0e2010-04-22 05:17:155882bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:105883 const BufferManager::BufferInfo* buffer = GetBufferInfo(client_id);
5884 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:155885}
5886
5887bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:105888 const FramebufferManager::FramebufferInfo* framebuffer =
[email protected]06c8b082011-01-05 18:00:365889 GetFramebufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:105890 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:155891}
5892
5893bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:365894 // IsProgram is true for programs as soon as they are created, until they are
5895 // deleted and no longer in use.
[email protected]a0b78dc2011-11-11 10:43:105896 const ProgramManager::ProgramInfo* program = GetProgramInfo(client_id);
5897 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:155898}
5899
5900bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:105901 const RenderbufferManager::RenderbufferInfo* renderbuffer =
[email protected]06c8b082011-01-05 18:00:365902 GetRenderbufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:105903 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:155904}
5905
5906bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:365907 // IsShader is true for shaders as soon as they are created, until they
5908 // are deleted and not attached to any programs.
[email protected]a0b78dc2011-11-11 10:43:105909 const ShaderManager::ShaderInfo* shader = GetShaderInfo(client_id);
5910 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:155911}
5912
5913bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:105914 const TextureManager::TextureInfo* texture = GetTextureInfo(client_id);
5915 return texture && texture->IsValid() && !texture->IsDeleted();
[email protected]ae51d192010-04-27 00:48:035916}
5917
5918void GLES2DecoderImpl::DoAttachShader(
5919 GLuint program_client_id, GLint shader_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:585920 ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader(
5921 program_client_id, "glAttachShader");
[email protected]ae51d192010-04-27 00:48:035922 if (!program_info) {
[email protected]ae51d192010-04-27 00:48:035923 return;
[email protected]1958e0e2010-04-22 05:17:155924 }
[email protected]6b8cf1a2010-05-06 16:13:585925 ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram(
5926 shader_client_id, "glAttachShader");
[email protected]ae51d192010-04-27 00:48:035927 if (!shader_info) {
[email protected]ae51d192010-04-27 00:48:035928 return;
5929 }
[email protected]ca488e12010-12-13 20:06:145930 if (!program_info->AttachShader(shader_manager(), shader_info)) {
[email protected]fb96c8e2010-08-12 04:10:315931 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435932 "glAttachShader", "can not attach more than"
[email protected]fb96c8e2010-08-12 04:10:315933 " one shader of the same type.");
5934 return;
5935 }
[email protected]ae51d192010-04-27 00:48:035936 glAttachShader(program_info->service_id(), shader_info->service_id());
5937}
5938
5939void GLES2DecoderImpl::DoDetachShader(
5940 GLuint program_client_id, GLint shader_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:585941 ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader(
5942 program_client_id, "glDetachShader");
[email protected]ae51d192010-04-27 00:48:035943 if (!program_info) {
[email protected]ae51d192010-04-27 00:48:035944 return;
5945 }
[email protected]6b8cf1a2010-05-06 16:13:585946 ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram(
5947 shader_client_id, "glDetachShader");
[email protected]ae51d192010-04-27 00:48:035948 if (!shader_info) {
[email protected]ae51d192010-04-27 00:48:035949 return;
5950 }
[email protected]9a0ccd42011-03-16 23:58:225951 if (!program_info->DetachShader(shader_manager(), shader_info)) {
5952 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435953 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:225954 return;
5955 }
[email protected]ae51d192010-04-27 00:48:035956 glDetachShader(program_info->service_id(), shader_info->service_id());
5957}
5958
5959void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:585960 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
5961 program_client_id, "glValidateProgram");
[email protected]ae51d192010-04-27 00:48:035962 if (!info) {
[email protected]ae51d192010-04-27 00:48:035963 return;
5964 }
[email protected]d685a682011-04-29 16:19:575965 info->Validate();
[email protected]1958e0e2010-04-22 05:17:155966}
5967
[email protected]b1122982010-05-17 23:04:245968void GLES2DecoderImpl::DoGetVertexAttribfv(
5969 GLuint index, GLenum pname, GLfloat* params) {
5970 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:245971 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:245972 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:435973 SetGLError(GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]b1122982010-05-17 23:04:245974 return;
5975 }
5976 switch (pname) {
5977 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
5978 BufferManager::BufferInfo* buffer = info->buffer();
5979 if (buffer && !buffer->IsDeleted()) {
5980 GLuint client_id;
5981 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
5982 *params = static_cast<GLfloat>(client_id);
5983 }
5984 break;
5985 }
5986 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5987 *params = static_cast<GLfloat>(info->enabled());
5988 break;
5989 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5990 *params = static_cast<GLfloat>(info->size());
5991 break;
5992 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5993 *params = static_cast<GLfloat>(info->gl_stride());
5994 break;
5995 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5996 *params = static_cast<GLfloat>(info->type());
5997 break;
5998 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5999 *params = static_cast<GLfloat>(info->normalized());
6000 break;
6001 case GL_CURRENT_VERTEX_ATTRIB:
6002 params[0] = info->value().v[0];
6003 params[1] = info->value().v[1];
6004 params[2] = info->value().v[2];
6005 params[3] = info->value().v[3];
6006 break;
[email protected]c6aef902012-02-14 03:31:426007 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
6008 *params = static_cast<GLfloat>(info->divisor());
6009 break;
[email protected]b1122982010-05-17 23:04:246010 default:
6011 NOTREACHED();
6012 break;
6013 }
6014}
6015
6016void GLES2DecoderImpl::DoGetVertexAttribiv(
6017 GLuint index, GLenum pname, GLint* params) {
6018 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246019 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246020 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436021 SetGLError(GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]b1122982010-05-17 23:04:246022 return;
6023 }
6024 switch (pname) {
6025 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
6026 BufferManager::BufferInfo* buffer = info->buffer();
6027 if (buffer && !buffer->IsDeleted()) {
6028 GLuint client_id;
6029 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6030 *params = client_id;
6031 }
6032 break;
6033 }
6034 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
6035 *params = info->enabled();
6036 break;
6037 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
6038 *params = info->size();
6039 break;
6040 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
6041 *params = info->gl_stride();
6042 break;
6043 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
6044 *params = info->type();
6045 break;
6046 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
6047 *params = static_cast<GLint>(info->normalized());
6048 break;
[email protected]c6aef902012-02-14 03:31:426049 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
6050 *params = info->divisor();
6051 break;
[email protected]b1122982010-05-17 23:04:246052 case GL_CURRENT_VERTEX_ATTRIB:
6053 params[0] = static_cast<GLint>(info->value().v[0]);
6054 params[1] = static_cast<GLint>(info->value().v[1]);
6055 params[2] = static_cast<GLint>(info->value().v[2]);
6056 params[3] = static_cast<GLint>(info->value().v[3]);
6057 break;
6058 default:
6059 NOTREACHED();
6060 break;
6061 }
6062}
6063
6064void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6065 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246066 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246067 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436068 SetGLError(GL_INVALID_VALUE, "glVertexAttrib1f", "index out of range");
[email protected]b1122982010-05-17 23:04:246069 return;
6070 }
6071 VertexAttribManager::VertexAttribInfo::Vec4 value;
6072 value.v[0] = v0;
6073 value.v[1] = 0.0f;
6074 value.v[2] = 0.0f;
6075 value.v[3] = 1.0f;
6076 info->set_value(value);
6077 glVertexAttrib1f(index, v0);
6078}
6079
6080void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
6081 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246082 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246083 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436084 SetGLError(GL_INVALID_VALUE, "glVertexAttrib2f", "index out of range");
[email protected]b1122982010-05-17 23:04:246085 return;
6086 }
6087 VertexAttribManager::VertexAttribInfo::Vec4 value;
6088 value.v[0] = v0;
6089 value.v[1] = v1;
6090 value.v[2] = 0.0f;
6091 value.v[3] = 1.0f;
6092 info->set_value(value);
6093 glVertexAttrib2f(index, v0, v1);
6094}
6095
6096void GLES2DecoderImpl::DoVertexAttrib3f(
6097 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
6098 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246099 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246100 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436101 SetGLError(GL_INVALID_VALUE, "glVertexAttrib3f", "index out of range");
[email protected]b1122982010-05-17 23:04:246102 return;
6103 }
6104 VertexAttribManager::VertexAttribInfo::Vec4 value;
6105 value.v[0] = v0;
6106 value.v[1] = v1;
6107 value.v[2] = v2;
6108 value.v[3] = 1.0f;
6109 info->set_value(value);
6110 glVertexAttrib3f(index, v0, v1, v2);
6111}
6112
6113void GLES2DecoderImpl::DoVertexAttrib4f(
6114 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
6115 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246116 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246117 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436118 SetGLError(GL_INVALID_VALUE, "glVertexAttrib4f", "index out of range");
[email protected]b1122982010-05-17 23:04:246119 return;
6120 }
6121 VertexAttribManager::VertexAttribInfo::Vec4 value;
6122 value.v[0] = v0;
6123 value.v[1] = v1;
6124 value.v[2] = v2;
6125 value.v[3] = v3;
6126 info->set_value(value);
6127 glVertexAttrib4f(index, v0, v1, v2, v3);
6128}
6129
6130void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
6131 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246132 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246133 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436134 SetGLError(GL_INVALID_VALUE, "glVertexAttrib1fv", "index out of range");
[email protected]b1122982010-05-17 23:04:246135 return;
6136 }
6137 VertexAttribManager::VertexAttribInfo::Vec4 value;
6138 value.v[0] = v[0];
6139 value.v[1] = 0.0f;
6140 value.v[2] = 0.0f;
6141 value.v[3] = 1.0f;
6142 info->set_value(value);
6143 glVertexAttrib1fv(index, v);
6144}
6145
6146void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
6147 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246148 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246149 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436150 SetGLError(GL_INVALID_VALUE, "glVertexAttrib2fv", "index out of range");
[email protected]b1122982010-05-17 23:04:246151 return;
6152 }
6153 VertexAttribManager::VertexAttribInfo::Vec4 value;
6154 value.v[0] = v[0];
6155 value.v[1] = v[1];
6156 value.v[2] = 0.0f;
6157 value.v[3] = 1.0f;
6158 info->set_value(value);
6159 glVertexAttrib2fv(index, v);
6160}
6161
6162void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
6163 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246164 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246165 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436166 SetGLError(GL_INVALID_VALUE, "glVertexAttrib3fv", "index out of range");
[email protected]b1122982010-05-17 23:04:246167 return;
6168 }
6169 VertexAttribManager::VertexAttribInfo::Vec4 value;
6170 value.v[0] = v[0];
6171 value.v[1] = v[1];
6172 value.v[2] = v[2];
6173 value.v[3] = 1.0f;
6174 info->set_value(value);
6175 glVertexAttrib3fv(index, v);
6176}
6177
6178void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
6179 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246180 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246181 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436182 SetGLError(GL_INVALID_VALUE, "glVertexAttrib4fv", "index out of range");
[email protected]b1122982010-05-17 23:04:246183 return;
6184 }
6185 VertexAttribManager::VertexAttribInfo::Vec4 value;
6186 value.v[0] = v[0];
6187 value.v[1] = v[1];
6188 value.v[2] = v[2];
6189 value.v[3] = v[3];
6190 info->set_value(value);
6191 glVertexAttrib4fv(index, v);
6192}
6193
[email protected]f7a64ee2010-02-01 22:24:146194error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]b9849abf2009-11-25 19:13:196195 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466196
[email protected]e259eb412012-10-13 05:47:246197 if (!state_.bound_array_buffer || state_.bound_array_buffer->IsDeleted()) {
6198 if (state_.vertex_attrib_manager == default_vertex_attrib_manager_) {
[email protected]944b62f32012-09-27 02:20:466199 SetGLError(GL_INVALID_VALUE,
6200 "glVertexAttribPointer", "no array buffer bound");
6201 return error::kNoError;
6202 } else if (c.offset != 0) {
6203 SetGLError(GL_INVALID_VALUE,
6204 "glVertexAttribPointer", "client side arrays are not allowed");
6205 return error::kNoError;
6206 }
[email protected]96449d2c2009-11-25 00:01:326207 }
[email protected]8eee29c2010-04-29 03:38:296208
6209 GLuint indx = c.indx;
6210 GLint size = c.size;
6211 GLenum type = c.type;
6212 GLboolean normalized = c.normalized;
6213 GLsizei stride = c.stride;
6214 GLsizei offset = c.offset;
6215 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056216 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536217 SetGLErrorInvalidEnum("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296218 return error::kNoError;
6219 }
[email protected]9438b012010-06-15 22:55:056220 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ff81c192011-01-07 23:04:316221 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436222 "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296223 return error::kNoError;
6224 }
6225 if (indx >= group_->max_vertex_attribs()) {
[email protected]ad84a3a2012-06-08 21:42:436226 SetGLError(GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296227 return error::kNoError;
6228 }
6229 if (stride < 0) {
6230 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436231 "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296232 return error::kNoError;
6233 }
6234 if (stride > 255) {
6235 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436236 "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296237 return error::kNoError;
6238 }
6239 if (offset < 0) {
6240 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436241 "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296242 return error::kNoError;
6243 }
6244 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316245 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296246 if (offset % component_size > 0) {
[email protected]ff81c192011-01-07 23:04:316247 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436248 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316249 return error::kNoError;
6250 }
6251 if (stride % component_size > 0) {
6252 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436253 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296254 return error::kNoError;
6255 }
[email protected]e259eb412012-10-13 05:47:246256 state_.vertex_attrib_manager->SetAttribInfo(
[email protected]8fbedc02010-11-18 18:43:406257 indx,
[email protected]e259eb412012-10-13 05:47:246258 state_.bound_array_buffer,
[email protected]8eee29c2010-04-29 03:38:296259 size,
6260 type,
[email protected]b1122982010-05-17 23:04:246261 normalized,
6262 stride,
6263 stride != 0 ? stride : component_size * size,
[email protected]8eee29c2010-04-29 03:38:296264 offset);
[email protected]8fbedc02010-11-18 18:43:406265 if (type != GL_FIXED) {
6266 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6267 }
[email protected]f7a64ee2010-02-01 22:24:146268 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326269}
6270
[email protected]43410e92012-04-20 17:06:286271void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6272 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246273 state_.viewport_x = x;
6274 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026275 state_.viewport_width = std::min(width, viewport_max_width_);
6276 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286277 glViewport(x, y, width, height);
6278}
6279
[email protected]c6aef902012-02-14 03:31:426280error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
6281 uint32 immediate_data_size, const gles2::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156282 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:426283 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436284 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426285 }
6286 GLuint index = c.index;
6287 GLuint divisor = c.divisor;
6288 if (index >= group_->max_vertex_attribs()) {
6289 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436290 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426291 return error::kNoError;
6292 }
6293
[email protected]e259eb412012-10-13 05:47:246294 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426295 index,
6296 divisor);
6297 glVertexAttribDivisorANGLE(index, divisor);
6298 return error::kNoError;
6299}
6300
[email protected]f7a64ee2010-02-01 22:24:146301error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]b9849abf2009-11-25 19:13:196302 uint32 immediate_data_size, const gles2::ReadPixels& c) {
[email protected]612d2f82009-12-08 20:49:316303 GLint x = c.x;
6304 GLint y = c.y;
6305 GLsizei width = c.width;
6306 GLsizei height = c.height;
6307 GLenum format = c.format;
6308 GLenum type = c.type;
[email protected]57f223832010-03-19 01:57:566309 if (width < 0 || height < 0) {
[email protected]ad84a3a2012-06-08 21:42:436310 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566311 return error::kNoError;
6312 }
[email protected]a51788e2010-02-24 21:54:256313 typedef gles2::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186314 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346315 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246316 width, height, format, type, state_.pack_alignment, &pixels_size,
6317 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186318 return error::kOutOfBounds;
6319 }
[email protected]612d2f82009-12-08 20:49:316320 void* pixels = GetSharedMemoryAs<void*>(
6321 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]a51788e2010-02-24 21:54:256322 Result* result = GetSharedMemoryAs<Result*>(
6323 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6324 if (!pixels || !result) {
[email protected]f7a64ee2010-02-01 22:24:146325 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466326 }
[email protected]a51788e2010-02-24 21:54:256327
[email protected]9438b012010-06-15 22:55:056328 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:536329 SetGLErrorInvalidEnum("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296330 return error::kNoError;
6331 }
[email protected]9438b012010-06-15 22:55:056332 if (!validators_->pixel_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536333 SetGLErrorInvalidEnum("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:126334 return error::kNoError;
6335 }
[email protected]57f223832010-03-19 01:57:566336 if (width == 0 || height == 0) {
6337 return error::kNoError;
6338 }
6339
[email protected]57f223832010-03-19 01:57:566340 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:306341 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:566342
[email protected]3aad1a32012-09-07 20:54:476343 int32 max_x;
6344 int32 max_y;
6345 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ad84a3a2012-06-08 21:42:436346 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:146347 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:316348 }
[email protected]57f223832010-03-19 01:57:566349
[email protected]0d6bfdc2011-11-02 01:32:206350 if (!CheckBoundFramebuffersValid("glReadPixels")) {
6351 return error::kNoError;
6352 }
6353
[email protected]a0b78dc2011-11-11 10:43:106354 CopyRealGLErrorsToWrapper();
6355
6356 ScopedResolvedFrameBufferBinder binder(this, false, true);
6357
[email protected]d37231fa2010-04-09 21:16:026358 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:566359 // The user requested an out of range area. Get the results 1 line
6360 // at a time.
6361 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346362 uint32 unpadded_row_size;
6363 uint32 padded_row_size;
6364 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246365 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346366 &unpadded_row_size, &padded_row_size)) {
[email protected]ad84a3a2012-06-08 21:42:436367 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566368 return error::kNoError;
6369 }
6370
6371 GLint dest_x_offset = std::max(-x, 0);
6372 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:346373 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246374 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
6375 NULL, NULL)) {
[email protected]ad84a3a2012-06-08 21:42:436376 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566377 return error::kNoError;
6378 }
6379
6380 // Copy each row into the larger dest rect.
6381 int8* dst = static_cast<int8*>(pixels);
6382 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:026383 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:566384 GLint read_width = read_end_x - read_x;
6385 for (GLint yy = 0; yy < height; ++yy) {
6386 GLint ry = y + yy;
6387
6388 // Clear the row.
6389 memset(dst, 0, unpadded_row_size);
6390
6391 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:026392 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:566393 glReadPixels(
6394 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6395 }
6396 dst += padded_row_size;
6397 }
6398 } else {
6399 glReadPixels(x, y, width, height, format, type, pixels);
6400 }
[email protected]1002c2d2011-06-28 22:39:046401 GLenum error = PeekGLError();
[email protected]a51788e2010-02-24 21:54:256402 if (error == GL_NO_ERROR) {
6403 *result = true;
[email protected]4848b9f82011-03-10 18:37:566404
6405 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6406 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
[email protected]84eb4252012-06-29 22:56:446407 if ((channels_exist & 0x0008) == 0 &&
[email protected]62e155e2012-10-23 22:43:156408 workarounds().clear_alpha_in_readpixels) {
[email protected]4848b9f82011-03-10 18:37:566409 // Set the alpha to 255 because some drivers are buggy in this regard.
6410 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346411
6412 uint32 unpadded_row_size;
6413 uint32 padded_row_size;
6414 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246415 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346416 &unpadded_row_size, &padded_row_size)) {
[email protected]ad84a3a2012-06-08 21:42:436417 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]4848b9f82011-03-10 18:37:566418 return error::kNoError;
6419 }
6420 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6421 // of this implementation.
6422 if (type != GL_UNSIGNED_BYTE) {
[email protected]ad84a3a2012-06-08 21:42:436423 SetGLError(
6424 GL_INVALID_OPERATION, "glReadPixels",
6425 "unsupported readPixel format");
[email protected]4848b9f82011-03-10 18:37:566426 return error::kNoError;
6427 }
6428 switch (format) {
6429 case GL_RGBA:
[email protected]297ca1c2011-06-20 23:08:466430 case GL_BGRA_EXT:
[email protected]4848b9f82011-03-10 18:37:566431 case GL_ALPHA: {
6432 int offset = (format == GL_ALPHA) ? 0 : 3;
6433 int step = (format == GL_ALPHA) ? 1 : 4;
6434 uint8* dst = static_cast<uint8*>(pixels) + offset;
6435 for (GLint yy = 0; yy < height; ++yy) {
6436 uint8* end = dst + unpadded_row_size;
6437 for (uint8* d = dst; d < end; d += step) {
6438 *d = 255;
6439 }
6440 dst += padded_row_size;
6441 }
6442 break;
6443 }
6444 default:
6445 break;
6446 }
6447 }
[email protected]a51788e2010-02-24 21:54:256448 }
[email protected]4848b9f82011-03-10 18:37:566449
[email protected]f7a64ee2010-02-01 22:24:146450 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326451}
6452
[email protected]f7a64ee2010-02-01 22:24:146453error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]b9849abf2009-11-25 19:13:196454 uint32 immediate_data_size, const gles2::PixelStorei& c) {
6455 GLenum pname = c.pname;
6456 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:056457 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]f80e6e12012-08-31 00:43:536458 SetGLErrorInvalidEnum("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:126459 return error::kNoError;
6460 }
[email protected]222471d2011-11-30 18:06:396461 switch (pname) {
6462 case GL_PACK_ALIGNMENT:
6463 case GL_UNPACK_ALIGNMENT:
6464 if (!validators_->pixel_store_alignment.IsValid(param)) {
6465 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436466 "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:396467 return error::kNoError;
6468 }
[email protected]164d6d52012-05-05 00:55:036469 break;
[email protected]0a1e9ad2012-05-04 21:13:036470 case GL_UNPACK_FLIP_Y_CHROMIUM:
6471 unpack_flip_y_ = (param != 0);
6472 return error::kNoError;
6473 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
6474 unpack_premultiply_alpha_ = (param != 0);
6475 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:176476 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
6477 unpack_unpremultiply_alpha_ = (param != 0);
6478 return error::kNoError;
[email protected]222471d2011-11-30 18:06:396479 default:
6480 break;
[email protected]b9849abf2009-11-25 19:13:196481 }
6482 glPixelStorei(pname, param);
6483 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:436484 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246485 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436486 break;
6487 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:426488 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:436489 break;
6490 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246491 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436492 break;
6493 default:
6494 // Validation should have prevented us from getting here.
6495 NOTREACHED();
6496 break;
[email protected]b9849abf2009-11-25 19:13:196497 }
[email protected]f7a64ee2010-02-01 22:24:146498 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196499}
6500
[email protected]1c75a3702011-11-11 14:15:286501error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
6502 uint32 immediate_data_size, const gles2::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:386503 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:456504 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]1c75a3702011-11-11 14:15:286505 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436506 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:286507 return error::kNoError;
6508 }
[email protected]7794d512012-04-17 20:36:496509 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:286510 return error::kNoError;
[email protected]7794d512012-04-17 20:36:496511 } else {
6512 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:286513 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:496514 }
[email protected]1c75a3702011-11-11 14:15:286515}
6516
[email protected]558847a2010-03-24 07:02:546517error::Error GLES2DecoderImpl::GetAttribLocationHelper(
6518 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6519 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576520 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ad84a3a2012-06-08 21:42:436521 SetGLError(GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576522 return error::kNoError;
6523 }
[email protected]6b8cf1a2010-05-06 16:13:586524 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6525 client_id, "glGetAttribLocation");
[email protected]ae51d192010-04-27 00:48:036526 if (!info) {
[email protected]f7a64ee2010-02-01 22:24:146527 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196528 }
[email protected]ae51d192010-04-27 00:48:036529 if (!info->IsValid()) {
[email protected]ad84a3a2012-06-08 21:42:436530 SetGLError(
6531 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256532 return error::kNoError;
6533 }
[email protected]b9849abf2009-11-25 19:13:196534 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:546535 location_shm_id, location_shm_offset, sizeof(GLint));
6536 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:146537 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196538 }
[email protected]558847a2010-03-24 07:02:546539 // Require the client to init this incase the context is lost and we are no
6540 // longer executing commands.
6541 if (*location != -1) {
6542 return error::kGenericError;
6543 }
[email protected]0bfd9882010-02-05 23:02:256544 *location = info->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:146545 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196546}
6547
[email protected]558847a2010-03-24 07:02:546548error::Error GLES2DecoderImpl::HandleGetAttribLocation(
6549 uint32 immediate_data_size, const gles2::GetAttribLocation& c) {
6550 uint32 name_size = c.data_size;
6551 const char* name = GetSharedMemoryAs<const char*>(
6552 c.name_shm_id, c.name_shm_offset, name_size);
6553 if (!name) {
6554 return error::kOutOfBounds;
6555 }
6556 String name_str(name, name_size);
6557 return GetAttribLocationHelper(
6558 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6559}
6560
[email protected]f7a64ee2010-02-01 22:24:146561error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]b9849abf2009-11-25 19:13:196562 uint32 immediate_data_size, const gles2::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:546563 uint32 name_size = c.data_size;
6564 const char* name = GetImmediateDataAs<const char*>(
6565 c, name_size, immediate_data_size);
6566 if (!name) {
6567 return error::kOutOfBounds;
6568 }
6569 String name_str(name, name_size);
6570 return GetAttribLocationHelper(
6571 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6572}
6573
6574error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
6575 uint32 immediate_data_size, const gles2::GetAttribLocationBucket& c) {
6576 Bucket* bucket = GetBucket(c.name_bucket_id);
6577 if (!bucket) {
6578 return error::kInvalidArguments;
6579 }
6580 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:186581 if (!bucket->GetAsString(&name_str)) {
6582 return error::kInvalidArguments;
6583 }
[email protected]558847a2010-03-24 07:02:546584 return GetAttribLocationHelper(
6585 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6586}
6587
6588error::Error GLES2DecoderImpl::GetUniformLocationHelper(
6589 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6590 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576591 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ad84a3a2012-06-08 21:42:436592 SetGLError(GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576593 return error::kNoError;
6594 }
[email protected]6b8cf1a2010-05-06 16:13:586595 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6596 client_id, "glUniformLocation");
[email protected]ae51d192010-04-27 00:48:036597 if (!info) {
[email protected]f7a64ee2010-02-01 22:24:146598 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196599 }
[email protected]ae51d192010-04-27 00:48:036600 if (!info->IsValid()) {
[email protected]ad84a3a2012-06-08 21:42:436601 SetGLError(
6602 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256603 return error::kNoError;
6604 }
[email protected]b9849abf2009-11-25 19:13:196605 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:546606 location_shm_id, location_shm_offset, sizeof(GLint));
6607 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:146608 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196609 }
[email protected]558847a2010-03-24 07:02:546610 // Require the client to init this incase the context is lost an we are no
6611 // longer executing commands.
6612 if (*location != -1) {
6613 return error::kGenericError;
6614 }
[email protected]2be6abf32012-06-26 00:28:336615 *location = info->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:146616 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196617}
6618
[email protected]f7a64ee2010-02-01 22:24:146619error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]b9849abf2009-11-25 19:13:196620 uint32 immediate_data_size, const gles2::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:196621 uint32 name_size = c.data_size;
6622 const char* name = GetSharedMemoryAs<const char*>(
6623 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:546624 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:146625 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196626 }
6627 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:546628 return GetUniformLocationHelper(
6629 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:196630}
6631
[email protected]f7a64ee2010-02-01 22:24:146632error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]b9849abf2009-11-25 19:13:196633 uint32 immediate_data_size, const gles2::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:196634 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:306635 const char* name = GetImmediateDataAs<const char*>(
6636 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:546637 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:146638 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196639 }
6640 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:546641 return GetUniformLocationHelper(
6642 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6643}
6644
6645error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
6646 uint32 immediate_data_size, const gles2::GetUniformLocationBucket& c) {
6647 Bucket* bucket = GetBucket(c.name_bucket_id);
6648 if (!bucket) {
6649 return error::kInvalidArguments;
6650 }
6651 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:186652 if (!bucket->GetAsString(&name_str)) {
6653 return error::kInvalidArguments;
6654 }
[email protected]558847a2010-03-24 07:02:546655 return GetUniformLocationHelper(
6656 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:196657}
6658
[email protected]ddd968b82010-03-02 00:44:296659error::Error GLES2DecoderImpl::HandleGetString(
6660 uint32 immediate_data_size, const gles2::GetString& c) {
6661 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:056662 if (!validators_->string_type.IsValid(name)) {
[email protected]f80e6e12012-08-31 00:43:536663 SetGLErrorInvalidEnum("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:296664 return error::kNoError;
6665 }
[email protected]1958e0e2010-04-22 05:17:156666 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
6667 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:046668 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:156669 switch (name) {
6670 case GL_VERSION:
6671 str = "OpenGL ES 2.0 Chromium";
6672 break;
6673 case GL_SHADING_LANGUAGE_VERSION:
6674 str = "OpenGL ES GLSL ES 1.0 Chromium";
6675 break;
[email protected]32939602012-05-09 06:25:166676 case GL_RENDERER:
6677 str = "Chromium";
6678 break;
6679 case GL_VENDOR:
6680 str = "Chromium";
6681 break;
[email protected]1958e0e2010-04-22 05:17:156682 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:046683 {
6684 // For WebGL contexts, strip out the OES derivatives extension if it has
6685 // not been enabled.
6686 if (force_webgl_glsl_validation_ &&
6687 !derivatives_explicitly_enabled_) {
6688 extensions = feature_info_->extensions();
6689 size_t offset = extensions.find(kOESDerivativeExtension);
6690 if (std::string::npos != offset) {
6691 extensions.replace(offset,
6692 offset + arraysize(kOESDerivativeExtension),
6693 std::string());
6694 }
[email protected]f0d74742011-10-03 16:31:046695 } else {
[email protected]6f5fac9d12012-06-26 21:02:456696 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:046697 }
[email protected]6f5fac9d12012-06-26 21:02:456698 std::string surface_extensions = surface_->GetExtensions();
6699 if (!surface_extensions.empty())
6700 extensions += " " + surface_extensions;
6701 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:046702 }
[email protected]1958e0e2010-04-22 05:17:156703 break;
6704 default:
6705 str = gl_str;
6706 break;
6707 }
[email protected]ddd968b82010-03-02 00:44:296708 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:156709 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:296710 return error::kNoError;
6711}
6712
[email protected]0c86dbf2010-03-05 08:14:116713void GLES2DecoderImpl::DoBufferData(
[email protected]b9363b22010-06-09 22:06:156714 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
[email protected]9438b012010-06-15 22:55:056715 if (!validators_->buffer_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:536716 SetGLErrorInvalidEnum("glBufferData", target, "target");
[email protected]8eee29c2010-04-29 03:38:296717 return;
6718 }
[email protected]9438b012010-06-15 22:55:056719 if (!validators_->buffer_usage.IsValid(usage)) {
[email protected]f80e6e12012-08-31 00:43:536720 SetGLErrorInvalidEnum("glBufferData", usage, "usage");
[email protected]0c86dbf2010-03-05 08:14:116721 return;
[email protected]3b6ec202010-03-05 05:16:236722 }
6723 if (size < 0) {
[email protected]ad84a3a2012-06-08 21:42:436724 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0");
[email protected]037896bd2010-04-21 19:07:286725 return;
[email protected]3b6ec202010-03-05 05:16:236726 }
6727 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target);
6728 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436729 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:286730 return;
[email protected]3b6ec202010-03-05 05:16:236731 }
6732 // Clear the buffer to 0 if no initial data was passed in.
6733 scoped_array<int8> zero;
6734 if (!data) {
6735 zero.reset(new int8[size]);
6736 memset(zero.get(), 0, size);
6737 data = zero.get();
6738 }
[email protected]473c01ccb2011-06-07 01:33:306739
[email protected]3b6ec202010-03-05 05:16:236740 CopyRealGLErrorsToWrapper();
6741 glBufferData(target, size, data, usage);
[email protected]1002c2d2011-06-28 22:39:046742 GLenum error = PeekGLError();
6743 if (error == GL_NO_ERROR) {
[email protected]473c01ccb2011-06-07 01:33:306744 buffer_manager()->SetInfo(info, size, usage);
[email protected]0c86dbf2010-03-05 08:14:116745 info->SetRange(0, size, data);
[email protected]a39370652012-09-25 21:52:136746 } else {
6747 buffer_manager()->SetInfo(info, 0, usage);
[email protected]3b6ec202010-03-05 05:16:236748 }
[email protected]0c86dbf2010-03-05 08:14:116749}
6750
6751error::Error GLES2DecoderImpl::HandleBufferData(
6752 uint32 immediate_data_size, const gles2::BufferData& c) {
6753 GLenum target = static_cast<GLenum>(c.target);
6754 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
6755 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
6756 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
6757 GLenum usage = static_cast<GLenum>(c.usage);
6758 const void* data = NULL;
6759 if (data_shm_id != 0 || data_shm_offset != 0) {
6760 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
6761 if (!data) {
6762 return error::kOutOfBounds;
6763 }
6764 }
6765 DoBufferData(target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:146766 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196767}
6768
[email protected]f7a64ee2010-02-01 22:24:146769error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]b9849abf2009-11-25 19:13:196770 uint32 immediate_data_size, const gles2::BufferDataImmediate& c) {
6771 GLenum target = static_cast<GLenum>(c.target);
6772 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:306773 const void* data = GetImmediateDataAs<const void*>(
6774 c, size, immediate_data_size);
6775 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146776 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:306777 }
[email protected]b9849abf2009-11-25 19:13:196778 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0c86dbf2010-03-05 08:14:116779 DoBufferData(target, size, data, usage);
6780 return error::kNoError;
6781}
6782
6783void GLES2DecoderImpl::DoBufferSubData(
6784 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]3916c97e2010-02-25 03:20:506785 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:476786 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436787 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:286788 return;
[email protected]a93bb842010-02-16 23:03:476789 }
[email protected]0c86dbf2010-03-05 08:14:116790 if (!info->SetRange(offset, size, data)) {
[email protected]ad84a3a2012-06-08 21:42:436791 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range");
[email protected]473c01ccb2011-06-07 01:33:306792 return;
[email protected]07f54fcc2009-12-22 02:46:306793 }
[email protected]473c01ccb2011-06-07 01:33:306794 glBufferSubData(target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:196795}
6796
[email protected]0d6bfdc2011-11-02 01:32:206797bool GLES2DecoderImpl::ClearLevel(
6798 unsigned service_id,
6799 unsigned bind_target,
6800 unsigned target,
6801 int level,
6802 unsigned format,
6803 unsigned type,
6804 int width,
[email protected]4502e6492011-12-14 19:39:156805 int height,
6806 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:006807 uint32 channels = GLES2Util::GetChannelsForFormat(format);
6808 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
6809 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
6810 // on depth formats.
6811 GLuint fb = 0;
6812 glGenFramebuffersEXT(1, &fb);
6813 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
6814
6815 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
6816 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
6817 GL_DEPTH_ATTACHMENT;
6818
6819 glFramebufferTexture2DEXT(
6820 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
6821 // ANGLE promises a depth only attachment ok.
6822 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
6823 GL_FRAMEBUFFER_COMPLETE) {
6824 return false;
6825 }
6826 glClearStencil(0);
6827 glStencilMask(-1);
6828 glClearDepth(1.0f);
6829 glDepthMask(true);
6830 glDisable(GL_SCISSOR_TEST);
6831 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
6832
6833 RestoreClearState();
6834
6835 glDeleteFramebuffersEXT(1, &fb);
6836 FramebufferManager::FramebufferInfo* framebuffer =
6837 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
6838 GLuint fb_service_id =
6839 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
6840 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
6841 return true;
6842 }
6843
[email protected]45d15a62012-04-18 14:33:176844 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
6845
6846 uint32 size;
6847 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:346848 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246849 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:176850 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:206851 return false;
6852 }
[email protected]45d15a62012-04-18 14:33:176853
[email protected]a5d3dad2012-05-26 04:34:446854 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
6855
[email protected]45d15a62012-04-18 14:33:176856 int tile_height;
6857
6858 if (size > kMaxZeroSize) {
6859 if (kMaxZeroSize < padded_row_size) {
6860 // That'd be an awfully large texture.
6861 return false;
6862 }
6863 // We should never have a large total size with a zero row size.
6864 DCHECK_GT(padded_row_size, 0U);
6865 tile_height = kMaxZeroSize / padded_row_size;
6866 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246867 width, tile_height, format, type, state_.unpack_alignment, &size,
6868 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:176869 return false;
6870 }
[email protected]4502e6492011-12-14 19:39:156871 } else {
[email protected]45d15a62012-04-18 14:33:176872 tile_height = height;
6873 }
6874
6875 // Assumes the size has already been checked.
6876 scoped_array<char> zero(new char[size]);
6877 memset(zero.get(), 0, size);
6878 glBindTexture(bind_target, service_id);
6879
6880 GLint y = 0;
6881 while (y < height) {
6882 GLint h = y + tile_height > height ? height - y : tile_height;
6883 if (is_texture_immutable || h != height) {
6884 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
6885 } else {
6886 WrappedTexImage2D(
6887 target, level, format, width, h, 0, format, type, zero.get());
6888 }
6889 y += tile_height;
[email protected]4502e6492011-12-14 19:39:156890 }
[email protected]0d6bfdc2011-11-02 01:32:206891 TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target);
6892 glBindTexture(bind_target, info ? info->service_id() : 0);
6893 return true;
6894}
6895
[email protected]ad84a3a2012-06-08 21:42:436896namespace {
6897
6898const int kS3TCBlockWidth = 4;
6899const int kS3TCBlockHeight = 4;
6900const int kS3TCDXT1BlockSize = 8;
6901const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:076902const int kETC1BlockWidth = 4;
6903const int kETC1BlockHeight = 4;
6904const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:436905
6906bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:516907 return (size == 1) ||
6908 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:436909}
6910
6911} // anonymous namespace.
6912
6913bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
6914 const char* function_name,
6915 GLsizei width, GLsizei height, GLenum format, size_t size) {
6916 unsigned int bytes_required = 0;
6917
6918 switch (format) {
6919 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6920 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
6921 int num_blocks_across =
6922 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
6923 int num_blocks_down =
6924 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
6925 int num_blocks = num_blocks_across * num_blocks_down;
6926 bytes_required = num_blocks * kS3TCDXT1BlockSize;
6927 break;
6928 }
6929 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
6930 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
6931 int num_blocks_across =
6932 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
6933 int num_blocks_down =
6934 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
6935 int num_blocks = num_blocks_across * num_blocks_down;
6936 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
6937 break;
6938 }
[email protected]2d3765b2012-10-03 00:31:076939 case GL_ETC1_RGB8_OES: {
6940 int num_blocks_across =
6941 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
6942 int num_blocks_down =
6943 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
6944 int num_blocks = num_blocks_across * num_blocks_down;
6945 bytes_required = num_blocks * kETC1BlockSize;
6946 break;
6947 }
[email protected]ad84a3a2012-06-08 21:42:436948 default:
[email protected]f80e6e12012-08-31 00:43:536949 SetGLErrorInvalidEnum(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:436950 return false;
6951 }
6952
6953 if (size != bytes_required) {
6954 SetGLError(
6955 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
6956 return false;
6957 }
6958
6959 return true;
6960}
6961
6962bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
6963 const char* function_name,
6964 GLint level, GLsizei width, GLsizei height, GLenum format) {
6965 switch (format) {
6966 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6967 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6968 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
6969 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
6970 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
6971 SetGLError(
6972 GL_INVALID_OPERATION, function_name,
6973 "width or height invalid for level");
6974 return false;
6975 }
6976 return true;
6977 }
[email protected]2d3765b2012-10-03 00:31:076978 case GL_ETC1_RGB8_OES:
6979 if (width <= 0 || height <= 0) {
6980 SetGLError(
6981 GL_INVALID_OPERATION, function_name,
6982 "width or height invalid for level");
6983 return false;
6984 }
6985 return true;
[email protected]ad84a3a2012-06-08 21:42:436986 default:
6987 return false;
6988 }
6989}
6990
6991bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
6992 const char* function_name,
6993 GLenum target, GLint level, GLint xoffset, GLint yoffset,
6994 GLsizei width, GLsizei height, GLenum format,
6995 TextureManager::TextureInfo* texture) {
6996 if (xoffset < 0 || yoffset < 0) {
6997 SetGLError(
6998 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
6999 return false;
7000 }
7001
7002 switch (format) {
7003 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7004 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7005 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7006 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7007 const int kBlockWidth = 4;
7008 const int kBlockHeight = 4;
7009 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
7010 SetGLError(
7011 GL_INVALID_OPERATION, function_name,
7012 "xoffset or yoffset not multiple of 4");
7013 return false;
7014 }
7015 GLsizei tex_width = 0;
7016 GLsizei tex_height = 0;
7017 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7018 width - xoffset > tex_width ||
7019 height - yoffset > tex_height) {
7020 SetGLError(
7021 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7022 return false;
7023 }
7024 return ValidateCompressedTexDimensions(
7025 function_name, level, width, height, format);
7026 }
[email protected]2d3765b2012-10-03 00:31:077027 case GL_ETC1_RGB8_OES: {
7028 SetGLError(
7029 GL_INVALID_OPERATION, function_name,
7030 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7031 return false;
7032 }
[email protected]ad84a3a2012-06-08 21:42:437033 default:
7034 return false;
7035 }
7036}
7037
[email protected]a93bb842010-02-16 23:03:477038error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7039 GLenum target,
7040 GLint level,
7041 GLenum internal_format,
7042 GLsizei width,
7043 GLsizei height,
7044 GLint border,
7045 GLsizei image_size,
7046 const void* data) {
[email protected]a93bb842010-02-16 23:03:477047 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057048 if (!validators_->texture_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:537049 SetGLErrorInvalidEnum("glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297050 return error::kNoError;
7051 }
[email protected]9438b012010-06-15 22:55:057052 if (!validators_->compressed_texture_format.IsValid(
7053 internal_format)) {
[email protected]f80e6e12012-08-31 00:43:537054 SetGLErrorInvalidEnum(
7055 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477056 return error::kNoError;
7057 }
[email protected]80eb6b52012-01-19 00:14:417058 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477059 border != 0) {
[email protected]8eee29c2010-04-29 03:38:297060 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437061 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477062 return error::kNoError;
7063 }
[email protected]3916c97e2010-02-25 03:20:507064 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477065 if (!info) {
[email protected]8eee29c2010-04-29 03:38:297066 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437067 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477068 return error::kNoError;
7069 }
[email protected]97dc7cbe2011-12-06 17:26:177070 if (info->IsImmutable()) {
7071 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437072 "glCompressedTexImage2D", "texture is immutable");
7073 return error::kNoError;
7074 }
7075
7076 if (!ValidateCompressedTexDimensions(
7077 "glCompressedTexImage2D", level, width, height, internal_format) ||
7078 !ValidateCompressedTexFuncData(
7079 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177080 return error::kNoError;
7081 }
[email protected]968351b2011-12-20 08:26:517082
7083 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427084 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517085 // TODO(gman): If textures tracked which framebuffers they were attached to
7086 // we could just mark those framebuffers as not complete.
7087 framebuffer_manager()->IncFramebufferStateChangeCount();
7088 }
7089
[email protected]a93bb842010-02-16 23:03:477090 scoped_array<int8> zero;
7091 if (!data) {
7092 zero.reset(new int8[image_size]);
7093 memset(zero.get(), 0, image_size);
7094 data = zero.get();
7095 }
[email protected]cadde4a2010-07-31 17:10:437096 CopyRealGLErrorsToWrapper();
[email protected]a93bb842010-02-16 23:03:477097 glCompressedTexImage2D(
7098 target, level, internal_format, width, height, border, image_size, data);
[email protected]1002c2d2011-06-28 22:39:047099 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437100 if (error == GL_NO_ERROR) {
7101 texture_manager()->SetLevelInfo(
[email protected]0d6bfdc2011-11-02 01:32:207102 info, target, level, internal_format, width, height, 1, border, 0, 0,
7103 true);
[email protected]cadde4a2010-07-31 17:10:437104 }
[email protected]a93bb842010-02-16 23:03:477105 return error::kNoError;
7106}
7107
[email protected]f7a64ee2010-02-01 22:24:147108error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197109 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) {
7110 GLenum target = static_cast<GLenum>(c.target);
7111 GLint level = static_cast<GLint>(c.level);
7112 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7113 GLsizei width = static_cast<GLsizei>(c.width);
7114 GLsizei height = static_cast<GLsizei>(c.height);
7115 GLint border = static_cast<GLint>(c.border);
7116 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7117 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7118 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7119 const void* data = NULL;
7120 if (data_shm_id != 0 || data_shm_offset != 0) {
7121 data = GetSharedMemoryAs<const void*>(
7122 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467123 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147124 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197125 }
7126 }
[email protected]a93bb842010-02-16 23:03:477127 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197128 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197129}
7130
[email protected]f7a64ee2010-02-01 22:24:147131error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]b9849abf2009-11-25 19:13:197132 uint32 immediate_data_size, const gles2::CompressedTexImage2DImmediate& c) {
7133 GLenum target = static_cast<GLenum>(c.target);
7134 GLint level = static_cast<GLint>(c.level);
7135 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7136 GLsizei width = static_cast<GLsizei>(c.width);
7137 GLsizei height = static_cast<GLsizei>(c.height);
7138 GLint border = static_cast<GLint>(c.border);
7139 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307140 const void* data = GetImmediateDataAs<const void*>(
7141 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467142 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147143 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467144 }
[email protected]a93bb842010-02-16 23:03:477145 return DoCompressedTexImage2D(
7146 target, level, internal_format, width, height, border, image_size, data);
7147}
7148
[email protected]b6140d02010-05-17 14:47:167149error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
7150 uint32 immediate_data_size, const gles2::CompressedTexImage2DBucket& c) {
7151 GLenum target = static_cast<GLenum>(c.target);
7152 GLint level = static_cast<GLint>(c.level);
7153 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7154 GLsizei width = static_cast<GLsizei>(c.width);
7155 GLsizei height = static_cast<GLsizei>(c.height);
7156 GLint border = static_cast<GLint>(c.border);
7157 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287158 if (!bucket) {
7159 return error::kInvalidArguments;
7160 }
7161 uint32 data_size = bucket->size();
7162 GLsizei imageSize = data_size;
7163 const void* data = bucket->GetData(0, data_size);
7164 if (!data) {
7165 return error::kInvalidArguments;
7166 }
[email protected]b6140d02010-05-17 14:47:167167 return DoCompressedTexImage2D(
7168 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287169 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167170}
7171
7172error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7173 uint32 immediate_data_size,
7174 const gles2::CompressedTexSubImage2DBucket& c) {
7175 GLenum target = static_cast<GLenum>(c.target);
7176 GLint level = static_cast<GLint>(c.level);
7177 GLint xoffset = static_cast<GLint>(c.xoffset);
7178 GLint yoffset = static_cast<GLint>(c.yoffset);
7179 GLsizei width = static_cast<GLsizei>(c.width);
7180 GLsizei height = static_cast<GLsizei>(c.height);
7181 GLenum format = static_cast<GLenum>(c.format);
7182 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287183 if (!bucket) {
7184 return error::kInvalidArguments;
7185 }
[email protected]b6140d02010-05-17 14:47:167186 uint32 data_size = bucket->size();
7187 GLsizei imageSize = data_size;
7188 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287189 if (!data) {
7190 return error::kInvalidArguments;
7191 }
[email protected]9438b012010-06-15 22:55:057192 if (!validators_->texture_target.IsValid(target)) {
[email protected]b6140d02010-05-17 14:47:167193 SetGLError(
[email protected]f80e6e12012-08-31 00:43:537194 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167195 return error::kNoError;
7196 }
[email protected]9438b012010-06-15 22:55:057197 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:537198 SetGLErrorInvalidEnum("glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057199 return error::kNoError;
7200 }
[email protected]b6140d02010-05-17 14:47:167201 if (width < 0) {
[email protected]ad84a3a2012-06-08 21:42:437202 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167203 return error::kNoError;
7204 }
7205 if (height < 0) {
[email protected]ad84a3a2012-06-08 21:42:437206 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167207 return error::kNoError;
7208 }
7209 if (imageSize < 0) {
[email protected]ad84a3a2012-06-08 21:42:437210 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167211 return error::kNoError;
7212 }
[email protected]cadde4a2010-07-31 17:10:437213 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167214 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7215 return error::kNoError;
7216}
7217
[email protected]81375742012-06-08 00:04:007218bool GLES2DecoderImpl::ValidateTextureParameters(
7219 const char* function_name,
7220 GLenum target, GLenum format, GLenum type, GLint level) {
7221 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
[email protected]ad84a3a2012-06-08 21:42:437222 SetGLError(GL_INVALID_OPERATION, function_name,
7223 (std::string("invalid type ") +
[email protected]81375742012-06-08 00:04:007224 GLES2Util::GetStringEnum(type) + " for format " +
7225 GLES2Util::GetStringEnum(format)).c_str());
7226 return false;
7227 }
7228
7229 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7230 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
[email protected]ad84a3a2012-06-08 21:42:437231 SetGLError(GL_INVALID_OPERATION, function_name,
7232 (std::string("invalid type ") +
[email protected]81375742012-06-08 00:04:007233 GLES2Util::GetStringEnum(type) + " for format " +
7234 GLES2Util::GetStringEnum(format)).c_str());
7235 return false;
7236 }
7237 return true;
7238}
7239
[email protected]a93bb842010-02-16 23:03:477240error::Error GLES2DecoderImpl::DoTexImage2D(
7241 GLenum target,
7242 GLint level,
7243 GLenum internal_format,
7244 GLsizei width,
7245 GLsizei height,
7246 GLint border,
7247 GLenum format,
7248 GLenum type,
7249 const void* pixels,
7250 uint32 pixels_size) {
[email protected]9438b012010-06-15 22:55:057251 if (!validators_->texture_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:537252 SetGLErrorInvalidEnum("glTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297253 return error::kNoError;
7254 }
[email protected]9438b012010-06-15 22:55:057255 if (!validators_->texture_format.IsValid(internal_format)) {
[email protected]f80e6e12012-08-31 00:43:537256 SetGLErrorInvalidEnum("glTexImage2D", internal_format, "internal_format");
[email protected]8eee29c2010-04-29 03:38:297257 return error::kNoError;
7258 }
[email protected]9438b012010-06-15 22:55:057259 if (!validators_->texture_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:537260 SetGLErrorInvalidEnum("glTexImage2D", format, "format");
[email protected]8eee29c2010-04-29 03:38:297261 return error::kNoError;
7262 }
[email protected]9438b012010-06-15 22:55:057263 if (!validators_->pixel_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:537264 SetGLErrorInvalidEnum("glTexImage2D", type, "type");
[email protected]f7a64ee2010-02-01 22:24:147265 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197266 }
[email protected]7b92c412010-07-20 17:48:257267 if (format != internal_format) {
[email protected]ad84a3a2012-06-08 21:42:437268 SetGLError(GL_INVALID_OPERATION,
7269 "glTexImage2D", "format != internalFormat");
[email protected]7b92c412010-07-20 17:48:257270 return error::kNoError;
7271 }
[email protected]81375742012-06-08 00:04:007272 if (!ValidateTextureParameters("glTexImage2D", target, format, type, level)) {
7273 return error::kNoError;
7274 }
[email protected]80eb6b52012-01-19 00:14:417275 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477276 border != 0) {
[email protected]ad84a3a2012-06-08 21:42:437277 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477278 return error::kNoError;
7279 }
[email protected]81375742012-06-08 00:04:007280 if ((GLES2Util::GetChannelsForFormat(format) &
7281 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
7282 SetGLError(
7283 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437284 "glTexImage2D", "can not supply data for depth or stencil textures");
[email protected]81375742012-06-08 00:04:007285 return error::kNoError;
7286 }
[email protected]3916c97e2010-02-25 03:20:507287 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477288 if (!info) {
[email protected]8eee29c2010-04-29 03:38:297289 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437290 "glTexImage2D", "unknown texture for target");
[email protected]a93bb842010-02-16 23:03:477291 return error::kNoError;
7292 }
[email protected]0226c112011-07-22 03:25:077293
[email protected]97dc7cbe2011-12-06 17:26:177294 if (info->IsImmutable()) {
7295 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437296 "glTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:177297 return error::kNoError;
7298 }
7299
[email protected]0226c112011-07-22 03:25:077300 GLsizei tex_width = 0;
7301 GLsizei tex_height = 0;
7302 GLenum tex_type = 0;
7303 GLenum tex_format = 0;
7304 bool level_is_same =
7305 info->GetLevelSize(target, level, &tex_width, &tex_height) &&
7306 info->GetLevelType(target, level, &tex_type, &tex_format) &&
7307 width == tex_width && height == tex_height &&
7308 type == tex_type && format == tex_format;
7309
7310 if (level_is_same && !pixels) {
[email protected]1bed6222011-12-21 11:21:397311 // Just set the level info but mark the texture as uncleared.
7312 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417313 info,
[email protected]1bed6222011-12-21 11:21:397314 target, level, internal_format, width, height, 1, border, format, type,
7315 false);
[email protected]ea72ed222011-08-17 18:58:437316 tex_image_2d_failed_ = false;
[email protected]0226c112011-07-22 03:25:077317 return error::kNoError;
7318 }
7319
[email protected]297ca1c2011-06-20 23:08:467320 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427321 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517322 // TODO(gman): If textures tracked which framebuffers they were attached to
7323 // we could just mark those framebuffers as not complete.
7324 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:467325 }
7326
[email protected]1bed6222011-12-21 11:21:397327 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) {
[email protected]0226c112011-07-22 03:25:077328 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
[email protected]57edfdad2012-02-07 04:57:157329 texture_manager()->SetLevelCleared(info, target, level);
[email protected]0226c112011-07-22 03:25:077330 tex_image_2d_failed_ = false;
7331 return error::kNoError;
[email protected]7488d962010-07-16 02:41:587332 }
[email protected]876f6fee2010-08-02 23:10:327333
[email protected]cadde4a2010-07-31 17:10:437334 CopyRealGLErrorsToWrapper();
[email protected]473c01ccb2011-06-07 01:33:307335 WrappedTexImage2D(
7336 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477337 pixels);
[email protected]1002c2d2011-06-28 22:39:047338 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437339 if (error == GL_NO_ERROR) {
[email protected]0d6bfdc2011-11-02 01:32:207340 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417341 info,
[email protected]0d6bfdc2011-11-02 01:32:207342 target, level, internal_format, width, height, 1, border, format, type,
7343 pixels != NULL);
[email protected]b493ee622011-04-13 23:52:007344 tex_image_2d_failed_ = false;
[email protected]cadde4a2010-07-31 17:10:437345 }
[email protected]f7a64ee2010-02-01 22:24:147346 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197347}
7348
[email protected]f7a64ee2010-02-01 22:24:147349error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197350 uint32 immediate_data_size, const gles2::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387351 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]b493ee622011-04-13 23:52:007352 tex_image_2d_failed_ = true;
[email protected]b9849abf2009-11-25 19:13:197353 GLenum target = static_cast<GLenum>(c.target);
7354 GLint level = static_cast<GLint>(c.level);
7355 GLint internal_format = static_cast<GLint>(c.internalformat);
7356 GLsizei width = static_cast<GLsizei>(c.width);
7357 GLsizei height = static_cast<GLsizei>(c.height);
7358 GLint border = static_cast<GLint>(c.border);
7359 GLenum format = static_cast<GLenum>(c.format);
7360 GLenum type = static_cast<GLenum>(c.type);
7361 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7362 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187363 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347364 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247365 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347366 NULL)) {
[email protected]a76b0052010-03-05 00:33:187367 return error::kOutOfBounds;
7368 }
[email protected]b9849abf2009-11-25 19:13:197369 const void* pixels = NULL;
7370 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7371 pixels = GetSharedMemoryAs<const void*>(
7372 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467373 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147374 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197375 }
7376 }
[email protected]a93bb842010-02-16 23:03:477377 return DoTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197378 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477379 pixels, pixels_size);
[email protected]b9849abf2009-11-25 19:13:197380}
7381
[email protected]f7a64ee2010-02-01 22:24:147382error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]b9849abf2009-11-25 19:13:197383 uint32 immediate_data_size, const gles2::TexImage2DImmediate& c) {
7384 GLenum target = static_cast<GLenum>(c.target);
7385 GLint level = static_cast<GLint>(c.level);
[email protected]ba3176a2009-12-16 18:19:467386 GLint internal_format = static_cast<GLint>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197387 GLsizei width = static_cast<GLsizei>(c.width);
7388 GLsizei height = static_cast<GLsizei>(c.height);
7389 GLint border = static_cast<GLint>(c.border);
7390 GLenum format = static_cast<GLenum>(c.format);
7391 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:187392 uint32 size;
[email protected]3458a64a2012-04-10 17:39:347393 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247394 width, height, format, type, state_.unpack_alignment, &size,
7395 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187396 return error::kOutOfBounds;
7397 }
[email protected]07f54fcc2009-12-22 02:46:307398 const void* pixels = GetImmediateDataAs<const void*>(
7399 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467400 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147401 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467402 }
[email protected]a93bb842010-02-16 23:03:477403 DoTexImage2D(
[email protected]ba3176a2009-12-16 18:19:467404 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477405 pixels, size);
[email protected]f7a64ee2010-02-01 22:24:147406 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327407}
7408
[email protected]cadde4a2010-07-31 17:10:437409void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7410 GLenum target,
7411 GLint level,
7412 GLint xoffset,
7413 GLint yoffset,
7414 GLsizei width,
7415 GLsizei height,
7416 GLenum format,
7417 GLsizei image_size,
7418 const void * data) {
7419 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7420 if (!info) {
7421 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437422 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437423 return;
7424 }
7425 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527426 GLenum internal_format = 0;
7427 if (!info->GetLevelType(target, level, &type, &internal_format)) {
7428 SetGLError(
7429 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437430 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527431 return;
7432 }
7433 if (internal_format != format) {
7434 SetGLError(
7435 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437436 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527437 return;
7438 }
7439 if (!info->ValidForTexture(
7440 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]cadde4a2010-07-31 17:10:437441 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437442 "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437443 return;
7444 }
[email protected]ad84a3a2012-06-08 21:42:437445
7446 if (!ValidateCompressedTexFuncData(
7447 "glCompressedTexSubImage2D", width, height, format, image_size) ||
7448 !ValidateCompressedTexSubDimensions(
7449 "glCompressedTexSubImage2D",
7450 target, level, xoffset, yoffset, width, height, format, info)) {
7451 return;
7452 }
7453
7454
[email protected]0d6bfdc2011-11-02 01:32:207455 // Note: There is no need to deal with texture cleared tracking here
7456 // because the validation above means you can only get here if the level
7457 // is already a matching compressed format and in that case
7458 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:437459 glCompressedTexSubImage2D(
7460 target, level, xoffset, yoffset, width, height, format, image_size, data);
7461}
7462
[email protected]6e288612010-12-21 20:45:037463static void Clip(
7464 GLint start, GLint range, GLint sourceRange,
7465 GLint* out_start, GLint* out_range) {
7466 DCHECK(out_start);
7467 DCHECK(out_range);
7468 if (start < 0) {
7469 range += start;
7470 start = 0;
7471 }
7472 GLint end = start + range;
7473 if (end > sourceRange) {
7474 range -= end - sourceRange;
7475 }
7476 *out_start = start;
7477 *out_range = range;
7478}
7479
[email protected]cadde4a2010-07-31 17:10:437480void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:447481 GLenum target,
7482 GLint level,
7483 GLenum internal_format,
7484 GLint x,
7485 GLint y,
7486 GLsizei width,
7487 GLsizei height,
7488 GLint border) {
[email protected]cadde4a2010-07-31 17:10:437489 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7490 if (!info) {
7491 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437492 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437493 return;
7494 }
[email protected]97dc7cbe2011-12-06 17:26:177495 if (info->IsImmutable()) {
7496 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437497 "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:177498 }
[email protected]80eb6b52012-01-19 00:14:417499 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:187500 border != 0) {
[email protected]ad84a3a2012-06-08 21:42:437501 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:187502 return;
7503 }
[email protected]81375742012-06-08 00:04:007504 if (!ValidateTextureParameters(
7505 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
7506 return;
7507 }
[email protected]f5719fb2010-08-04 18:27:187508
[email protected]9edc6b22010-12-23 02:00:267509 // Check we have compatible formats.
7510 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7511 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7512 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
7513
7514 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ad84a3a2012-06-08 21:42:437515 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:267516 return;
7517 }
7518
[email protected]81375742012-06-08 00:04:007519 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
7520 SetGLError(
7521 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437522 "glCopyImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:007523 return;
7524 }
7525
[email protected]a0b78dc2011-11-11 10:43:107526 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
7527 return;
7528 }
7529
[email protected]cadde4a2010-07-31 17:10:437530 CopyRealGLErrorsToWrapper();
[email protected]de26b3c2011-08-03 21:54:277531 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:037532 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:267533
[email protected]297ca1c2011-06-20 23:08:467534 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427535 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517536 // TODO(gman): If textures tracked which framebuffers they were attached to
7537 // we could just mark those framebuffers as not complete.
7538 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:467539 }
7540
[email protected]9edc6b22010-12-23 02:00:267541 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:037542 GLint copyX = 0;
7543 GLint copyY = 0;
7544 GLint copyWidth = 0;
7545 GLint copyHeight = 0;
7546 Clip(x, width, size.width(), &copyX, &copyWidth);
7547 Clip(y, height, size.height(), &copyY, &copyHeight);
7548
7549 if (copyX != x ||
7550 copyY != y ||
7551 copyWidth != width ||
7552 copyHeight != height) {
7553 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:207554 if (!ClearLevel(
7555 info->service_id(), info->target(),
[email protected]4502e6492011-12-14 19:39:157556 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
7557 info->IsImmutable())) {
[email protected]ad84a3a2012-06-08 21:42:437558 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:037559 return;
7560 }
[email protected]6e288612010-12-21 20:45:037561 if (copyHeight > 0 && copyWidth > 0) {
7562 GLint dx = copyX - x;
7563 GLint dy = copyY - y;
7564 GLint destX = dx;
7565 GLint destY = dy;
7566 glCopyTexSubImage2D(target, level,
7567 destX, destY, copyX, copyY,
7568 copyWidth, copyHeight);
7569 }
7570 } else {
7571 glCopyTexImage2D(target, level, internal_format,
7572 copyX, copyY, copyWidth, copyHeight, border);
7573 }
[email protected]1002c2d2011-06-28 22:39:047574 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437575 if (error == GL_NO_ERROR) {
7576 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417577 info, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:207578 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:437579 }
7580}
7581
7582void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:447583 GLenum target,
7584 GLint level,
7585 GLint xoffset,
7586 GLint yoffset,
7587 GLint x,
7588 GLint y,
7589 GLsizei width,
7590 GLsizei height) {
[email protected]cadde4a2010-07-31 17:10:437591 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7592 if (!info) {
7593 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437594 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437595 return;
7596 }
7597 GLenum type = 0;
7598 GLenum format = 0;
7599 if (!info->GetLevelType(target, level, &type, &format) ||
7600 !info->ValidForTexture(
7601 target, level, xoffset, yoffset, width, height, format, type)) {
7602 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437603 "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437604 return;
7605 }
[email protected]9edc6b22010-12-23 02:00:267606
7607 // Check we have compatible formats.
7608 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7609 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7610 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
7611
[email protected]2d3765b2012-10-03 00:31:077612 if (!channels_needed ||
7613 (channels_needed & channels_exist) != channels_needed) {
[email protected]9edc6b22010-12-23 02:00:267614 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:437615 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:267616 return;
7617 }
7618
[email protected]81375742012-06-08 00:04:007619 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
7620 SetGLError(
7621 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437622 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:007623 return;
7624 }
7625
[email protected]a0b78dc2011-11-11 10:43:107626 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
7627 return;
7628 }
7629
[email protected]de26b3c2011-08-03 21:54:277630 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:037631 gfx::Size size = GetBoundReadFrameBufferSize();
7632 GLint copyX = 0;
7633 GLint copyY = 0;
7634 GLint copyWidth = 0;
7635 GLint copyHeight = 0;
7636 Clip(x, width, size.width(), &copyX, &copyWidth);
7637 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:207638
7639 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
[email protected]ad84a3a2012-06-08 21:42:437640 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:207641 return;
7642 }
7643
[email protected]6e288612010-12-21 20:45:037644 if (copyX != x ||
7645 copyY != y ||
7646 copyWidth != width ||
7647 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:207648 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:037649 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:347650 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247651 width, height, format, type, state_.unpack_alignment, &pixels_size,
7652 NULL, NULL)) {
[email protected]ad84a3a2012-06-08 21:42:437653 SetGLError(
7654 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:037655 return;
7656 }
7657 scoped_array<char> zero(new char[pixels_size]);
7658 memset(zero.get(), 0, pixels_size);
7659 glTexSubImage2D(
7660 target, level, xoffset, yoffset, width, height,
7661 format, type, zero.get());
7662 }
[email protected]0d6bfdc2011-11-02 01:32:207663
[email protected]6e288612010-12-21 20:45:037664 if (copyHeight > 0 && copyWidth > 0) {
7665 GLint dx = copyX - x;
7666 GLint dy = copyY - y;
7667 GLint destX = xoffset + dx;
7668 GLint destY = yoffset + dy;
7669 glCopyTexSubImage2D(target, level,
7670 destX, destY, copyX, copyY,
7671 copyWidth, copyHeight);
7672 }
[email protected]cadde4a2010-07-31 17:10:437673}
7674
7675void GLES2DecoderImpl::DoTexSubImage2D(
7676 GLenum target,
7677 GLint level,
7678 GLint xoffset,
7679 GLint yoffset,
7680 GLsizei width,
7681 GLsizei height,
7682 GLenum format,
7683 GLenum type,
7684 const void * data) {
7685 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7686 if (!info) {
7687 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437688 "glTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437689 return;
7690 }
[email protected]df6cf1ad2011-01-29 01:20:527691 GLenum current_type = 0;
7692 GLenum internal_format = 0;
7693 if (!info->GetLevelType(target, level, &current_type, &internal_format)) {
7694 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:437695 GL_INVALID_OPERATION, "glTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527696 return;
7697 }
7698 if (format != internal_format) {
7699 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437700 "glTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527701 return;
7702 }
7703 if (type != current_type) {
7704 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437705 "glTexSubImage2D", "type does not match type of texture.");
[email protected]df6cf1ad2011-01-29 01:20:527706 return;
7707 }
7708
[email protected]cadde4a2010-07-31 17:10:437709 if (!info->ValidForTexture(
7710 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ad84a3a2012-06-08 21:42:437711 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437712 return;
7713 }
[email protected]473c01ccb2011-06-07 01:33:307714
[email protected]81375742012-06-08 00:04:007715 if ((GLES2Util::GetChannelsForFormat(format) &
7716 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
7717 SetGLError(
7718 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437719 "glTexSubImage2D", "can not supply data for depth or stencil textures");
[email protected]81375742012-06-08 00:04:007720 return;
7721 }
7722
[email protected]4502e6492011-12-14 19:39:157723 GLsizei tex_width = 0;
7724 GLsizei tex_height = 0;
7725 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height);
7726 DCHECK(ok);
7727 if (xoffset != 0 || yoffset != 0 ||
7728 width != tex_width || height != tex_height) {
7729 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
[email protected]ad84a3a2012-06-08 21:42:437730 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]473c01ccb2011-06-07 01:33:307731 return;
7732 }
[email protected]63b465922012-09-06 02:04:527733 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:157734 glTexSubImage2D(
7735 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]0d6bfdc2011-11-02 01:32:207736 return;
7737 }
[email protected]4502e6492011-12-14 19:39:157738
7739 if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) {
[email protected]63b465922012-09-06 02:04:527740 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:157741 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
7742 // same as internal_foramt. If that changes we'll need to look them up.
7743 WrappedTexImage2D(
7744 target, level, format, width, height, 0, format, type, data);
7745 } else {
[email protected]63b465922012-09-06 02:04:527746 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:157747 glTexSubImage2D(
7748 target, level, xoffset, yoffset, width, height, format, type, data);
7749 }
7750 texture_manager()->SetLevelCleared(info, target, level);
[email protected]cadde4a2010-07-31 17:10:437751}
7752
[email protected]b493ee622011-04-13 23:52:007753error::Error GLES2DecoderImpl::HandleTexSubImage2D(
7754 uint32 immediate_data_size, const gles2::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387755 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:007756 GLboolean internal = static_cast<GLboolean>(c.internal);
7757 if (internal == GL_TRUE && tex_image_2d_failed_)
7758 return error::kNoError;
7759
7760 GLenum target = static_cast<GLenum>(c.target);
7761 GLint level = static_cast<GLint>(c.level);
7762 GLint xoffset = static_cast<GLint>(c.xoffset);
7763 GLint yoffset = static_cast<GLint>(c.yoffset);
7764 GLsizei width = static_cast<GLsizei>(c.width);
7765 GLsizei height = static_cast<GLsizei>(c.height);
7766 GLenum format = static_cast<GLenum>(c.format);
7767 GLenum type = static_cast<GLenum>(c.type);
7768 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:347769 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247770 width, height, format, type, state_.unpack_alignment, &data_size,
7771 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:007772 return error::kOutOfBounds;
7773 }
7774 const void* pixels = GetSharedMemoryAs<const void*>(
7775 c.pixels_shm_id, c.pixels_shm_offset, data_size);
7776 if (!validators_->texture_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:537777 SetGLErrorInvalidEnum("glTexSubImage2D", target, "target");
[email protected]b493ee622011-04-13 23:52:007778 return error::kNoError;
7779 }
7780 if (width < 0) {
[email protected]ad84a3a2012-06-08 21:42:437781 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "width < 0");
[email protected]b493ee622011-04-13 23:52:007782 return error::kNoError;
7783 }
7784 if (height < 0) {
[email protected]ad84a3a2012-06-08 21:42:437785 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "height < 0");
[email protected]b493ee622011-04-13 23:52:007786 return error::kNoError;
7787 }
7788 if (!validators_->texture_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:537789 SetGLErrorInvalidEnum("glTexSubImage2D", format, "format");
[email protected]b493ee622011-04-13 23:52:007790 return error::kNoError;
7791 }
7792 if (!validators_->pixel_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:537793 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type");
[email protected]b493ee622011-04-13 23:52:007794 return error::kNoError;
7795 }
7796 if (pixels == NULL) {
7797 return error::kOutOfBounds;
7798 }
7799 DoTexSubImage2D(
7800 target, level, xoffset, yoffset, width, height, format, type, pixels);
7801 return error::kNoError;
7802}
7803
7804error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
7805 uint32 immediate_data_size, const gles2::TexSubImage2DImmediate& c) {
7806 GLboolean internal = static_cast<GLboolean>(c.internal);
7807 if (internal == GL_TRUE && tex_image_2d_failed_)
7808 return error::kNoError;
7809
7810 GLenum target = static_cast<GLenum>(c.target);
7811 GLint level = static_cast<GLint>(c.level);
7812 GLint xoffset = static_cast<GLint>(c.xoffset);
7813 GLint yoffset = static_cast<GLint>(c.yoffset);
7814 GLsizei width = static_cast<GLsizei>(c.width);
7815 GLsizei height = static_cast<GLsizei>(c.height);
7816 GLenum format = static_cast<GLenum>(c.format);
7817 GLenum type = static_cast<GLenum>(c.type);
7818 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:347819 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247820 width, height, format, type, state_.unpack_alignment, &data_size,
7821 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:007822 return error::kOutOfBounds;
7823 }
7824 const void* pixels = GetImmediateDataAs<const void*>(
7825 c, data_size, immediate_data_size);
7826 if (!validators_->texture_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:537827 SetGLErrorInvalidEnum("glTexSubImage2D", target, "target");
[email protected]b493ee622011-04-13 23:52:007828 return error::kNoError;
7829 }
7830 if (width < 0) {
[email protected]ad84a3a2012-06-08 21:42:437831 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "width < 0");
[email protected]b493ee622011-04-13 23:52:007832 return error::kNoError;
7833 }
7834 if (height < 0) {
[email protected]ad84a3a2012-06-08 21:42:437835 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "height < 0");
[email protected]b493ee622011-04-13 23:52:007836 return error::kNoError;
7837 }
7838 if (!validators_->texture_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:537839 SetGLErrorInvalidEnum("glTexSubImage2D", format, "format");
[email protected]b493ee622011-04-13 23:52:007840 return error::kNoError;
7841 }
7842 if (!validators_->pixel_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:537843 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type");
[email protected]b493ee622011-04-13 23:52:007844 return error::kNoError;
7845 }
7846 if (pixels == NULL) {
7847 return error::kOutOfBounds;
7848 }
7849 DoTexSubImage2D(
7850 target, level, xoffset, yoffset, width, height, format, type, pixels);
7851 return error::kNoError;
7852}
7853
[email protected]f7a64ee2010-02-01 22:24:147854error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]b9849abf2009-11-25 19:13:197855 uint32 immediate_data_size, const gles2::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:367856 GLuint index = static_cast<GLuint>(c.index);
7857 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]0bfd9882010-02-05 23:02:257858 typedef gles2::GetVertexAttribPointerv::Result Result;
7859 Result* result = GetSharedMemoryAs<Result*>(
7860 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:367861 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:147862 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:367863 }
[email protected]07d0cc82010-02-17 04:51:407864 // Check that the client initialized the result.
7865 if (result->size != 0) {
7866 return error::kInvalidArguments;
7867 }
[email protected]9438b012010-06-15 22:55:057868 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]f80e6e12012-08-31 00:43:537869 SetGLErrorInvalidEnum("glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:147870 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:367871 }
[email protected]3916c97e2010-02-25 03:20:507872 if (index >= group_->max_vertex_attribs()) {
[email protected]8eee29c2010-04-29 03:38:297873 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437874 "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:147875 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:367876 }
[email protected]0bfd9882010-02-05 23:02:257877 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:087878 *result->GetData() =
[email protected]e259eb412012-10-13 05:47:247879 state_.vertex_attrib_manager->GetVertexAttribInfo(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:147880 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327881}
7882
[email protected]f7b85372010-02-03 01:11:377883bool GLES2DecoderImpl::GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:127884 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:377885 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:127886 error::Error* error, GLint* real_location,
7887 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:107888 DCHECK(error);
7889 DCHECK(service_id);
7890 DCHECK(result_pointer);
7891 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:127892 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:377893 *error = error::kNoError;
7894 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:257895 SizedResult<GLint>* result;
7896 result = GetSharedMemoryAs<SizedResult<GLint>*>(
7897 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
7898 if (!result) {
[email protected]f7b85372010-02-03 01:11:377899 *error = error::kOutOfBounds;
7900 return false;
7901 }
[email protected]0bfd9882010-02-05 23:02:257902 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:377903 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:257904 result->SetNumResults(0);
[email protected]6b8cf1a2010-05-06 16:13:587905 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
7906 program, "glGetUniform");
[email protected]f7b85372010-02-03 01:11:377907 if (!info) {
[email protected]ae51d192010-04-27 00:48:037908 return false;
7909 }
7910 if (!info->IsValid()) {
[email protected]f7b85372010-02-03 01:11:377911 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ad84a3a2012-06-08 21:42:437912 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:377913 return false;
7914 }
[email protected]ae51d192010-04-27 00:48:037915 *service_id = info->service_id();
[email protected]43c2f1f2011-03-25 18:35:367916 GLint array_index = -1;
7917 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]1b0a6752012-02-22 03:44:127918 info->GetUniformInfoByFakeLocation(
7919 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:367920 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:377921 // No such location.
[email protected]ad84a3a2012-06-08 21:42:437922 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:377923 return false;
7924 }
[email protected]43c2f1f2011-03-25 18:35:367925 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:507926 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:377927 if (size == 0) {
[email protected]ad84a3a2012-06-08 21:42:437928 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:377929 return false;
7930 }
[email protected]0bfd9882010-02-05 23:02:257931 result = GetSharedMemoryAs<SizedResult<GLint>*>(
7932 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
7933 if (!result) {
[email protected]f7b85372010-02-03 01:11:377934 *error = error::kOutOfBounds;
7935 return false;
7936 }
[email protected]0bfd9882010-02-05 23:02:257937 result->size = size;
[email protected]939e7362010-05-13 20:49:107938 *result_type = type;
[email protected]f7b85372010-02-03 01:11:377939 return true;
7940}
7941
[email protected]f7a64ee2010-02-01 22:24:147942error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]b9849abf2009-11-25 19:13:197943 uint32 immediate_data_size, const gles2::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:377944 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:337945 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:377946 GLuint service_id;
[email protected]939e7362010-05-13 20:49:107947 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:127948 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:377949 Error error;
[email protected]0bfd9882010-02-05 23:02:257950 void* result;
[email protected]f7b85372010-02-03 01:11:377951 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:127952 program, fake_location, c.params_shm_id, c.params_shm_offset,
7953 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:257954 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:127955 service_id, real_location,
[email protected]0bfd9882010-02-05 23:02:257956 static_cast<gles2::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:377957 }
7958 return error;
[email protected]96449d2c2009-11-25 00:01:327959}
7960
[email protected]f7a64ee2010-02-01 22:24:147961error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]b9849abf2009-11-25 19:13:197962 uint32 immediate_data_size, const gles2::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:377963 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:337964 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:377965 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:127966 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:377967 Error error;
[email protected]0bfd9882010-02-05 23:02:257968 typedef gles2::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:107969 Result* result;
7970 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:377971 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:127972 program, fake_location, c.params_shm_id, c.params_shm_offset,
7973 &error, &real_location, &service_id,
7974 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:107975 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
7976 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
7977 GLsizei num_values = result->GetNumResults();
7978 scoped_array<GLint> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:127979 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:107980 GLfloat* dst = result->GetData();
7981 for (GLsizei ii = 0; ii < num_values; ++ii) {
7982 dst[ii] = (temp[ii] != 0);
7983 }
7984 } else {
[email protected]1b0a6752012-02-22 03:44:127985 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:107986 }
[email protected]f7b85372010-02-03 01:11:377987 }
7988 return error;
[email protected]96449d2c2009-11-25 00:01:327989}
7990
[email protected]f7a64ee2010-02-01 22:24:147991error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]b9849abf2009-11-25 19:13:197992 uint32 immediate_data_size, const gles2::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:257993 GLenum shader_type = static_cast<GLenum>(c.shadertype);
7994 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
7995 typedef gles2::GetShaderPrecisionFormat::Result Result;
7996 Result* result = GetSharedMemoryAs<Result*>(
7997 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7998 if (!result) {
7999 return error::kOutOfBounds;
8000 }
[email protected]07d0cc82010-02-17 04:51:408001 // Check that the client initialized the result.
8002 if (result->success != 0) {
8003 return error::kInvalidArguments;
8004 }
[email protected]9438b012010-06-15 22:55:058005 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]f80e6e12012-08-31 00:43:538006 SetGLErrorInvalidEnum(
8007 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298008 return error::kNoError;
8009 }
[email protected]9438b012010-06-15 22:55:058010 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]f80e6e12012-08-31 00:43:538011 SetGLErrorInvalidEnum(
8012 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298013 return error::kNoError;
8014 }
8015
8016 result->success = 1; // true
8017 switch (precision_type) {
8018 case GL_LOW_INT:
8019 case GL_MEDIUM_INT:
8020 case GL_HIGH_INT:
[email protected]0a34b582012-04-09 22:42:568021 // These values are for a 32-bit twos-complement integer format.
8022 result->min_range = 31;
8023 result->max_range = 30;
[email protected]8eee29c2010-04-29 03:38:298024 result->precision = 0;
[email protected]4e8a5b122010-05-08 22:00:108025 break;
[email protected]8eee29c2010-04-29 03:38:298026 case GL_LOW_FLOAT:
8027 case GL_MEDIUM_FLOAT:
8028 case GL_HIGH_FLOAT:
[email protected]0a34b582012-04-09 22:42:568029 // These values are for an IEEE single-precision floating-point format.
8030 result->min_range = 127;
8031 result->max_range = 127;
8032 result->precision = 23;
[email protected]8eee29c2010-04-29 03:38:298033 break;
8034 default:
8035 NOTREACHED();
8036 break;
[email protected]0bfd9882010-02-05 23:02:258037 }
[email protected]f7a64ee2010-02-01 22:24:148038 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328039}
8040
[email protected]f7a64ee2010-02-01 22:24:148041error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]b9849abf2009-11-25 19:13:198042 uint32 immediate_data_size, const gles2::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258043 uint32 result_size = c.result_size;
[email protected]6b8cf1a2010-05-06 16:13:588044 GLuint program = static_cast<GLuint>(c.program);
8045 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8046 program, "glGetAttachedShaders");
[email protected]ae51d192010-04-27 00:48:038047 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258048 return error::kNoError;
8049 }
8050 typedef gles2::GetAttachedShaders::Result Result;
8051 uint32 max_count = Result::ComputeMaxResults(result_size);
8052 Result* result = GetSharedMemoryAs<Result*>(
8053 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8054 if (!result) {
8055 return error::kOutOfBounds;
8056 }
[email protected]07d0cc82010-02-17 04:51:408057 // Check that the client initialized the result.
8058 if (result->size != 0) {
8059 return error::kInvalidArguments;
8060 }
[email protected]0bfd9882010-02-05 23:02:258061 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038062 glGetAttachedShaders(
8063 info->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258064 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038065 if (!shader_manager()->GetClientId(result->GetData()[ii],
8066 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258067 NOTREACHED();
8068 return error::kGenericError;
8069 }
8070 }
8071 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148072 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328073}
8074
[email protected]f7a64ee2010-02-01 22:24:148075error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]b9849abf2009-11-25 19:13:198076 uint32 immediate_data_size, const gles2::GetActiveUniform& c) {
[email protected]0bfd9882010-02-05 23:02:258077 GLuint program = c.program;
8078 GLuint index = c.index;
8079 uint32 name_bucket_id = c.name_bucket_id;
[email protected]0bfd9882010-02-05 23:02:258080 typedef gles2::GetActiveUniform::Result Result;
8081 Result* result = GetSharedMemoryAs<Result*>(
8082 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8083 if (!result) {
8084 return error::kOutOfBounds;
8085 }
[email protected]07d0cc82010-02-17 04:51:408086 // Check that the client initialized the result.
8087 if (result->success != 0) {
8088 return error::kInvalidArguments;
8089 }
[email protected]6b8cf1a2010-05-06 16:13:588090 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8091 program, "glGetActiveUniform");
[email protected]ae51d192010-04-27 00:48:038092 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258093 return error::kNoError;
8094 }
8095 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
8096 info->GetUniformInfo(index);
8097 if (!uniform_info) {
[email protected]ad84a3a2012-06-08 21:42:438098 SetGLError(GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258099 return error::kNoError;
8100 }
8101 result->success = 1; // true.
8102 result->size = uniform_info->size;
8103 result->type = uniform_info->type;
8104 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298105 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148106 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328107}
8108
[email protected]f7a64ee2010-02-01 22:24:148109error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]b9849abf2009-11-25 19:13:198110 uint32 immediate_data_size, const gles2::GetActiveAttrib& c) {
[email protected]0bfd9882010-02-05 23:02:258111 GLuint program = c.program;
8112 GLuint index = c.index;
8113 uint32 name_bucket_id = c.name_bucket_id;
[email protected]0bfd9882010-02-05 23:02:258114 typedef gles2::GetActiveAttrib::Result Result;
8115 Result* result = GetSharedMemoryAs<Result*>(
8116 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8117 if (!result) {
8118 return error::kOutOfBounds;
8119 }
[email protected]07d0cc82010-02-17 04:51:408120 // Check that the client initialized the result.
8121 if (result->success != 0) {
8122 return error::kInvalidArguments;
8123 }
[email protected]6b8cf1a2010-05-06 16:13:588124 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8125 program, "glGetActiveAttrib");
[email protected]ae51d192010-04-27 00:48:038126 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258127 return error::kNoError;
8128 }
8129 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
8130 info->GetAttribInfo(index);
8131 if (!attrib_info) {
[email protected]ad84a3a2012-06-08 21:42:438132 SetGLError(GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258133 return error::kNoError;
8134 }
8135 result->success = 1; // true.
8136 result->size = attrib_info->size;
8137 result->type = attrib_info->type;
8138 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298139 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148140 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328141}
8142
[email protected]b273e432010-04-12 17:23:588143error::Error GLES2DecoderImpl::HandleShaderBinary(
8144 uint32 immediate_data_size, const gles2::ShaderBinary& c) {
8145#if 1 // No binary shader support.
[email protected]ad84a3a2012-06-08 21:42:438146 SetGLError(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588147 return error::kNoError;
8148#else
8149 GLsizei n = static_cast<GLsizei>(c.n);
8150 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:438151 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588152 return error::kNoError;
8153 }
8154 GLsizei length = static_cast<GLsizei>(c.length);
8155 if (length < 0) {
[email protected]ad84a3a2012-06-08 21:42:438156 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588157 return error::kNoError;
8158 }
8159 uint32 data_size;
8160 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8161 return error::kOutOfBounds;
8162 }
8163 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8164 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8165 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8166 const void* binary = GetSharedMemoryAs<const void*>(
8167 c.binary_shm_id, c.binary_shm_offset, length);
8168 if (shaders == NULL || binary == NULL) {
8169 return error::kOutOfBounds;
8170 }
8171 scoped_array<GLuint> service_ids(new GLuint[n]);
8172 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ae51d192010-04-27 00:48:038173 ShaderManager::ShaderInfo* info = GetShaderInfo(shaders[ii]);
8174 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:438175 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588176 return error::kNoError;
8177 }
[email protected]ae51d192010-04-27 00:48:038178 service_ids[ii] = info->service_id();
[email protected]b273e432010-04-12 17:23:588179 }
8180 // TODO(gman): call glShaderBinary
8181 return error::kNoError;
8182#endif
8183}
8184
[email protected]6217d392010-03-25 22:08:358185error::Error GLES2DecoderImpl::HandleSwapBuffers(
8186 uint32 immediate_data_size, const gles2::SwapBuffers& c) {
[email protected]64ace852011-05-19 21:49:498187 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088188 if (!is_offscreen && surface_->DeferSwapBuffers()) {
8189 return error::kDeferCommandUntilLater;
8190 }
8191
[email protected]64ace852011-05-19 21:49:498192 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428193 // TRACE_EVENT for gpu tests:
8194 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
8195 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8196 "width", (is_offscreen ? offscreen_size_.width() :
8197 surface_->GetSize().width()));
[email protected]64ace852011-05-19 21:49:498198 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleSwapBuffers",
8199 "offscreen", is_offscreen,
8200 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358201 // If offscreen then don't actually SwapBuffers to the display. Just copy
8202 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498203 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318204 TRACE_EVENT2("gpu", "Offscreen",
8205 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538206 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8207 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8208 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8209 // fix this.
[email protected]62e155e2012-10-23 22:43:158210 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538211 offscreen_saved_frame_buffer_->Create();
8212 glFinish();
8213 }
8214
8215 // Allocate the offscreen saved color texture.
8216 DCHECK(offscreen_saved_color_format_);
8217 offscreen_saved_color_texture_->AllocateStorage(
8218 offscreen_size_, offscreen_saved_color_format_);
8219
8220 offscreen_saved_frame_buffer_->AttachRenderTexture(
8221 offscreen_saved_color_texture_.get());
8222 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8223 GL_FRAMEBUFFER_COMPLETE) {
8224 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8225 << "because offscreen saved FBO was incomplete.";
8226 return error::kLostContext;
8227 }
8228
[email protected]1fb8c482011-08-31 01:01:538229 // Clear the offscreen color texture.
8230 // TODO(piman): Is this still necessary?
8231 {
8232 ScopedFrameBufferBinder binder(this,
8233 offscreen_saved_frame_buffer_->id());
8234 glClearColor(0, 0, 0, 0);
8235 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8236 glDisable(GL_SCISSOR_TEST);
8237 glClear(GL_COLOR_BUFFER_BIT);
8238 RestoreClearState();
8239 }
8240
8241 UpdateParentTextureInfo();
8242 }
8243
[email protected]6217d392010-03-25 22:08:358244 ScopedGLErrorSuppressor suppressor(this);
8245
[email protected]34ff8b0c2010-10-01 20:06:028246 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138247 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278248 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]89d6ed02011-04-20 00:23:238249 return error::kNoError;
[email protected]b86b14982010-10-11 18:45:488250 } else {
[email protected]069944672012-04-25 20:52:238251 ScopedFrameBufferBinder binder(this,
8252 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138253
[email protected]069944672012-04-25 20:52:238254 if (offscreen_target_buffer_preserved_) {
8255 // Copy the target frame buffer to the saved offscreen texture.
8256 offscreen_saved_color_texture_->Copy(
8257 offscreen_saved_color_texture_->size(),
8258 offscreen_saved_color_format_);
8259 } else {
8260 // Flip the textures in the parent context via the texture manager.
8261 if (!!offscreen_saved_color_texture_info_.get())
8262 offscreen_saved_color_texture_info_->
8263 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568264
[email protected]069944672012-04-25 20:52:238265 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8266 offscreen_target_frame_buffer_->AttachRenderTexture(
8267 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488268 }
[email protected]069944672012-04-25 20:52:238269
8270 // Ensure the side effects of the copy are visible to the parent
8271 // context. There is no need to do this for ANGLE because it uses a
8272 // single D3D device for all contexts.
8273 if (!IsAngle())
8274 glFlush();
[email protected]89d6ed02011-04-20 00:23:238275 return error::kNoError;
[email protected]0c8c9d22010-06-25 17:36:398276 }
[email protected]6217d392010-03-25 22:08:358277 } else {
[email protected]111975c62012-09-06 01:37:318278 TRACE_EVENT2("gpu", "Onscreen",
8279 "width", surface_->GetSize().width(),
8280 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158281 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018282 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]5259ead82010-09-10 18:02:028283 return error::kLostContext;
[email protected]d0498742010-09-20 20:27:018284 }
[email protected]6217d392010-03-25 22:08:358285 }
8286
[email protected]89d6ed02011-04-20 00:23:238287 return error::kNoError;
[email protected]6217d392010-03-25 22:08:358288}
8289
[email protected]d4239852011-08-12 04:51:228290error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
8291 uint32 immediate_data_size, const gles2::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188292 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288293 if (!bucket || bucket->size() == 0) {
8294 return error::kInvalidArguments;
8295 }
[email protected]d4239852011-08-12 04:51:228296 typedef gles2::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188297 Result* result = GetSharedMemoryAs<Result*>(
8298 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8299 if (!result) {
8300 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108301 }
[email protected]b1d2dcb2010-05-17 19:24:188302 // Check that the client initialized the result.
8303 if (*result != 0) {
8304 return error::kInvalidArguments;
8305 }
8306 std::string feature_str;
8307 if (!bucket->GetAsString(&feature_str)) {
8308 return error::kInvalidArguments;
8309 }
8310
8311 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228312 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188313 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228314 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408315 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8316 // TODO(gman): decide how to remove the need for this const_cast.
8317 // I could make validators_ non const but that seems bad as this is the only
8318 // place it is needed. I could make some special friend class of validators
8319 // just to allow this to set them. That seems silly. I could refactor this
8320 // code to use the extension mechanism or the initialization attributes to
8321 // turn this feature on. Given that the only real point of this is to make
8322 // the conformance tests pass and given that there is lots of real work that
8323 // needs to be done it seems like refactoring for one to one of those
8324 // methods is a very low priority.
8325 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048326 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8327 force_webgl_glsl_validation_ = true;
8328 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188329 } else {
8330 return error::kNoError;
8331 }
8332
8333 *result = 1; // true.
8334 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108335}
8336
[email protected]c2f8c8402010-12-06 18:07:248337error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8338 uint32 immediate_data_size,
8339 const gles2::GetRequestableExtensionsCHROMIUM& c) {
8340 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]80eb6b52012-01-19 00:14:418341 FeatureInfo::Ref info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:298342 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:248343 bucket->SetFromString(info->extensions().c_str());
8344 return error::kNoError;
8345}
8346
8347error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
8348 uint32 immediate_data_size, const gles2::RequestExtensionCHROMIUM& c) {
8349 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288350 if (!bucket || bucket->size() == 0) {
8351 return error::kInvalidArguments;
8352 }
[email protected]c2f8c8402010-12-06 18:07:248353 std::string feature_str;
8354 if (!bucket->GetAsString(&feature_str)) {
8355 return error::kInvalidArguments;
8356 }
8357
[email protected]62e155e2012-10-23 22:43:158358 bool std_derivatives_enabled = features().oes_standard_derivatives;
8359 bool webglsl_enabled = features().chromium_webglsl;
[email protected]c2f8c8402010-12-06 18:07:248360
8361 feature_info_->AddFeatures(feature_str.c_str());
8362
[email protected]f0d74742011-10-03 16:31:048363 bool initialization_required = false;
8364 if (force_webgl_glsl_validation_ && !derivatives_explicitly_enabled_) {
8365 size_t derivatives_offset = feature_str.find(kOESDerivativeExtension);
8366 if (std::string::npos != derivatives_offset) {
8367 derivatives_explicitly_enabled_ = true;
8368 initialization_required = true;
8369 }
8370 }
8371
[email protected]c2f8c8402010-12-06 18:07:248372 // If we just enabled a feature which affects the shader translator,
8373 // we may need to re-initialize it.
[email protected]62e155e2012-10-23 22:43:158374 if (std_derivatives_enabled != features().oes_standard_derivatives ||
8375 webglsl_enabled != features().chromium_webglsl ||
[email protected]f0d74742011-10-03 16:31:048376 initialization_required) {
[email protected]c2f8c8402010-12-06 18:07:248377 InitializeShaderTranslator();
8378 }
8379
[email protected]302ce6d2011-07-07 23:28:118380 UpdateCapabilities();
8381
[email protected]c2f8c8402010-12-06 18:07:248382 return error::kNoError;
8383}
8384
[email protected]372e0412011-06-28 16:08:568385error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
8386 uint32 immediate_data_size, const gles2::GetMultipleIntegervCHROMIUM& c) {
8387 GLuint count = c.count;
8388 uint32 pnames_size;
8389 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8390 return error::kOutOfBounds;
8391 }
8392 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8393 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8394 if (pnames == NULL) {
8395 return error::kOutOfBounds;
8396 }
8397
8398 // We have to copy them since we use them twice so the client
8399 // can't change them between the time we validate them and the time we use
8400 // them.
8401 scoped_array<GLenum> enums(new GLenum[count]);
8402 memcpy(enums.get(), pnames, pnames_size);
8403
8404 // Count up the space needed for the result.
8405 uint32 num_results = 0;
8406 for (GLuint ii = 0; ii < count; ++ii) {
8407 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8408 if (num == 0) {
[email protected]f80e6e12012-08-31 00:43:538409 SetGLErrorInvalidEnum("glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568410 return error::kNoError;
8411 }
8412 // Num will never be more than 4.
8413 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478414 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568415 return error::kOutOfBounds;
8416 }
8417 }
8418
8419 uint32 result_size = 0;
8420 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8421 return error::kOutOfBounds;
8422 }
8423
8424 if (result_size != static_cast<uint32>(c.size)) {
8425 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438426 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:568427 return error::kNoError;
8428 }
8429
8430 GLint* results = GetSharedMemoryAs<GLint*>(
8431 c.results_shm_id, c.results_shm_offset, result_size);
8432 if (results == NULL) {
8433 return error::kOutOfBounds;
8434 }
8435
8436 // Check the results have been cleared in case the context was lost.
8437 for (uint32 ii = 0; ii < num_results; ++ii) {
8438 if (results[ii]) {
8439 return error::kInvalidArguments;
8440 }
8441 }
8442
8443 // Get each result.
8444 GLint* start = results;
8445 for (GLuint ii = 0; ii < count; ++ii) {
8446 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:268447 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:538448 !GetHelper(enums[ii], results, &num_written)) {
[email protected]372e0412011-06-28 16:08:568449 glGetIntegerv(enums[ii], results);
8450 }
8451 results += num_written;
8452 }
8453
8454 // Just to verify. Should this be a DCHECK?
8455 if (static_cast<uint32>(results - start) != num_results) {
8456 return error::kOutOfBounds;
8457 }
8458
8459 return error::kNoError;
8460}
8461
[email protected]2318d342011-07-11 22:27:428462error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
8463 uint32 immediate_data_size, const gles2::GetProgramInfoCHROMIUM& c) {
8464 GLuint program = static_cast<GLuint>(c.program);
8465 uint32 bucket_id = c.bucket_id;
8466 Bucket* bucket = CreateBucket(bucket_id);
8467 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
8468 ProgramManager::ProgramInfo* info = NULL;
[email protected]9a14ae612011-08-08 17:51:468469 info = GetProgramInfo(program);
8470 if (!info || !info->IsValid()) {
8471 return error::kNoError;
[email protected]2318d342011-07-11 22:27:428472 }
[email protected]5d4c6b22012-02-07 08:22:288473 info->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:428474 return error::kNoError;
8475}
8476
[email protected]38d139d2011-07-14 00:38:438477error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
8478 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:438479 case GL_NO_ERROR:
8480 // TODO(kbr): improve the precision of the error code in this case.
8481 // Consider delegating to context for error code if MakeCurrent fails.
8482 return error::kUnknown;
8483 case GL_GUILTY_CONTEXT_RESET_ARB:
8484 return error::kGuilty;
8485 case GL_INNOCENT_CONTEXT_RESET_ARB:
8486 return error::kInnocent;
8487 case GL_UNKNOWN_CONTEXT_RESET_ARB:
8488 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:438489 }
8490
8491 NOTREACHED();
8492 return error::kUnknown;
8493}
8494
8495bool GLES2DecoderImpl::WasContextLost() {
[email protected]706b69f2012-07-27 04:59:308496 if (context_->WasAllocatedUsingRobustnessExtension()) {
8497 GLenum status = GL_NO_ERROR;
8498 if (has_robustness_extension_)
8499 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:438500 if (status != GL_NO_ERROR) {
8501 // The graphics card was reset. Signal a lost context to the application.
8502 reset_status_ = status;
8503 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]706b69f2012-07-27 04:59:308504 << " context lost via ARB/EXT_robustness. Reset status = 0x"
[email protected]38d139d2011-07-14 00:38:438505 << std::hex << status << std::dec;
8506 return true;
8507 }
8508 }
8509 return false;
8510}
8511
[email protected]882ba1e22012-03-08 19:02:538512bool GLES2DecoderImpl::GenQueriesEXTHelper(
8513 GLsizei n, const GLuint* client_ids) {
8514 for (GLsizei ii = 0; ii < n; ++ii) {
8515 if (query_manager_->GetQuery(client_ids[ii])) {
8516 return false;
8517 }
8518 }
[email protected]c45f1972012-03-14 07:27:368519 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:538520 return true;
8521}
8522
8523void GLES2DecoderImpl::DeleteQueriesEXTHelper(
8524 GLsizei n, const GLuint* client_ids) {
8525 for (GLsizei ii = 0; ii < n; ++ii) {
8526 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
8527 if (query && !query->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:248528 if (query == state_.current_query) {
8529 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:538530 }
[email protected]c45f1972012-03-14 07:27:368531 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:538532 query_manager_->RemoveQuery(client_ids[ii]);
8533 }
8534 }
8535}
8536
[email protected]22e3f552012-03-13 01:54:198537bool GLES2DecoderImpl::ProcessPendingQueries() {
8538 if (query_manager_.get() == NULL) {
8539 return false;
8540 }
[email protected]c45f1972012-03-14 07:27:368541 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:198542 current_decoder_error_ = error::kOutOfBounds;
8543 }
8544 return query_manager_->HavePendingQueries();
8545}
8546
[email protected]882ba1e22012-03-08 19:02:538547error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
8548 uint32 immediate_data_size, const gles2::BeginQueryEXT& c) {
8549 GLenum target = static_cast<GLenum>(c.target);
8550 GLuint client_id = static_cast<GLuint>(c.id);
8551 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
8552 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
8553
[email protected]c45f1972012-03-14 07:27:368554 switch (target) {
8555 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:558556 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:368557 break;
8558 default:
[email protected]62e155e2012-10-23 22:43:158559 if (!features().occlusion_query_boolean) {
[email protected]ad84a3a2012-06-08 21:42:438560 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "not enabled");
[email protected]c45f1972012-03-14 07:27:368561 return error::kNoError;
8562 }
8563 break;
[email protected]882ba1e22012-03-08 19:02:538564 }
8565
[email protected]e259eb412012-10-13 05:47:248566 if (state_.current_query) {
[email protected]882ba1e22012-03-08 19:02:538567 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:438568 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:538569 return error::kNoError;
8570 }
8571
8572 if (client_id == 0) {
[email protected]ad84a3a2012-06-08 21:42:438573 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:538574 return error::kNoError;
8575 }
8576
8577 QueryManager::Query* query = query_manager_->GetQuery(client_id);
8578 if (!query) {
[email protected]c45f1972012-03-14 07:27:368579 // TODO(gman): Decide if we need this check.
8580 //
[email protected]882ba1e22012-03-08 19:02:538581 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:368582 //
8583 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
8584 // for all Query ids but from the POV of the command buffer service maybe
8585 // you don't.
8586 //
8587 // The client can enforce this. I don't think the service cares.
8588 //
8589 // IdAllocatorInterface* id_allocator =
8590 // group_->GetIdAllocator(id_namespaces::kQueries);
8591 // if (!id_allocator->InUse(client_id)) {
8592 // SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438593 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:368594 // return error::kNoError;
8595 // }
8596 query = query_manager_->CreateQuery(
8597 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:538598 }
8599
[email protected]c45f1972012-03-14 07:27:368600 if (query->target() != target) {
[email protected]ad84a3a2012-06-08 21:42:438601 SetGLError(
8602 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:538603 return error::kNoError;
8604 } else if (query->shm_id() != sync_shm_id ||
8605 query->shm_offset() != sync_shm_offset) {
8606 DLOG(ERROR) << "Shared memory used by query not the same as before";
8607 return error::kInvalidArguments;
8608 }
8609
[email protected]c45f1972012-03-14 07:27:368610 if (!query_manager_->BeginQuery(query)) {
8611 return error::kOutOfBounds;
8612 }
[email protected]882ba1e22012-03-08 19:02:538613
[email protected]e259eb412012-10-13 05:47:248614 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:538615 return error::kNoError;
8616}
8617
8618error::Error GLES2DecoderImpl::HandleEndQueryEXT(
8619 uint32 immediate_data_size, const gles2::EndQueryEXT& c) {
8620 GLenum target = static_cast<GLenum>(c.target);
8621 uint32 submit_count = static_cast<GLuint>(c.submit_count);
8622
[email protected]e259eb412012-10-13 05:47:248623 if (!state_.current_query) {
[email protected]ad84a3a2012-06-08 21:42:438624 SetGLError(GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:538625 return error::kNoError;
8626 }
[email protected]e259eb412012-10-13 05:47:248627 if (state_.current_query->target() != target) {
[email protected]882ba1e22012-03-08 19:02:538628 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438629 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:538630 return error::kNoError;
8631 }
[email protected]882ba1e22012-03-08 19:02:538632
[email protected]e259eb412012-10-13 05:47:248633 if (!query_manager_->EndQuery(state_.current_query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:368634 return error::kOutOfBounds;
8635 }
8636
[email protected]e259eb412012-10-13 05:47:248637 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:538638 return error::kNoError;
8639}
8640
[email protected]944b62f32012-09-27 02:20:468641bool GLES2DecoderImpl::GenVertexArraysOESHelper(
8642 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:468643 for (GLsizei ii = 0; ii < n; ++ii) {
8644 if (GetVertexAttribManager(client_ids[ii])) {
8645 return false;
8646 }
8647 }
[email protected]ab4fd7282012-10-12 16:25:578648
[email protected]62e155e2012-10-23 22:43:158649 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:578650 // Emulated VAO
8651 for (GLsizei ii = 0; ii < n; ++ii) {
8652 CreateVertexAttribManager(client_ids[ii], 0);
8653 }
8654 } else {
8655 scoped_array<GLuint> service_ids(new GLuint[n]);
8656
8657 glGenVertexArraysOES(n, service_ids.get());
8658 for (GLsizei ii = 0; ii < n; ++ii) {
8659 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
8660 }
[email protected]944b62f32012-09-27 02:20:468661 }
[email protected]ab4fd7282012-10-12 16:25:578662
[email protected]944b62f32012-09-27 02:20:468663 return true;
8664}
8665
8666void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
8667 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:468668 for (GLsizei ii = 0; ii < n; ++ii) {
8669 VertexAttribManager* vao =
8670 GetVertexAttribManager(client_ids[ii]);
8671 if (vao && !vao->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:248672 if (state_.vertex_attrib_manager == vao) {
8673 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:468674 }
8675 RemoveVertexAttribManager(client_ids[ii]);
8676 }
8677 }
8678}
8679
8680void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:468681 VertexAttribManager* vao = NULL;
8682 GLuint service_id = 0;
8683 if (client_id != 0) {
8684 vao = GetVertexAttribManager(client_id);
8685 if (!vao) {
8686 // Unlike most Bind* methods, the spec explicitly states that VertexArray
8687 // only allows names that have been previously generated. As such, we do
8688 // not generate new names here.
8689 SetGLError(GL_INVALID_OPERATION,
8690 "glBindVertexArrayOES", ""
8691 "bad vertex array id.");
8692 current_decoder_error_ = error::kNoError;
8693 return;
8694 } else {
8695 service_id = vao->service_id();
8696 }
[email protected]944b62f32012-09-27 02:20:468697 } else {
[email protected]ab4fd7282012-10-12 16:25:578698 vao = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:468699 }
8700
[email protected]ab4fd7282012-10-12 16:25:578701 // Only set the VAO state if it's changed
[email protected]e259eb412012-10-13 05:47:248702 if (state_.vertex_attrib_manager != vao) {
8703 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:158704 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:578705 EmulateVertexArrayState();
8706 } else {
8707 glBindVertexArrayOES(service_id);
8708 }
8709 }
8710}
8711
8712// Used when OES_vertex_array_object isn't natively supported
8713void GLES2DecoderImpl::EmulateVertexArrayState() {
8714 // Setup the Vertex attribute state
8715 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
8716 RestoreStateForAttrib(vv);
8717 }
8718
8719 // Setup the element buffer
8720 BufferManager::BufferInfo* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:248721 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:578722 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
8723 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:468724}
8725
8726bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:468727 const VertexAttribManager* vao =
8728 GetVertexAttribManager(client_id);
8729 return vao && vao->IsValid() && !vao->IsDeleted();
8730}
8731
[email protected]b0af4f52011-09-28 22:04:428732error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
8733 uint32 immediate_data_size,
8734 const gles2::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:158735 if (!features().chromium_stream_texture) {
[email protected]b0af4f52011-09-28 22:04:428736 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438737 "glOpenStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:428738 "not supported.");
8739 return error::kNoError;
8740 }
8741
8742 uint32 client_id = c.client_id;
8743 typedef gles2::CreateStreamTextureCHROMIUM::Result Result;
8744 Result* result = GetSharedMemoryAs<Result*>(
8745 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8746
[email protected]e5081262012-01-05 23:09:038747 if (!result)
8748 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:428749 *result = GL_ZERO;
8750 TextureManager::TextureInfo* info =
8751 texture_manager()->GetTextureInfo(client_id);
8752 if (!info) {
8753 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438754 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:428755 "bad texture id.");
8756 return error::kNoError;
8757 }
8758
8759 if (info->IsStreamTexture()) {
8760 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438761 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:428762 "is already a stream texture.");
8763 return error::kNoError;
8764 }
8765
8766 if (info->target() && info->target() != GL_TEXTURE_EXTERNAL_OES) {
8767 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438768 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:428769 "is already bound to incompatible target.");
8770 return error::kNoError;
8771 }
8772
8773 if (!stream_texture_manager_)
8774 return error::kInvalidArguments;
8775
8776 GLuint object_id = stream_texture_manager_->CreateStreamTexture(
8777 info->service_id(), client_id);
8778
8779 if (object_id) {
8780 info->SetStreamTexture(true);
8781 } else {
8782 SetGLError(GL_OUT_OF_MEMORY,
[email protected]ad84a3a2012-06-08 21:42:438783 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:428784 "failed to create platform texture.");
8785 }
8786
8787 *result = object_id;
8788 return error::kNoError;
8789}
8790
8791error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
8792 uint32 immediate_data_size,
8793 const gles2::DestroyStreamTextureCHROMIUM& c) {
8794 GLuint client_id = c.texture;
8795 TextureManager::TextureInfo* info =
8796 texture_manager()->GetTextureInfo(client_id);
8797 if (info && info->IsStreamTexture()) {
8798 if (!stream_texture_manager_)
8799 return error::kInvalidArguments;
8800
8801 stream_texture_manager_->DestroyStreamTexture(info->service_id());
8802 info->SetStreamTexture(false);
[email protected]80eb6b52012-01-19 00:14:418803 texture_manager()->SetInfoTarget(info, 0);
[email protected]b0af4f52011-09-28 22:04:428804 } else {
8805 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438806 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:428807 }
8808
8809 return error::kNoError;
8810}
8811
[email protected]e51bdf32011-11-23 22:21:468812#if defined(OS_MACOSX)
8813void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
8814 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
8815 texture_id);
8816 if (it != texture_to_io_surface_map_.end()) {
8817 // Found a previous IOSurface bound to this texture; release it.
8818 CFTypeRef surface = it->second;
8819 CFRelease(surface);
8820 texture_to_io_surface_map_.erase(it);
8821 }
8822}
8823#endif
8824
8825void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
8826 GLenum target, GLsizei width, GLsizei height,
8827 GLuint io_surface_id, GLuint plane) {
8828#if defined(OS_MACOSX)
8829 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ad84a3a2012-06-08 21:42:438830 SetGLError(
8831 GL_INVALID_OPERATION,
8832 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:468833 return;
8834 }
8835
8836 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
8837 if (!surface_support) {
8838 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438839 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:468840 return;
8841 }
8842
8843 if (target != GL_TEXTURE_RECTANGLE_ARB) {
8844 // This might be supported in the future, and if we could require
8845 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
8846 // could delete a lot of code. For now, perform strict validation so we
8847 // know what's going on.
8848 SetGLError(
8849 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438850 "glTexImageIOSurface2DCHROMIUM",
8851 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:468852 return;
8853 }
8854
[email protected]09d50362012-10-18 20:54:378855 // Default target might be conceptually valid, but disallow it to avoid
8856 // accidents.
8857 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
8858 target);
[email protected]e51bdf32011-11-23 22:21:468859 if (!info) {
8860 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438861 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:468862 return;
8863 }
[email protected]e51bdf32011-11-23 22:21:468864
8865 // Look up the new IOSurface. Note that because of asynchrony
8866 // between processes this might fail; during live resizing the
8867 // plugin process might allocate and release an IOSurface before
8868 // this process gets a chance to look it up. Hold on to any old
8869 // IOSurface in this case.
8870 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
8871 if (!surface) {
[email protected]ad84a3a2012-06-08 21:42:438872 SetGLError(
8873 GL_INVALID_OPERATION,
8874 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:468875 return;
8876 }
8877
8878 // Release any IOSurface previously bound to this texture.
8879 ReleaseIOSurfaceForTexture(info->service_id());
8880
8881 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
8882 texture_to_io_surface_map_.insert(
8883 std::make_pair(info->service_id(), surface));
8884
8885 CGLContextObj context =
8886 static_cast<CGLContextObj>(context_->GetHandle());
8887
8888 CGLError err = surface_support->CGLTexImageIOSurface2D(
8889 context,
8890 target,
8891 GL_RGBA,
8892 width,
8893 height,
8894 GL_BGRA,
8895 GL_UNSIGNED_INT_8_8_8_8_REV,
8896 surface,
8897 plane);
8898
8899 if (err != kCGLNoError) {
8900 SetGLError(
8901 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438902 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:468903 return;
8904 }
8905
8906 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:418907 info, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:468908 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
8909
8910#else
8911 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438912 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:468913#endif
8914}
8915
[email protected]97dc7cbe2011-12-06 17:26:178916static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
8917 switch (internalformat) {
8918 case GL_RGB565:
8919 return GL_RGB;
8920 case GL_RGBA4:
8921 return GL_RGBA;
8922 case GL_RGB5_A1:
8923 return GL_RGBA;
8924 case GL_RGB8_OES:
8925 return GL_RGB;
8926 case GL_RGBA8_OES:
8927 return GL_RGBA;
8928 case GL_LUMINANCE8_ALPHA8_EXT:
8929 return GL_LUMINANCE_ALPHA;
8930 case GL_LUMINANCE8_EXT:
8931 return GL_LUMINANCE;
8932 case GL_ALPHA8_EXT:
8933 return GL_ALPHA;
8934 case GL_RGBA32F_EXT:
8935 return GL_RGBA;
8936 case GL_RGB32F_EXT:
8937 return GL_RGB;
8938 case GL_ALPHA32F_EXT:
8939 return GL_ALPHA;
8940 case GL_LUMINANCE32F_EXT:
8941 return GL_LUMINANCE;
8942 case GL_LUMINANCE_ALPHA32F_EXT:
8943 return GL_LUMINANCE_ALPHA;
8944 case GL_RGBA16F_EXT:
8945 return GL_RGBA;
8946 case GL_RGB16F_EXT:
8947 return GL_RGB;
8948 case GL_ALPHA16F_EXT:
8949 return GL_ALPHA;
8950 case GL_LUMINANCE16F_EXT:
8951 return GL_LUMINANCE;
8952 case GL_LUMINANCE_ALPHA16F_EXT:
8953 return GL_LUMINANCE_ALPHA;
8954 case GL_BGRA8_EXT:
8955 return GL_BGRA_EXT;
8956 default:
8957 return GL_NONE;
8958 }
8959}
8960
[email protected]43410e92012-04-20 17:06:288961void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:038962 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
8963 GLenum internal_format) {
[email protected]43410e92012-04-20 17:06:288964 TextureManager::TextureInfo* dest_info = GetTextureInfo(dest_id);
8965 TextureManager::TextureInfo* source_info = GetTextureInfo(source_id);
8966
8967 if (!source_info || !dest_info) {
[email protected]ad84a3a2012-06-08 21:42:438968 SetGLError(GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:288969 return;
8970 }
8971
8972 if (GL_TEXTURE_2D != target) {
8973 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438974 "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:288975 return;
8976 }
8977
[email protected]0a1e9ad2012-05-04 21:13:038978 if (dest_info->target() != GL_TEXTURE_2D ||
8979 source_info->target() != GL_TEXTURE_2D) {
8980 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438981 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:038982 return;
8983 }
8984
[email protected]43410e92012-04-20 17:06:288985 int source_width, source_height, dest_width, dest_height;
8986 if (!source_info->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
8987 &source_height)) {
8988 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438989 "glCopyTextureChromium", "source texture has no level 0");
[email protected]43410e92012-04-20 17:06:288990 return;
8991 }
8992
[email protected]43410e92012-04-20 17:06:288993 // Check that this type of texture is allowed.
8994 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
8995 source_height, 1)) {
8996 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438997 "glCopyTextureCHROMIUM", "Bad dimensions");
[email protected]43410e92012-04-20 17:06:288998 return;
8999 }
9000
[email protected]cf6b8f62012-05-25 21:43:379001 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9002 // needed because it takes 10s of milliseconds to initialize.
9003 if (!copy_texture_CHROMIUM_.get()) {
9004 CopyRealGLErrorsToWrapper();
9005 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
9006 copy_texture_CHROMIUM_->Initialize();
9007 RestoreCurrentFramebufferBindings();
9008 if (PeekGLError() != GL_NO_ERROR)
9009 return;
9010 }
9011
[email protected]0a1e9ad2012-05-04 21:13:039012 GLenum dest_type;
9013 GLenum dest_internal_format;
9014 bool dest_level_defined = dest_info->GetLevelSize(GL_TEXTURE_2D, level,
9015 &dest_width,
9016 &dest_height);
[email protected]43410e92012-04-20 17:06:289017
[email protected]0a1e9ad2012-05-04 21:13:039018 if (dest_level_defined) {
9019 dest_info->GetLevelType(GL_TEXTURE_2D, level, &dest_type,
9020 &dest_internal_format);
9021 } else {
9022 GLenum source_internal_format;
9023 source_info->GetLevelType(GL_TEXTURE_2D, 0, &dest_type,
9024 &source_internal_format);
9025 }
9026
9027 // Resize the destination texture to the dimensions of the source texture.
9028 if (!dest_level_defined || dest_width != source_width ||
9029 dest_height != source_height ||
9030 dest_internal_format != internal_format) {
[email protected]43410e92012-04-20 17:06:289031 // Ensure that the glTexImage2D succeeds.
9032 CopyRealGLErrorsToWrapper();
[email protected]0a1e9ad2012-05-04 21:13:039033 glBindTexture(GL_TEXTURE_2D, dest_info->service_id());
[email protected]43410e92012-04-20 17:06:289034 WrappedTexImage2D(
9035 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039036 0, internal_format, dest_type, NULL);
[email protected]43410e92012-04-20 17:06:289037 GLenum error = PeekGLError();
[email protected]0a1e9ad2012-05-04 21:13:039038 if (error != GL_NO_ERROR) {
9039 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289040 return;
[email protected]0a1e9ad2012-05-04 21:13:039041 }
[email protected]43410e92012-04-20 17:06:289042
9043 texture_manager()->SetLevelInfo(
9044 dest_info, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039045 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259046 } else {
9047 texture_manager()->SetLevelCleared(dest_info, GL_TEXTURE_2D, level);
[email protected]43410e92012-04-20 17:06:289048 }
9049
[email protected]88a61bf2012-10-27 13:00:429050 clear_state_dirty_ = true;
[email protected]0a1e9ad2012-05-04 21:13:039051 glViewport(0, 0, source_width, source_height);
[email protected]43410e92012-04-20 17:06:289052 copy_texture_CHROMIUM_->DoCopyTexture(target, source_info->service_id(),
9053 dest_info->service_id(), level,
9054 unpack_flip_y_,
[email protected]6c75c712012-06-19 15:43:179055 unpack_premultiply_alpha_,
9056 unpack_unpremultiply_alpha_);
[email protected]e259eb412012-10-13 05:47:249057 glViewport(
9058 state_.viewport_x, state_.viewport_y,
9059 state_.viewport_width, state_.viewport_height);
[email protected]43410e92012-04-20 17:06:289060
9061 // Restore all of the state touched by the extension.
[email protected]e259eb412012-10-13 05:47:249062 if (state_.current_program)
9063 glUseProgram(state_.current_program->service_id());
[email protected]43410e92012-04-20 17:06:289064 else
9065 glUseProgram(0);
9066
9067 RestoreCurrentFramebufferBindings();
9068 RestoreCurrentTexture2DBindings();
9069 RestoreStateForAttrib(
9070 CopyTextureCHROMIUMResourceManager::kVertexPositionAttrib);
9071 RestoreStateForAttrib(
9072 CopyTextureCHROMIUMResourceManager::kVertexTextureAttrib);
9073
9074 ApplyDirtyState();
9075}
9076
[email protected]97dc7cbe2011-12-06 17:26:179077static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9078 switch (internalformat) {
9079 case GL_RGB565:
9080 return GL_UNSIGNED_SHORT_5_6_5;
9081 case GL_RGBA4:
9082 return GL_UNSIGNED_SHORT_4_4_4_4;
9083 case GL_RGB5_A1:
9084 return GL_UNSIGNED_SHORT_5_5_5_1;
9085 case GL_RGB8_OES:
9086 return GL_UNSIGNED_BYTE;
9087 case GL_RGBA8_OES:
9088 return GL_UNSIGNED_BYTE;
9089 case GL_LUMINANCE8_ALPHA8_EXT:
9090 return GL_UNSIGNED_BYTE;
9091 case GL_LUMINANCE8_EXT:
9092 return GL_UNSIGNED_BYTE;
9093 case GL_ALPHA8_EXT:
9094 return GL_UNSIGNED_BYTE;
9095 case GL_RGBA32F_EXT:
9096 return GL_FLOAT;
9097 case GL_RGB32F_EXT:
9098 return GL_FLOAT;
9099 case GL_ALPHA32F_EXT:
9100 return GL_FLOAT;
9101 case GL_LUMINANCE32F_EXT:
9102 return GL_FLOAT;
9103 case GL_LUMINANCE_ALPHA32F_EXT:
9104 return GL_FLOAT;
9105 case GL_RGBA16F_EXT:
9106 return GL_HALF_FLOAT_OES;
9107 case GL_RGB16F_EXT:
9108 return GL_HALF_FLOAT_OES;
9109 case GL_ALPHA16F_EXT:
9110 return GL_HALF_FLOAT_OES;
9111 case GL_LUMINANCE16F_EXT:
9112 return GL_HALF_FLOAT_OES;
9113 case GL_LUMINANCE_ALPHA16F_EXT:
9114 return GL_HALF_FLOAT_OES;
9115 case GL_BGRA8_EXT:
9116 return GL_UNSIGNED_BYTE;
9117 default:
9118 return GL_NONE;
9119 }
9120}
9121
9122void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449123 GLenum target,
9124 GLint levels,
9125 GLenum internal_format,
9126 GLsizei width,
9127 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389128 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419129 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179130 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ad84a3a2012-06-08 21:42:439131 SetGLError(
9132 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179133 return;
9134 }
9135 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9136 if (!info) {
9137 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439138 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179139 return;
9140 }
9141 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:429142 clear_state_dirty_ = true;
[email protected]97dc7cbe2011-12-06 17:26:179143 }
9144 if (info->IsImmutable()) {
9145 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439146 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179147 return;
9148 }
9149 CopyRealGLErrorsToWrapper();
[email protected]f0e6a34f2012-01-04 20:53:409150 glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format),
9151 width, height);
[email protected]97dc7cbe2011-12-06 17:26:179152 GLenum error = PeekGLError();
9153 if (error == GL_NO_ERROR) {
9154 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9155 GLenum type = ExtractTypeFromStorageFormat(internal_format);
[email protected]4502e6492011-12-14 19:39:159156 GLsizei level_width = width;
9157 GLsizei level_height = height;
9158 for (int ii = 0; ii < levels; ++ii) {
9159 texture_manager()->SetLevelInfo(
[email protected]e071ea72012-11-26 22:29:599160 info, target, ii, format, level_width, level_height, 1, 0, format,
[email protected]80eb6b52012-01-19 00:14:419161 type, false);
[email protected]4502e6492011-12-14 19:39:159162 level_width = std::max(1, level_width >> 1);
9163 level_height = std::max(1, level_height >> 1);
9164 }
[email protected]97dc7cbe2011-12-06 17:26:179165 info->SetImmutable(true);
9166 }
[email protected]97dc7cbe2011-12-06 17:26:179167}
[email protected]e51bdf32011-11-23 22:21:469168
[email protected]78b514b2012-05-01 21:50:599169error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
9170 uint32 immediate_data_size, const gles2::GenMailboxCHROMIUM& c) {
9171 MailboxName name;
9172 mailbox_manager()->GenerateMailboxName(&name);
9173 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
9174 Bucket* bucket = CreateBucket(bucket_id);
9175
9176 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
9177 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
9178
9179 return error::kNoError;
9180}
9181
9182void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9183 const GLbyte* mailbox) {
9184 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9185 if (!info) {
9186 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439187 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599188 return;
9189 }
9190
9191 TextureDefinition* definition = texture_manager()->Save(info);
9192 if (!definition) {
9193 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439194 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599195 return;
9196 }
9197
9198 if (!group_->mailbox_manager()->ProduceTexture(
9199 target,
9200 *reinterpret_cast<const MailboxName*>(mailbox),
9201 definition,
9202 texture_manager())) {
9203 bool success = texture_manager()->Restore(info, definition);
9204 DCHECK(success);
9205 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439206 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599207 return;
9208 }
9209
9210 BindAndApplyTextureParameters(info);
9211}
9212
9213void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9214 const GLbyte* mailbox) {
9215 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9216 if (!info) {
9217 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439218 "glConsumeTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599219 return;
9220 }
9221
9222 scoped_ptr<TextureDefinition> definition(
9223 group_->mailbox_manager()->ConsumeTexture(
9224 target,
9225 *reinterpret_cast<const MailboxName*>(mailbox)));
9226 if (!definition.get()) {
9227 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439228 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599229 return;
9230 }
9231
9232 if (!texture_manager()->Restore(info, definition.release())) {
9233 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439234 "glConsumeTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599235 return;
9236 }
9237
9238 BindAndApplyTextureParameters(info);
9239}
9240
[email protected]d2a0e1a2012-08-12 02:25:019241void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9242 GLsizei length, const GLchar* marker) {
9243 if (!marker) {
9244 marker = "";
9245 }
9246 debug_marker_manager_.SetMarker(
9247 length ? std::string(marker, length) : std::string(marker));
9248}
9249
9250void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9251 GLsizei length, const GLchar* marker) {
9252 if (!marker) {
9253 marker = "";
9254 }
9255 debug_marker_manager_.PushGroup(
9256 length ? std::string(marker, length) : std::string(marker));
9257}
9258
9259void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9260 debug_marker_manager_.PopGroup();
9261}
9262
[email protected]09d50362012-10-18 20:54:379263void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9264 GLenum target, GLint image_id) {
9265 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9266 if (target != GL_TEXTURE_2D) {
9267 // This might be supported in the future.
9268 SetGLError(
9269 GL_INVALID_OPERATION,
9270 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9271 return;
9272 }
9273
9274 // Default target might be conceptually valid, but disallow it to avoid
9275 // accidents.
9276 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9277 target);
9278 if (!info) {
9279 SetGLError(GL_INVALID_OPERATION,
9280 "glBindTexImage2DCHROMIUM", "no texture bound");
9281 return;
9282 }
9283
9284 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9285 if (!gl_image) {
9286 SetGLError(GL_INVALID_OPERATION,
9287 "glBindTexImage2DCHROMIUM",
9288 "no image found with the given ID");
9289 return;
9290 }
9291
9292 if (!gl_image->BindTexImage()) {
9293 SetGLError(GL_INVALID_OPERATION,
9294 "glBindTexImage2DCHROMIUM",
9295 "fail to bind image with the given ID");
9296 return;
9297 }
9298
9299 gfx::Size size = gl_image->GetSize();
9300 texture_manager()->SetLevelInfo(
9301 info, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
9302 GL_RGBA, GL_UNSIGNED_BYTE, true);
9303 texture_manager()->SetLevelImage(info, target, 0, gl_image);
9304}
9305
9306void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
9307 GLenum target, GLint image_id) {
9308 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
9309 if (target != GL_TEXTURE_2D) {
9310 // This might be supported in the future.
9311 SetGLError(
9312 GL_INVALID_OPERATION,
9313 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9314 return;
9315 }
9316
9317 // Default target might be conceptually valid, but disallow it to avoid
9318 // accidents.
9319 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9320 target);
9321 if (!info) {
9322 SetGLError(GL_INVALID_OPERATION,
9323 "glReleaseTexImage2DCHROMIUM", "no texture bound");
9324 return;
9325 }
9326
9327 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9328 if (!gl_image) {
9329 SetGLError(GL_INVALID_OPERATION,
9330 "glReleaseTexImage2DCHROMIUM",
9331 "no image found with the given ID");
9332 return;
9333 }
9334
9335 // Do nothing when image is not currently bound.
9336 if (info->GetLevelImage(target, 0) != gl_image)
9337 return;
9338
9339 gl_image->ReleaseTexImage();
9340
9341 texture_manager()->SetLevelInfo(
9342 info, target, 0, GL_RGBA, 0, 0, 1, 0,
9343 GL_RGBA, GL_UNSIGNED_BYTE, false);
9344}
[email protected]d2a0e1a2012-08-12 02:25:019345
[email protected]94307712012-11-16 23:26:119346error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
9347 uint32 immediate_data_size, const gles2::TraceBeginCHROMIUM& c) {
9348 Bucket* bucket = GetBucket(c.bucket_id);
9349 if (!bucket || bucket->size() == 0) {
9350 return error::kInvalidArguments;
9351 }
9352 std::string command_name;
9353 if (!bucket->GetAsString(&command_name)) {
9354 return error::kInvalidArguments;
9355 }
9356
9357 linked_ptr<GPUTrace> trace(new GPUTrace(command_name));
9358 trace->EnableStartTrace();
9359 gpu_trace_stack_.push(trace);
9360
9361 return error::kNoError;
9362}
9363
9364void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
9365 if (gpu_trace_stack_.empty()) {
9366 SetGLError(GL_INVALID_OPERATION,
9367 "glTraceEndCHROMIUM", "no trace begin found");
9368 return;
9369 }
9370
9371 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top();
9372 trace->EnableEndTrace();
9373 gpu_trace_stack_.pop();
9374}
9375
[email protected]96449d2c2009-11-25 00:01:329376// Include the auto-generated part of this file. We split this because it means
9377// we can easily edit the non-auto generated parts right here in this file
9378// instead of having to edit some template or the code generator.
9379#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
9380
9381} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:259382} // namespace gpu