blob: 6469c62ca1078c66cc1f3be9247a7a8d1f91d247 [file] [log] [blame]
[email protected]529c6672012-01-04 02:18:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]96449d2c2009-11-25 00:01:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8a837bb2010-01-05 00:21:245#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
[email protected]74470702010-01-06 18:51:166
7#include <stdio.h>
8
[email protected]1aef98132010-02-23 18:00:079#include <algorithm>
[email protected]f39f4b3f2010-05-12 17:04:0810#include <list>
[email protected]96449d2c2009-11-25 00:01:3211#include <map>
[email protected]94307712012-11-16 23:26:1112#include <stack>
[email protected]f39f4b3f2010-05-12 17:04:0813#include <string>
14#include <vector>
[email protected]5a6db6c2010-04-22 18:32:0615
[email protected]00eb49a2010-08-12 20:46:5716#include "base/at_exit.h"
[email protected]d353541f2012-05-03 22:45:4117#include "base/atomicops.h"
[email protected]9d37f062011-11-22 01:24:5218#include "base/bind.h"
[email protected]e844ae22012-01-14 03:36:2619#include "base/command_line.h"
[email protected]1078f912011-12-23 13:12:1420#include "base/debug/trace_event.h"
[email protected]e51bdf32011-11-23 22:21:4621#if defined(OS_MACOSX)
22#include "base/mac/scoped_cftyperef.h"
23#endif
[email protected]3b63f8f42011-03-28 01:54:1524#include "base/memory/scoped_ptr.h"
[email protected]0f8afe82012-05-14 23:43:0125#include "base/string_number_conversions.h"
[email protected]445a8762012-12-06 15:43:2126#include "base/stringprintf.h"
[email protected]d37231fa2010-04-09 21:16:0227#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3228#define GLES2_GPU_SERVICE 1
29#include "gpu/command_buffer/common/gles2_cmd_format.h"
30#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]d2a0e1a2012-08-12 02:25:0131#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]066849e32010-05-03 19:14:1032#include "gpu/command_buffer/common/id_allocator.h"
[email protected]3916c97e2010-02-25 03:20:5033#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3234#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5035#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2436#include "gpu/command_buffer/service/context_state.h"
[email protected]915a59a12010-09-30 21:29:1137#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5838#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3239#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2840#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4641#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]e844ae22012-01-14 03:36:2642#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]94307712012-11-16 23:26:1143#include "gpu/command_buffer/service/gpu_trace.h"
[email protected]09d50362012-10-18 20:54:3744#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5945#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2546#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4747#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5348#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5849#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4750#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4551#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0452#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]b0af4f52011-09-28 22:04:4253#include "gpu/command_buffer/service/stream_texture.h"
54#include "gpu/command_buffer/service/stream_texture_manager.h"
[email protected]78b514b2012-05-01 21:50:5955#include "gpu/command_buffer/service/texture_definition.h"
[email protected]a93bb842010-02-16 23:03:4756#include "gpu/command_buffer/service/texture_manager.h"
[email protected]d8ea9772011-07-11 18:11:4357#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]944b62f32012-09-27 02:20:4658#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]32145a92012-12-17 09:01:5959#include "ui/gl/async_pixel_transfer_delegate.h"
[email protected]09d50362012-10-18 20:54:3760#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2761#include "ui/gl/gl_implementation.h"
62#include "ui/gl/gl_surface.h"
[email protected]e51bdf32011-11-23 22:21:4663#if defined(OS_MACOSX)
[email protected]d353541f2012-05-03 22:45:4164#include "ui/surface/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4665#endif
[email protected]de17df392010-04-23 21:09:4166
[email protected]6217d392010-03-25 22:08:3567#if !defined(GL_DEPTH24_STENCIL8)
68#define GL_DEPTH24_STENCIL8 0x88F0
69#endif
70
[email protected]693ca512012-11-13 18:09:1371// TODO(zmo): we can't include "City.h" due to type def conflicts.
72extern uint64 CityHash64(const char*, size_t);
73
[email protected]a7a27ace2009-12-12 00:11:2574namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3275namespace gles2 {
76
[email protected]f0d74742011-10-03 16:31:0477namespace {
[email protected]693ca512012-11-13 18:09:1378
[email protected]f0d74742011-10-03 16:31:0479static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]693ca512012-11-13 18:09:1380
81khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
82 return static_cast<khronos_uint64_t>(
83 CityHash64(name, static_cast<size_t>(len)));
84}
85
[email protected]b04e24c2013-01-08 18:35:2586} // namespace
[email protected]f0d74742011-10-03 16:31:0487
[email protected]6217d392010-03-25 22:08:3588class GLES2DecoderImpl;
89
[email protected]07f54fcc2009-12-22 02:46:3090// Check that certain assumptions the code makes are true. There are places in
91// the code where shared memory is passed direclty to GL. Example, glUniformiv,
92// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
93// a few others) are 32bits. If they are not 32bits the code will have to change
94// to call those GL functions with service side memory and then copy the results
95// to shared memory, converting the sizes.
96COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
97 GLint_not_same_size_as_uint32);
98COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
99 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37100COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
101 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30102
[email protected]43f28f832010-02-03 02:28:48103// TODO(kbr): the use of this anonymous namespace core dumps the
104// linker on Mac OS X 10.6 when the symbol ordering file is used
105// namespace {
[email protected]96449d2c2009-11-25 00:01:32106
107// Returns the address of the first byte after a struct.
108template <typename T>
109const void* AddressAfterStruct(const T& pod) {
110 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
111}
112
[email protected]07f54fcc2009-12-22 02:46:30113// Returns the address of the frst byte after the struct or NULL if size >
114// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32115template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30116RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
117 uint32 size,
118 uint32 immediate_data_size) {
119 return (size <= immediate_data_size) ?
120 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
121 NULL;
[email protected]96449d2c2009-11-25 00:01:32122}
123
[email protected]07f54fcc2009-12-22 02:46:30124// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18125bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32126 GLuint count,
127 size_t size,
[email protected]a76b0052010-03-05 00:33:18128 unsigned int elements_per_unit,
129 uint32* dst) {
130 uint32 value;
131 if (!SafeMultiplyUint32(count, size, &value)) {
132 return false;
133 }
134 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
135 return false;
136 }
137 *dst = value;
138 return true;
[email protected]96449d2c2009-11-25 00:01:32139}
140
141// A struct to hold info about each command.
142struct CommandInfo {
143 int arg_flags; // How to handle the arguments for this command
144 int arg_count; // How many arguments are expected for this command.
145};
146
147// A table of CommandInfo for all the commands.
148const CommandInfo g_command_info[] = {
149 #define GLES2_CMD_OP(name) { \
150 name::kArgFlags, \
151 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
152
153 GLES2_COMMAND_LIST(GLES2_CMD_OP)
154
155 #undef GLES2_CMD_OP
156};
157
[email protected]258a3313f2011-10-18 20:13:57158// Return true if a character belongs to the ASCII subset as defined in
159// GLSL ES 1.0 spec section 3.1.
160static bool CharacterIsValidForGLES(unsigned char c) {
161 // Printing characters are valid except " $ ` @ \ ' DEL.
162 if (c >= 32 && c <= 126 &&
163 c != '"' &&
164 c != '$' &&
165 c != '`' &&
166 c != '@' &&
167 c != '\\' &&
168 c != '\'') {
169 return true;
170 }
171 // Horizontal tab, line feed, vertical tab, form feed, carriage return
172 // are also valid.
173 if (c >= 9 && c <= 13) {
174 return true;
175 }
176
177 return false;
178}
179
180static bool StringIsValidForGLES(const char* str) {
181 for (; *str; ++str) {
182 if (!CharacterIsValidForGLES(*str)) {
183 return false;
184 }
185 }
186 return true;
187}
188
[email protected]f0e6a34f2012-01-04 20:53:40189static inline GLenum GetTexInternalFormat(GLenum internal_format) {
190 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
191 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT)
192 return GL_RGBA8;
193 }
194 return internal_format;
195}
196
[email protected]32145a92012-12-17 09:01:59197// TODO(epenner): Could the above function be merged into this and removed?
198static inline GLenum GetTexInternalFormat(GLenum internal_format,
199 GLenum format,
200 GLenum type) {
201 GLenum gl_internal_format = GetTexInternalFormat(internal_format);
202
203 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
204 return gl_internal_format;
205
206 if (type == GL_FLOAT) {
207 switch (format) {
208 case GL_RGBA:
209 gl_internal_format = GL_RGBA32F_ARB;
210 break;
211 case GL_RGB:
212 gl_internal_format = GL_RGB32F_ARB;
213 break;
214 case GL_LUMINANCE_ALPHA:
215 gl_internal_format = GL_LUMINANCE_ALPHA32F_ARB;
216 break;
217 case GL_LUMINANCE:
218 gl_internal_format = GL_LUMINANCE32F_ARB;
219 break;
220 case GL_ALPHA:
221 gl_internal_format = GL_ALPHA32F_ARB;
222 break;
223 default:
224 NOTREACHED();
225 break;
226 }
227 } else if (type == GL_HALF_FLOAT_OES) {
228 switch (format) {
229 case GL_RGBA:
230 gl_internal_format = GL_RGBA16F_ARB;
231 break;
232 case GL_RGB:
233 gl_internal_format = GL_RGB16F_ARB;
234 break;
235 case GL_LUMINANCE_ALPHA:
236 gl_internal_format = GL_LUMINANCE_ALPHA16F_ARB;
237 break;
238 case GL_LUMINANCE:
239 gl_internal_format = GL_LUMINANCE16F_ARB;
240 break;
241 case GL_ALPHA:
242 gl_internal_format = GL_ALPHA16F_ARB;
243 break;
244 default:
245 NOTREACHED();
246 break;
247 }
248 }
249 return gl_internal_format;
250}
251
[email protected]297ca1c2011-06-20 23:08:46252static void WrappedTexImage2D(
[email protected]473c01ccb2011-06-07 01:33:30253 GLenum target,
254 GLint level,
255 GLenum internal_format,
256 GLsizei width,
257 GLsizei height,
258 GLint border,
259 GLenum format,
260 GLenum type,
261 const void* pixels) {
[email protected]473c01ccb2011-06-07 01:33:30262 glTexImage2D(
[email protected]32145a92012-12-17 09:01:59263 target, level, GetTexInternalFormat(internal_format, format, type),
264 width, height, border, format, type, pixels);
[email protected]473c01ccb2011-06-07 01:33:30265}
266
[email protected]297ca1c2011-06-20 23:08:46267// Wrapper for glEnable/glDisable that doesn't suck.
268static void EnableDisable(GLenum pname, bool enable) {
269 if (enable) {
270 glEnable(pname);
271 } else {
272 glDisable(pname);
273 }
274}
275
[email protected]6217d392010-03-25 22:08:35276// This class prevents any GL errors that occur when it is in scope from
277// being reported to the client.
278class ScopedGLErrorSuppressor {
279 public:
280 explicit ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder);
281 ~ScopedGLErrorSuppressor();
282 private:
283 GLES2DecoderImpl* decoder_;
284 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
285};
286
287// Temporarily changes a decoder's bound 2D texture and restore it when this
288// object goes out of scope. Also temporarily switches to using active texture
289// unit zero in case the client has changed that to something invalid.
290class ScopedTexture2DBinder {
291 public:
292 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
293 ~ScopedTexture2DBinder();
294
295 private:
296 GLES2DecoderImpl* decoder_;
297 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
298};
299
300// Temporarily changes a decoder's bound render buffer and restore it when this
301// object goes out of scope.
302class ScopedRenderBufferBinder {
303 public:
304 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
305 ~ScopedRenderBufferBinder();
306
307 private:
308 GLES2DecoderImpl* decoder_;
309 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
310};
311
312// Temporarily changes a decoder's bound frame buffer and restore it when this
313// object goes out of scope.
314class ScopedFrameBufferBinder {
315 public:
316 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
317 ~ScopedFrameBufferBinder();
318
319 private:
320 GLES2DecoderImpl* decoder_;
321 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
322};
323
[email protected]34ff8b0c2010-10-01 20:06:02324// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52325// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27326// if it is bound or enforce_internal_framebuffer is true. If internal is
327// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02328class ScopedResolvedFrameBufferBinder {
329 public:
[email protected]e7e38032011-07-26 17:25:25330 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27331 bool enforce_internal_framebuffer,
332 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02333 ~ScopedResolvedFrameBufferBinder();
334
335 private:
336 GLES2DecoderImpl* decoder_;
337 bool resolve_and_bind_;
338 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
339};
340
[email protected]63b465922012-09-06 02:04:52341// This class records texture upload time when in scope.
342class ScopedTextureUploadTimer {
343 public:
344 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder);
345 ~ScopedTextureUploadTimer();
346
347 private:
348 GLES2DecoderImpl* decoder_;
349 base::TimeTicks begin_time_;
350 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer);
351};
352
[email protected]6217d392010-03-25 22:08:35353// Encapsulates an OpenGL texture.
354class Texture {
355 public:
356 explicit Texture(GLES2DecoderImpl* decoder);
357 ~Texture();
358
359 // Create a new render texture.
360 void Create();
361
362 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09363 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35364
365 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58366 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35367
368 // Destroy the render texture. This must be explicitly called before
369 // destroying this object.
370 void Destroy();
371
[email protected]97872062010-11-03 19:07:05372 // Invalidate the texture. This can be used when a context is lost and it is
373 // not possible to make it current in order to free the resource.
374 void Invalidate();
375
[email protected]6217d392010-03-25 22:08:35376 GLuint id() const {
377 return id_;
378 }
379
[email protected]d37231fa2010-04-09 21:16:02380 gfx::Size size() const {
381 return size_;
382 }
383
[email protected]1078f912011-12-23 13:12:14384 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25385 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14386 }
387
[email protected]6217d392010-03-25 22:08:35388 private:
389 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25390 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48391 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35392 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02393 gfx::Size size_;
[email protected]6217d392010-03-25 22:08:35394 DISALLOW_COPY_AND_ASSIGN(Texture);
395};
396
397// Encapsulates an OpenGL render buffer of any format.
398class RenderBuffer {
399 public:
400 explicit RenderBuffer(GLES2DecoderImpl* decoder);
401 ~RenderBuffer();
402
403 // Create a new render buffer.
404 void Create();
405
406 // Set the initial size and format of a render buffer or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02407 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
[email protected]6217d392010-03-25 22:08:35408
409 // Destroy the render buffer. This must be explicitly called before destroying
410 // this object.
411 void Destroy();
412
[email protected]97872062010-11-03 19:07:05413 // Invalidate the render buffer. This can be used when a context is lost and
414 // it is not possible to make it current in order to free the resource.
415 void Invalidate();
416
[email protected]6217d392010-03-25 22:08:35417 GLuint id() const {
418 return id_;
419 }
420
[email protected]1078f912011-12-23 13:12:14421 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25422 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14423 }
424
[email protected]6217d392010-03-25 22:08:35425 private:
426 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25427 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48428 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35429 GLuint id_;
430 DISALLOW_COPY_AND_ASSIGN(RenderBuffer);
431};
432
433// Encapsulates an OpenGL frame buffer.
434class FrameBuffer {
435 public:
436 explicit FrameBuffer(GLES2DecoderImpl* decoder);
437 ~FrameBuffer();
438
439 // Create a new frame buffer.
440 void Create();
441
442 // Attach a color render buffer to a frame buffer.
443 void AttachRenderTexture(Texture* texture);
444
[email protected]b9363b22010-06-09 22:06:15445 // Attach a render buffer to a frame buffer. Note that this unbinds any
446 // currently bound frame buffer.
447 void AttachRenderBuffer(GLenum target, RenderBuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35448
[email protected]6217d392010-03-25 22:08:35449 // Destroy the frame buffer. This must be explicitly called before destroying
450 // this object.
451 void Destroy();
452
[email protected]97872062010-11-03 19:07:05453 // Invalidate the frame buffer. This can be used when a context is lost and it
454 // is not possible to make it current in order to free the resource.
455 void Invalidate();
456
[email protected]6217d392010-03-25 22:08:35457 // See glCheckFramebufferStatusEXT.
458 GLenum CheckStatus();
459
460 GLuint id() const {
461 return id_;
462 }
463
464 private:
465 GLES2DecoderImpl* decoder_;
466 GLuint id_;
467 DISALLOW_COPY_AND_ASSIGN(FrameBuffer);
468};
[email protected]34ff8b0c2010-10-01 20:06:02469
[email protected]43f28f832010-02-03 02:28:48470// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32471
[email protected]ddb1e5a2010-12-13 20:10:45472bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
473 uint32* service_texture_id) {
474 return false;
475}
476
[email protected]a3ded6d2010-10-19 06:44:39477GLES2Decoder::GLES2Decoder()
[email protected]e844ae22012-01-14 03:36:26478 : debug_(false),
[email protected]b5d647c2012-02-10 01:41:32479 log_commands_(false),
480 log_synthesized_gl_errors_(true) {
[email protected]96449d2c2009-11-25 00:01:32481}
482
[email protected]3916c97e2010-02-25 03:20:50483GLES2Decoder::~GLES2Decoder() {
484}
485
[email protected]57edfdad2012-02-07 04:57:15486bool GLES2Decoder::testing_force_is_angle_;
487
488void GLES2Decoder::set_testing_force_is_angle(bool force) {
489 testing_force_is_angle_ = force;
490}
491
492bool GLES2Decoder::IsAngle() {
493#if defined(OS_WIN)
494 return testing_force_is_angle_ ||
495 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
496#else
497 return testing_force_is_angle_;
498#endif
499}
500
[email protected]f39f4b3f2010-05-12 17:04:08501// This class implements GLES2Decoder so we don't have to expose all the GLES2
502// cmd stuff to outside this class.
[email protected]ee1e6aa2012-11-29 09:24:10503class GLES2DecoderImpl : public GLES2Decoder {
[email protected]f39f4b3f2010-05-12 17:04:08504 public:
[email protected]0f8afe82012-05-14 23:43:01505 static const int kMaxLogMessages = 256;
[email protected]fa20ec82012-05-04 04:02:48506
[email protected]476ccb72012-12-06 15:52:52507 // Used by PrepForSetUniformByLocation to validate types.
508 struct BaseUniformInfo {
509 const GLenum* const valid_types;
510 size_t num_valid_types;
511 };
512
[email protected]aa7666122011-09-02 19:45:52513 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00514 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08515
[email protected]96449d2c2009-11-25 00:01:32516 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14517 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50518 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00519 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32520
521 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00522 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32523
524 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38525 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
526 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23527 bool offscreen,
[email protected]6217d392010-03-25 22:08:35528 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29529 const DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39530 const char* allowed_extensions,
[email protected]b8e97b62012-09-30 15:09:00531 const std::vector<int32>& attribs) OVERRIDE;
532 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38533 virtual void SetSurface(
534 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]3c644d82011-06-20 19:58:24535 virtual bool SetParent(GLES2Decoder* parent_decoder,
[email protected]b8e97b62012-09-30 15:09:00536 uint32 parent_texture_id) OVERRIDE;
537 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39538 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00539 virtual bool MakeCurrent() OVERRIDE;
540 virtual void ReleaseCurrent() OVERRIDE;
541 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
542 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
543 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]1868a342012-11-07 15:56:02544 virtual void RestoreState() const OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00545 virtual QueryManager* GetQueryManager() OVERRIDE {
546 return query_manager_.get();
547 }
548 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46549 return vertex_array_manager_.get();
550 }
[email protected]b8e97b62012-09-30 15:09:00551 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48552
[email protected]b8e97b62012-09-30 15:09:00553 virtual void SetGLError(GLenum error,
554 const char* function_name,
555 const char* msg);
556 virtual void SetGLErrorInvalidEnum(const char* function_name,
557 GLenum value,
558 const char* label);
[email protected]9d37f062011-11-22 01:24:52559 virtual void SetResizeCallback(
[email protected]b8e97b62012-09-30 15:09:00560 const base::Callback<void(gfx::Size)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00561
[email protected]b8e97b62012-09-30 15:09:00562 virtual void SetMsgCallback(const MsgCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00563
[email protected]b8e97b62012-09-30 15:09:00564 virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE;
[email protected]32145a92012-12-17 09:01:59565
566 virtual gfx::AsyncPixelTransferDelegate*
567 GetAsyncPixelTransferDelegate() OVERRIDE;
568 virtual void SetAsyncPixelTransferDelegate(
569 gfx::AsyncPixelTransferDelegate* delegate) OVERRIDE;
570
[email protected]1318e922010-09-17 22:03:16571 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00572 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48573
[email protected]efcdd2362012-07-09 21:07:00574 virtual uint32 GetGLError() OVERRIDE;
575
[email protected]63b465922012-09-06 02:04:52576 virtual uint32 GetTextureUploadCount() OVERRIDE;
577 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
578 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30579 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52580
[email protected]8e3e0662010-08-23 18:46:30581 // Restores the current state to the user's settings.
582 void RestoreCurrentFramebufferBindings();
583 void RestoreCurrentRenderbufferBindings();
584 void RestoreCurrentTexture2DBindings();
585
[email protected]297ca1c2011-06-20 23:08:46586 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
587 void ApplyDirtyState();
588
[email protected]78b514b2012-05-01 21:50:59589 // Reapply the texture parameters to the given texture.
590 void BindAndApplyTextureParameters(TextureManager::TextureInfo* info);
591
[email protected]297ca1c2011-06-20 23:08:46592 // These check the state of the currently bound framebuffer or the
593 // backbuffer if no framebuffer is bound.
594 bool BoundFramebufferHasColorAttachmentWithAlpha();
595 bool BoundFramebufferHasDepthAttachment();
596 bool BoundFramebufferHasStencilAttachment();
597
[email protected]b8e97b62012-09-30 15:09:00598 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43599
[email protected]96449d2c2009-11-25 00:01:32600 private:
[email protected]6217d392010-03-25 22:08:35601 friend class ScopedGLErrorSuppressor;
[email protected]34ff8b0c2010-10-01 20:06:02602 friend class ScopedResolvedFrameBufferBinder;
[email protected]63b465922012-09-06 02:04:52603 friend class ScopedTextureUploadTimer;
[email protected]1078f912011-12-23 13:12:14604 friend class Texture;
[email protected]6217d392010-03-25 22:08:35605 friend class RenderBuffer;
606 friend class FrameBuffer;
607
[email protected]c2f8c8402010-12-06 18:07:24608 // Initialize or re-initialize the shader translator.
609 bool InitializeShaderTranslator();
610
[email protected]302ce6d2011-07-07 23:28:11611 void UpdateCapabilities();
612
[email protected]ae51d192010-04-27 00:48:03613 // Helpers for the glGen and glDelete functions.
614 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
615 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
616 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
617 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
618 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
619 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
620 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
621 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53622 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
623 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46624 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
625 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47626
[email protected]3916c97e2010-02-25 03:20:50627 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50628 BufferManager* buffer_manager() {
629 return group_->buffer_manager();
630 }
631
[email protected]a25fa872010-03-25 02:57:58632 RenderbufferManager* renderbuffer_manager() {
633 return group_->renderbuffer_manager();
634 }
635
636 FramebufferManager* framebuffer_manager() {
637 return group_->framebuffer_manager();
638 }
639
[email protected]3916c97e2010-02-25 03:20:50640 ProgramManager* program_manager() {
641 return group_->program_manager();
642 }
643
644 ShaderManager* shader_manager() {
645 return group_->shader_manager();
646 }
647
648 TextureManager* texture_manager() {
649 return group_->texture_manager();
650 }
651
[email protected]78b514b2012-05-01 21:50:59652 MailboxManager* mailbox_manager() {
653 return group_->mailbox_manager();
654 }
655
[email protected]09d50362012-10-18 20:54:37656 ImageManager* image_manager() {
657 return group_->image_manager();
658 }
659
[email protected]944b62f32012-09-27 02:20:46660 VertexArrayManager* vertex_array_manager() {
661 return vertex_array_manager_.get();
662 }
663
[email protected]34ff8b0c2010-10-01 20:06:02664 bool IsOffscreenBufferMultisampled() const {
665 return offscreen_target_samples_ > 1;
666 }
667
[email protected]a93bb842010-02-16 23:03:47668 // Creates a TextureInfo for the given texture.
[email protected]ae51d192010-04-27 00:48:03669 TextureManager::TextureInfo* CreateTextureInfo(
670 GLuint client_id, GLuint service_id) {
[email protected]80eb6b52012-01-19 00:14:41671 return texture_manager()->CreateTextureInfo(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47672 }
673
674 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]ae51d192010-04-27 00:48:03675 TextureManager::TextureInfo* GetTextureInfo(GLuint client_id) {
[email protected]3916c97e2010-02-25 03:20:50676 TextureManager::TextureInfo* info =
[email protected]ae51d192010-04-27 00:48:03677 texture_manager()->GetTextureInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10678 return info;
[email protected]a93bb842010-02-16 23:03:47679 }
680
681 // Deletes the texture info for the given texture.
[email protected]ae51d192010-04-27 00:48:03682 void RemoveTextureInfo(GLuint client_id) {
[email protected]80eb6b52012-01-19 00:14:41683 texture_manager()->RemoveTextureInfo(client_id);
[email protected]3916c97e2010-02-25 03:20:50684 }
[email protected]a93bb842010-02-16 23:03:47685
[email protected]d37231fa2010-04-09 21:16:02686 // Get the size (in pixels) of the currently bound frame buffer (either FBO
687 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30688 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02689
[email protected]9edc6b22010-12-23 02:00:26690 // Get the format of the currently bound frame buffer (either FBO or regular
691 // back buffer)
692 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46693 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26694
[email protected]a93bb842010-02-16 23:03:47695 // Wrapper for CompressedTexImage2D commands.
696 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37697 GLenum target,
698 GLint level,
699 GLenum internal_format,
700 GLsizei width,
701 GLsizei height,
702 GLint border,
703 GLsizei image_size,
704 const void* data);
[email protected]a93bb842010-02-16 23:03:47705
[email protected]cadde4a2010-07-31 17:10:43706 // Wrapper for CompressedTexSubImage2D.
707 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37708 GLenum target,
709 GLint level,
710 GLint xoffset,
711 GLint yoffset,
712 GLsizei width,
713 GLsizei height,
714 GLenum format,
715 GLsizei imageSize,
716 const void * data);
[email protected]cadde4a2010-07-31 17:10:43717
718 // Wrapper for CopyTexImage2D.
719 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37720 GLenum target,
721 GLint level,
722 GLenum internal_format,
723 GLint x,
724 GLint y,
725 GLsizei width,
726 GLsizei height,
727 GLint border);
[email protected]cadde4a2010-07-31 17:10:43728
729 // Wrapper for CopyTexSubImage2D.
730 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37731 GLenum target,
732 GLint level,
733 GLint xoffset,
734 GLint yoffset,
735 GLint x,
736 GLint y,
737 GLsizei width,
738 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43739
[email protected]f598f422012-12-07 08:30:03740 // Validation for TexImage2D commands.
741 bool ValidateTexImage2D(
742 const char* function_name,
[email protected]09d50362012-10-18 20:54:37743 GLenum target,
744 GLint level,
745 GLenum internal_format,
746 GLsizei width,
747 GLsizei height,
748 GLint border,
749 GLenum format,
750 GLenum type,
751 const void* pixels,
752 uint32 pixels_size);
[email protected]a93bb842010-02-16 23:03:47753
[email protected]f598f422012-12-07 08:30:03754 // Wrapper for TexImage2D commands.
755 void DoTexImage2D(
756 GLenum target,
757 GLint level,
758 GLenum internal_format,
759 GLsizei width,
760 GLsizei height,
761 GLint border,
762 GLenum format,
763 GLenum type,
764 const void* pixels,
765 uint32 pixels_size);
766
767 // Validation for TexSubImage2D.
768 bool ValidateTexSubImage2D(
769 error::Error* error,
770 const char* function_name,
771 GLenum target,
772 GLint level,
773 GLint xoffset,
774 GLint yoffset,
775 GLsizei width,
776 GLsizei height,
777 GLenum format,
778 GLenum type,
779 const void * data);
780
[email protected]cadde4a2010-07-31 17:10:43781 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03782 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37783 GLenum target,
784 GLint level,
785 GLint xoffset,
786 GLint yoffset,
787 GLsizei width,
788 GLsizei height,
789 GLenum format,
790 GLenum type,
791 const void * data);
[email protected]cadde4a2010-07-31 17:10:43792
[email protected]32145a92012-12-17 09:01:59793 // Extra validation for async tex(Sub)Image2D.
794 bool ValidateAsyncTransfer(
795 const char* function_name,
796 TextureManager::TextureInfo* info,
797 GLenum target,
798 GLint level,
799 const void * data);
800
[email protected]e51bdf32011-11-23 22:21:46801 // Wrapper for TexImageIOSurface2DCHROMIUM.
802 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37803 GLenum target,
804 GLsizei width,
805 GLsizei height,
806 GLuint io_surface_id,
807 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46808
[email protected]43410e92012-04-20 17:06:28809 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37810 GLenum target,
811 GLuint source_id,
812 GLuint target_id,
813 GLint level,
814 GLenum internal_format);
[email protected]43410e92012-04-20 17:06:28815
[email protected]97dc7cbe2011-12-06 17:26:17816 // Wrapper for TexStorage2DEXT.
817 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37818 GLenum target,
819 GLint levels,
820 GLenum internal_format,
821 GLsizei width,
822 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17823
[email protected]78b514b2012-05-01 21:50:59824 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
825 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
826
[email protected]09d50362012-10-18 20:54:37827 void DoBindTexImage2DCHROMIUM(
828 GLenum target,
829 GLint image_id);
830 void DoReleaseTexImage2DCHROMIUM(
831 GLenum target,
832 GLint image_id);
833
[email protected]94307712012-11-16 23:26:11834 void DoTraceEndCHROMIUM(void);
835
[email protected]a93bb842010-02-16 23:03:47836 // Creates a ProgramInfo for the given program.
[email protected]d685a682011-04-29 16:19:57837 ProgramManager::ProgramInfo* CreateProgramInfo(
838 GLuint client_id, GLuint service_id) {
839 return program_manager()->CreateProgramInfo(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47840 }
841
[email protected]07f54fcc2009-12-22 02:46:30842 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ae51d192010-04-27 00:48:03843 ProgramManager::ProgramInfo* GetProgramInfo(GLuint client_id) {
[email protected]ca488e12010-12-13 20:06:14844 return program_manager()->GetProgramInfo(client_id);
[email protected]1d32bc82010-01-13 22:06:46845 }
[email protected]07f54fcc2009-12-22 02:46:30846
[email protected]cae20172012-12-07 00:06:19847#if defined(NDEBUG)
848 void LogClientServiceMapping(
849 const char* /* function_name */,
850 GLuint /* client_id */,
851 GLuint /* service_id */) {
852 }
853 template<typename T>
854 void LogClientServiceForInfo(
855 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
856 }
857#else
858 void LogClientServiceMapping(
859 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26860 if (service_logging_) {
861 DLOG(INFO) << "[" << GetLogPrefix() << "] " << function_name
862 << ": client_id = " << client_id
863 << ", service_id = " << service_id;
864 }
[email protected]cae20172012-12-07 00:06:19865 }
866 template<typename T>
867 void LogClientServiceForInfo(
868 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26869 if (info) {
[email protected]cae20172012-12-07 00:06:19870 LogClientServiceMapping(function_name, client_id, info->service_id());
871 }
872 }
873#endif
874
[email protected]6b8cf1a2010-05-06 16:13:58875 // Gets the program info for the given program. If it's not a program
876 // generates a GL error. Returns NULL if not program.
877 ProgramManager::ProgramInfo* GetProgramInfoNotShader(
878 GLuint client_id, const char* function_name) {
879 ProgramManager::ProgramInfo* info = GetProgramInfo(client_id);
880 if (!info) {
881 if (GetShaderInfo(client_id)) {
[email protected]ad84a3a2012-06-08 21:42:43882 SetGLError(
883 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58884 } else {
[email protected]ad84a3a2012-06-08 21:42:43885 SetGLError(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58886 }
887 }
[email protected]cae20172012-12-07 00:06:19888 LogClientServiceForInfo(info, client_id, function_name);
[email protected]6b8cf1a2010-05-06 16:13:58889 return info;
890 }
891
892
[email protected]45bf5152010-02-12 00:11:31893 // Creates a ShaderInfo for the given shader.
[email protected]d685a682011-04-29 16:19:57894 ShaderManager::ShaderInfo* CreateShaderInfo(
895 GLuint client_id,
896 GLuint service_id,
897 GLenum shader_type) {
898 return shader_manager()->CreateShaderInfo(
899 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31900 }
901
902 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ae51d192010-04-27 00:48:03903 ShaderManager::ShaderInfo* GetShaderInfo(GLuint client_id) {
[email protected]ca488e12010-12-13 20:06:14904 return shader_manager()->GetShaderInfo(client_id);
[email protected]45bf5152010-02-12 00:11:31905 }
906
[email protected]6b8cf1a2010-05-06 16:13:58907 // Gets the shader info for the given shader. If it's not a shader generates a
908 // GL error. Returns NULL if not shader.
909 ShaderManager::ShaderInfo* GetShaderInfoNotProgram(
910 GLuint client_id, const char* function_name) {
911 ShaderManager::ShaderInfo* info = GetShaderInfo(client_id);
912 if (!info) {
913 if (GetProgramInfo(client_id)) {
914 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:43915 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58916 } else {
[email protected]ad84a3a2012-06-08 21:42:43917 SetGLError(
918 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58919 }
920 }
[email protected]cae20172012-12-07 00:06:19921 LogClientServiceForInfo(info, client_id, function_name);
[email protected]6b8cf1a2010-05-06 16:13:58922 return info;
923 }
924
[email protected]a93bb842010-02-16 23:03:47925 // Creates a buffer info for the given buffer.
[email protected]ae51d192010-04-27 00:48:03926 void CreateBufferInfo(GLuint client_id, GLuint service_id) {
927 return buffer_manager()->CreateBufferInfo(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47928 }
929
[email protected]07f54fcc2009-12-22 02:46:30930 // Gets the buffer info for the given buffer.
[email protected]ae51d192010-04-27 00:48:03931 BufferManager::BufferInfo* GetBufferInfo(GLuint client_id) {
932 BufferManager::BufferInfo* info =
933 buffer_manager()->GetBufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10934 return info;
[email protected]1d32bc82010-01-13 22:06:46935 }
[email protected]07f54fcc2009-12-22 02:46:30936
[email protected]a93bb842010-02-16 23:03:47937 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
938 // on glDeleteBuffers so we can make sure the user does not try to render
939 // with deleted buffers.
[email protected]ae51d192010-04-27 00:48:03940 void RemoveBufferInfo(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:47941
[email protected]a25fa872010-03-25 02:57:58942 // Creates a framebuffer info for the given framebuffer.
[email protected]ae51d192010-04-27 00:48:03943 void CreateFramebufferInfo(GLuint client_id, GLuint service_id) {
944 return framebuffer_manager()->CreateFramebufferInfo(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58945 }
946
947 // Gets the framebuffer info for the given framebuffer.
948 FramebufferManager::FramebufferInfo* GetFramebufferInfo(
[email protected]ae51d192010-04-27 00:48:03949 GLuint client_id) {
[email protected]a25fa872010-03-25 02:57:58950 FramebufferManager::FramebufferInfo* info =
[email protected]ae51d192010-04-27 00:48:03951 framebuffer_manager()->GetFramebufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10952 return info;
[email protected]a25fa872010-03-25 02:57:58953 }
954
955 // Removes the framebuffer info for the given framebuffer.
[email protected]ae51d192010-04-27 00:48:03956 void RemoveFramebufferInfo(GLuint client_id) {
957 framebuffer_manager()->RemoveFramebufferInfo(client_id);
[email protected]a25fa872010-03-25 02:57:58958 }
959
960 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ae51d192010-04-27 00:48:03961 void CreateRenderbufferInfo(GLuint client_id, GLuint service_id) {
962 return renderbuffer_manager()->CreateRenderbufferInfo(
963 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58964 }
965
966 // Gets the renderbuffer info for the given renderbuffer.
967 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfo(
[email protected]ae51d192010-04-27 00:48:03968 GLuint client_id) {
[email protected]a25fa872010-03-25 02:57:58969 RenderbufferManager::RenderbufferInfo* info =
[email protected]ae51d192010-04-27 00:48:03970 renderbuffer_manager()->GetRenderbufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:10971 return info;
[email protected]a25fa872010-03-25 02:57:58972 }
973
974 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ae51d192010-04-27 00:48:03975 void RemoveRenderbufferInfo(GLuint client_id) {
976 renderbuffer_manager()->RemoveRenderbufferInfo(client_id);
[email protected]a25fa872010-03-25 02:57:58977 }
978
[email protected]944b62f32012-09-27 02:20:46979 // Gets the vertex attrib manager for the given vertex array.
980 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
981 VertexAttribManager* info =
982 vertex_array_manager()->GetVertexAttribManager(client_id);
983 return info;
984 }
985
986 // Removes the vertex attrib manager for the given vertex array.
987 void RemoveVertexAttribManager(GLuint client_id) {
988 vertex_array_manager()->RemoveVertexAttribManager(client_id);
989 }
990
991 // Creates a vertex attrib manager for the given vertex array.
992 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
993 return vertex_array_manager()->CreateVertexAttribManager(
994 client_id, service_id, group_->max_vertex_attribs());
995 }
996
[email protected]258a3313f2011-10-18 20:13:57997 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:33998 void DoBindUniformLocationCHROMIUM(
999 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571000
[email protected]558847a2010-03-24 07:02:541001 error::Error GetAttribLocationHelper(
1002 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1003 const std::string& name_str);
1004
1005 error::Error GetUniformLocationHelper(
1006 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1007 const std::string& name_str);
1008
[email protected]3916c97e2010-02-25 03:20:501009 // Helper for glShaderSource.
1010 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031011 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301012
[email protected]0d6bfdc2011-11-02 01:32:201013 // Clear any textures used by the current program.
1014 bool ClearUnclearedTextures();
1015
1016 // Clear any uncleared level in texture.
1017 // Returns false if there was a generated GL error.
1018 bool ClearTexture(TextureManager::TextureInfo* info);
1019
1020 // Clears any uncleared attachments attached to the given frame buffer.
1021 // Returns false if there was a generated GL error.
1022 void ClearUnclearedAttachments(
[email protected]8e3e0662010-08-23 18:46:301023 GLenum target, FramebufferManager::FramebufferInfo* info);
[email protected]3a2e7c7b2010-08-06 01:12:281024
[email protected]0d6bfdc2011-11-02 01:32:201025 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001026 virtual bool ClearLevel(unsigned service_id,
1027 unsigned bind_target,
1028 unsigned target,
1029 int level,
1030 unsigned format,
1031 unsigned type,
1032 int width,
1033 int height,
1034 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201035
[email protected]c007aa02010-09-02 22:22:401036 // Restore all GL state that affects clearing.
1037 void RestoreClearState();
1038
[email protected]3a2e7c7b2010-08-06 01:12:281039 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461040 // Returns: true if glEnable/glDisable should actually be called.
1041 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281042
[email protected]0d6bfdc2011-11-02 01:32:201043 // Check that the currently bound framebuffers are valid.
1044 // Generates GL error if not.
1045 bool CheckBoundFramebuffersValid(const char* func_name);
1046
1047 // Check if a framebuffer meets our requirements.
1048 bool CheckFramebufferValid(
1049 FramebufferManager::FramebufferInfo* framebuffer,
1050 GLenum target,
1051 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271052
[email protected]939e7362010-05-13 20:49:101053 // Checks if the current program exists and is valid. If not generates the
1054 // appropriate GL error. Returns true if the current program is in a usable
1055 // state.
1056 bool CheckCurrentProgram(const char* function_name);
1057
1058 // Checks if the current program exists and is valid and that location is not
1059 // -1. If the current program is not valid generates the appropriate GL
1060 // error. Returns true if the current program is in a usable state and
1061 // location is not -1.
1062 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1063
1064 // Gets the type of a uniform for a location in the current program. Sets GL
1065 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361066 // program is valid and the location exists. Adjusts count so it
1067 // does not overflow the uniform.
1068 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121069 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521070 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121071 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101072
[email protected]b177ae22011-11-01 03:29:111073 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021074 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111075
[email protected]b273e432010-04-12 17:23:581076 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1077 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1078
[email protected]96449d2c2009-11-25 00:01:321079 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031080 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321081
1082 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031083 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321084
[email protected]3916c97e2010-02-25 03:20:501085 // Wrapper for glActiveTexture
1086 void DoActiveTexture(GLenum texture_unit);
1087
[email protected]ae51d192010-04-27 00:48:031088 // Wrapper for glAttachShader
1089 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1090
[email protected]96449d2c2009-11-25 00:01:321091 // Wrapper for glBindBuffer since we need to track the current targets.
1092 void DoBindBuffer(GLenum target, GLuint buffer);
1093
[email protected]86093972010-03-11 00:13:561094 // Wrapper for glBindFramebuffer since we need to track the current targets.
1095 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1096
1097 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1098 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1099
[email protected]a93bb842010-02-16 23:03:471100 // Wrapper for glBindTexture since we need to track the current targets.
1101 void DoBindTexture(GLenum target, GLuint texture);
1102
[email protected]944b62f32012-09-27 02:20:461103 // Wrapper for glBindVertexArrayOES
1104 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571105 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461106
[email protected]8e3e0662010-08-23 18:46:301107 // Wrapper for glBlitFramebufferEXT.
1108 void DoBlitFramebufferEXT(
1109 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1110 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1111 GLbitfield mask, GLenum filter);
1112
[email protected]36cef8ce2010-03-16 07:34:451113 // Wrapper for glBufferData.
[email protected]0c86dbf2010-03-05 08:14:111114 void DoBufferData(
1115 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
1116
[email protected]36cef8ce2010-03-16 07:34:451117 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111118 void DoBufferSubData(
1119 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1120
[email protected]36cef8ce2010-03-16 07:34:451121 // Wrapper for glCheckFramebufferStatus
1122 GLenum DoCheckFramebufferStatus(GLenum target);
1123
[email protected]3a03a8f2011-03-19 00:51:271124 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081125 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271126
[email protected]88a61bf2012-10-27 13:00:421127 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421128 void DoDepthRangef(GLclampf znear, GLclampf zfar);
1129 void DoHint(GLenum target, GLenum mode);
[email protected]b04e24c2013-01-08 18:35:251130 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281131
[email protected]45bf5152010-02-12 00:11:311132 // Wrapper for glCompileShader.
1133 void DoCompileShader(GLuint shader);
1134
[email protected]269200b12010-11-18 22:53:061135 // Helper for DeleteSharedIdsCHROMIUM commands.
1136 void DoDeleteSharedIdsCHROMIUM(
1137 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101138
[email protected]ae51d192010-04-27 00:48:031139 // Wrapper for glDetachShader
1140 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1141
[email protected]3a2e7c7b2010-08-06 01:12:281142 // Wrapper for glDisable
1143 void DoDisable(GLenum cap);
1144
[email protected]07f54fcc2009-12-22 02:46:301145 // Wrapper for glDisableVertexAttribArray.
1146 void DoDisableVertexAttribArray(GLuint index);
1147
[email protected]60f22d32012-12-12 00:31:581148 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1149 // attachments.
1150 void DoDiscardFramebufferEXT(GLenum target,
1151 GLsizei numAttachments,
1152 const GLenum* attachments);
1153
[email protected]3a2e7c7b2010-08-06 01:12:281154 // Wrapper for glEnable
1155 void DoEnable(GLenum cap);
1156
[email protected]07f54fcc2009-12-22 02:46:301157 // Wrapper for glEnableVertexAttribArray.
1158 void DoEnableVertexAttribArray(GLuint index);
1159
[email protected]882ba1e22012-03-08 19:02:531160 // Wrapper for glFinish.
1161 void DoFinish();
1162
1163 // Wrapper for glFlush.
1164 void DoFlush();
1165
[email protected]36cef8ce2010-03-16 07:34:451166 // Wrapper for glFramebufferRenderbufffer.
1167 void DoFramebufferRenderbuffer(
1168 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1169 GLuint renderbuffer);
1170
1171 // Wrapper for glFramebufferTexture2D.
1172 void DoFramebufferTexture2D(
1173 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1174 GLint level);
1175
[email protected]a93bb842010-02-16 23:03:471176 // Wrapper for glGenerateMipmap
1177 void DoGenerateMipmap(GLenum target);
1178
[email protected]269200b12010-11-18 22:53:061179 // Helper for GenSharedIdsCHROMIUM commands.
1180 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101181 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1182
[email protected]b273e432010-04-12 17:23:581183 // Wrapper for DoGetBooleanv.
1184 void DoGetBooleanv(GLenum pname, GLboolean* params);
1185
1186 // Wrapper for DoGetFloatv.
1187 void DoGetFloatv(GLenum pname, GLfloat* params);
1188
[email protected]36cef8ce2010-03-16 07:34:451189 // Wrapper for glGetFramebufferAttachmentParameteriv.
1190 void DoGetFramebufferAttachmentParameteriv(
1191 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1192
[email protected]a0c3e972010-04-21 00:49:131193 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581194 void DoGetIntegerv(GLenum pname, GLint* params);
1195
[email protected]29a9eb52010-04-13 09:04:231196 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061197 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231198 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1199
[email protected]a0c3e972010-04-21 00:49:131200 // Wrapper for glGetProgramiv.
1201 void DoGetProgramiv(
1202 GLuint program_id, GLenum pname, GLint* params);
1203
[email protected]36cef8ce2010-03-16 07:34:451204 // Wrapper for glRenderbufferParameteriv.
1205 void DoGetRenderbufferParameteriv(
1206 GLenum target, GLenum pname, GLint* params);
1207
[email protected]ddd968b82010-03-02 00:44:291208 // Wrapper for glGetShaderiv
1209 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1210
[email protected]b1122982010-05-17 23:04:241211 // Wrappers for glGetVertexAttrib.
1212 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1213 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1214
[email protected]1958e0e2010-04-22 05:17:151215 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241216 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151217 bool DoIsBuffer(GLuint client_id);
1218 bool DoIsFramebuffer(GLuint client_id);
1219 bool DoIsProgram(GLuint client_id);
1220 bool DoIsRenderbuffer(GLuint client_id);
1221 bool DoIsShader(GLuint client_id);
1222 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461223 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151224
[email protected]07f54fcc2009-12-22 02:46:301225 // Wrapper for glLinkProgram
1226 void DoLinkProgram(GLuint program);
1227
[email protected]269200b12010-11-18 22:53:061228 // Helper for RegisterSharedIdsCHROMIUM.
1229 void DoRegisterSharedIdsCHROMIUM(
1230 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101231
[email protected]36cef8ce2010-03-16 07:34:451232 // Wrapper for glRenderbufferStorage.
1233 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031234 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451235
[email protected]8e3e0662010-08-23 18:46:301236 // Wrapper for glRenderbufferStorageMultisampleEXT.
1237 void DoRenderbufferStorageMultisample(
1238 GLenum target, GLsizei samples, GLenum internalformat,
1239 GLsizei width, GLsizei height);
1240
[email protected]b273e432010-04-12 17:23:581241 // Wrapper for glReleaseShaderCompiler.
1242 void DoReleaseShaderCompiler() { }
1243
[email protected]3916c97e2010-02-25 03:20:501244 // Wrappers for glTexParameter functions.
1245 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1246 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1247 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1248 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1249
1250 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1251 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121252 void DoUniform1i(GLint fake_location, GLint v0);
1253 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1254 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1255 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1256 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101257
1258 // Wrappers for glUniformfv because some drivers don't correctly accept
1259 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121260 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1261 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1262 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1263 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501264
[email protected]43c2f1f2011-03-25 18:35:361265 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121266 GLint fake_location, GLsizei count, GLboolean transpose,
1267 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361268 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121269 GLint fake_location, GLsizei count, GLboolean transpose,
1270 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361271 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121272 GLint fake_location, GLsizei count, GLboolean transpose,
1273 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361274
[email protected]af6380962012-11-29 23:24:131275 bool SetVertexAttribValue(
1276 const char* function_name, GLuint index, const GLfloat* value);
1277
[email protected]b1122982010-05-17 23:04:241278 // Wrappers for glVertexAttrib??
1279 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1280 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1281 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1282 void DoVertexAttrib4f(
1283 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1284 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1285 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1286 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1287 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1288
[email protected]43410e92012-04-20 17:06:281289 // Wrapper for glViewport
1290 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1291
[email protected]07f54fcc2009-12-22 02:46:301292 // Wrapper for glUseProgram
1293 void DoUseProgram(GLuint program);
1294
[email protected]ae51d192010-04-27 00:48:031295 // Wrapper for glValidateProgram.
1296 void DoValidateProgram(GLuint program_client_id);
1297
[email protected]d2a0e1a2012-08-12 02:25:011298 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1299 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1300 void DoPopGroupMarkerEXT(void);
1301
[email protected]4e8a5b122010-05-08 22:00:101302 // Gets the number of values that will be returned by glGetXXX. Returns
1303 // false if pname is unknown.
1304 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1305
[email protected]1002c2d2011-06-28 22:39:041306 // Gets the GLError and stores it in our wrapper. Effectively
1307 // this lets us peek at the error without losing it.
1308 GLenum PeekGLError();
1309
[email protected]07f54fcc2009-12-22 02:46:301310 // Copies the real GL errors to the wrapper. This is so we can
1311 // make sure there are no native GL errors before calling some GL function
1312 // so that on return we know any error generated was for that specific
1313 // command.
1314 void CopyRealGLErrorsToWrapper();
1315
[email protected]6217d392010-03-25 22:08:351316 // Clear all real GL errors. This is to prevent the client from seeing any
1317 // errors caused by GL calls that it was not responsible for issuing.
1318 void ClearRealGLErrors();
1319
[email protected]445a8762012-12-06 15:43:211320 // Generates a GL error for a bad parameter.
1321 void SetGLErrorInvalidParam(
1322 GLenum error,
1323 const char* function_name,
1324 GLenum pname,
1325 GLint param);
1326
[email protected]07f54fcc2009-12-22 02:46:301327 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431328 bool IsDrawValid(
1329 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301330
[email protected]c13e1da62011-09-09 21:48:301331 // Returns true if successful, simulated will be true if attrib0 was
1332 // simulated.
[email protected]c6aef902012-02-14 03:31:421333 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431334 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281335 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241336
[email protected]ef526492010-06-02 23:12:251337 // Returns true if textures were set.
1338 bool SetBlackTextureForNonRenderableTextures();
[email protected]3916c97e2010-02-25 03:20:501339 void RestoreStateForNonRenderableTextures();
1340
[email protected]8fbedc02010-11-18 18:43:401341 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421342 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431343 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421344 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401345 void RestoreStateForSimulatedFixedAttribs();
1346
[email protected]c6aef902012-02-14 03:31:421347 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1348 // cases (primcount is 0 for non-instanced).
1349 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431350 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421351 bool instanced, GLenum mode, GLint first, GLsizei count,
1352 GLsizei primcount);
1353 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431354 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421355 bool instanced, GLenum mode, GLsizei count, GLenum type,
1356 int32 offset, GLsizei primcount);
1357
[email protected]07f54fcc2009-12-22 02:46:301358 // Gets the buffer id for a given target.
[email protected]3916c97e2010-02-25 03:20:501359 BufferManager::BufferInfo* GetBufferInfoForTarget(GLenum target) {
[email protected]07f54fcc2009-12-22 02:46:301360 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
[email protected]944b62f32012-09-27 02:20:461361 if (target == GL_ARRAY_BUFFER) {
[email protected]e259eb412012-10-13 05:47:241362 return state_.bound_array_buffer;
[email protected]944b62f32012-09-27 02:20:461363 } else {
[email protected]e259eb412012-10-13 05:47:241364 return state_.vertex_attrib_manager->element_array_buffer();
[email protected]944b62f32012-09-27 02:20:461365 }
[email protected]07f54fcc2009-12-22 02:46:301366 }
1367
[email protected]a93bb842010-02-16 23:03:471368 // Gets the texture id for a given target.
[email protected]3916c97e2010-02-25 03:20:501369 TextureManager::TextureInfo* GetTextureInfoForTarget(GLenum target) {
[email protected]e259eb412012-10-13 05:47:241370 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:501371 TextureManager::TextureInfo* info = NULL;
[email protected]a93bb842010-02-16 23:03:471372 switch (target) {
1373 case GL_TEXTURE_2D:
[email protected]3916c97e2010-02-25 03:20:501374 info = unit.bound_texture_2d;
1375 break;
[email protected]a93bb842010-02-16 23:03:471376 case GL_TEXTURE_CUBE_MAP:
1377 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1378 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1379 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1380 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1381 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1382 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
[email protected]3916c97e2010-02-25 03:20:501383 info = unit.bound_texture_cube_map;
1384 break;
[email protected]61eeb33f2011-07-26 15:30:311385 case GL_TEXTURE_EXTERNAL_OES:
1386 info = unit.bound_texture_external_oes;
1387 break;
[email protected]e51bdf32011-11-23 22:21:461388 case GL_TEXTURE_RECTANGLE_ARB:
1389 info = unit.bound_texture_rectangle_arb;
1390 break;
[email protected]a93bb842010-02-16 23:03:471391 default:
1392 NOTREACHED();
[email protected]3916c97e2010-02-25 03:20:501393 return NULL;
[email protected]a93bb842010-02-16 23:03:471394 }
[email protected]a0b78dc2011-11-11 10:43:101395 return info;
[email protected]a93bb842010-02-16 23:03:471396 }
1397
[email protected]09d50362012-10-18 20:54:371398 TextureManager::TextureInfo* GetTextureInfoForTargetUnlessDefault(
1399 GLenum target) {
1400 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
1401 if (!info)
1402 return NULL;
1403 if (info == texture_manager()->GetDefaultTextureInfo(target))
1404 return NULL;
1405 return info;
1406 }
1407
[email protected]61eeb33f2011-07-26 15:30:311408 GLenum GetBindTargetForSamplerType(GLenum type) {
1409 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461410 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1411 switch (type) {
1412 case GL_SAMPLER_2D:
1413 return GL_TEXTURE_2D;
1414 case GL_SAMPLER_CUBE:
1415 return GL_TEXTURE_CUBE_MAP;
1416 case GL_SAMPLER_EXTERNAL_OES:
1417 return GL_TEXTURE_EXTERNAL_OES;
1418 case GL_SAMPLER_2D_RECT_ARB:
1419 return GL_TEXTURE_RECTANGLE_ARB;
1420 }
1421
1422 NOTREACHED();
1423 return 0;
[email protected]61eeb33f2011-07-26 15:30:311424 }
1425
[email protected]8e3e0662010-08-23 18:46:301426 // Gets the framebuffer info for a particular target.
1427 FramebufferManager::FramebufferInfo* GetFramebufferInfoForTarget(
1428 GLenum target) {
1429 FramebufferManager::FramebufferInfo* info = NULL;
1430 switch (target) {
1431 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451432 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]e259eb412012-10-13 05:47:241433 info = state_.bound_draw_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301434 break;
[email protected]ebfb73c2012-08-15 02:37:451435 case GL_READ_FRAMEBUFFER_EXT:
[email protected]e259eb412012-10-13 05:47:241436 info = state_.bound_read_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301437 break;
1438 default:
1439 NOTREACHED();
1440 break;
1441 }
[email protected]a0b78dc2011-11-11 10:43:101442 return info;
[email protected]8e3e0662010-08-23 18:46:301443 }
1444
[email protected]0d6bfdc2011-11-02 01:32:201445 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfoForTarget(
1446 GLenum target) {
1447 RenderbufferManager::RenderbufferInfo* info = NULL;
1448 switch (target) {
1449 case GL_RENDERBUFFER:
[email protected]e259eb412012-10-13 05:47:241450 info = state_.bound_renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201451 break;
1452 default:
1453 NOTREACHED();
1454 break;
1455 }
[email protected]a0b78dc2011-11-11 10:43:101456 return info;
[email protected]0d6bfdc2011-11-02 01:32:201457 }
1458
[email protected]f7b85372010-02-03 01:11:371459 // Validates the program and location for a glGetUniform call and returns
1460 // a SizeResult setup to receive the result. Returns true if glGetUniform
1461 // should be called.
1462 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121463 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371464 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121465 error::Error* error, GLint* real_location, GLuint* service_id,
1466 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371467
[email protected]1078f912011-12-23 13:12:141468 // Computes the estimated memory used for the backbuffer and passes it to
1469 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531470 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141471
[email protected]a10b4a02012-11-26 23:09:501472 virtual bool WasContextLost() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091473 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431474
[email protected]e51bdf32011-11-23 22:21:461475#if defined(OS_MACOSX)
1476 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1477#endif
1478
[email protected]81375742012-06-08 00:04:001479 // Validates the combination of texture parameters. For example validates that
1480 // for a given format the specific type, level and targets are valid.
1481 // Synthesizes the correct GL error if invalid. Returns true if valid.
1482 bool ValidateTextureParameters(
1483 const char* function_name,
1484 GLenum target, GLenum format, GLenum type, GLint level);
1485
[email protected]ad84a3a2012-06-08 21:42:431486 bool ValidateCompressedTexDimensions(
1487 const char* function_name,
1488 GLint level, GLsizei width, GLsizei height, GLenum format);
1489 bool ValidateCompressedTexFuncData(
1490 const char* function_name,
1491 GLsizei width, GLsizei height, GLenum format, size_t size);
1492 bool ValidateCompressedTexSubDimensions(
1493 const char* function_name,
1494 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1495 GLsizei width, GLsizei height, GLenum format,
1496 TextureManager::TextureInfo* texture);
1497
[email protected]0f8afe82012-05-14 23:43:011498 void LogMessage(const std::string& msg);
1499 void RenderWarning(const std::string& msg);
1500 void PerformanceWarning(const std::string& msg);
[email protected]d2a0e1a2012-08-12 02:25:011501 const std::string& GetLogPrefix() const;
[email protected]0f8afe82012-05-14 23:43:011502
[email protected]62e155e2012-10-23 22:43:151503 const FeatureInfo::FeatureFlags& features() const {
1504 return feature_info_->feature_flags();
1505 }
1506
1507 const FeatureInfo::Workarounds& workarounds() const {
1508 return feature_info_->workarounds();
1509 }
1510
[email protected]a7266a92012-06-28 02:11:081511 bool ShouldDeferDraws() {
1512 return !offscreen_target_frame_buffer_.get() &&
[email protected]e259eb412012-10-13 05:47:241513 state_.bound_draw_framebuffer == NULL &&
[email protected]a7266a92012-06-28 02:11:081514 surface_->DeferDraws();
1515 }
1516
[email protected]09e17272012-11-30 10:30:441517 bool ShouldDeferReads() {
1518 return !offscreen_target_frame_buffer_.get() &&
1519 state_.bound_read_framebuffer == NULL &&
1520 surface_->DeferDraws();
1521 }
1522
[email protected]c447acd2012-07-23 23:48:411523 void ForceCompileShaderIfPending(ShaderManager::ShaderInfo* info);
1524
[email protected]96449d2c2009-11-25 00:01:321525 // Generate a member function prototype for each command in an automated and
1526 // typesafe way.
1527 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141528 Error Handle ## name( \
[email protected]b9849abf2009-11-25 19:13:191529 uint32 immediate_data_size, \
[email protected]96449d2c2009-11-25 00:01:321530 const gles2::name& args); \
1531
1532 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1533
1534 #undef GLES2_CMD_OP
1535
[email protected]2f2d7042010-04-14 21:45:581536 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381537 scoped_refptr<gfx::GLSurface> surface_;
1538 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021539
[email protected]a3ded6d2010-10-19 06:44:391540 // The ContextGroup for this decoder uses to track resources.
1541 ContextGroup::Ref group_;
1542
[email protected]e259eb412012-10-13 05:47:241543 // All the state for this context.
1544 ContextState state_;
1545
[email protected]6217d392010-03-25 22:08:351546 // A parent decoder can access this decoders saved offscreen frame buffer.
1547 // The parent pointer is reset if the parent is destroyed.
1548 base::WeakPtr<GLES2DecoderImpl> parent_;
1549
[email protected]34ff8b0c2010-10-01 20:06:021550 // Current width and height of the offscreen frame buffer.
1551 gfx::Size offscreen_size_;
1552
[email protected]96449d2c2009-11-25 00:01:321553 // Current GL error bits.
1554 uint32 error_bits_;
1555
[email protected]96449d2c2009-11-25 00:01:321556 // Util to help with GL.
1557 GLES2Util util_;
1558
[email protected]43410e92012-04-20 17:06:281559 // unpack flip y as last set by glPixelStorei
1560 bool unpack_flip_y_;
1561
[email protected]6c75c712012-06-19 15:43:171562 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281563 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171564 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281565
[email protected]944b62f32012-09-27 02:20:461566 // Default vertex attribs manager, used when no VAOs are bound.
1567 VertexAttribManager::Ref default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301568
[email protected]b1122982010-05-17 23:04:241569 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1570 GLuint attrib_0_buffer_id_;
1571
1572 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131573 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241574
[email protected]fc753442011-02-04 19:49:491575 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1576 bool attrib_0_buffer_matches_value_;
1577
[email protected]b1122982010-05-17 23:04:241578 // The size of attrib 0.
1579 GLsizei attrib_0_size_;
1580
[email protected]8fbedc02010-11-18 18:43:401581 // The buffer used to simulate GL_FIXED attribs.
1582 GLuint fixed_attrib_buffer_id_;
1583
1584 // The size of fiixed attrib buffer.
1585 GLsizei fixed_attrib_buffer_size_;
1586
[email protected]3a2e7c7b2010-08-06 01:12:281587 // state saved for clearing so we can clear render buffers and then
1588 // restore to these values.
[email protected]88a61bf2012-10-27 13:00:421589 bool clear_state_dirty_;
[email protected]3a2e7c7b2010-08-06 01:12:281590
[email protected]b9363b22010-06-09 22:06:151591 // The offscreen frame buffer that the client renders to. With EGL, the
1592 // depth and stencil buffers are separate. With regular GL there is a single
1593 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1594 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]6217d392010-03-25 22:08:351595 scoped_ptr<FrameBuffer> offscreen_target_frame_buffer_;
1596 scoped_ptr<Texture> offscreen_target_color_texture_;
[email protected]34ff8b0c2010-10-01 20:06:021597 scoped_ptr<RenderBuffer> offscreen_target_color_render_buffer_;
[email protected]b9363b22010-06-09 22:06:151598 scoped_ptr<RenderBuffer> offscreen_target_depth_render_buffer_;
1599 scoped_ptr<RenderBuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021600 GLenum offscreen_target_color_format_;
1601 GLenum offscreen_target_depth_format_;
1602 GLenum offscreen_target_stencil_format_;
1603 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561604 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351605
[email protected]de26b3c2011-08-03 21:54:271606 // The copy that is saved when SwapBuffers is called.
[email protected]34ff8b0c2010-10-01 20:06:021607 scoped_ptr<FrameBuffer> offscreen_saved_frame_buffer_;
[email protected]6217d392010-03-25 22:08:351608 scoped_ptr<Texture> offscreen_saved_color_texture_;
[email protected]8a61d872012-01-20 12:43:561609 TextureManager::TextureInfo::Ref offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271610
1611 // The copy that is used as the destination for multi-sample resolves.
1612 scoped_ptr<FrameBuffer> offscreen_resolved_frame_buffer_;
1613 scoped_ptr<Texture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051614 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351615
[email protected]882ba1e22012-03-08 19:02:531616 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531617
[email protected]944b62f32012-09-27 02:20:461618 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1619
[email protected]9d37f062011-11-22 01:24:521620 base::Callback<void(gfx::Size)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001621
[email protected]6b6e7ee2011-12-13 08:04:521622 MsgCallback msg_callback_;
[email protected]43f28f832010-02-03 02:28:481623
[email protected]b0af4f52011-09-28 22:04:421624 StreamTextureManager* stream_texture_manager_;
[email protected]32145a92012-12-17 09:01:591625 scoped_ptr<gfx::AsyncPixelTransferDelegate> async_pixel_transfer_delegate_;
[email protected]b0af4f52011-09-28 22:04:421626
[email protected]32fe9aa2011-01-21 23:47:131627 // The format of the back buffer_
1628 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461629 bool back_buffer_has_depth_;
1630 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131631
[email protected]60f22d32012-12-12 00:31:581632 // Backbuffer attachments that are currently undefined.
1633 uint32 backbuffer_needs_clear_bits_;
1634
[email protected]473c01ccb2011-06-07 01:33:301635 bool teximage2d_faster_than_texsubimage2d_;
[email protected]473c01ccb2011-06-07 01:33:301636
[email protected]8eee29c2010-04-29 03:38:291637 // The last error message set.
1638 std::string last_error_;
1639
[email protected]0f8afe82012-05-14 23:43:011640 int log_message_count_;
[email protected]fa20ec82012-05-04 04:02:481641
[email protected]a3a93e7b2010-08-28 00:48:561642 // The current decoder error.
1643 error::Error current_decoder_error_;
1644
[email protected]d2a0e1a2012-08-12 02:25:011645 DebugMarkerManager debug_marker_manager_;
1646 std::string this_in_hex_;
1647
[email protected]b1d2dcb2010-05-17 19:24:181648 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041649 scoped_refptr<ShaderTranslator> vertex_translator_;
1650 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181651
[email protected]e82fb792011-09-22 00:33:291652 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411653
[email protected]915a59a12010-09-30 21:29:111654 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051655 const Validators* validators_;
[email protected]80eb6b52012-01-19 00:14:411656 FeatureInfo::Ref feature_info_;
[email protected]9438b012010-06-15 22:55:051657
[email protected]b493ee622011-04-13 23:52:001658 // This indicates all the following texSubImage2D calls that are part of the
1659 // failed texImage2D call should be ignored.
1660 bool tex_image_2d_failed_;
1661
[email protected]65225772011-05-12 21:10:241662 int frame_number_;
1663
[email protected]706b69f2012-07-27 04:59:301664 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431665 GLenum reset_status_;
1666
[email protected]f0d74742011-10-03 16:31:041667 // These flags are used to override the state of the shared feature_info_
1668 // member. Because the same FeatureInfo instance may be shared among many
1669 // contexts, the assumptions on the availablity of extensions in WebGL
1670 // contexts may be broken. These flags override the shared state to preserve
1671 // WebGL semantics.
1672 bool force_webgl_glsl_validation_;
1673 bool derivatives_explicitly_enabled_;
1674
[email protected]062c38b2012-01-18 03:25:101675 bool compile_shader_always_succeeds_;
1676
[email protected]cae20172012-12-07 00:06:191677 // Log extra info.
1678 bool service_logging_;
1679
[email protected]e51bdf32011-11-23 22:21:461680#if defined(OS_MACOSX)
1681 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1682 TextureToIOSurfaceMap texture_to_io_surface_map_;
1683#endif
1684
[email protected]c826d732012-02-09 04:40:261685 typedef std::vector<GLES2DecoderImpl*> ChildList;
1686 ChildList children_;
1687
[email protected]43410e92012-04-20 17:06:281688 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1689
[email protected]1868a342012-11-07 15:56:021690 // Cached values of the currently assigned viewport dimensions.
1691 GLsizei viewport_max_width_;
1692 GLsizei viewport_max_height_;
1693
[email protected]63b465922012-09-06 02:04:521694 // Command buffer stats.
1695 int texture_upload_count_;
1696 base::TimeDelta total_texture_upload_time_;
1697 base::TimeDelta total_processing_commands_time_;
1698
[email protected]94307712012-11-16 23:26:111699 std::stack<linked_ptr<GPUTrace> > gpu_trace_stack_;
1700
[email protected]96449d2c2009-11-25 00:01:321701 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1702};
1703
[email protected]6217d392010-03-25 22:08:351704ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder)
1705 : decoder_(decoder) {
1706 decoder_->CopyRealGLErrorsToWrapper();
1707}
1708
1709ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
1710 decoder_->ClearRealGLErrors();
1711}
1712
1713ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1714 GLuint id)
1715 : decoder_(decoder) {
1716 ScopedGLErrorSuppressor suppressor(decoder_);
1717
1718 // TODO(apatrick): Check if there are any other states that need to be reset
1719 // before binding a new texture.
1720 glActiveTexture(GL_TEXTURE0);
1721 glBindTexture(GL_TEXTURE_2D, id);
1722}
1723
1724ScopedTexture2DBinder::~ScopedTexture2DBinder() {
1725 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301726 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351727}
1728
1729ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1730 GLuint id)
1731 : decoder_(decoder) {
1732 ScopedGLErrorSuppressor suppressor(decoder_);
1733 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1734}
1735
1736ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
1737 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301738 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351739}
1740
1741ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1742 GLuint id)
1743 : decoder_(decoder) {
1744 ScopedGLErrorSuppressor suppressor(decoder_);
1745 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
1746}
1747
1748ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
1749 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301750 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351751}
1752
[email protected]34ff8b0c2010-10-01 20:06:021753ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271754 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521755 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021756 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1757 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241758 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521759 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021760 if (!resolve_and_bind_)
1761 return;
1762
1763 ScopedGLErrorSuppressor suppressor(decoder_);
1764 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1765 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271766 GLuint targetid;
1767 if (internal) {
1768 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1769 decoder_->offscreen_resolved_frame_buffer_.reset(
1770 new FrameBuffer(decoder_));
1771 decoder_->offscreen_resolved_frame_buffer_->Create();
1772 decoder_->offscreen_resolved_color_texture_.reset(new Texture(decoder_));
1773 decoder_->offscreen_resolved_color_texture_->Create();
1774
1775 DCHECK(decoder_->offscreen_saved_color_format_);
1776 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091777 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1778 false);
[email protected]de26b3c2011-08-03 21:54:271779 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1780 decoder_->offscreen_resolved_color_texture_.get());
1781 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1782 GL_FRAMEBUFFER_COMPLETE) {
1783 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1784 << "because offscreen resolved FBO was incomplete.";
1785 return;
1786 }
1787 }
1788 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1789 } else {
1790 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1791 }
1792 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021793 const int width = decoder_->offscreen_size_.width();
1794 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181795 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151796 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021797 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1798 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1799 } else {
1800 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1801 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1802 }
[email protected]de26b3c2011-08-03 21:54:271803 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021804}
1805
1806ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1807 if (!resolve_and_bind_)
1808 return;
1809
1810 ScopedGLErrorSuppressor suppressor(decoder_);
1811 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221812 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181813 glEnable(GL_SCISSOR_TEST);
1814 }
[email protected]34ff8b0c2010-10-01 20:06:021815}
1816
[email protected]63b465922012-09-06 02:04:521817ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder)
1818 : decoder_(decoder),
1819 begin_time_(base::TimeTicks::HighResNow()) {
1820}
1821
1822ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1823 decoder_->texture_upload_count_++;
1824 decoder_->total_texture_upload_time_ +=
1825 base::TimeTicks::HighResNow() - begin_time_;
1826}
1827
[email protected]6217d392010-03-25 22:08:351828Texture::Texture(GLES2DecoderImpl* decoder)
1829 : decoder_(decoder),
[email protected]68e81a4a62012-12-13 01:16:481830 memory_tracker_(decoder->GetContextGroup()->memory_tracker(),
1831 MemoryTracker::kUnmanaged),
1832 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251833 id_(0) {
[email protected]6217d392010-03-25 22:08:351834}
1835
1836Texture::~Texture() {
1837 // This does not destroy the render texture because that would require that
1838 // the associated GL context was current. Just check that it was explicitly
1839 // destroyed.
1840 DCHECK_EQ(id_, 0u);
1841}
1842
1843void Texture::Create() {
1844 ScopedGLErrorSuppressor suppressor(decoder_);
1845 Destroy();
1846 glGenTextures(1, &id_);
[email protected]3a4d0c52011-06-29 23:11:581847 ScopedTexture2DBinder binder(decoder_, id_);
1848 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1849 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1850 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1851 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161852
1853 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1854 // never called on an offscreen context, no data will ever be uploaded to the
1855 // saved offscreen color texture (it is deferred until to when SwapBuffers
1856 // is called). My idea is that some nvidia drivers might have a bug where
1857 // deleting a texture that has never been populated might cause a
1858 // crash.
1859 glTexImage2D(
1860 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481861
1862 bytes_allocated_ = 16u * 16u * 4u;
1863 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351864}
1865
[email protected]678a73f2012-12-19 19:22:091866bool Texture::AllocateStorage(const gfx::Size& size, GLenum format,
1867 bool zero) {
[email protected]6217d392010-03-25 22:08:351868 DCHECK_NE(id_, 0u);
1869 ScopedGLErrorSuppressor suppressor(decoder_);
1870 ScopedTexture2DBinder binder(decoder_, id_);
[email protected]678a73f2012-12-19 19:22:091871 uint32 image_size = 0;
1872 GLES2Util::ComputeImageDataSizes(
1873 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1874 NULL, NULL);
1875
1876 scoped_array<char> zero_data;
1877 if (zero) {
1878 zero_data.reset(new char[image_size]);
1879 memset(zero_data.get(), 0, image_size);
1880 }
[email protected]6217d392010-03-25 22:08:351881
[email protected]f0e6a34f2012-01-04 20:53:401882 WrappedTexImage2D(GL_TEXTURE_2D,
1883 0, // mip level
1884 format,
1885 size.width(),
1886 size.height(),
1887 0, // border
1888 format,
1889 GL_UNSIGNED_BYTE,
[email protected]678a73f2012-12-19 19:22:091890 zero_data.get());
[email protected]6217d392010-03-25 22:08:351891
[email protected]d37231fa2010-04-09 21:16:021892 size_ = size;
1893
[email protected]1078f912011-12-23 13:12:141894 bool success = glGetError() == GL_NO_ERROR;
1895 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481896 memory_tracker_.TrackMemFree(bytes_allocated_);
1897 bytes_allocated_ = image_size;
1898 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141899 }
1900 return success;
[email protected]6217d392010-03-25 22:08:351901}
1902
[email protected]3a4d0c52011-06-29 23:11:581903void Texture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351904 DCHECK_NE(id_, 0u);
1905 ScopedGLErrorSuppressor suppressor(decoder_);
1906 ScopedTexture2DBinder binder(decoder_, id_);
1907 glCopyTexImage2D(GL_TEXTURE_2D,
1908 0, // level
[email protected]3a4d0c52011-06-29 23:11:581909 format,
[email protected]6217d392010-03-25 22:08:351910 0, 0,
1911 size.width(),
1912 size.height(),
1913 0); // border
1914}
1915
1916void Texture::Destroy() {
1917 if (id_ != 0) {
1918 ScopedGLErrorSuppressor suppressor(decoder_);
1919 glDeleteTextures(1, &id_);
1920 id_ = 0;
[email protected]6217d392010-03-25 22:08:351921 }
[email protected]68e81a4a62012-12-13 01:16:481922 memory_tracker_.TrackMemFree(bytes_allocated_);
1923 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351924}
1925
[email protected]97872062010-11-03 19:07:051926void Texture::Invalidate() {
1927 id_ = 0;
1928}
1929
[email protected]6217d392010-03-25 22:08:351930RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder)
1931 : decoder_(decoder),
[email protected]68e81a4a62012-12-13 01:16:481932 memory_tracker_(decoder->GetContextGroup()->memory_tracker(),
1933 MemoryTracker::kUnmanaged),
1934 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251935 id_(0) {
[email protected]6217d392010-03-25 22:08:351936}
1937
1938RenderBuffer::~RenderBuffer() {
1939 // This does not destroy the render buffer because that would require that
1940 // the associated GL context was current. Just check that it was explicitly
1941 // destroyed.
1942 DCHECK_EQ(id_, 0u);
1943}
1944
1945void RenderBuffer::Create() {
1946 ScopedGLErrorSuppressor suppressor(decoder_);
1947 Destroy();
1948 glGenRenderbuffersEXT(1, &id_);
1949}
1950
[email protected]34ff8b0c2010-10-01 20:06:021951bool RenderBuffer::AllocateStorage(const gfx::Size& size, GLenum format,
1952 GLsizei samples) {
[email protected]6217d392010-03-25 22:08:351953 ScopedGLErrorSuppressor suppressor(decoder_);
1954 ScopedRenderBufferBinder binder(decoder_, id_);
[email protected]34ff8b0c2010-10-01 20:06:021955 if (samples <= 1) {
1956 glRenderbufferStorageEXT(GL_RENDERBUFFER,
1957 format,
1958 size.width(),
1959 size.height());
1960 } else {
[email protected]57edfdad2012-02-07 04:57:151961 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021962 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
1963 samples,
1964 format,
1965 size.width(),
1966 size.height());
1967 } else {
1968 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
1969 samples,
1970 format,
1971 size.width(),
1972 size.height());
1973 }
1974 }
[email protected]1078f912011-12-23 13:12:141975 bool success = glGetError() == GL_NO_ERROR;
1976 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481977 memory_tracker_.TrackMemFree(bytes_allocated_);
1978 bytes_allocated_ =
[email protected]ff6493f2012-07-31 19:52:251979 size.width() * size.height() * samples *
[email protected]68e81a4a62012-12-13 01:16:481980 GLES2Util::RenderbufferBytesPerPixel(format);
1981 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141982 }
1983 return success;
[email protected]6217d392010-03-25 22:08:351984}
1985
1986void RenderBuffer::Destroy() {
1987 if (id_ != 0) {
1988 ScopedGLErrorSuppressor suppressor(decoder_);
1989 glDeleteRenderbuffersEXT(1, &id_);
1990 id_ = 0;
[email protected]6217d392010-03-25 22:08:351991 }
[email protected]68e81a4a62012-12-13 01:16:481992 memory_tracker_.TrackMemFree(bytes_allocated_);
1993 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351994}
1995
[email protected]97872062010-11-03 19:07:051996void RenderBuffer::Invalidate() {
1997 id_ = 0;
1998}
1999
[email protected]6217d392010-03-25 22:08:352000FrameBuffer::FrameBuffer(GLES2DecoderImpl* decoder)
2001 : decoder_(decoder),
2002 id_(0) {
2003}
2004
2005FrameBuffer::~FrameBuffer() {
2006 // This does not destroy the frame buffer because that would require that
2007 // the associated GL context was current. Just check that it was explicitly
2008 // destroyed.
2009 DCHECK_EQ(id_, 0u);
2010}
2011
2012void FrameBuffer::Create() {
2013 ScopedGLErrorSuppressor suppressor(decoder_);
2014 Destroy();
2015 glGenFramebuffersEXT(1, &id_);
2016}
2017
2018void FrameBuffer::AttachRenderTexture(Texture* texture) {
2019 DCHECK_NE(id_, 0u);
2020 ScopedGLErrorSuppressor suppressor(decoder_);
2021 ScopedFrameBufferBinder binder(decoder_, id_);
2022 GLuint attach_id = texture ? texture->id() : 0;
2023 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2024 GL_COLOR_ATTACHMENT0,
2025 GL_TEXTURE_2D,
2026 attach_id,
2027 0);
2028}
2029
[email protected]b9363b22010-06-09 22:06:152030void FrameBuffer::AttachRenderBuffer(GLenum target,
2031 RenderBuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352032 DCHECK_NE(id_, 0u);
2033 ScopedGLErrorSuppressor suppressor(decoder_);
2034 ScopedFrameBufferBinder binder(decoder_, id_);
2035 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2036 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152037 target,
[email protected]6217d392010-03-25 22:08:352038 GL_RENDERBUFFER,
2039 attach_id);
2040}
2041
[email protected]6217d392010-03-25 22:08:352042void FrameBuffer::Destroy() {
2043 if (id_ != 0) {
2044 ScopedGLErrorSuppressor suppressor(decoder_);
2045 glDeleteFramebuffersEXT(1, &id_);
2046 id_ = 0;
2047 }
2048}
2049
[email protected]97872062010-11-03 19:07:052050void FrameBuffer::Invalidate() {
2051 id_ = 0;
2052}
2053
[email protected]6217d392010-03-25 22:08:352054GLenum FrameBuffer::CheckStatus() {
2055 DCHECK_NE(id_, 0u);
2056 ScopedGLErrorSuppressor suppressor(decoder_);
2057 ScopedFrameBufferBinder binder(decoder_, id_);
2058 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2059}
2060
[email protected]aa7666122011-09-02 19:45:522061GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2062 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322063}
2064
[email protected]aa7666122011-09-02 19:45:522065GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392066 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572067 group_(group),
[email protected]b3cbad12012-12-05 19:56:362068 state_(group_->feature_info()),
[email protected]96449d2c2009-11-25 00:01:322069 error_bits_(0),
[email protected]43410e92012-04-20 17:06:282070 unpack_flip_y_(false),
2071 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172072 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242073 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492074 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242075 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402076 fixed_attrib_buffer_id_(0),
2077 fixed_attrib_buffer_size_(0),
[email protected]88a61bf2012-10-27 13:00:422078 clear_state_dirty_(true),
[email protected]34ff8b0c2010-10-01 20:06:022079 offscreen_target_color_format_(0),
2080 offscreen_target_depth_format_(0),
2081 offscreen_target_stencil_format_(0),
2082 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562083 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052084 offscreen_saved_color_format_(0),
[email protected]b0af4f52011-09-28 22:04:422085 stream_texture_manager_(NULL),
[email protected]32fe9aa2011-01-21 23:47:132086 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462087 back_buffer_has_depth_(false),
2088 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582089 backbuffer_needs_clear_bits_(0),
[email protected]473c01ccb2011-06-07 01:33:302090 teximage2d_faster_than_texsubimage2d_(true),
[email protected]0f8afe82012-05-14 23:43:012091 log_message_count_(0),
[email protected]a3a93e7b2010-08-28 00:48:562092 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052093 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112094 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002095 feature_info_(group_->feature_info()),
[email protected]65225772011-05-12 21:10:242096 tex_image_2d_failed_(false),
[email protected]38d139d2011-07-14 00:38:432097 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302098 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512099 reset_status_(GL_NO_ERROR),
[email protected]f0d74742011-10-03 16:31:042100 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102101 derivatives_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282102 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192103 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2104 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022105 viewport_max_width_(0),
2106 viewport_max_height_(0),
[email protected]63b465922012-09-06 02:04:522107 texture_upload_count_(0) {
[email protected]3b1ecc262011-08-03 22:49:572108 DCHECK(group);
2109
[email protected]d2a0e1a2012-08-12 02:25:012110 GLES2DecoderImpl* this_temp = this;
2111 this_in_hex_ = HexEncode(&this_temp, sizeof(this_temp));
2112
[email protected]b1122982010-05-17 23:04:242113 attrib_0_value_.v[0] = 0.0f;
2114 attrib_0_value_.v[1] = 0.0f;
2115 attrib_0_value_.v[2] = 0.0f;
2116 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152117
[email protected]c2f8c8402010-12-06 18:07:242118 // The shader translator is used for WebGL even when running on EGL
2119 // because additional restrictions are needed (like only enabling
2120 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562121 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2122 // the empty string to CompileShader and this is not a valid shader.
2123 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002124 CommandLine::ForCurrentProcess()->HasSwitch(
2125 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152126 use_shader_translator_ = false;
2127 }
[email protected]473c01ccb2011-06-07 01:33:302128
[email protected]a39370652012-09-25 21:52:132129 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:302130 if (IsAngle()) {
2131 teximage2d_faster_than_texsubimage2d_ = false;
[email protected]473c01ccb2011-06-07 01:33:302132 }
[email protected]96449d2c2009-11-25 00:01:322133}
2134
[email protected]80eb6b52012-01-19 00:14:412135GLES2DecoderImpl::~GLES2DecoderImpl() {
2136}
2137
[email protected]c410da802011-03-14 19:17:412138bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382139 const scoped_refptr<gfx::GLSurface>& surface,
2140 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232141 bool offscreen,
[email protected]c410da802011-03-14 19:17:412142 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292143 const DisallowedFeatures& disallowed_features,
[email protected]c410da802011-03-14 19:17:412144 const char* allowed_extensions,
[email protected]3c644d82011-06-20 19:58:242145 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322146 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382147 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302148 DCHECK(!context_.get());
2149
[email protected]e844ae22012-01-14 03:36:262150 if (CommandLine::ForCurrentProcess()->HasSwitch(
2151 switches::kEnableGPUDebugging)) {
2152 set_debug(true);
2153 }
2154
[email protected]39ba4f02012-03-26 01:16:002155 if (CommandLine::ForCurrentProcess()->HasSwitch(
2156 switches::kEnableGPUCommandLogging)) {
2157 set_log_commands(true);
2158 }
2159
[email protected]062c38b2012-01-18 03:25:102160 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2161 switches::kCompileShaderAlwaysSucceeds);
2162
[email protected]f62a5ab2011-05-23 20:34:152163
[email protected]63c9b052012-05-17 18:27:382164 // Take ownership of the context and surface. The surface can be replaced with
2165 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382166 context_ = context;
[email protected]63c9b052012-05-17 18:27:382167 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182168
[email protected]c4485aad62012-12-17 10:19:092169 if (!group_->Initialize(this, disallowed_features, allowed_extensions)) {
[email protected]09ddb91f2011-04-14 23:16:222170 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392171 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422172 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382173 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032174 return false;
[email protected]a3ded6d2010-10-19 06:44:392175 }
[email protected]b64c24952012-04-19 03:20:272176 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282177
[email protected]e82fb792011-09-22 00:33:292178 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502179
[email protected]af6380962012-11-29 23:24:132180 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462181 default_vertex_attrib_manager_ = new VertexAttribManager();
2182 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2183
[email protected]ab4fd7282012-10-12 16:25:572184 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2185 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322186
[email protected]d6ca4792012-05-14 19:24:132187 query_manager_.reset(new QueryManager(this, feature_info_));
[email protected]944b62f32012-09-27 02:20:462188 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532189
[email protected]302ce6d2011-07-07 23:28:112190 util_.set_num_compressed_texture_formats(
2191 validators_->compressed_texture_format.GetValues().size());
2192
[email protected]1071e572011-02-09 20:00:122193 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2194 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2195 // OpenGL ES 2.0 does not have this issue.
2196 glEnableVertexAttribArray(0);
2197 }
[email protected]b1122982010-05-17 23:04:242198 glGenBuffersARB(1, &attrib_0_buffer_id_);
2199 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2200 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2201 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402202 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082203
[email protected]1868a342012-11-07 15:56:022204 state_.texture_units.resize(group_->max_texture_units());
2205 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492206 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312207 // We want the last bind to be 2D.
2208 TextureManager::TextureInfo* info;
[email protected]62e155e2012-10-23 22:43:152209 if (features().oes_egl_image_external) {
[email protected]61eeb33f2011-07-26 15:30:312210 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_EXTERNAL_OES);
[email protected]e259eb412012-10-13 05:47:242211 state_.texture_units[tt].bound_texture_external_oes = info;
[email protected]61eeb33f2011-07-26 15:30:312212 glBindTexture(GL_TEXTURE_EXTERNAL_OES, info->service_id());
2213 }
[email protected]62e155e2012-10-23 22:43:152214 if (features().arb_texture_rectangle) {
[email protected]e51bdf32011-11-23 22:21:462215 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_RECTANGLE_ARB);
[email protected]e259eb412012-10-13 05:47:242216 state_.texture_units[tt].bound_texture_rectangle_arb = info;
[email protected]e51bdf32011-11-23 22:21:462217 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, info->service_id());
2218 }
[email protected]61eeb33f2011-07-26 15:30:312219 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
[email protected]e259eb412012-10-13 05:47:242220 state_.texture_units[tt].bound_texture_cube_map = info;
[email protected]00f893d2010-08-24 18:55:492221 glBindTexture(GL_TEXTURE_CUBE_MAP, info->service_id());
2222 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
[email protected]e259eb412012-10-13 05:47:242223 state_.texture_units[tt].bound_texture_2d = info;
[email protected]00f893d2010-08-24 18:55:492224 glBindTexture(GL_TEXTURE_2D, info->service_id());
[email protected]1958e0e2010-04-22 05:17:152225 }
[email protected]00f893d2010-08-24 18:55:492226 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502227 CHECK_GL_ERROR();
2228
[email protected]297ca1c2011-06-20 23:08:462229 ContextCreationAttribParser attrib_parser;
2230 if (!attrib_parser.Parse(attribs))
2231 return false;
[email protected]41c56362011-06-14 16:47:432232
[email protected]297ca1c2011-06-20 23:08:462233 // These are NOT if the back buffer has these proprorties. They are
2234 // if we want the command buffer to enforce them regardless of what
2235 // the real backbuffer is assuming the real back buffer gives us more than
2236 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2237 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2238 // can't do anything about that.
2239
2240 GLint v = 0;
2241 glGetIntegerv(GL_ALPHA_BITS, &v);
2242 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2243 // user requested RGB then RGB. If the user did not specify a preference than
2244 // use whatever we were given. Same for DEPTH and STENCIL.
2245 back_buffer_color_format_ =
2246 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2247 glGetIntegerv(GL_DEPTH_BITS, &v);
2248 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2249 glGetIntegerv(GL_STENCIL_BITS, &v);
2250 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
2251
[email protected]069944672012-04-25 20:52:232252 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022253 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542254 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022255 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432256 // max_sample_count must be initialized to a sane value. If
2257 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2258 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022259 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2260 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2261 max_sample_count);
2262 } else {
2263 offscreen_target_samples_ = 1;
2264 }
[email protected]8a61d872012-01-20 12:43:562265 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022266
2267 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2268 const bool rgb8_supported =
2269 context_->HasExtension("GL_OES_rgb8_rgba8");
2270 // The only available default render buffer formats in GLES2 have very
2271 // little precision. Don't enable multisampling unless 8-bit render
2272 // buffer formats are available--instead fall back to 8-bit textures.
2273 if (rgb8_supported && offscreen_target_samples_ > 1) {
2274 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2275 GL_RGBA8 : GL_RGB8;
2276 } else {
2277 offscreen_target_samples_ = 1;
2278 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2279 GL_RGBA : GL_RGB;
2280 }
2281
2282 // ANGLE only supports packed depth/stencil formats, so use it if it is
2283 // available.
2284 const bool depth24_stencil8_supported =
2285 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272286 VLOG(1) << "GL_OES_packed_depth_stencil "
2287 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002288 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2289 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022290 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2291 offscreen_target_stencil_format_ = 0;
2292 } else {
2293 // It may be the case that this depth/stencil combination is not
2294 // supported, but this will be checked later by CheckFramebufferStatus.
2295 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2296 GL_DEPTH_COMPONENT16 : 0;
2297 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2298 GL_STENCIL_INDEX8 : 0;
2299 }
2300 } else {
2301 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2302 GL_RGBA : GL_RGB;
2303
2304 // If depth is requested at all, use the packed depth stencil format if
2305 // it's available, as some desktop GL drivers don't support any non-packed
2306 // formats for depth attachments.
2307 const bool depth24_stencil8_supported =
2308 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272309 VLOG(1) << "GL_EXT_packed_depth_stencil "
2310 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022311
[email protected]71ee3642010-10-14 18:08:002312 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2313 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022314 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2315 offscreen_target_stencil_format_ = 0;
2316 } else {
2317 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2318 GL_DEPTH_COMPONENT : 0;
2319 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2320 GL_STENCIL_INDEX : 0;
2321 }
2322 }
2323
[email protected]97872062010-11-03 19:07:052324 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2325 GL_RGBA : GL_RGB;
2326
[email protected]6217d392010-03-25 22:08:352327 // Create the target frame buffer. This is the one that the client renders
2328 // directly to.
2329 offscreen_target_frame_buffer_.reset(new FrameBuffer(this));
2330 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022331 // Due to GLES2 format limitations, either the color texture (for
2332 // non-multisampling) or the color render buffer (for multisampling) will be
2333 // attached to the offscreen frame buffer. The render buffer has more
2334 // limited formats available to it, but the texture can't do multisampling.
2335 if (IsOffscreenBufferMultisampled()) {
2336 offscreen_target_color_render_buffer_.reset(new RenderBuffer(this));
2337 offscreen_target_color_render_buffer_->Create();
2338 } else {
2339 offscreen_target_color_texture_.reset(new Texture(this));
2340 offscreen_target_color_texture_->Create();
2341 }
2342 offscreen_target_depth_render_buffer_.reset(new RenderBuffer(this));
[email protected]b9363b22010-06-09 22:06:152343 offscreen_target_depth_render_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022344 offscreen_target_stencil_render_buffer_.reset(new RenderBuffer(this));
[email protected]b9363b22010-06-09 22:06:152345 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352346
2347 // Create the saved offscreen texture. The target frame buffer is copied
2348 // here when SwapBuffers is called.
[email protected]34ff8b0c2010-10-01 20:06:022349 offscreen_saved_frame_buffer_.reset(new FrameBuffer(this));
2350 offscreen_saved_frame_buffer_->Create();
2351 //
[email protected]6217d392010-03-25 22:08:352352 offscreen_saved_color_texture_.reset(new Texture(this));
2353 offscreen_saved_color_texture_->Create();
2354
[email protected]6217d392010-03-25 22:08:352355 // Allocate the render buffers at their initial size and check the status
2356 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592357 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012358 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382359 Destroy(true);
[email protected]6217d392010-03-25 22:08:352360 return false;
2361 }
2362
[email protected]678a73f2012-12-19 19:22:092363 // Allocate the offscreen saved color texture.
2364 DCHECK(offscreen_saved_color_format_);
2365 offscreen_saved_color_texture_->AllocateStorage(
2366 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2367
2368 offscreen_saved_frame_buffer_->AttachRenderTexture(
2369 offscreen_saved_color_texture_.get());
2370 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2371 GL_FRAMEBUFFER_COMPLETE) {
2372 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2373 Destroy(true);
2374 return false;
2375 }
2376
[email protected]6217d392010-03-25 22:08:352377 // Bind to the new default frame buffer (the offscreen target frame buffer).
2378 // This should now be associated with ID zero.
2379 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2380 }
2381
[email protected]295faf4b2012-01-25 23:31:412382 // Clear the backbuffer.
2383 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2384
[email protected]76a0ee102010-04-07 21:03:042385 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2386 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2387 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372388 // mailing list archives. It also implicitly enables the desktop GL
2389 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2390 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152391 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2392 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372393 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152394 }
[email protected]de17df392010-04-23 21:09:412395
[email protected]706b69f2012-07-27 04:59:302396 has_robustness_extension_ =
2397 context->HasExtension("GL_ARB_robustness") ||
2398 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432399
[email protected]c2f8c8402010-12-06 18:07:242400 if (!InitializeShaderTranslator()) {
2401 return false;
[email protected]de17df392010-04-23 21:09:412402 }
[email protected]76a0ee102010-04-07 21:03:042403
[email protected]e259eb412012-10-13 05:47:242404 state_.viewport_width = size.width();
2405 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282406
[email protected]5904806b2012-05-08 18:10:222407 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282408 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022409 viewport_max_width_ = viewport_params[0];
2410 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282411
[email protected]88a61bf2012-10-27 13:00:422412 state_.scissor_width = state_.viewport_width;
2413 state_.scissor_height = state_.viewport_height;
2414
[email protected]11f3e702012-06-19 19:00:012415 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222416 state_.InitCapabilities();
2417 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242418 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]88a61bf2012-10-27 13:00:422419 glHint(GL_GENERATE_MIPMAP_HINT, state_.hint_generate_mipmap);
[email protected]e259eb412012-10-13 05:47:242420 glPixelStorei(GL_PACK_ALIGNMENT, state_.pack_alignment);
[email protected]e259eb412012-10-13 05:47:242421 glPixelStorei(GL_UNPACK_ALIGNMENT, state_.unpack_alignment);
[email protected]11f3e702012-06-19 19:00:012422
2423 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2424 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2425 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2426 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2427
[email protected]6d9374e2012-07-17 03:31:242428 // AMD and Intel drivers on Mac OS apparently get gl_PointCoord
2429 // backward from the spec and this setting makes them work
2430 // correctly. rdar://problem/11883495
[email protected]62e155e2012-10-23 22:43:152431 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462432 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2433 }
[email protected]dd289a5d62012-06-30 22:05:462434
[email protected]32145a92012-12-17 09:01:592435 // Create a delegate to perform async pixel transfers.
2436 async_pixel_transfer_delegate_ =
2437 gfx::AsyncPixelTransferDelegate::Create(context.get());
2438
[email protected]246a70452010-03-05 21:53:502439 return true;
[email protected]96449d2c2009-11-25 00:01:322440}
2441
[email protected]302ce6d2011-07-07 23:28:112442void GLES2DecoderImpl::UpdateCapabilities() {
2443 util_.set_num_compressed_texture_formats(
2444 validators_->compressed_texture_format.GetValues().size());
2445 util_.set_num_shader_binary_formats(
2446 validators_->shader_binary_format.GetValues().size());
2447}
2448
[email protected]c2f8c8402010-12-06 18:07:242449bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442450 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2451
[email protected]c2f8c8402010-12-06 18:07:242452 if (!use_shader_translator_) {
2453 return true;
2454 }
2455 ShBuiltInResources resources;
2456 ShInitBuiltInResources(&resources);
2457 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2458 resources.MaxVertexUniformVectors =
2459 group_->max_vertex_uniform_vectors();
2460 resources.MaxVaryingVectors = group_->max_varying_vectors();
2461 resources.MaxVertexTextureImageUnits =
2462 group_->max_vertex_texture_image_units();
2463 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2464 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2465 resources.MaxFragmentUniformVectors =
2466 group_->max_fragment_uniform_vectors();
2467 resources.MaxDrawBuffers = 1;
[email protected]f0d74742011-10-03 16:31:042468
2469 if (force_webgl_glsl_validation_) {
2470 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
2471 } else {
2472 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152473 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462474 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152475 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062476 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152477 features().oes_egl_image_external ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042478 }
2479
[email protected]693ca512012-11-13 18:09:132480 if (features().enable_shader_name_hashing)
2481 resources.HashFunction = &CityHashForAngle;
2482
[email protected]f0d74742011-10-03 16:31:042483 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ||
[email protected]4b7eba92013-01-08 02:23:562484 force_webgl_glsl_validation_ ? SH_WEBGL_SPEC : SH_GLES2_SPEC;
[email protected]a2a0fe762011-09-20 00:59:122485 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2486 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2487 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2488 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
[email protected]62e155e2012-10-23 22:43:152489 workarounds().needs_glsl_built_in_function_emulation ?
[email protected]a2a0fe762011-09-20 00:59:122490 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
2491 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
[email protected]87fb6ab2012-06-13 22:28:042492
2493 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2494 vertex_translator_ = cache->GetTranslator(
2495 SH_VERTEX_SHADER, shader_spec, &resources,
2496 implementation_type, function_behavior);
2497 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242498 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382499 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242500 return false;
2501 }
[email protected]87fb6ab2012-06-13 22:28:042502
2503 fragment_translator_ = cache->GetTranslator(
2504 SH_FRAGMENT_SHADER, shader_spec, &resources,
2505 implementation_type, function_behavior);
2506 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242507 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382508 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242509 return false;
2510 }
2511 return true;
2512}
2513
[email protected]ae51d192010-04-27 00:48:032514bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472515 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ae51d192010-04-27 00:48:032516 if (GetBufferInfo(client_ids[ii])) {
2517 return false;
2518 }
2519 }
2520 scoped_array<GLuint> service_ids(new GLuint[n]);
2521 glGenBuffersARB(n, service_ids.get());
2522 for (GLsizei ii = 0; ii < n; ++ii) {
2523 CreateBufferInfo(client_ids[ii], service_ids[ii]);
2524 }
2525 return true;
2526}
2527
2528bool GLES2DecoderImpl::GenFramebuffersHelper(
2529 GLsizei n, const GLuint* client_ids) {
2530 for (GLsizei ii = 0; ii < n; ++ii) {
2531 if (GetFramebufferInfo(client_ids[ii])) {
2532 return false;
2533 }
2534 }
2535 scoped_array<GLuint> service_ids(new GLuint[n]);
2536 glGenFramebuffersEXT(n, service_ids.get());
2537 for (GLsizei ii = 0; ii < n; ++ii) {
2538 CreateFramebufferInfo(client_ids[ii], service_ids[ii]);
2539 }
2540 return true;
2541}
2542
2543bool GLES2DecoderImpl::GenRenderbuffersHelper(
2544 GLsizei n, const GLuint* client_ids) {
2545 for (GLsizei ii = 0; ii < n; ++ii) {
2546 if (GetRenderbufferInfo(client_ids[ii])) {
2547 return false;
2548 }
2549 }
2550 scoped_array<GLuint> service_ids(new GLuint[n]);
2551 glGenRenderbuffersEXT(n, service_ids.get());
2552 for (GLsizei ii = 0; ii < n; ++ii) {
2553 CreateRenderbufferInfo(client_ids[ii], service_ids[ii]);
2554 }
2555 return true;
2556}
2557
2558bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2559 for (GLsizei ii = 0; ii < n; ++ii) {
2560 if (GetTextureInfo(client_ids[ii])) {
2561 return false;
2562 }
2563 }
2564 scoped_array<GLuint> service_ids(new GLuint[n]);
2565 glGenTextures(n, service_ids.get());
2566 for (GLsizei ii = 0; ii < n; ++ii) {
2567 CreateTextureInfo(client_ids[ii], service_ids[ii]);
2568 }
2569 return true;
2570}
2571
2572void GLES2DecoderImpl::DeleteBuffersHelper(
2573 GLsizei n, const GLuint* client_ids) {
2574 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102575 BufferManager::BufferInfo* buffer = GetBufferInfo(client_ids[ii]);
2576 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242577 state_.vertex_attrib_manager->Unbind(buffer);
2578 if (state_.bound_array_buffer == buffer) {
2579 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102580 }
[email protected]ae51d192010-04-27 00:48:032581 RemoveBufferInfo(client_ids[ii]);
2582 }
[email protected]a93bb842010-02-16 23:03:472583 }
[email protected]07f54fcc2009-12-22 02:46:302584}
2585
[email protected]ae51d192010-04-27 00:48:032586void GLES2DecoderImpl::DeleteFramebuffersHelper(
2587 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452588 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152589 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112590
[email protected]a25fa872010-03-25 02:57:582591 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102592 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ae51d192010-04-27 00:48:032593 GetFramebufferInfo(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102594 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242595 if (framebuffer == state_.bound_draw_framebuffer) {
2596 state_.bound_draw_framebuffer = NULL;
[email protected]88a61bf2012-10-27 13:00:422597 clear_state_dirty_ = true;
[email protected]ebfb73c2012-08-15 02:37:452598 GLenum target = supports_separate_framebuffer_binds ?
2599 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112600 glBindFramebufferEXT(target, GetBackbufferServiceId());
2601 }
[email protected]e259eb412012-10-13 05:47:242602 if (framebuffer == state_.bound_read_framebuffer) {
2603 state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452604 GLenum target = supports_separate_framebuffer_binds ?
2605 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112606 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462607 }
[email protected]ae51d192010-04-27 00:48:032608 RemoveFramebufferInfo(client_ids[ii]);
2609 }
[email protected]a25fa872010-03-25 02:57:582610 }
[email protected]07f54fcc2009-12-22 02:46:302611}
2612
[email protected]ae51d192010-04-27 00:48:032613void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2614 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452615 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152616 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582617 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102618 RenderbufferManager::RenderbufferInfo* renderbuffer =
[email protected]ae51d192010-04-27 00:48:032619 GetRenderbufferInfo(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102620 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242621 if (state_.bound_renderbuffer == renderbuffer) {
2622 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102623 }
2624 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452625 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242626 if (state_.bound_read_framebuffer) {
2627 state_.bound_read_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452628 GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102629 }
[email protected]e259eb412012-10-13 05:47:242630 if (state_.bound_draw_framebuffer) {
2631 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452632 GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102633 }
2634 } else {
[email protected]e259eb412012-10-13 05:47:242635 if (state_.bound_draw_framebuffer) {
2636 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]a0b78dc2011-11-11 10:43:102637 GL_FRAMEBUFFER, renderbuffer);
2638 }
2639 }
[email protected]88a61bf2012-10-27 13:00:422640 clear_state_dirty_ = true;
[email protected]ae51d192010-04-27 00:48:032641 RemoveRenderbufferInfo(client_ids[ii]);
2642 }
[email protected]a25fa872010-03-25 02:57:582643 }
[email protected]07f54fcc2009-12-22 02:46:302644}
2645
[email protected]ae51d192010-04-27 00:48:032646void GLES2DecoderImpl::DeleteTexturesHelper(
2647 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452648 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152649 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472650 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]a0b78dc2011-11-11 10:43:102651 TextureManager::TextureInfo* texture = GetTextureInfo(client_ids[ii]);
2652 if (texture && !texture->IsDeleted()) {
2653 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:422654 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462655 }
[email protected]a0b78dc2011-11-11 10:43:102656 // Unbind texture from texture units.
[email protected]1868a342012-11-07 15:56:022657 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]e259eb412012-10-13 05:47:242658 state_.texture_units[jj].Unbind(texture);
[email protected]a0b78dc2011-11-11 10:43:102659 }
2660 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452661 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242662 if (state_.bound_read_framebuffer) {
2663 state_.bound_read_framebuffer->UnbindTexture(
[email protected]ebfb73c2012-08-15 02:37:452664 GL_READ_FRAMEBUFFER_EXT, texture);
[email protected]a0b78dc2011-11-11 10:43:102665 }
[email protected]e259eb412012-10-13 05:47:242666 if (state_.bound_draw_framebuffer) {
2667 state_.bound_draw_framebuffer->UnbindTexture(
[email protected]ebfb73c2012-08-15 02:37:452668 GL_DRAW_FRAMEBUFFER_EXT, texture);
[email protected]a0b78dc2011-11-11 10:43:102669 }
2670 } else {
[email protected]e259eb412012-10-13 05:47:242671 if (state_.bound_draw_framebuffer) {
2672 state_.bound_draw_framebuffer->UnbindTexture(GL_FRAMEBUFFER, texture);
[email protected]a0b78dc2011-11-11 10:43:102673 }
2674 }
2675 GLuint service_id = texture->service_id();
2676 if (texture->IsStreamTexture() && stream_texture_manager_) {
[email protected]b0af4f52011-09-28 22:04:422677 stream_texture_manager_->DestroyStreamTexture(service_id);
2678 }
[email protected]e51bdf32011-11-23 22:21:462679#if defined(OS_MACOSX)
2680 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2681 ReleaseIOSurfaceForTexture(service_id);
2682 }
2683#endif
[email protected]ae51d192010-04-27 00:48:032684 RemoveTextureInfo(client_ids[ii]);
2685 }
[email protected]a93bb842010-02-16 23:03:472686 }
[email protected]07f54fcc2009-12-22 02:46:302687}
2688
[email protected]43f28f832010-02-03 02:28:482689// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322690
[email protected]eb54a562010-01-20 21:55:182691bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382692 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2693 return false;
2694
2695 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432696 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]63c9b052012-05-17 18:27:382697 return false;
[email protected]38d139d2011-07-14 00:38:432698 }
2699
[email protected]32145a92012-12-17 09:01:592700 // TODO(epenner): Is there a better place to do this? Transfers
2701 // can complete any time we yield the main thread. So we *must*
2702 // process transfers after any such yield, before resuming.
2703 bool frame_buffer_dirty = false;
2704 bool texture_dirty = false;
2705 texture_manager()->BindFinishedAsyncPixelTransfers(
2706 &texture_dirty, &frame_buffer_dirty);
2707 // Texture unit zero might be stomped.
2708 if (texture_dirty)
2709 RestoreCurrentTexture2DBindings();
2710 // A texture attached to frame-buffer might have changed size.
2711 if (frame_buffer_dirty) {
2712 clear_state_dirty_ = true;
2713 // TODO(gman): If textures tracked which framebuffers they were attached to
2714 // we could just mark those framebuffers as not complete.
2715 framebuffer_manager()->IncFramebufferStateChangeCount();
2716 }
2717
[email protected]63c9b052012-05-17 18:27:382718 return true;
[email protected]eb54a562010-01-20 21:55:182719}
2720
[email protected]a96a6022011-11-04 00:58:122721void GLES2DecoderImpl::ReleaseCurrent() {
2722 if (context_.get())
2723 context_->ReleaseCurrent(surface_.get());
2724}
2725
[email protected]8e3e0662010-08-23 18:46:302726void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
[email protected]0d6bfdc2011-11-02 01:32:202727 RenderbufferManager::RenderbufferInfo* renderbuffer =
2728 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
[email protected]8e3e0662010-08-23 18:46:302729 glBindRenderbufferEXT(
[email protected]0d6bfdc2011-11-02 01:32:202730 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
[email protected]8e3e0662010-08-23 18:46:302731}
2732
2733static void RebindCurrentFramebuffer(
2734 GLenum target,
2735 FramebufferManager::FramebufferInfo* info,
[email protected]a3783712012-01-20 22:18:242736 GLuint back_buffer_service_id) {
[email protected]8e3e0662010-08-23 18:46:302737 GLuint framebuffer_id = info ? info->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462738
[email protected]a3783712012-01-20 22:18:242739 if (framebuffer_id == 0) {
2740 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302741 }
[email protected]297ca1c2011-06-20 23:08:462742
[email protected]8e3e0662010-08-23 18:46:302743 glBindFramebufferEXT(target, framebuffer_id);
2744}
2745
2746void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]88a61bf2012-10-27 13:00:422747 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462748
[email protected]62e155e2012-10-23 22:43:152749 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302750 RebindCurrentFramebuffer(
2751 GL_FRAMEBUFFER,
[email protected]e259eb412012-10-13 05:47:242752 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242753 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302754 } else {
2755 RebindCurrentFramebuffer(
2756 GL_READ_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242757 state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242758 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302759 RebindCurrentFramebuffer(
2760 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242761 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242762 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302763 }
2764}
2765
2766void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
[email protected]e259eb412012-10-13 05:47:242767 TextureUnit& info = state_.texture_units[0];
[email protected]8e3e0662010-08-23 18:46:302768 GLuint last_id;
2769 if (info.bound_texture_2d) {
2770 last_id = info.bound_texture_2d->service_id();
2771 } else {
2772 last_id = 0;
2773 }
2774
2775 glBindTexture(GL_TEXTURE_2D, last_id);
[email protected]e259eb412012-10-13 05:47:242776 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]8e3e0662010-08-23 18:46:302777}
2778
[email protected]0d6bfdc2011-11-02 01:32:202779bool GLES2DecoderImpl::CheckFramebufferValid(
2780 FramebufferManager::FramebufferInfo* framebuffer,
2781 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102782 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582783 if (backbuffer_needs_clear_bits_) {
2784 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2785 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2786 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2787 glClearStencil(0);
2788 glStencilMask(-1);
2789 glClearDepth(1.0f);
2790 glDepthMask(true);
2791 glDisable(GL_SCISSOR_TEST);
2792 glClear(backbuffer_needs_clear_bits_);
2793 backbuffer_needs_clear_bits_ = 0;
2794 RestoreClearState();
2795 }
[email protected]0d6bfdc2011-11-02 01:32:202796 return true;
2797 }
2798
[email protected]968351b2011-12-20 08:26:512799 if (framebuffer_manager()->IsComplete(framebuffer)) {
2800 return true;
2801 }
2802
[email protected]0d6bfdc2011-11-02 01:32:202803 GLenum completeness = framebuffer->IsPossiblyComplete();
2804 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
2805 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:432806 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272807 return false;
2808 }
[email protected]0d6bfdc2011-11-02 01:32:202809
2810 // Are all the attachments cleared?
2811 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2812 texture_manager()->HaveUnclearedMips()) {
2813 if (!framebuffer->IsCleared()) {
2814 // Can we clear them?
[email protected]73276522012-11-09 05:50:202815 if (framebuffer->GetStatus(texture_manager(), target) !=
2816 GL_FRAMEBUFFER_COMPLETE) {
[email protected]0d6bfdc2011-11-02 01:32:202817 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:432818 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2819 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202820 return false;
2821 }
2822 ClearUnclearedAttachments(target, framebuffer);
2823 }
2824 }
2825
[email protected]968351b2011-12-20 08:26:512826 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202827 if (framebuffer->GetStatus(texture_manager(), target) !=
2828 GL_FRAMEBUFFER_COMPLETE) {
[email protected]968351b2011-12-20 08:26:512829 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:432830 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2831 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512832 return false;
2833 }
2834 framebuffer_manager()->MarkAsComplete(framebuffer);
2835 }
2836
[email protected]0d6bfdc2011-11-02 01:32:202837 // NOTE: At this point we don't know if the framebuffer is complete but
2838 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272839 return true;
2840}
2841
[email protected]0d6bfdc2011-11-02 01:32:202842bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:152843 if (!features().chromium_framebuffer_multisample) {
[email protected]0d6bfdc2011-11-02 01:32:202844 return CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242845 state_.bound_draw_framebuffer, GL_FRAMEBUFFER_EXT, func_name);
[email protected]0d6bfdc2011-11-02 01:32:202846 }
2847 return CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242848 state_.bound_draw_framebuffer,
2849 GL_DRAW_FRAMEBUFFER_EXT, func_name) &&
[email protected]0d6bfdc2011-11-02 01:32:202850 CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242851 state_.bound_read_framebuffer,
2852 GL_READ_FRAMEBUFFER_EXT, func_name);
[email protected]0d6bfdc2011-11-02 01:32:202853}
2854
[email protected]8e3e0662010-08-23 18:46:302855gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]0d6bfdc2011-11-02 01:32:202856 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452857 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202858 if (framebuffer != NULL) {
[email protected]9edc6b22010-12-23 02:00:262859 const FramebufferManager::FramebufferInfo::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:202860 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:262861 if (attachment) {
2862 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:502863 }
[email protected]9edc6b22010-12-23 02:00:262864 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:022865 } else if (offscreen_target_frame_buffer_.get()) {
2866 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:352867 } else {
[email protected]f62a5ab2011-05-23 20:34:152868 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:022869 }
[email protected]246a70452010-03-05 21:53:502870}
2871
[email protected]9edc6b22010-12-23 02:00:262872GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]0d6bfdc2011-11-02 01:32:202873 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452874 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202875 if (framebuffer != NULL) {
2876 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:462877 } else if (offscreen_target_frame_buffer_.get()) {
2878 return offscreen_target_color_format_;
2879 } else {
2880 return back_buffer_color_format_;
2881 }
2882}
2883
2884GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]0d6bfdc2011-11-02 01:32:202885 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452886 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202887 if (framebuffer != NULL) {
2888 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:262889 } else if (offscreen_target_frame_buffer_.get()) {
2890 return offscreen_target_color_format_;
2891 } else {
[email protected]32fe9aa2011-01-21 23:47:132892 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:262893 }
2894}
2895
[email protected]9a5afa432011-07-22 18:16:392896void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]34ff8b0c2010-10-01 20:06:022897 if (parent_) {
[email protected]2f2d7042010-04-14 21:45:582898 // Update the info about the offscreen saved color texture in the parent.
2899 // The reference to the parent is a weak pointer and will become null if the
2900 // parent is later destroyed.
[email protected]262d7aa2010-12-03 22:07:292901 TextureManager* parent_texture_manager = parent_->texture_manager();
[email protected]262d7aa2010-12-03 22:07:292902 parent_texture_manager->SetLevelInfo(
[email protected]8a61d872012-01-20 12:43:562903 offscreen_saved_color_texture_info_,
[email protected]ef526492010-06-02 23:12:252904 GL_TEXTURE_2D,
2905 0, // level
2906 GL_RGBA,
[email protected]799b4b22011-08-22 17:09:592907 offscreen_size_.width(),
2908 offscreen_size_.height(),
[email protected]ef526492010-06-02 23:12:252909 1, // depth
2910 0, // border
2911 GL_RGBA,
[email protected]0d6bfdc2011-11-02 01:32:202912 GL_UNSIGNED_BYTE,
2913 true);
[email protected]262d7aa2010-12-03 22:07:292914 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562915 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042916 GL_TEXTURE_MAG_FILTER,
2917 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:292918 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562919 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042920 GL_TEXTURE_MIN_FILTER,
2921 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:292922 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562923 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042924 GL_TEXTURE_WRAP_S,
2925 GL_CLAMP_TO_EDGE);
[email protected]262d7aa2010-12-03 22:07:292926 parent_texture_manager->SetParameter(
[email protected]8a61d872012-01-20 12:43:562927 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042928 GL_TEXTURE_WRAP_T,
2929 GL_CLAMP_TO_EDGE);
[email protected]8a61d872012-01-20 12:43:562930 } else {
2931 offscreen_saved_color_texture_info_ = NULL;
[email protected]0c8c9d22010-06-25 17:36:392932 }
[email protected]6217d392010-03-25 22:08:352933}
2934
[email protected]799b4b22011-08-22 17:09:592935void GLES2DecoderImpl::SetResizeCallback(
[email protected]9d37f062011-11-22 01:24:522936 const base::Callback<void(gfx::Size)>& callback) {
2937 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:002938}
2939
[email protected]6b6e7ee2011-12-13 08:04:522940void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) {
2941 msg_callback_ = callback;
2942}
2943
[email protected]b0af4f52011-09-28 22:04:422944void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) {
2945 stream_texture_manager_ = manager;
2946}
2947
[email protected]32145a92012-12-17 09:01:592948gfx::AsyncPixelTransferDelegate*
2949 GLES2DecoderImpl::GetAsyncPixelTransferDelegate() {
2950 return async_pixel_transfer_delegate_.get();
2951}
2952
2953void GLES2DecoderImpl::SetAsyncPixelTransferDelegate(
2954 gfx::AsyncPixelTransferDelegate* delegate) {
2955 async_pixel_transfer_delegate_ = make_scoped_ptr(delegate);
2956}
2957
[email protected]1318e922010-09-17 22:03:162958bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
2959 uint32* service_texture_id) {
2960 TextureManager::TextureInfo* texture =
2961 texture_manager()->GetTextureInfo(client_texture_id);
2962 if (texture) {
2963 *service_texture_id = texture->service_id();
2964 return true;
2965 }
2966 return false;
2967}
2968
[email protected]63b465922012-09-06 02:04:522969uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]b9804322013-01-08 17:54:122970 return texture_upload_count_ +
2971 async_pixel_transfer_delegate_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:522972}
2973
2974base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]b9804322013-01-08 17:54:122975 return total_texture_upload_time_ +
2976 async_pixel_transfer_delegate_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:522977}
2978
2979base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
2980 return total_processing_commands_time_;
2981}
2982
[email protected]dc25dda2012-09-27 21:36:302983void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
2984 total_processing_commands_time_ += time;
2985}
2986
[email protected]63c9b052012-05-17 18:27:382987void GLES2DecoderImpl::Destroy(bool have_context) {
2988 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:052989
[email protected]c826d732012-02-09 04:40:262990 ChildList children = children_;
2991 for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
2992 (*it)->SetParent(NULL, 0);
2993 DCHECK(children_.empty());
[email protected]3c644d82011-06-20 19:58:242994 SetParent(NULL, 0);
2995
[email protected]80eb6b52012-01-19 00:14:412996 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:242997 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:462998 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:022999 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243000 state_.bound_array_buffer = NULL;
3001 state_.current_query = NULL;
3002 state_.current_program = NULL;
3003 state_.bound_read_framebuffer = NULL;
3004 state_.bound_draw_framebuffer = NULL;
3005 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413006
[email protected]eadc96792010-10-27 19:39:393007 if (have_context) {
[email protected]c322e882012-05-23 18:06:183008 if (copy_texture_CHROMIUM_.get()) {
3009 copy_texture_CHROMIUM_->Destroy();
3010 copy_texture_CHROMIUM_.reset();
3011 }
[email protected]43410e92012-04-20 17:06:283012
[email protected]e259eb412012-10-13 05:47:243013 if (state_.current_program) {
3014 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
3015 state_.current_program = NULL;
[email protected]ca488e12010-12-13 20:06:143016 }
3017
[email protected]b1122982010-05-17 23:04:243018 if (attrib_0_buffer_id_) {
3019 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3020 }
[email protected]8fbedc02010-11-18 18:43:403021 if (fixed_attrib_buffer_id_) {
3022 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3023 }
[email protected]b1122982010-05-17 23:04:243024
[email protected]97872062010-11-03 19:07:053025 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543026 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053027 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543028 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053029 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023030 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053031 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153032 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053033 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153034 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053035 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023036 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053037 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543038 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273039 if (offscreen_resolved_frame_buffer_.get())
3040 offscreen_resolved_frame_buffer_->Destroy();
3041 if (offscreen_resolved_color_texture_.get())
3042 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053043 } else {
3044 if (offscreen_target_frame_buffer_.get())
3045 offscreen_target_frame_buffer_->Invalidate();
3046 if (offscreen_target_color_texture_.get())
3047 offscreen_target_color_texture_->Invalidate();
3048 if (offscreen_target_color_render_buffer_.get())
3049 offscreen_target_color_render_buffer_->Invalidate();
3050 if (offscreen_target_depth_render_buffer_.get())
3051 offscreen_target_depth_render_buffer_->Invalidate();
3052 if (offscreen_target_stencil_render_buffer_.get())
3053 offscreen_target_stencil_render_buffer_->Invalidate();
3054 if (offscreen_saved_frame_buffer_.get())
3055 offscreen_saved_frame_buffer_->Invalidate();
3056 if (offscreen_saved_color_texture_.get())
3057 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273058 if (offscreen_resolved_frame_buffer_.get())
3059 offscreen_resolved_frame_buffer_->Invalidate();
3060 if (offscreen_resolved_color_texture_.get())
3061 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023062 }
[email protected]43410e92012-04-20 17:06:283063 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053064
[email protected]882ba1e22012-03-08 19:02:533065 if (query_manager_.get()) {
3066 query_manager_->Destroy(have_context);
3067 query_manager_.reset();
3068 }
3069
[email protected]944b62f32012-09-27 02:20:463070 if (vertex_array_manager_ .get()) {
3071 vertex_array_manager_->Destroy(have_context);
3072 vertex_array_manager_.reset();
3073 }
3074
[email protected]1871a092011-10-10 21:46:423075 if (group_) {
[email protected]c4485aad62012-12-17 10:19:093076 group_->Destroy(this, have_context);
[email protected]1871a092011-10-10 21:46:423077 group_ = NULL;
3078 }
[email protected]3ae019382011-10-05 19:42:413079
[email protected]fe871662011-06-16 20:43:053080 if (context_.get()) {
3081 context_->ReleaseCurrent(NULL);
[email protected]79311e82011-09-20 00:40:503082 context_ = NULL;
[email protected]fe871662011-06-16 20:43:053083 }
[email protected]0fc35742011-04-13 17:57:543084
[email protected]97872062010-11-03 19:07:053085 offscreen_target_frame_buffer_.reset();
3086 offscreen_target_color_texture_.reset();
3087 offscreen_target_color_render_buffer_.reset();
3088 offscreen_target_depth_render_buffer_.reset();
3089 offscreen_target_stencil_render_buffer_.reset();
3090 offscreen_saved_frame_buffer_.reset();
3091 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273092 offscreen_resolved_frame_buffer_.reset();
3093 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463094
3095#if defined(OS_MACOSX)
3096 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3097 it != texture_to_io_surface_map_.end(); ++it) {
3098 CFRelease(it->second);
3099 }
3100 texture_to_io_surface_map_.clear();
3101#endif
[email protected]96449d2c2009-11-25 00:01:323102}
3103
[email protected]63c9b052012-05-17 18:27:383104void GLES2DecoderImpl::SetSurface(
3105 const scoped_refptr<gfx::GLSurface>& surface) {
3106 DCHECK(context_->IsCurrent(NULL));
3107 DCHECK(surface_.get());
3108 surface_ = surface;
3109 RestoreCurrentFramebufferBindings();
3110}
3111
[email protected]3c644d82011-06-20 19:58:243112bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent,
3113 uint32 new_parent_texture_id) {
[email protected]9a5afa432011-07-22 18:16:393114 if (!offscreen_saved_color_texture_.get())
3115 return false;
3116
[email protected]3c644d82011-06-20 19:58:243117 // Remove the saved frame buffer mapping from the parent decoder. The
3118 // parent pointer is a weak pointer so it will be null if the parent has
3119 // already been destroyed.
3120 if (parent_) {
[email protected]c826d732012-02-09 04:40:263121 ChildList::iterator it = std::find(
3122 parent_->children_.begin(),
3123 parent_->children_.end(),
3124 this);
3125 DCHECK(it != parent_->children_.end());
3126 parent_->children_.erase(it);
[email protected]3c644d82011-06-20 19:58:243127 // First check the texture has been mapped into the parent. This might not
3128 // be the case if initialization failed midway through.
3129 GLuint service_id = offscreen_saved_color_texture_->id();
3130 GLuint client_id = 0;
3131 if (parent_->texture_manager()->GetClientId(service_id, &client_id)) {
[email protected]80eb6b52012-01-19 00:14:413132 parent_->texture_manager()->RemoveTextureInfo(client_id);
[email protected]3c644d82011-06-20 19:58:243133 }
3134 }
3135
3136 GLES2DecoderImpl* new_parent_impl = static_cast<GLES2DecoderImpl*>(
3137 new_parent);
3138 if (new_parent_impl) {
[email protected]c826d732012-02-09 04:40:263139#ifndef NDEBUG
3140 ChildList::iterator it = std::find(
3141 new_parent_impl->children_.begin(),
3142 new_parent_impl->children_.end(),
3143 this);
3144 DCHECK(it == new_parent_impl->children_.end());
3145#endif
3146 new_parent_impl->children_.push_back(this);
[email protected]3c644d82011-06-20 19:58:243147 // Map the ID of the saved offscreen texture into the parent so that
3148 // it can reference it.
3149 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]98687862011-07-11 23:31:303150
3151 // Replace texture info when ID is already in use by parent.
3152 if (new_parent_impl->texture_manager()->GetTextureInfo(
[email protected]80eb6b52012-01-19 00:14:413153 new_parent_texture_id))
[email protected]98687862011-07-11 23:31:303154 new_parent_impl->texture_manager()->RemoveTextureInfo(
[email protected]80eb6b52012-01-19 00:14:413155 new_parent_texture_id);
[email protected]98687862011-07-11 23:31:303156
[email protected]8a61d872012-01-20 12:43:563157 offscreen_saved_color_texture_info_ =
[email protected]5f4f2a732011-07-30 00:47:553158 new_parent_impl->CreateTextureInfo(new_parent_texture_id, service_id);
[email protected]8a61d872012-01-20 12:43:563159 offscreen_saved_color_texture_info_->SetNotOwned();
3160 new_parent_impl->texture_manager()->
3161 SetInfoTarget(offscreen_saved_color_texture_info_, GL_TEXTURE_2D);
[email protected]3c644d82011-06-20 19:58:243162
[email protected]ee1e6aa2012-11-29 09:24:103163 parent_ = base::AsWeakPtr<GLES2DecoderImpl>(new_parent_impl);
[email protected]9a5afa432011-07-22 18:16:393164
3165 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243166 } else {
3167 parent_.reset();
[email protected]8a61d872012-01-20 12:43:563168 offscreen_saved_color_texture_info_ = NULL;
[email protected]3c644d82011-06-20 19:58:243169 }
3170
3171 return true;
3172}
3173
[email protected]260ddc4e2012-06-28 00:01:533174size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143175 size_t total = 0;
3176 if (offscreen_target_frame_buffer_.get()) {
3177 if (offscreen_target_color_texture_.get()) {
3178 total += offscreen_target_color_texture_->estimated_size();
3179 }
3180 if (offscreen_target_color_render_buffer_.get()) {
3181 total += offscreen_target_color_render_buffer_->estimated_size();
3182 }
3183 if (offscreen_target_depth_render_buffer_.get()) {
3184 total += offscreen_target_depth_render_buffer_->estimated_size();
3185 }
3186 if (offscreen_target_stencil_render_buffer_.get()) {
3187 total += offscreen_target_stencil_render_buffer_->estimated_size();
3188 }
3189 if (offscreen_saved_color_texture_.get()) {
3190 total += offscreen_saved_color_texture_->estimated_size();
3191 }
3192 if (offscreen_resolved_color_texture_.get()) {
3193 total += offscreen_resolved_color_texture_->estimated_size();
3194 }
3195 } else {
3196 gfx::Size size = surface_->GetSize();
3197 total += size.width() * size.height() *
3198 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3199 }
[email protected]260ddc4e2012-06-28 00:01:533200 return total;
[email protected]1078f912011-12-23 13:12:143201}
3202
[email protected]799b4b22011-08-22 17:09:593203bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3204 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3205 if (!is_offscreen) {
3206 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3207 << " with an onscreen framebuffer.";
3208 return false;
3209 }
3210
3211 if (offscreen_size_ == size)
3212 return true;
3213
3214 offscreen_size_ = size;
3215 int w = offscreen_size_.width();
3216 int h = offscreen_size_.height();
3217 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3218 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3219 << "to allocate storage due to excessive dimensions.";
3220 return false;
3221 }
3222
3223 // Reallocate the offscreen target buffers.
3224 DCHECK(offscreen_target_color_format_);
3225 if (IsOffscreenBufferMultisampled()) {
3226 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3227 offscreen_size_, offscreen_target_color_format_,
3228 offscreen_target_samples_)) {
3229 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3230 << "to allocate storage for offscreen target color buffer.";
3231 return false;
3232 }
3233 } else {
3234 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093235 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593236 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3237 << "to allocate storage for offscreen target color texture.";
3238 return false;
3239 }
3240 }
3241 if (offscreen_target_depth_format_ &&
3242 !offscreen_target_depth_render_buffer_->AllocateStorage(
3243 offscreen_size_, offscreen_target_depth_format_,
3244 offscreen_target_samples_)) {
3245 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3246 << "to allocate storage for offscreen target depth buffer.";
3247 return false;
3248 }
3249 if (offscreen_target_stencil_format_ &&
3250 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3251 offscreen_size_, offscreen_target_stencil_format_,
3252 offscreen_target_samples_)) {
3253 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3254 << "to allocate storage for offscreen target stencil buffer.";
3255 return false;
3256 }
3257
3258 // Attach the offscreen target buffers to the target frame buffer.
3259 if (IsOffscreenBufferMultisampled()) {
3260 offscreen_target_frame_buffer_->AttachRenderBuffer(
3261 GL_COLOR_ATTACHMENT0,
3262 offscreen_target_color_render_buffer_.get());
3263 } else {
3264 offscreen_target_frame_buffer_->AttachRenderTexture(
3265 offscreen_target_color_texture_.get());
3266 }
3267 if (offscreen_target_depth_format_) {
3268 offscreen_target_frame_buffer_->AttachRenderBuffer(
3269 GL_DEPTH_ATTACHMENT,
3270 offscreen_target_depth_render_buffer_.get());
3271 }
3272 const bool packed_depth_stencil =
3273 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3274 if (packed_depth_stencil) {
3275 offscreen_target_frame_buffer_->AttachRenderBuffer(
3276 GL_STENCIL_ATTACHMENT,
3277 offscreen_target_depth_render_buffer_.get());
3278 } else if (offscreen_target_stencil_format_) {
3279 offscreen_target_frame_buffer_->AttachRenderBuffer(
3280 GL_STENCIL_ATTACHMENT,
3281 offscreen_target_stencil_render_buffer_.get());
3282 }
3283
3284 if (offscreen_target_frame_buffer_->CheckStatus() !=
3285 GL_FRAMEBUFFER_COMPLETE) {
3286 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3287 << "because offscreen FBO was incomplete.";
3288 return false;
3289 }
3290
3291 // Clear the target frame buffer.
3292 {
3293 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3294 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3295 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3296 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3297 glClearStencil(0);
3298 glStencilMaskSeparate(GL_FRONT, -1);
3299 glStencilMaskSeparate(GL_BACK, -1);
3300 glClearDepth(0);
3301 glDepthMask(GL_TRUE);
3302 glDisable(GL_SCISSOR_TEST);
3303 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3304 RestoreClearState();
3305 }
[email protected]d85ef76d2011-09-08 22:21:433306
3307 // Destroy the offscreen resolved framebuffers.
3308 if (offscreen_resolved_frame_buffer_.get())
3309 offscreen_resolved_frame_buffer_->Destroy();
3310 if (offscreen_resolved_color_texture_.get())
3311 offscreen_resolved_color_texture_->Destroy();
3312 offscreen_resolved_color_texture_.reset();
3313 offscreen_resolved_frame_buffer_.reset();
3314
[email protected]799b4b22011-08-22 17:09:593315 return true;
[email protected]6217d392010-03-25 22:08:353316}
3317
[email protected]799b4b22011-08-22 17:09:593318error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
3319 uint32 immediate_data_size, const gles2::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443320 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023321 return error::kDeferCommandUntilLater;
3322
[email protected]799b4b22011-08-22 17:09:593323 GLuint width = static_cast<GLuint>(c.width);
3324 GLuint height = static_cast<GLuint>(c.height);
3325 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]a0d989162011-11-22 13:15:073326#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3327 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003328 // Make sure that we are done drawing to the back buffer before resizing.
3329 glFinish();
3330#endif
[email protected]799b4b22011-08-22 17:09:593331 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3332 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493333 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3334 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3335 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593336 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493337 }
[email protected]7ff86b92010-11-25 17:50:003338 }
[email protected]799b4b22011-08-22 17:09:593339
[email protected]9d37f062011-11-22 01:24:523340 if (!resize_callback_.is_null()) {
3341 resize_callback_.Run(gfx::Size(width, height));
[email protected]c777de52011-09-09 23:08:563342 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493343 if (!context_->IsCurrent(surface_.get())) {
3344 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3345 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053346 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493347 }
[email protected]658f7562011-09-09 05:24:053348 }
[email protected]799b4b22011-08-22 17:09:593349
3350 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393351}
3352
[email protected]96449d2c2009-11-25 00:01:323353const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3354 if (command_id > kStartPoint && command_id < kNumCommands) {
3355 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3356 }
3357 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3358}
3359
3360// Decode command with its arguments, and call the corresponding GL function.
3361// Note: args is a pointer to the command buffer. As such, it could be changed
3362// by a (malicious) client at any time, so if validation has to happen, it
3363// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143364error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323365 unsigned int command,
3366 unsigned int arg_count,
3367 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143368 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263369 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003370 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3371 // LOG(INFO), tried VLOG(1), no luck.
[email protected]d2a0e1a2012-08-12 02:25:013372 LOG(ERROR) << "[" << GetLogPrefix() << "]" << "cmd: "
3373 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193374 }
[email protected]96449d2c2009-11-25 00:01:323375 unsigned int command_index = command - kStartPoint - 1;
3376 if (command_index < arraysize(g_command_info)) {
3377 const CommandInfo& info = g_command_info[command_index];
3378 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3379 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3380 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193381 uint32 immediate_data_size =
3382 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323383 switch (command) {
3384 #define GLES2_CMD_OP(name) \
3385 case name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193386 result = Handle ## name( \
3387 immediate_data_size, \
[email protected]96449d2c2009-11-25 00:01:323388 *static_cast<const name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193389 break; \
[email protected]96449d2c2009-11-25 00:01:323390
3391 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323392 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383393 }
3394 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303395 GLenum error;
3396 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]d2a0e1a2012-08-12 02:25:013397 LOG(ERROR) << "[" << GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003398 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3399 << GetCommandName(command);
[email protected]ad84a3a2012-06-08 21:42:433400 SetGLError(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193401 }
[email protected]96449d2c2009-11-25 00:01:323402 }
3403 } else {
[email protected]f7a64ee2010-02-01 22:24:143404 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323405 }
[email protected]b9849abf2009-11-25 19:13:193406 } else {
3407 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323408 }
[email protected]a3a93e7b2010-08-28 00:48:563409 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3410 result = current_decoder_error_;
3411 current_decoder_error_ = error::kNoError;
3412 }
[email protected]b9849abf2009-11-25 19:13:193413 return result;
[email protected]96449d2c2009-11-25 00:01:323414}
3415
[email protected]ae51d192010-04-27 00:48:033416void GLES2DecoderImpl::RemoveBufferInfo(GLuint client_id) {
3417 buffer_manager()->RemoveBufferInfo(client_id);
[email protected]3916c97e2010-02-25 03:20:503418}
3419
[email protected]ae51d192010-04-27 00:48:033420bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
3421 if (GetProgramInfo(client_id)) {
3422 return false;
3423 }
[email protected]96449d2c2009-11-25 00:01:323424 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033425 if (service_id != 0) {
3426 CreateProgramInfo(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323427 }
[email protected]ae51d192010-04-27 00:48:033428 return true;
[email protected]96449d2c2009-11-25 00:01:323429}
3430
[email protected]ae51d192010-04-27 00:48:033431bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
3432 if (GetShaderInfo(client_id)) {
3433 return false;
[email protected]96449d2c2009-11-25 00:01:323434 }
[email protected]ae51d192010-04-27 00:48:033435 GLuint service_id = glCreateShader(type);
3436 if (service_id != 0) {
[email protected]7cea56d92010-04-28 17:21:383437 CreateShaderInfo(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033438 }
3439 return true;
[email protected]96449d2c2009-11-25 00:01:323440}
3441
[email protected]882ba1e22012-03-08 19:02:533442void GLES2DecoderImpl::DoFinish() {
3443 glFinish();
[email protected]22e3f552012-03-13 01:54:193444 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533445}
3446
3447void GLES2DecoderImpl::DoFlush() {
3448 glFlush();
[email protected]22e3f552012-03-13 01:54:193449 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533450}
3451
[email protected]3916c97e2010-02-25 03:20:503452void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453453 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023454 if (texture_index >= state_.texture_units.size()) {
[email protected]f80e6e12012-08-31 00:43:533455 SetGLErrorInvalidEnum(
3456 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503457 return;
3458 }
[email protected]e259eb412012-10-13 05:47:243459 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453460 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503461}
3462
[email protected]051b1372010-04-12 02:42:083463void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]3916c97e2010-02-25 03:20:503464 BufferManager::BufferInfo* info = NULL;
[email protected]051b1372010-04-12 02:42:083465 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033466 if (client_id != 0) {
3467 info = GetBufferInfo(client_id);
3468 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353469 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153470 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3471 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353472 return;
3473 }
3474
[email protected]ae51d192010-04-27 00:48:033475 // It's a new id so make a buffer info for it.
3476 glGenBuffersARB(1, &service_id);
3477 CreateBufferInfo(client_id, service_id);
3478 info = GetBufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573479 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103480 group_->GetIdAllocator(id_namespaces::kBuffers);
3481 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033482 }
[email protected]051b1372010-04-12 02:42:083483 }
[email protected]cae20172012-12-07 00:06:193484 LogClientServiceForInfo(info, client_id, "glBindBuffer");
[email protected]ae51d192010-04-27 00:48:033485 if (info) {
[email protected]4e8a5b122010-05-08 22:00:103486 if (!buffer_manager()->SetTarget(info, target)) {
[email protected]8eee29c2010-04-29 03:38:293487 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433488 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473489 return;
3490 }
[email protected]ae51d192010-04-27 00:48:033491 service_id = info->service_id();
[email protected]a93bb842010-02-16 23:03:473492 }
[email protected]96449d2c2009-11-25 00:01:323493 switch (target) {
3494 case GL_ARRAY_BUFFER:
[email protected]e259eb412012-10-13 05:47:243495 state_.bound_array_buffer = info;
[email protected]96449d2c2009-11-25 00:01:323496 break;
3497 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]e259eb412012-10-13 05:47:243498 state_.vertex_attrib_manager->SetElementArrayBuffer(info);
[email protected]96449d2c2009-11-25 00:01:323499 break;
3500 default:
[email protected]a93bb842010-02-16 23:03:473501 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323502 break;
3503 }
[email protected]051b1372010-04-12 02:42:083504 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323505}
3506
[email protected]297ca1c2011-06-20 23:08:463507bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
3508 return (GLES2Util::GetChannelsForFormat(
3509 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3510}
3511
3512bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]0d6bfdc2011-11-02 01:32:203513 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453514 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203515 if (framebuffer) {
3516 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463517 }
3518 if (offscreen_target_frame_buffer_.get()) {
3519 return offscreen_target_depth_format_ != 0;
3520 }
3521 return back_buffer_has_depth_;
3522}
3523
3524bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]0d6bfdc2011-11-02 01:32:203525 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453526 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203527 if (framebuffer) {
3528 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463529 }
3530 if (offscreen_target_frame_buffer_.get()) {
3531 return offscreen_target_stencil_format_ != 0 ||
3532 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3533 }
3534 return back_buffer_has_stencil_;
3535}
3536
3537void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]88a61bf2012-10-27 13:00:423538 if (clear_state_dirty_) {
[email protected]297ca1c2011-06-20 23:08:463539 glColorMask(
[email protected]e259eb412012-10-13 05:47:243540 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3541 state_.color_mask_alpha &&
3542 BoundFramebufferHasColorAttachmentWithAlpha());
[email protected]297ca1c2011-06-20 23:08:463543 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243544 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223545 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463546 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243547 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423548 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243549 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423550 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223551 EnableDisable(
3552 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3553 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3554 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3555 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]88a61bf2012-10-27 13:00:423556 clear_state_dirty_ = false;
[email protected]297ca1c2011-06-20 23:08:463557 }
3558}
3559
[email protected]78b514b2012-05-01 21:50:593560void GLES2DecoderImpl::BindAndApplyTextureParameters(
3561 TextureManager::TextureInfo* info) {
3562 glBindTexture(info->target(), info->service_id());
3563 glTexParameteri(info->target(), GL_TEXTURE_MIN_FILTER, info->min_filter());
3564 glTexParameteri(info->target(), GL_TEXTURE_MAG_FILTER, info->mag_filter());
3565 glTexParameteri(info->target(), GL_TEXTURE_WRAP_S, info->wrap_s());
3566 glTexParameteri(info->target(), GL_TEXTURE_WRAP_T, info->wrap_t());
3567}
3568
[email protected]1868a342012-11-07 15:56:023569GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]b177ae22011-11-01 03:29:113570 return (offscreen_target_frame_buffer_.get()) ?
3571 offscreen_target_frame_buffer_->id() :
[email protected]1868a342012-11-07 15:56:023572 (surface_ ? surface_->GetBackingFrameBufferObject() : 0);
3573}
3574
3575void GLES2DecoderImpl::RestoreState() const {
3576 state_.RestoreState();
3577
3578 // TODO: Restore multisample bindings
3579 GLuint service_id = state_.bound_draw_framebuffer ?
3580 state_.bound_draw_framebuffer->service_id() :
3581 GetBackbufferServiceId();
3582 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
[email protected]b177ae22011-11-01 03:29:113583}
3584
[email protected]051b1372010-04-12 02:42:083585void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
3586 FramebufferManager::FramebufferInfo* info = NULL;
3587 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033588 if (client_id != 0) {
3589 info = GetFramebufferInfo(client_id);
[email protected]051b1372010-04-12 02:42:083590 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353591 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153592 LOG(ERROR)
3593 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3594 current_decoder_error_ = error::kGenericError;
3595 return;
[email protected]bf5a8d132011-08-16 08:39:353596 }
3597
[email protected]ae51d192010-04-27 00:48:033598 // It's a new id so make a framebuffer info for it.
3599 glGenFramebuffersEXT(1, &service_id);
3600 CreateFramebufferInfo(client_id, service_id);
3601 info = GetFramebufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573602 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103603 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3604 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033605 } else {
3606 service_id = info->service_id();
[email protected]051b1372010-04-12 02:42:083607 }
[email protected]06c8b082011-01-05 18:00:363608 info->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083609 }
[email protected]cae20172012-12-07 00:06:193610 LogClientServiceForInfo(info, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303611
3612 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]e259eb412012-10-13 05:47:243613 state_.bound_draw_framebuffer = info;
[email protected]8e3e0662010-08-23 18:46:303614 }
3615 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]e259eb412012-10-13 05:47:243616 state_.bound_read_framebuffer = info;
[email protected]8e3e0662010-08-23 18:46:303617 }
[email protected]6217d392010-03-25 22:08:353618
[email protected]88a61bf2012-10-27 13:00:423619 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:463620
[email protected]b177ae22011-11-01 03:29:113621 // If we are rendering to the backbuffer get the FBO id for any simulated
3622 // backbuffer.
3623 if (info == NULL) {
3624 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463625 }
[email protected]6217d392010-03-25 22:08:353626
[email protected]051b1372010-04-12 02:42:083627 glBindFramebufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563628}
3629
[email protected]051b1372010-04-12 02:42:083630void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
3631 RenderbufferManager::RenderbufferInfo* info = NULL;
3632 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033633 if (client_id != 0) {
3634 info = GetRenderbufferInfo(client_id);
[email protected]051b1372010-04-12 02:42:083635 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353636 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153637 LOG(ERROR)
3638 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3639 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353640 return;
3641 }
3642
[email protected]ae51d192010-04-27 00:48:033643 // It's a new id so make a renderbuffer info for it.
3644 glGenRenderbuffersEXT(1, &service_id);
3645 CreateRenderbufferInfo(client_id, service_id);
[email protected]066849e32010-05-03 19:14:103646 info = GetRenderbufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573647 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103648 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3649 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033650 } else {
3651 service_id = info->service_id();
[email protected]051b1372010-04-12 02:42:083652 }
[email protected]06c8b082011-01-05 18:00:363653 info->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083654 }
[email protected]cae20172012-12-07 00:06:193655 LogClientServiceForInfo(info, client_id, "glBindRenerbuffer");
[email protected]e259eb412012-10-13 05:47:243656 state_.bound_renderbuffer = info;
[email protected]051b1372010-04-12 02:42:083657 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563658}
3659
[email protected]051b1372010-04-12 02:42:083660void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]ae51d192010-04-27 00:48:033661 TextureManager::TextureInfo* info = NULL;
[email protected]051b1372010-04-12 02:42:083662 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033663 if (client_id != 0) {
3664 info = GetTextureInfo(client_id);
3665 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353666 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153667 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3668 current_decoder_error_ = error::kGenericError;
3669 return;
[email protected]bf5a8d132011-08-16 08:39:353670 }
3671
[email protected]ae51d192010-04-27 00:48:033672 // It's a new id so make a texture info for it.
3673 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413674 DCHECK_NE(0u, service_id);
[email protected]ae51d192010-04-27 00:48:033675 CreateTextureInfo(client_id, service_id);
3676 info = GetTextureInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573677 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103678 group_->GetIdAllocator(id_namespaces::kTextures);
3679 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033680 }
3681 } else {
3682 info = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083683 }
[email protected]ae51d192010-04-27 00:48:033684
[email protected]1958e0e2010-04-22 05:17:153685 // Check the texture exists
3686 // Check that we are not trying to bind it to a different target.
[email protected]ae51d192010-04-27 00:48:033687 if (info->target() != 0 && info->target() != target) {
[email protected]8eee29c2010-04-29 03:38:293688 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433689 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153690 return;
3691 }
[email protected]b0af4f52011-09-28 22:04:423692 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
3693 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433694 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423695 return;
3696 }
[email protected]cae20172012-12-07 00:06:193697 LogClientServiceForInfo(info, client_id, "glBindTexture");
[email protected]1958e0e2010-04-22 05:17:153698 if (info->target() == 0) {
[email protected]80eb6b52012-01-19 00:14:413699 texture_manager()->SetInfoTarget(info, target);
[email protected]a93bb842010-02-16 23:03:473700 }
[email protected]ae51d192010-04-27 00:48:033701 glBindTexture(target, info->service_id());
[email protected]32145a92012-12-17 09:01:593702
[email protected]e259eb412012-10-13 05:47:243703 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503704 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473705 switch (target) {
3706 case GL_TEXTURE_2D:
[email protected]3916c97e2010-02-25 03:20:503707 unit.bound_texture_2d = info;
[email protected]a93bb842010-02-16 23:03:473708 break;
3709 case GL_TEXTURE_CUBE_MAP:
[email protected]3916c97e2010-02-25 03:20:503710 unit.bound_texture_cube_map = info;
[email protected]a93bb842010-02-16 23:03:473711 break;
[email protected]61eeb33f2011-07-26 15:30:313712 case GL_TEXTURE_EXTERNAL_OES:
3713 unit.bound_texture_external_oes = info;
[email protected]b0af4f52011-09-28 22:04:423714 if (info->IsStreamTexture()) {
3715 DCHECK(stream_texture_manager_);
3716 StreamTexture* stream_tex =
3717 stream_texture_manager_->LookupStreamTexture(info->service_id());
3718 if (stream_tex)
3719 stream_tex->Update();
3720 }
[email protected]61eeb33f2011-07-26 15:30:313721 break;
[email protected]e51bdf32011-11-23 22:21:463722 case GL_TEXTURE_RECTANGLE_ARB:
3723 unit.bound_texture_rectangle_arb = info;
3724 break;
[email protected]a93bb842010-02-16 23:03:473725 default:
3726 NOTREACHED(); // Validation should prevent us getting here.
3727 break;
3728 }
3729}
3730
[email protected]07f54fcc2009-12-22 02:46:303731void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243732 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123733 if (index != 0 ||
3734 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243735 glDisableVertexAttribArray(index);
3736 }
[email protected]07f54fcc2009-12-22 02:46:303737 } else {
[email protected]8eee29c2010-04-29 03:38:293738 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:433739 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303740 }
3741}
3742
[email protected]60f22d32012-12-12 00:31:583743void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3744 GLsizei numAttachments,
3745 const GLenum* attachments) {
3746 FramebufferManager::FramebufferInfo* framebuffer =
3747 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3748
3749 // Validates the attachments. If one of them fails
3750 // the whole command fails.
3751 for (GLsizei i = 0; i < numAttachments; ++i) {
3752 if ((framebuffer &&
3753 !validators_->attachment.IsValid(attachments[i])) ||
3754 (!framebuffer &&
3755 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
3756 SetGLErrorInvalidEnum("glDiscardFramebufferEXT",
3757 attachments[i],
3758 "attachments");
3759 return;
3760 }
3761 }
3762
3763 // Marks each one of them as not cleared
3764 for (GLsizei i = 0; i < numAttachments; ++i) {
3765 if (framebuffer) {
3766 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3767 texture_manager(),
3768 attachments[i],
3769 false);
3770 } else {
3771 switch (attachments[i]) {
3772 case GL_COLOR_EXT:
3773 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3774 break;
3775 case GL_DEPTH_EXT:
3776 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
3777 case GL_STENCIL_EXT:
3778 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
3779 break;
3780 default:
3781 NOTREACHED();
3782 break;
3783 }
3784 }
3785 }
3786
3787 glDiscardFramebufferEXT(target, numAttachments, attachments);
3788}
3789
[email protected]07f54fcc2009-12-22 02:46:303790void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243791 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:303792 glEnableVertexAttribArray(index);
3793 } else {
[email protected]8eee29c2010-04-29 03:38:293794 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:433795 "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303796 }
3797}
3798
[email protected]a93bb842010-02-16 23:03:473799void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]3916c97e2010-02-25 03:20:503800 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]97dc7cbe2011-12-06 17:26:173801 if (!info ||
[email protected]38c0a972012-05-12 00:48:023802 !texture_manager()->CanGenerateMipmaps(info)) {
[email protected]8eee29c2010-04-29 03:38:293803 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433804 "glGenerateMipmaps", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:473805 return;
3806 }
[email protected]38c0a972012-05-12 00:48:023807
[email protected]12d95352012-12-14 07:23:543808 if (target == GL_TEXTURE_CUBE_MAP) {
3809 for (int i = 0; i < 6; ++i) {
3810 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
3811 if (!texture_manager()->ClearTextureLevel(this, info, face, 0)) {
3812 SetGLError(GL_OUT_OF_MEMORY, "glGenerateMipmaps", "dimensions too big");
3813 return;
3814 }
3815 }
3816 } else {
3817 if (!texture_manager()->ClearTextureLevel(this, info, target, 0)) {
3818 SetGLError(GL_OUT_OF_MEMORY, "glGenerateMipmaps", "dimensions too big");
3819 return;
3820 }
[email protected]7687479c2012-05-14 23:54:043821 }
3822
[email protected]38c0a972012-05-12 00:48:023823 CopyRealGLErrorsToWrapper();
[email protected]59f3ca02011-03-26 22:24:193824 // Workaround for Mac driver bug. In the large scheme of things setting
3825 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:563826 // hit so there's probably no need to make this conditional. The bug appears
3827 // to be that if the filtering mode is set to something that doesn't require
3828 // mipmaps for rendering, or is never set to something other than the default,
3829 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:153830 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193831 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3832 }
[email protected]a93bb842010-02-16 23:03:473833 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:153834 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193835 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, info->min_filter());
3836 }
[email protected]38c0a972012-05-12 00:48:023837 GLenum error = PeekGLError();
3838 if (error == GL_NO_ERROR) {
3839 texture_manager()->MarkMipmapsGenerated(info);
3840 }
[email protected]a93bb842010-02-16 23:03:473841}
3842
[email protected]b273e432010-04-12 17:23:583843bool GLES2DecoderImpl::GetHelper(
3844 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:583845 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:153846 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
3847 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:433848 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3849 *num_written = 1;
3850 if (params) {
3851 *params = GL_RGBA; // We don't support other formats.
3852 }
3853 return true;
3854 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3855 *num_written = 1;
3856 if (params) {
3857 *params = GL_UNSIGNED_BYTE; // We don't support other types.
3858 }
3859 return true;
3860 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
3861 *num_written = 1;
3862 if (params) {
3863 *params = group_->max_fragment_uniform_vectors();
3864 }
3865 return true;
3866 case GL_MAX_VARYING_VECTORS:
3867 *num_written = 1;
3868 if (params) {
3869 *params = group_->max_varying_vectors();
3870 }
3871 return true;
3872 case GL_MAX_VERTEX_UNIFORM_VECTORS:
3873 *num_written = 1;
3874 if (params) {
3875 *params = group_->max_vertex_uniform_vectors();
3876 }
3877 return true;
[email protected]4e8a5b122010-05-08 22:00:103878 }
[email protected]5cb735d2011-10-13 01:37:233879 }
3880 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:243881 case GL_MAX_VIEWPORT_DIMS:
3882 if (offscreen_target_frame_buffer_.get()) {
3883 *num_written = 2;
3884 if (params) {
3885 params[0] = renderbuffer_manager()->max_renderbuffer_size();
3886 params[1] = renderbuffer_manager()->max_renderbuffer_size();
3887 }
3888 return true;
3889 }
[email protected]5cb735d2011-10-13 01:37:233890 return false;
[email protected]84afefa2011-10-19 21:45:533891 case GL_MAX_SAMPLES:
3892 *num_written = 1;
3893 if (params) {
3894 params[0] = renderbuffer_manager()->max_samples();
3895 }
3896 return true;
3897 case GL_MAX_RENDERBUFFER_SIZE:
3898 *num_written = 1;
3899 if (params) {
3900 params[0] = renderbuffer_manager()->max_renderbuffer_size();
3901 }
3902 return true;
[email protected]5cb735d2011-10-13 01:37:233903 case GL_MAX_TEXTURE_SIZE:
3904 *num_written = 1;
3905 if (params) {
3906 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
3907 }
3908 return true;
3909 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
3910 *num_written = 1;
3911 if (params) {
3912 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
3913 }
3914 return true;
[email protected]297ca1c2011-06-20 23:08:463915 case GL_ALPHA_BITS:
3916 *num_written = 1;
3917 if (params) {
3918 GLint v = 0;
3919 glGetIntegerv(GL_ALPHA_BITS, &v);
3920 params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0;
3921 }
3922 return true;
3923 case GL_DEPTH_BITS:
3924 *num_written = 1;
3925 if (params) {
3926 GLint v = 0;
3927 glGetIntegerv(GL_DEPTH_BITS, &v);
3928 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
3929 }
3930 return true;
3931 case GL_STENCIL_BITS:
3932 *num_written = 1;
3933 if (params) {
3934 GLint v = 0;
3935 glGetIntegerv(GL_STENCIL_BITS, &v);
3936 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
3937 }
3938 return true;
[email protected]656dcaad2010-05-07 17:18:373939 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:113940 *num_written = validators_->compressed_texture_format.GetValues().size();
3941 if (params) {
3942 for (GLint ii = 0; ii < *num_written; ++ii) {
3943 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
3944 }
3945 }
[email protected]656dcaad2010-05-07 17:18:373946 return true;
[email protected]b273e432010-04-12 17:23:583947 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
3948 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103949 if (params) {
[email protected]302ce6d2011-07-07 23:28:113950 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:103951 }
[email protected]b273e432010-04-12 17:23:583952 return true;
3953 case GL_NUM_SHADER_BINARY_FORMATS:
3954 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103955 if (params) {
[email protected]302ce6d2011-07-07 23:28:113956 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:103957 }
[email protected]b273e432010-04-12 17:23:583958 return true;
3959 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:113960 *num_written = validators_->shader_binary_format.GetValues().size();
3961 if (params) {
3962 for (GLint ii = 0; ii < *num_written; ++ii) {
3963 params[ii] = validators_->shader_binary_format.GetValues()[ii];
3964 }
3965 }
3966 return true;
[email protected]b273e432010-04-12 17:23:583967 case GL_SHADER_COMPILER:
3968 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103969 if (params) {
3970 *params = GL_TRUE;
3971 }
[email protected]b273e432010-04-12 17:23:583972 return true;
[email protected]6b8cf1a2010-05-06 16:13:583973 case GL_ARRAY_BUFFER_BINDING:
3974 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103975 if (params) {
[email protected]e259eb412012-10-13 05:47:243976 if (state_.bound_array_buffer) {
[email protected]4e8a5b122010-05-08 22:00:103977 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:243978 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:103979 &client_id);
3980 *params = client_id;
3981 } else {
3982 *params = 0;
3983 }
[email protected]6b8cf1a2010-05-06 16:13:583984 }
3985 return true;
3986 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
3987 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103988 if (params) {
[email protected]e259eb412012-10-13 05:47:243989 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:103990 GLuint client_id = 0;
3991 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:253992 state_.vertex_attrib_manager->element_array_buffer()->
3993 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:103994 *params = client_id;
3995 } else {
3996 *params = 0;
3997 }
[email protected]6b8cf1a2010-05-06 16:13:583998 }
3999 return true;
4000 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304001 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584002 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104003 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:204004 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454005 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204006 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104007 GLuint client_id = 0;
4008 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204009 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304010 *params = client_id;
4011 } else {
4012 *params = 0;
4013 }
4014 }
4015 return true;
[email protected]ebfb73c2012-08-15 02:37:454016 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304017 *num_written = 1;
4018 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:204019 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454020 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204021 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304022 GLuint client_id = 0;
4023 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204024 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104025 *params = client_id;
4026 } else {
4027 *params = 0;
4028 }
[email protected]6b8cf1a2010-05-06 16:13:584029 }
4030 return true;
4031 case GL_RENDERBUFFER_BINDING:
4032 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104033 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:204034 RenderbufferManager::RenderbufferInfo* renderbuffer =
4035 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4036 if (renderbuffer) {
[email protected]4e8a5b122010-05-08 22:00:104037 GLuint client_id = 0;
4038 renderbuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204039 renderbuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104040 *params = client_id;
4041 } else {
4042 *params = 0;
4043 }
[email protected]6b8cf1a2010-05-06 16:13:584044 }
4045 return true;
4046 case GL_CURRENT_PROGRAM:
4047 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104048 if (params) {
[email protected]e259eb412012-10-13 05:47:244049 if (state_.current_program) {
[email protected]4e8a5b122010-05-08 22:00:104050 GLuint client_id = 0;
4051 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244052 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104053 *params = client_id;
4054 } else {
4055 *params = 0;
4056 }
[email protected]6b8cf1a2010-05-06 16:13:584057 }
4058 return true;
[email protected]bf835842012-11-19 15:21:514059 case GL_VERTEX_ARRAY_BINDING_OES:
4060 *num_written = 1;
4061 if (params) {
4062 if (state_.vertex_attrib_manager != default_vertex_attrib_manager_) {
4063 GLuint client_id = 0;
4064 vertex_array_manager_->GetClientId(
4065 state_.vertex_attrib_manager->service_id(), &client_id);
4066 *params = client_id;
4067 } else {
4068 *params = 0;
4069 }
4070 }
4071 return true;
[email protected]4e8a5b122010-05-08 22:00:104072 case GL_TEXTURE_BINDING_2D:
4073 *num_written = 1;
4074 if (params) {
[email protected]e259eb412012-10-13 05:47:244075 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584076 if (unit.bound_texture_2d) {
4077 GLuint client_id = 0;
4078 texture_manager()->GetClientId(
4079 unit.bound_texture_2d->service_id(), &client_id);
4080 *params = client_id;
4081 } else {
4082 *params = 0;
4083 }
[email protected]6b8cf1a2010-05-06 16:13:584084 }
[email protected]4e8a5b122010-05-08 22:00:104085 return true;
4086 case GL_TEXTURE_BINDING_CUBE_MAP:
4087 *num_written = 1;
4088 if (params) {
[email protected]e259eb412012-10-13 05:47:244089 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584090 if (unit.bound_texture_cube_map) {
4091 GLuint client_id = 0;
4092 texture_manager()->GetClientId(
4093 unit.bound_texture_cube_map->service_id(), &client_id);
4094 *params = client_id;
4095 } else {
4096 *params = 0;
4097 }
[email protected]6b8cf1a2010-05-06 16:13:584098 }
[email protected]4e8a5b122010-05-08 22:00:104099 return true;
[email protected]61eeb33f2011-07-26 15:30:314100 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4101 *num_written = 1;
4102 if (params) {
[email protected]e259eb412012-10-13 05:47:244103 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]61eeb33f2011-07-26 15:30:314104 if (unit.bound_texture_external_oes) {
4105 GLuint client_id = 0;
4106 texture_manager()->GetClientId(
4107 unit.bound_texture_external_oes->service_id(), &client_id);
4108 *params = client_id;
4109 } else {
4110 *params = 0;
4111 }
4112 }
4113 return true;
[email protected]e51bdf32011-11-23 22:21:464114 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4115 *num_written = 1;
4116 if (params) {
[email protected]e259eb412012-10-13 05:47:244117 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]e51bdf32011-11-23 22:21:464118 if (unit.bound_texture_rectangle_arb) {
4119 GLuint client_id = 0;
4120 texture_manager()->GetClientId(
4121 unit.bound_texture_rectangle_arb->service_id(), &client_id);
4122 *params = client_id;
4123 } else {
4124 *params = 0;
4125 }
4126 }
4127 return true;
[email protected]6c75c712012-06-19 15:43:174128 case GL_UNPACK_FLIP_Y_CHROMIUM:
4129 *num_written = 1;
4130 if (params) {
4131 params[0] = unpack_flip_y_;
4132 }
4133 return true;
4134 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4135 *num_written = 1;
4136 if (params) {
4137 params[0] = unpack_premultiply_alpha_;
4138 }
4139 return true;
4140 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4141 *num_written = 1;
4142 if (params) {
4143 params[0] = unpack_unpremultiply_alpha_;
4144 }
4145 return true;
[email protected]b273e432010-04-12 17:23:584146 default:
[email protected]4e8a5b122010-05-08 22:00:104147 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534148 return false;
[email protected]b273e432010-04-12 17:23:584149 }
4150}
4151
[email protected]4e8a5b122010-05-08 22:00:104152bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4153 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264154 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534155 return true;
4156 }
[email protected]4e8a5b122010-05-08 22:00:104157 return GetHelper(pname, NULL, num_values);
4158}
4159
[email protected]b273e432010-04-12 17:23:584160void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4161 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104162 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534163 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]4e8a5b122010-05-08 22:00:104164 scoped_array<GLint> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264165 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534166 GetHelper(pname, values.get(), &num_written);
4167 }
[email protected]b273e432010-04-12 17:23:584168 for (GLsizei ii = 0; ii < num_written; ++ii) {
4169 params[ii] = static_cast<GLboolean>(values[ii]);
4170 }
4171 } else {
4172 glGetBooleanv(pname, params);
4173 }
4174}
4175
4176void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4177 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104178 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264179 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534180 if (GetHelper(pname, NULL, &num_written)) {
4181 scoped_array<GLint> values(new GLint[num_written]);
4182 GetHelper(pname, values.get(), &num_written);
4183 for (GLsizei ii = 0; ii < num_written; ++ii) {
4184 params[ii] = static_cast<GLfloat>(values[ii]);
4185 }
4186 } else {
4187 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584188 }
[email protected]b273e432010-04-12 17:23:584189 }
4190}
4191
4192void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4193 DCHECK(params);
4194 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264195 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534196 !GetHelper(pname, params, &num_written)) {
[email protected]b273e432010-04-12 17:23:584197 glGetIntegerv(pname, params);
4198 }
4199}
4200
[email protected]a0c3e972010-04-21 00:49:134201void GLES2DecoderImpl::DoGetProgramiv(
4202 GLuint program_id, GLenum pname, GLint* params) {
[email protected]6b8cf1a2010-05-06 16:13:584203 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4204 program_id, "glGetProgramiv");
[email protected]a0c3e972010-04-21 00:49:134205 if (!info) {
[email protected]a0c3e972010-04-21 00:49:134206 return;
4207 }
4208 info->GetProgramiv(pname, params);
4209}
4210
[email protected]258a3313f2011-10-18 20:13:574211void GLES2DecoderImpl::DoBindAttribLocation(
4212 GLuint program, GLuint index, const char* name) {
4213 if (!StringIsValidForGLES(name)) {
[email protected]ad84a3a2012-06-08 21:42:434214 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574215 return;
4216 }
[email protected]68dcb1f2012-04-07 00:14:564217 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ad84a3a2012-06-08 21:42:434218 SetGLError(GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564219 return;
4220 }
4221 if (index >= group_->max_vertex_attribs()) {
[email protected]ad84a3a2012-06-08 21:42:434222 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564223 return;
4224 }
[email protected]6b8cf1a2010-05-06 16:13:584225 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4226 program, "glBindAttribLocation");
[email protected]ae51d192010-04-27 00:48:034227 if (!info) {
[email protected]258a3313f2011-10-18 20:13:574228 return;
[email protected]558847a2010-03-24 07:02:544229 }
[email protected]c3e4c4e2012-03-02 19:23:244230 info->SetAttribLocationBinding(name, static_cast<GLint>(index));
[email protected]258a3313f2011-10-18 20:13:574231 glBindAttribLocation(info->service_id(), index, name);
4232}
4233
4234error::Error GLES2DecoderImpl::HandleBindAttribLocation(
4235 uint32 immediate_data_size, const gles2::BindAttribLocation& c) {
4236 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544237 GLuint index = static_cast<GLuint>(c.index);
4238 uint32 name_size = c.data_size;
4239 const char* name = GetSharedMemoryAs<const char*>(
4240 c.name_shm_id, c.name_shm_offset, name_size);
4241 if (name == NULL) {
4242 return error::kOutOfBounds;
4243 }
4244 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574245 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544246 return error::kNoError;
4247}
4248
4249error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate(
4250 uint32 immediate_data_size, const gles2::BindAttribLocationImmediate& c) {
[email protected]6b8cf1a2010-05-06 16:13:584251 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544252 GLuint index = static_cast<GLuint>(c.index);
4253 uint32 name_size = c.data_size;
4254 const char* name = GetImmediateDataAs<const char*>(
4255 c, name_size, immediate_data_size);
4256 if (name == NULL) {
4257 return error::kOutOfBounds;
4258 }
4259 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574260 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544261 return error::kNoError;
4262}
4263
4264error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
4265 uint32 immediate_data_size, const gles2::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584266 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544267 GLuint index = static_cast<GLuint>(c.index);
4268 Bucket* bucket = GetBucket(c.name_bucket_id);
4269 if (!bucket || bucket->size() == 0) {
4270 return error::kInvalidArguments;
4271 }
4272 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184273 if (!bucket->GetAsString(&name_str)) {
4274 return error::kInvalidArguments;
4275 }
[email protected]258a3313f2011-10-18 20:13:574276 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544277 return error::kNoError;
4278}
4279
[email protected]2be6abf32012-06-26 00:28:334280void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
4281 GLuint program, GLint location, const char* name) {
4282 if (!StringIsValidForGLES(name)) {
4283 SetGLError(GL_INVALID_VALUE,
4284 "glBindUniformLocationCHROMIUM", "Invalid character");
4285 return;
4286 }
4287 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
4288 SetGLError(GL_INVALID_OPERATION,
4289 "glBindUniformLocationCHROMIUM", "reserved prefix");
4290 return;
4291 }
4292 if (location < 0 || static_cast<uint32>(location) >=
4293 (group_->max_fragment_uniform_vectors() +
4294 group_->max_vertex_uniform_vectors()) * 4) {
4295 SetGLError(GL_INVALID_VALUE,
4296 "glBindUniformLocationCHROMIUM", "location out of range");
4297 return;
4298 }
4299 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4300 program, "glBindUniformLocationCHROMIUM");
4301 if (!info) {
4302 return;
4303 }
4304 if (!info->SetUniformLocationBinding(name, location)) {
4305 SetGLError(GL_INVALID_VALUE,
4306 "glBindUniformLocationCHROMIUM", "location out of range");
4307 }
4308}
4309
4310error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
4311 uint32 immediate_data_size, const gles2::BindUniformLocationCHROMIUM& c) {
4312 GLuint program = static_cast<GLuint>(c.program);
4313 GLint location = static_cast<GLint>(c.location);
4314 uint32 name_size = c.data_size;
4315 const char* name = GetSharedMemoryAs<const char*>(
4316 c.name_shm_id, c.name_shm_offset, name_size);
4317 if (name == NULL) {
4318 return error::kOutOfBounds;
4319 }
4320 String name_str(name, name_size);
4321 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4322 return error::kNoError;
4323}
4324
4325error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4326 uint32 immediate_data_size,
4327 const gles2::BindUniformLocationCHROMIUMImmediate& c) {
4328 GLuint program = static_cast<GLuint>(c.program);
4329 GLint location = static_cast<GLint>(c.location);
4330 uint32 name_size = c.data_size;
4331 const char* name = GetImmediateDataAs<const char*>(
4332 c, name_size, immediate_data_size);
4333 if (name == NULL) {
4334 return error::kOutOfBounds;
4335 }
4336 String name_str(name, name_size);
4337 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4338 return error::kNoError;
4339}
4340
4341error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4342 uint32 immediate_data_size,
4343 const gles2::BindUniformLocationCHROMIUMBucket& c) {
4344 GLuint program = static_cast<GLuint>(c.program);
4345 GLint location = static_cast<GLint>(c.location);
4346 Bucket* bucket = GetBucket(c.name_bucket_id);
4347 if (!bucket || bucket->size() == 0) {
4348 return error::kInvalidArguments;
4349 }
4350 std::string name_str;
4351 if (!bucket->GetAsString(&name_str)) {
4352 return error::kInvalidArguments;
4353 }
4354 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4355 return error::kNoError;
4356}
4357
[email protected]f7a64ee2010-02-01 22:24:144358error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ba3176a2009-12-16 18:19:464359 uint32 immediate_data_size, const gles2::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034360 GLuint client_id = c.shader;
4361 if (client_id) {
4362 ShaderManager::ShaderInfo* info = GetShaderInfo(client_id);
4363 if (info) {
[email protected]ca488e12010-12-13 20:06:144364 if (!info->IsDeleted()) {
4365 glDeleteShader(info->service_id());
4366 shader_manager()->MarkAsDeleted(info);
4367 }
[email protected]ae51d192010-04-27 00:48:034368 } else {
[email protected]ad84a3a2012-06-08 21:42:434369 SetGLError(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034370 }
[email protected]96449d2c2009-11-25 00:01:324371 }
[email protected]f7a64ee2010-02-01 22:24:144372 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324373}
4374
[email protected]f7a64ee2010-02-01 22:24:144375error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ba3176a2009-12-16 18:19:464376 uint32 immediate_data_size, const gles2::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034377 GLuint client_id = c.program;
4378 if (client_id) {
4379 ProgramManager::ProgramInfo* info = GetProgramInfo(client_id);
4380 if (info) {
[email protected]ca488e12010-12-13 20:06:144381 if (!info->IsDeleted()) {
[email protected]ca488e12010-12-13 20:06:144382 program_manager()->MarkAsDeleted(shader_manager(), info);
4383 }
[email protected]ae51d192010-04-27 00:48:034384 } else {
[email protected]ad84a3a2012-06-08 21:42:434385 SetGLError(GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034386 }
[email protected]96449d2c2009-11-25 00:01:324387 }
[email protected]f7a64ee2010-02-01 22:24:144388 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324389}
4390
[email protected]269200b12010-11-18 22:53:064391void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104392 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574393 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104394 for (GLsizei ii = 0; ii < n; ++ii) {
4395 id_allocator->FreeID(ids[ii]);
4396 }
4397}
4398
[email protected]269200b12010-11-18 22:53:064399error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
4400 uint32 immediate_data_size, const gles2::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104401 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4402 GLsizei n = static_cast<GLsizei>(c.n);
4403 uint32 data_size;
4404 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4405 return error::kOutOfBounds;
4406 }
4407 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4408 c.ids_shm_id, c.ids_shm_offset, data_size);
4409 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434410 SetGLError(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104411 return error::kNoError;
4412 }
4413 if (ids == NULL) {
4414 return error::kOutOfBounds;
4415 }
[email protected]269200b12010-11-18 22:53:064416 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104417 return error::kNoError;
4418}
4419
[email protected]269200b12010-11-18 22:53:064420void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104421 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574422 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104423 if (id_offset == 0) {
4424 for (GLsizei ii = 0; ii < n; ++ii) {
4425 ids[ii] = id_allocator->AllocateID();
4426 }
4427 } else {
4428 for (GLsizei ii = 0; ii < n; ++ii) {
4429 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4430 id_offset = ids[ii] + 1;
4431 }
4432 }
4433}
4434
[email protected]269200b12010-11-18 22:53:064435error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
4436 uint32 immediate_data_size, const gles2::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104437 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4438 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4439 GLsizei n = static_cast<GLsizei>(c.n);
4440 uint32 data_size;
4441 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4442 return error::kOutOfBounds;
4443 }
4444 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4445 c.ids_shm_id, c.ids_shm_offset, data_size);
4446 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434447 SetGLError(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104448 return error::kNoError;
4449 }
4450 if (ids == NULL) {
4451 return error::kOutOfBounds;
4452 }
[email protected]269200b12010-11-18 22:53:064453 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104454 return error::kNoError;
4455}
4456
[email protected]269200b12010-11-18 22:53:064457void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104458 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574459 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104460 for (GLsizei ii = 0; ii < n; ++ii) {
4461 if (!id_allocator->MarkAsUsed(ids[ii])) {
4462 for (GLsizei jj = 0; jj < ii; ++jj) {
4463 id_allocator->FreeID(ids[jj]);
4464 }
4465 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:434466 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4467 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104468 return;
4469 }
4470 }
4471}
4472
[email protected]269200b12010-11-18 22:53:064473error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
4474 uint32 immediate_data_size, const gles2::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104475 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4476 GLsizei n = static_cast<GLsizei>(c.n);
4477 uint32 data_size;
4478 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4479 return error::kOutOfBounds;
4480 }
4481 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4482 c.ids_shm_id, c.ids_shm_offset, data_size);
4483 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434484 SetGLError(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104485 return error::kNoError;
4486 }
4487 if (ids == NULL) {
4488 return error::kOutOfBounds;
4489 }
[email protected]269200b12010-11-18 22:53:064490 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104491 return error::kNoError;
4492}
4493
[email protected]a7266a92012-06-28 02:11:084494error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444495 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204496 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]e259eb412012-10-13 05:47:244497 UNSHIPPED_TRACE_EVENT_INSTANT2(
4498 "test_gpu", "DoClear",
4499 "red", state_.color_clear_red,
4500 "green", state_.color_clear_green);
[email protected]297ca1c2011-06-20 23:08:464501 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274502 glClear(mask);
4503 }
[email protected]a7266a92012-06-28 02:11:084504 return error::kNoError;
4505}
4506
[email protected]36cef8ce2010-03-16 07:34:454507void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4508 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034509 GLuint client_renderbuffer_id) {
[email protected]8e3e0662010-08-23 18:46:304510 FramebufferManager::FramebufferInfo* framebuffer_info =
4511 GetFramebufferInfoForTarget(target);
4512 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294513 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434514 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454515 return;
4516 }
[email protected]ae51d192010-04-27 00:48:034517 GLuint service_id = 0;
[email protected]3a2e7c7b2010-08-06 01:12:284518 RenderbufferManager::RenderbufferInfo* info = NULL;
[email protected]ae51d192010-04-27 00:48:034519 if (client_renderbuffer_id) {
[email protected]3a2e7c7b2010-08-06 01:12:284520 info = GetRenderbufferInfo(client_renderbuffer_id);
[email protected]ae51d192010-04-27 00:48:034521 if (!info) {
[email protected]8eee29c2010-04-29 03:38:294522 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434523 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034524 return;
4525 }
4526 service_id = info->service_id();
4527 }
[email protected]9edc6b22010-12-23 02:00:264528 CopyRealGLErrorsToWrapper();
[email protected]ae51d192010-04-27 00:48:034529 glFramebufferRenderbufferEXT(
4530 target, attachment, renderbuffertarget, service_id);
[email protected]1002c2d2011-06-28 22:39:044531 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264532 if (error == GL_NO_ERROR) {
[email protected]8e3e0662010-08-23 18:46:304533 framebuffer_info->AttachRenderbuffer(attachment, info);
[email protected]3a2e7c7b2010-08-06 01:12:284534 }
[email protected]e259eb412012-10-13 05:47:244535 if (framebuffer_info == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424536 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464537 }
[email protected]3a2e7c7b2010-08-06 01:12:284538}
4539
[email protected]3a2e7c7b2010-08-06 01:12:284540void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464541 if (SetCapabilityState(cap, false)) {
4542 glDisable(cap);
4543 }
[email protected]3a2e7c7b2010-08-06 01:12:284544}
4545
4546void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464547 if (SetCapabilityState(cap, true)) {
4548 glEnable(cap);
4549 }
[email protected]3a2e7c7b2010-08-06 01:12:284550}
4551
[email protected]88a61bf2012-10-27 13:00:424552void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4553 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4554 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4555 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284556}
4557
[email protected]88a61bf2012-10-27 13:00:424558void GLES2DecoderImpl::DoHint(GLenum target, GLenum mode) {
4559 switch (target) {
4560 case GL_GENERATE_MIPMAP_HINT:
4561 state_.hint_generate_mipmap = mode;
4562 break;
4563 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4564 state_.hint_fragment_shader_derivative = mode;
4565 break;
4566 default:
4567 NOTREACHED();
4568 }
4569 glHint(target, mode);
4570}
4571
[email protected]b04e24c2013-01-08 18:35:254572void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424573 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4574 state_.sample_coverage_invert = (invert != 0);
4575 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284576}
4577
[email protected]0d6bfdc2011-11-02 01:32:204578// Assumes framebuffer is complete.
4579void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]8e3e0662010-08-23 18:46:304580 GLenum target, FramebufferManager::FramebufferInfo* info) {
4581 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204582 // bind this to the DRAW point, clear then bind back to READ
4583 // TODO(gman): I don't think there is any guarantee that an FBO that
4584 // is complete on the READ attachment will be complete as a DRAW
4585 // attachment.
4586 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
4587 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, info->service_id());
[email protected]8e3e0662010-08-23 18:46:304588 }
[email protected]3a2e7c7b2010-08-06 01:12:284589 GLbitfield clear_bits = 0;
4590 if (info->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464591 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204592 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464593 (GLES2Util::GetChannelsForFormat(
[email protected]0d6bfdc2011-11-02 01:32:204594 info->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f : 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284595 glColorMask(true, true, true, true);
4596 clear_bits |= GL_COLOR_BUFFER_BIT;
4597 }
4598
4599 if (info->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4600 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
4601 glClearStencil(0);
4602 glStencilMask(-1);
4603 clear_bits |= GL_STENCIL_BUFFER_BIT;
4604 }
4605
4606 if (info->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4607 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
4608 glClearDepth(1.0f);
4609 glDepthMask(true);
4610 clear_bits |= GL_DEPTH_BUFFER_BIT;
4611 }
4612
4613 glDisable(GL_SCISSOR_TEST);
4614 glClear(clear_bits);
4615
[email protected]968351b2011-12-20 08:26:514616 framebuffer_manager()->MarkAttachmentsAsCleared(
4617 info, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284618
[email protected]c007aa02010-09-02 22:22:404619 RestoreClearState();
4620
4621 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204622 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, info->service_id());
[email protected]87d1a3fe2011-12-01 04:25:484623 FramebufferManager::FramebufferInfo* framebuffer =
4624 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4625 GLuint service_id =
4626 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
4627 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404628 }
4629}
4630
4631void GLES2DecoderImpl::RestoreClearState() {
[email protected]88a61bf2012-10-27 13:00:424632 clear_state_dirty_ = true;
[email protected]e259eb412012-10-13 05:47:244633 glClearColor(
4634 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4635 state_.color_clear_alpha);
4636 glClearStencil(state_.stencil_clear);
4637 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224638 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284639 glEnable(GL_SCISSOR_TEST);
4640 }
[email protected]36cef8ce2010-03-16 07:34:454641}
4642
4643GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]0d6bfdc2011-11-02 01:32:204644 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304645 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204646 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454647 return GL_FRAMEBUFFER_COMPLETE;
4648 }
[email protected]0d6bfdc2011-11-02 01:32:204649 GLenum completeness = framebuffer->IsPossiblyComplete();
4650 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4651 return completeness;
4652 }
[email protected]73276522012-11-09 05:50:204653 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454654}
4655
4656void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034657 GLenum target, GLenum attachment, GLenum textarget,
4658 GLuint client_texture_id, GLint level) {
[email protected]8e3e0662010-08-23 18:46:304659 FramebufferManager::FramebufferInfo* framebuffer_info =
4660 GetFramebufferInfoForTarget(target);
4661 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294662 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434663 "glFramebufferTexture2D", "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454664 return;
4665 }
[email protected]ae51d192010-04-27 00:48:034666 GLuint service_id = 0;
[email protected]3a2e7c7b2010-08-06 01:12:284667 TextureManager::TextureInfo* info = NULL;
[email protected]ae51d192010-04-27 00:48:034668 if (client_texture_id) {
[email protected]3a2e7c7b2010-08-06 01:12:284669 info = GetTextureInfo(client_texture_id);
[email protected]ae51d192010-04-27 00:48:034670 if (!info) {
[email protected]8eee29c2010-04-29 03:38:294671 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434672 "glFramebufferTexture2D", "unknown texture");
[email protected]ae51d192010-04-27 00:48:034673 return;
4674 }
4675 service_id = info->service_id();
4676 }
[email protected]0d6bfdc2011-11-02 01:32:204677
[email protected]80eb6b52012-01-19 00:14:414678 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]0d6bfdc2011-11-02 01:32:204679 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434680 "glFramebufferTexture2D", "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204681 return;
4682 }
4683
[email protected]9edc6b22010-12-23 02:00:264684 CopyRealGLErrorsToWrapper();
[email protected]ae51d192010-04-27 00:48:034685 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
[email protected]1002c2d2011-06-28 22:39:044686 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264687 if (error == GL_NO_ERROR) {
4688 framebuffer_info->AttachTexture(attachment, info, textarget, level);
[email protected]3a2e7c7b2010-08-06 01:12:284689 }
[email protected]e259eb412012-10-13 05:47:244690 if (framebuffer_info == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424691 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464692 }
[email protected]36cef8ce2010-03-16 07:34:454693}
4694
4695void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4696 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]8e3e0662010-08-23 18:46:304697 FramebufferManager::FramebufferInfo* framebuffer_info =
4698 GetFramebufferInfoForTarget(target);
4699 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294700 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434701 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454702 return;
4703 }
4704 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:574705 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
4706 GLint type = 0;
4707 GLuint client_id = 0;
4708 glGetFramebufferAttachmentParameterivEXT(
4709 target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
4710 switch (type) {
4711 case GL_RENDERBUFFER: {
4712 renderbuffer_manager()->GetClientId(*params, &client_id);
4713 break;
4714 }
4715 case GL_TEXTURE: {
4716 texture_manager()->GetClientId(*params, &client_id);
4717 break;
4718 }
4719 default:
4720 break;
4721 }
4722 *params = client_id;
4723 }
[email protected]36cef8ce2010-03-16 07:34:454724}
4725
4726void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
4727 GLenum target, GLenum pname, GLint* params) {
[email protected]0d6bfdc2011-11-02 01:32:204728 RenderbufferManager::RenderbufferInfo* renderbuffer =
4729 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4730 if (!renderbuffer) {
[email protected]8eee29c2010-04-29 03:38:294731 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434732 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454733 return;
4734 }
[email protected]3a03a8f2011-03-19 00:51:274735 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434736 case GL_RENDERBUFFER_INTERNAL_FORMAT:
4737 *params = renderbuffer->internal_format();
4738 break;
4739 case GL_RENDERBUFFER_WIDTH:
4740 *params = renderbuffer->width();
4741 break;
4742 case GL_RENDERBUFFER_HEIGHT:
4743 *params = renderbuffer->height();
4744 break;
4745 default:
4746 glGetRenderbufferParameterivEXT(target, pname, params);
4747 break;
[email protected]b71f52c2010-06-18 22:20:204748 }
[email protected]36cef8ce2010-03-16 07:34:454749}
4750
[email protected]8e3e0662010-08-23 18:46:304751void GLES2DecoderImpl::DoBlitFramebufferEXT(
4752 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4753 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4754 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:444755 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:154756 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:304757 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434758 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304759 }
[email protected]d058bca2012-11-26 10:27:264760 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:244761 if (IsAngle()) {
4762 glBlitFramebufferANGLE(
4763 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4764 } else {
4765 glBlitFramebufferEXT(
4766 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4767 }
[email protected]d058bca2012-11-26 10:27:264768 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]529c6672012-01-04 02:18:264769 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", "width", srcX1 - srcX0);
[email protected]8e3e0662010-08-23 18:46:304770}
4771
4772void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
4773 GLenum target, GLsizei samples, GLenum internalformat,
4774 GLsizei width, GLsizei height) {
[email protected]62e155e2012-10-23 22:43:154775 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:304776 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434777 "glRenderbufferStorageMultisampleEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304778 return;
4779 }
[email protected]8e3e0662010-08-23 18:46:304780
[email protected]0d6bfdc2011-11-02 01:32:204781 RenderbufferManager::RenderbufferInfo* renderbuffer =
4782 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4783 if (!renderbuffer) {
4784 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434785 "glGetRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:204786 return;
4787 }
4788
[email protected]84afefa2011-10-19 21:45:534789 if (samples > renderbuffer_manager()->max_samples()) {
4790 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434791 "glGetRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:534792 return;
4793 }
4794
4795 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
4796 height > renderbuffer_manager()->max_renderbuffer_size()) {
4797 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434798 "glGetRenderbufferStorageMultisample", "size too large");
[email protected]84afefa2011-10-19 21:45:534799 return;
4800 }
4801
[email protected]9edc6b22010-12-23 02:00:264802 GLenum impl_format = internalformat;
[email protected]8e3e0662010-08-23 18:46:304803 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
[email protected]9edc6b22010-12-23 02:00:264804 switch (impl_format) {
[email protected]8e3e0662010-08-23 18:46:304805 case GL_DEPTH_COMPONENT16:
[email protected]9edc6b22010-12-23 02:00:264806 impl_format = GL_DEPTH_COMPONENT;
[email protected]8e3e0662010-08-23 18:46:304807 break;
4808 case GL_RGBA4:
4809 case GL_RGB5_A1:
[email protected]9edc6b22010-12-23 02:00:264810 impl_format = GL_RGBA;
[email protected]8e3e0662010-08-23 18:46:304811 break;
4812 case GL_RGB565:
[email protected]9edc6b22010-12-23 02:00:264813 impl_format = GL_RGB;
[email protected]8e3e0662010-08-23 18:46:304814 break;
4815 }
4816 }
4817
[email protected]9edc6b22010-12-23 02:00:264818 CopyRealGLErrorsToWrapper();
[email protected]866b91c52011-03-23 14:38:084819 if (IsAngle()) {
4820 glRenderbufferStorageMultisampleANGLE(
4821 target, samples, impl_format, width, height);
4822 } else {
4823 glRenderbufferStorageMultisampleEXT(
4824 target, samples, impl_format, width, height);
4825 }
[email protected]1002c2d2011-06-28 22:39:044826 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264827 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:514828 // TODO(gman): If renderbuffers tracked which framebuffers they were
4829 // attached to we could just mark those framebuffers as not complete.
4830 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:204831 renderbuffer_manager()->SetInfo(
4832 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:264833 }
[email protected]8e3e0662010-08-23 18:46:304834}
4835
[email protected]36cef8ce2010-03-16 07:34:454836void GLES2DecoderImpl::DoRenderbufferStorage(
4837 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]0d6bfdc2011-11-02 01:32:204838 RenderbufferManager::RenderbufferInfo* renderbuffer =
4839 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4840 if (!renderbuffer) {
[email protected]8eee29c2010-04-29 03:38:294841 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434842 "glGetRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454843 return;
4844 }
[email protected]876f6fee2010-08-02 23:10:324845
[email protected]84afefa2011-10-19 21:45:534846 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
4847 height > renderbuffer_manager()->max_renderbuffer_size()) {
4848 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434849 "glGetRenderbufferStorage", "size too large");
[email protected]84afefa2011-10-19 21:45:534850 return;
4851 }
4852
[email protected]9edc6b22010-12-23 02:00:264853 GLenum impl_format = internalformat;
[email protected]876f6fee2010-08-02 23:10:324854 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
[email protected]9edc6b22010-12-23 02:00:264855 switch (impl_format) {
[email protected]876f6fee2010-08-02 23:10:324856 case GL_DEPTH_COMPONENT16:
[email protected]9edc6b22010-12-23 02:00:264857 impl_format = GL_DEPTH_COMPONENT;
[email protected]876f6fee2010-08-02 23:10:324858 break;
4859 case GL_RGBA4:
4860 case GL_RGB5_A1:
[email protected]9edc6b22010-12-23 02:00:264861 impl_format = GL_RGBA;
[email protected]876f6fee2010-08-02 23:10:324862 break;
4863 case GL_RGB565:
[email protected]9edc6b22010-12-23 02:00:264864 impl_format = GL_RGB;
[email protected]876f6fee2010-08-02 23:10:324865 break;
4866 }
[email protected]b71f52c2010-06-18 22:20:204867 }
[email protected]876f6fee2010-08-02 23:10:324868
[email protected]9edc6b22010-12-23 02:00:264869 CopyRealGLErrorsToWrapper();
4870 glRenderbufferStorageEXT(target, impl_format, width, height);
[email protected]1002c2d2011-06-28 22:39:044871 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264872 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:514873 // TODO(gman): If tetxures tracked which framebuffers they were attached to
4874 // we could just mark those framebuffers as not complete.
4875 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:204876 renderbuffer_manager()->SetInfo(
4877 renderbuffer, 0, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:264878 }
[email protected]36cef8ce2010-03-16 07:34:454879}
4880
[email protected]07f54fcc2009-12-22 02:46:304881void GLES2DecoderImpl::DoLinkProgram(GLuint program) {
[email protected]43ed3a72012-05-30 22:55:384882 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]6b8cf1a2010-05-06 16:13:584883 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4884 program, "glLinkProgram");
[email protected]a93bb842010-02-16 23:03:474885 if (!info) {
[email protected]a93bb842010-02-16 23:03:474886 return;
4887 }
[email protected]05afda12011-01-20 00:17:344888
[email protected]cae20172012-12-07 00:06:194889 LogClientServiceForInfo(info, program, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:394890 ShaderTranslator* vertex_translator = NULL;
4891 ShaderTranslator* fragment_translator = NULL;
4892 if (use_shader_translator_) {
4893 vertex_translator = vertex_translator_;
4894 fragment_translator = fragment_translator_;
4895 }
4896 if (info->Link(shader_manager(),
4897 vertex_translator,
4898 fragment_translator,
4899 feature_info_)) {
[email protected]e259eb412012-10-13 05:47:244900 if (info == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:154901 if (workarounds().use_current_program_after_successful_link) {
4902 glUseProgram(info->service_id());
[email protected]c2a3caf12012-10-23 19:32:004903 }
[email protected]62e155e2012-10-23 22:43:154904 program_manager()->ClearUniforms(info);
[email protected]2df73892012-04-28 01:09:544905 }
4906 }
[email protected]07f54fcc2009-12-22 02:46:304907};
4908
[email protected]3916c97e2010-02-25 03:20:504909void GLES2DecoderImpl::DoTexParameterf(
4910 GLenum target, GLenum pname, GLfloat param) {
4911 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]07f54fcc2009-12-22 02:46:304912 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434913 SetGLError(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244914 return;
[email protected]07f54fcc2009-12-22 02:46:304915 }
[email protected]cbb22e42011-05-12 23:36:244916
[email protected]445a8762012-12-06 15:43:214917 GLenum error = texture_manager()->SetParameter(
4918 info, pname, static_cast<GLint>(param));
4919 if (error != GL_NO_ERROR) {
4920 SetGLErrorInvalidParam(
4921 error, "glTexParameterf", pname, static_cast<GLint>(param));
[email protected]cbb22e42011-05-12 23:36:244922 return;
4923 }
4924 glTexParameterf(target, pname, param);
[email protected]07f54fcc2009-12-22 02:46:304925}
4926
[email protected]3916c97e2010-02-25 03:20:504927void GLES2DecoderImpl::DoTexParameteri(
4928 GLenum target, GLenum pname, GLint param) {
4929 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4930 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434931 SetGLError(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244932 return;
[email protected]3916c97e2010-02-25 03:20:504933 }
[email protected]cbb22e42011-05-12 23:36:244934
[email protected]445a8762012-12-06 15:43:214935 GLenum error = texture_manager()->SetParameter(info, pname, param);
[email protected]b04e24c2013-01-08 18:35:254936 if (error != GL_NO_ERROR) {
[email protected]445a8762012-12-06 15:43:214937 SetGLErrorInvalidParam(error, "glTexParameteri", pname, param);
[email protected]cbb22e42011-05-12 23:36:244938 return;
4939 }
[email protected]36f65962012-12-14 21:38:564940 // Texture tracking pools exist only for the command decoder, so
4941 // do not pass them on to the native GL implementation.
4942 if (pname == GL_TEXTURE_POOL_CHROMIUM) {
4943 return;
4944 }
[email protected]cbb22e42011-05-12 23:36:244945 glTexParameteri(target, pname, param);
[email protected]3916c97e2010-02-25 03:20:504946}
4947
4948void GLES2DecoderImpl::DoTexParameterfv(
4949 GLenum target, GLenum pname, const GLfloat* params) {
4950 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4951 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434952 SetGLError(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244953 return;
[email protected]3916c97e2010-02-25 03:20:504954 }
[email protected]cbb22e42011-05-12 23:36:244955
[email protected]445a8762012-12-06 15:43:214956 GLenum error =texture_manager()->SetParameter(
4957 info, pname, static_cast<GLint>(params[0]));
4958 if (error != GL_NO_ERROR) {
4959 SetGLErrorInvalidParam(
4960 error, "glTexParameterfv", pname, static_cast<GLint>(params[0]));
[email protected]cbb22e42011-05-12 23:36:244961 return;
4962 }
4963 glTexParameterfv(target, pname, params);
[email protected]3916c97e2010-02-25 03:20:504964}
4965
4966void GLES2DecoderImpl::DoTexParameteriv(
4967 GLenum target, GLenum pname, const GLint* params) {
4968 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4969 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434970 SetGLError(GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244971 return;
[email protected]3916c97e2010-02-25 03:20:504972 }
[email protected]cbb22e42011-05-12 23:36:244973
[email protected]445a8762012-12-06 15:43:214974 GLenum error = texture_manager()->SetParameter(info, pname, *params);
4975 if (error != GL_NO_ERROR) {
4976 SetGLErrorInvalidParam(error, "glTexParameteriv", pname, *params);
[email protected]cbb22e42011-05-12 23:36:244977 return;
4978 }
4979 glTexParameteriv(target, pname, params);
[email protected]3916c97e2010-02-25 03:20:504980}
4981
[email protected]939e7362010-05-13 20:49:104982bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]e259eb412012-10-13 05:47:244983 if (!state_.current_program) {
[email protected]ad84a3a2012-06-08 21:42:434984 // The program does not exist.
4985 SetGLError(GL_INVALID_OPERATION, function_name, "no program in use");
4986 return false;
[email protected]939e7362010-05-13 20:49:104987 }
[email protected]e259eb412012-10-13 05:47:244988 if (!state_.current_program->InUse()) {
[email protected]ad84a3a2012-06-08 21:42:434989 SetGLError(GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:104990 return false;
4991 }
4992 return true;
4993}
4994
4995bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
4996 GLint location, const char* function_name) {
4997 if (!CheckCurrentProgram(function_name)) {
4998 return false;
4999 }
5000 return location != -1;
5001}
5002
[email protected]476ccb72012-12-06 15:52:525003namespace {
5004
5005static const GLenum valid_int_vec1_types_list[] = {
5006 GL_INT,
5007 GL_BOOL,
5008 GL_SAMPLER_2D,
5009 GL_SAMPLER_2D_RECT_ARB,
5010 GL_SAMPLER_CUBE,
5011 GL_SAMPLER_EXTERNAL_OES,
5012};
5013
5014static const GLenum valid_int_vec2_types_list[] = {
5015 GL_INT_VEC2,
5016 GL_BOOL_VEC2,
5017};
5018
5019static const GLenum valid_int_vec3_types_list[] = {
5020 GL_INT_VEC3,
5021 GL_BOOL_VEC3,
5022};
5023
5024static const GLenum valid_int_vec4_types_list[] = {
5025 GL_INT_VEC4,
5026 GL_BOOL_VEC4,
5027};
5028
5029static const GLenum valid_float_vec1_types_list[] = {
5030 GL_FLOAT,
5031 GL_BOOL,
5032};
5033
5034static const GLenum valid_float_vec2_types_list[] = {
5035 GL_FLOAT_VEC2,
5036 GL_BOOL_VEC2,
5037};
5038
5039static const GLenum valid_float_vec3_types_list[] = {
5040 GL_FLOAT_VEC3,
5041 GL_BOOL_VEC3,
5042};
5043
5044static const GLenum valid_float_vec4_types_list[] = {
5045 GL_FLOAT_VEC4,
5046 GL_BOOL_VEC4,
5047};
5048
5049static const GLenum valid_float_mat2_types_list[] = {
5050 GL_FLOAT_MAT2,
5051};
5052
5053static const GLenum valid_float_mat3_types_list[] = {
5054 GL_FLOAT_MAT3,
5055};
5056
5057static const GLenum valid_float_mat4_types_list[] = {
5058 GL_FLOAT_MAT4,
5059};
5060
5061static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5062 valid_int_vec1_types_list,
5063 arraysize(valid_int_vec1_types_list),
5064};
5065
5066static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5067 valid_int_vec2_types_list,
5068 arraysize(valid_int_vec2_types_list),
5069};
5070
5071static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5072 valid_int_vec3_types_list,
5073 arraysize(valid_int_vec3_types_list),
5074};
5075
5076static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5077 valid_int_vec4_types_list,
5078 arraysize(valid_int_vec4_types_list),
5079};
5080
5081static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5082 valid_float_vec1_types_list,
5083 arraysize(valid_float_vec1_types_list),
5084};
5085
5086static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5087 valid_float_vec2_types_list,
5088 arraysize(valid_float_vec2_types_list),
5089};
5090
5091static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5092 valid_float_vec3_types_list,
5093 arraysize(valid_float_vec3_types_list),
5094};
5095
5096static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5097 valid_float_vec4_types_list,
5098 arraysize(valid_float_vec4_types_list),
5099};
5100
5101static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5102 valid_float_mat2_types_list,
5103 arraysize(valid_float_mat2_types_list),
5104};
5105
5106static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5107 valid_float_mat3_types_list,
5108 arraysize(valid_float_mat3_types_list),
5109};
5110
5111static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5112 valid_float_mat4_types_list,
5113 arraysize(valid_float_mat4_types_list),
5114};
5115
5116} // anonymous namespace.
5117
[email protected]43c2f1f2011-03-25 18:35:365118bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125119 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525120 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125121 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365122 DCHECK(type);
5123 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125124 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525125
[email protected]1b0a6752012-02-22 03:44:125126 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105127 return false;
5128 }
[email protected]43c2f1f2011-03-25 18:35:365129 GLint array_index = -1;
5130 const ProgramManager::ProgramInfo::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245131 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125132 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365133 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:435134 SetGLError(GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105135 return false;
5136 }
[email protected]476ccb72012-12-06 15:52:525137 bool okay = false;
5138 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5139 if (base_info.valid_types[ii] == info->type) {
5140 okay = true;
5141 break;
5142 }
5143 }
5144 if (!okay) {
5145 SetGLError(
5146 GL_INVALID_OPERATION, function_name, "wrong uniform function for type");
5147 return false;
5148 }
[email protected]43c2f1f2011-03-25 18:35:365149 if (*count > 1 && !info->is_array) {
5150 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435151 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365152 return false;
5153 }
5154 *count = std::min(info->size - array_index, *count);
5155 if (*count <= 0) {
5156 return false;
5157 }
5158 *type = info->type;
[email protected]939e7362010-05-13 20:49:105159 return true;
5160}
5161
[email protected]1b0a6752012-02-22 03:44:125162void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5163 GLenum type = 0;
5164 GLsizei count = 1;
5165 GLint real_location = -1;
5166 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525167 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5168 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505169 return;
5170 }
[email protected]e259eb412012-10-13 05:47:245171 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025172 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ad84a3a2012-06-08 21:42:435173 SetGLError(GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465174 return;
5175 }
[email protected]1b0a6752012-02-22 03:44:125176 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505177}
5178
5179void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125180 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365181 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125182 GLint real_location = -1;
5183 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525184 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5185 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365186 return;
5187 }
[email protected]74727112012-06-13 21:18:085188 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5189 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245190 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025191 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ad84a3a2012-06-08 21:42:435192 SetGLError(GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465193 return;
5194 }
[email protected]43c2f1f2011-03-25 18:35:365195 }
[email protected]1b0a6752012-02-22 03:44:125196 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505197}
5198
[email protected]939e7362010-05-13 20:49:105199void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125200 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365201 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125202 GLint real_location = -1;
5203 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525204 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5205 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105206 return;
5207 }
5208 if (type == GL_BOOL) {
5209 scoped_array<GLint> temp(new GLint[count]);
5210 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535211 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105212 }
[email protected]1b0a6752012-02-22 03:44:125213 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105214 } else {
[email protected]1b0a6752012-02-22 03:44:125215 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105216 }
5217}
5218
5219void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125220 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365221 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125222 GLint real_location = -1;
5223 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525224 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5225 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105226 return;
5227 }
5228 if (type == GL_BOOL_VEC2) {
5229 GLsizei num_values = count * 2;
5230 scoped_array<GLint> temp(new GLint[num_values]);
5231 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535232 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105233 }
[email protected]1b0a6752012-02-22 03:44:125234 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105235 } else {
[email protected]1b0a6752012-02-22 03:44:125236 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105237 }
5238}
5239
5240void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125241 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365242 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125243 GLint real_location = -1;
5244 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525245 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5246 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105247 return;
5248 }
5249 if (type == GL_BOOL_VEC3) {
5250 GLsizei num_values = count * 3;
5251 scoped_array<GLint> temp(new GLint[num_values]);
5252 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535253 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105254 }
[email protected]1b0a6752012-02-22 03:44:125255 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105256 } else {
[email protected]1b0a6752012-02-22 03:44:125257 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105258 }
5259}
5260
5261void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125262 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365263 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125264 GLint real_location = -1;
5265 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525266 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5267 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105268 return;
5269 }
5270 if (type == GL_BOOL_VEC4) {
5271 GLsizei num_values = count * 4;
5272 scoped_array<GLint> temp(new GLint[num_values]);
5273 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535274 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105275 }
[email protected]1b0a6752012-02-22 03:44:125276 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105277 } else {
[email protected]1b0a6752012-02-22 03:44:125278 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105279 }
5280}
5281
[email protected]43c2f1f2011-03-25 18:35:365282void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125283 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365284 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125285 GLint real_location = -1;
5286 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525287 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5288 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365289 return;
5290 }
[email protected]1b0a6752012-02-22 03:44:125291 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365292}
5293
5294void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125295 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365296 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125297 GLint real_location = -1;
5298 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525299 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5300 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365301 return;
5302 }
[email protected]1b0a6752012-02-22 03:44:125303 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365304}
5305
5306void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125307 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365308 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125309 GLint real_location = -1;
5310 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525311 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5312 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365313 return;
5314 }
[email protected]1b0a6752012-02-22 03:44:125315 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365316}
5317
5318void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125319 GLint fake_location, GLsizei count, GLboolean transpose,
5320 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365321 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125322 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365323 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525324 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5325 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365326 return;
5327 }
[email protected]1b0a6752012-02-22 03:44:125328 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365329}
5330
5331void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125332 GLint fake_location, GLsizei count, GLboolean transpose,
5333 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365334 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125335 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365336 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525337 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5338 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365339 return;
5340 }
[email protected]1b0a6752012-02-22 03:44:125341 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365342}
5343
5344void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125345 GLint fake_location, GLsizei count, GLboolean transpose,
5346 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365347 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125348 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365349 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525350 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5351 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365352 return;
5353 }
[email protected]1b0a6752012-02-22 03:44:125354 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365355}
5356
[email protected]3916c97e2010-02-25 03:20:505357void GLES2DecoderImpl::DoUseProgram(GLuint program) {
[email protected]ae51d192010-04-27 00:48:035358 GLuint service_id = 0;
[email protected]3916c97e2010-02-25 03:20:505359 ProgramManager::ProgramInfo* info = NULL;
5360 if (program) {
[email protected]6b8cf1a2010-05-06 16:13:585361 info = GetProgramInfoNotShader(program, "glUseProgram");
[email protected]3916c97e2010-02-25 03:20:505362 if (!info) {
[email protected]ae51d192010-04-27 00:48:035363 return;
5364 }
5365 if (!info->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505366 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ad84a3a2012-06-08 21:42:435367 SetGLError(GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505368 return;
5369 }
[email protected]ae51d192010-04-27 00:48:035370 service_id = info->service_id();
[email protected]3916c97e2010-02-25 03:20:505371 }
[email protected]e259eb412012-10-13 05:47:245372 if (state_.current_program) {
5373 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
[email protected]ca488e12010-12-13 20:06:145374 }
[email protected]e259eb412012-10-13 05:47:245375 state_.current_program = info;
[email protected]cae20172012-12-07 00:06:195376 LogClientServiceMapping("glUseProgram", program, service_id);
[email protected]2df73892012-04-28 01:09:545377 glUseProgram(service_id);
[email protected]e259eb412012-10-13 05:47:245378 if (state_.current_program) {
5379 program_manager()->UseProgram(state_.current_program);
[email protected]ca488e12010-12-13 20:06:145380 }
[email protected]3916c97e2010-02-25 03:20:505381}
5382
[email protected]efcdd2362012-07-09 21:07:005383uint32 GLES2DecoderImpl::GetGLError() {
[email protected]96449d2c2009-11-25 00:01:325384 // Check the GL error first, then our wrapped error.
5385 GLenum error = glGetError();
5386 if (error == GL_NO_ERROR && error_bits_ != 0) {
[email protected]03f882a2010-01-08 20:46:375387 for (uint32 mask = 1; mask != 0; mask = mask << 1) {
[email protected]96449d2c2009-11-25 00:01:325388 if ((error_bits_ & mask) != 0) {
[email protected]ddd968b82010-03-02 00:44:295389 error = GLES2Util::GLErrorBitToGLError(mask);
[email protected]96449d2c2009-11-25 00:01:325390 break;
5391 }
5392 }
5393 }
5394
5395 if (error != GL_NO_ERROR) {
5396 // There was an error, clear the corresponding wrapped error.
[email protected]ddd968b82010-03-02 00:44:295397 error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
[email protected]96449d2c2009-11-25 00:01:325398 }
5399 return error;
5400}
5401
[email protected]1002c2d2011-06-28 22:39:045402GLenum GLES2DecoderImpl::PeekGLError() {
5403 GLenum error = glGetError();
5404 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435405 SetGLError(error, "", "");
[email protected]1002c2d2011-06-28 22:39:045406 }
5407 return error;
5408}
5409
[email protected]ad84a3a2012-06-08 21:42:435410void GLES2DecoderImpl::SetGLError(
5411 GLenum error, const char* function_name, const char* msg) {
[email protected]8eee29c2010-04-29 03:38:295412 if (msg) {
5413 last_error_ = msg;
[email protected]d2a0e1a2012-08-12 02:25:015414 LogMessage(GetLogPrefix() + ": " + std::string("GL ERROR :") +
[email protected]ad84a3a2012-06-08 21:42:435415 GLES2Util::GetStringEnum(error) + " : " +
5416 function_name + ": " + msg);
[email protected]8eee29c2010-04-29 03:38:295417 }
[email protected]ddd968b82010-03-02 00:44:295418 error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
[email protected]96449d2c2009-11-25 00:01:325419}
5420
[email protected]f80e6e12012-08-31 00:43:535421void GLES2DecoderImpl::SetGLErrorInvalidEnum(
5422 const char* function_name, GLenum value, const char* label) {
5423 SetGLError(GL_INVALID_ENUM, function_name,
5424 (std::string(label) + " was " +
5425 GLES2Util::GetStringEnum(value)).c_str());
5426}
5427
[email protected]445a8762012-12-06 15:43:215428void GLES2DecoderImpl::SetGLErrorInvalidParam(
5429 GLenum error,
5430 const char* function_name,
5431 GLenum pname,
5432 GLint param) {
5433 if (error == GL_INVALID_ENUM) {
5434 SetGLError(
5435 GL_INVALID_ENUM, function_name,
5436 (std::string("trying to set ") +
5437 GLES2Util::GetStringEnum(pname) + " to " +
5438 GLES2Util::GetStringEnum(param)).c_str());
5439 } else {
5440 SetGLError(
5441 error, function_name,
5442 (std::string("trying to set ") +
5443 GLES2Util::GetStringEnum(pname) + " to " +
5444 base::StringPrintf("%d", param)).c_str());
5445 }
5446}
5447
[email protected]d2a0e1a2012-08-12 02:25:015448const std::string& GLES2DecoderImpl::GetLogPrefix() const {
5449 const std::string& prefix(debug_marker_manager_.GetMarker());
5450 return prefix.empty() ? this_in_hex_ : prefix;
5451}
5452
[email protected]0f8afe82012-05-14 23:43:015453void GLES2DecoderImpl::LogMessage(const std::string& msg) {
5454 if (log_message_count_ < kMaxLogMessages ||
5455 CommandLine::ForCurrentProcess()->HasSwitch(
5456 switches::kDisableGLErrorLimit)) {
5457 ++log_message_count_;
5458 // LOG this unless logging is turned off as any chromium code that
5459 // generates these errors probably has a bug.
5460 if (log_synthesized_gl_errors()) {
[email protected]3f00df92012-06-19 00:44:585461 LOG(ERROR) << msg;
[email protected]0f8afe82012-05-14 23:43:015462 }
5463 if (!msg_callback_.is_null()) {
5464 msg_callback_.Run(0, msg);
5465 }
5466 } else {
5467 if (log_message_count_ == kMaxLogMessages) {
5468 ++log_message_count_;
5469 LOG(ERROR)
5470 << "Too many GL errors, not reporting any more for this context."
5471 << " use --disable-gl-error-limit to see all errors.";
5472 }
5473 }
5474}
5475
5476void GLES2DecoderImpl::RenderWarning(const std::string& msg) {
5477 LogMessage(std::string("RENDER WARNING: ") + msg);
5478}
5479
5480void GLES2DecoderImpl::PerformanceWarning(const std::string& msg) {
5481 LogMessage(std::string("PERFORMANCE WARNING: ") + msg);
5482}
5483
[email protected]c447acd2012-07-23 23:48:415484void GLES2DecoderImpl::ForceCompileShaderIfPending(
5485 ShaderManager::ShaderInfo* info) {
5486 if (info->compilation_status() ==
5487 ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE) {
[email protected]c447acd2012-07-23 23:48:415488 ShaderTranslator* translator = NULL;
5489 if (use_shader_translator_) {
5490 translator = info->shader_type() == GL_VERTEX_SHADER ?
5491 vertex_translator_.get() : fragment_translator_.get();
5492 }
5493 // We know there will be no errors, because we only defer compilation on
5494 // shaders that were previously compiled successfully.
5495 program_manager()->ForceCompileShader(info->deferred_compilation_source(),
5496 info,
5497 translator,
5498 feature_info_);
5499 }
5500}
5501
[email protected]07f54fcc2009-12-22 02:46:305502void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() {
5503 GLenum error;
5504 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435505 SetGLError(error, "", NULL);
[email protected]07f54fcc2009-12-22 02:46:305506 }
5507}
5508
[email protected]6217d392010-03-25 22:08:355509void GLES2DecoderImpl::ClearRealGLErrors() {
5510 GLenum error;
5511 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]3ed14d112011-12-13 22:05:515512 if (error != GL_OUT_OF_MEMORY) {
5513 // GL_OUT_OF_MEMORY can legally happen on lost device.
5514 NOTREACHED() << "GL error " << error << " was unhandled.";
5515 }
[email protected]6217d392010-03-25 22:08:355516 }
5517}
5518
[email protected]ef526492010-06-02 23:12:255519bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245520 DCHECK(state_.current_program);
[email protected]ef526492010-06-02 23:12:255521 // Only check if there are some unrenderable textures.
5522 if (!texture_manager()->HaveUnrenderableTextures()) {
5523 return false;
5524 }
5525 bool textures_set = false;
[email protected]3916c97e2010-02-25 03:20:505526 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245527 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505528 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5529 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245530 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505531 DCHECK(uniform_info);
5532 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5533 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025534 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245535 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]3916c97e2010-02-25 03:20:505536 TextureManager::TextureInfo* texture_info =
[email protected]61eeb33f2011-07-26 15:30:315537 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]80eb6b52012-01-19 00:14:415538 if (!texture_info || !texture_manager()->CanRender(texture_info)) {
[email protected]ef526492010-06-02 23:12:255539 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505540 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5541 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315542 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495543 texture_manager()->black_texture_id(uniform_info->type));
[email protected]0f8afe82012-05-14 23:43:015544 RenderWarning(
5545 std::string("texture bound to texture unit ") +
5546 base::IntToString(texture_unit_index) +
5547 " is not renderable. It maybe non-power-of-2 and have "
5548 " incompatible texture filtering or is not "
5549 "'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505550 }
5551 }
5552 // else: should this be an error?
5553 }
5554 }
[email protected]ef526492010-06-02 23:12:255555 return textures_set;
[email protected]3916c97e2010-02-25 03:20:505556}
5557
5558void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245559 DCHECK(state_.current_program);
[email protected]3916c97e2010-02-25 03:20:505560 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245561 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505562 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5563 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245564 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505565 DCHECK(uniform_info);
5566 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5567 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025568 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245569 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]3916c97e2010-02-25 03:20:505570 TextureManager::TextureInfo* texture_info =
5571 uniform_info->type == GL_SAMPLER_2D ?
5572 texture_unit.bound_texture_2d :
5573 texture_unit.bound_texture_cube_map;
[email protected]80eb6b52012-01-19 00:14:415574 if (!texture_info || !texture_manager()->CanRender(texture_info)) {
[email protected]3916c97e2010-02-25 03:20:505575 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5576 // Get the texture info that was previously bound here.
5577 texture_info = texture_unit.bind_target == GL_TEXTURE_2D ?
5578 texture_unit.bound_texture_2d :
5579 texture_unit.bound_texture_cube_map;
5580 glBindTexture(texture_unit.bind_target,
[email protected]ae51d192010-04-27 00:48:035581 texture_info ? texture_info->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505582 }
5583 }
5584 }
5585 }
5586 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245587 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305588}
5589
[email protected]0d6bfdc2011-11-02 01:32:205590bool GLES2DecoderImpl::ClearUnclearedTextures() {
5591 // Only check if there are some uncleared textures.
5592 if (!texture_manager()->HaveUnsafeTextures()) {
5593 return true;
5594 }
5595
5596 // 1: Check all textures we are about to render with.
[email protected]e259eb412012-10-13 05:47:245597 if (state_.current_program) {
[email protected]0d6bfdc2011-11-02 01:32:205598 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245599 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205600 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5601 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245602 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205603 DCHECK(uniform_info);
5604 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5605 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025606 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245607 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]0d6bfdc2011-11-02 01:32:205608 TextureManager::TextureInfo* texture_info =
5609 texture_unit.GetInfoForSamplerType(uniform_info->type);
5610 if (texture_info && !texture_info->SafeToRenderFrom()) {
5611 if (!texture_manager()->ClearRenderableLevels(this, texture_info)) {
5612 return false;
5613 }
5614 }
5615 }
5616 }
5617 }
5618 }
5619 return true;
5620}
5621
[email protected]c6aef902012-02-14 03:31:425622bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435623 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035624 // NOTE: We specifically do not check current_program->IsValid() because
5625 // it could never be invalid since glUseProgram would have failed. While
5626 // glLinkProgram could later mark the program as invalid the previous
5627 // valid program will still function if it is still the current program.
[email protected]e259eb412012-10-13 05:47:245628 if (!state_.current_program) {
[email protected]3916c97e2010-02-25 03:20:505629 // The program does not exist.
5630 // But GL says no ERROR.
[email protected]0f8afe82012-05-14 23:43:015631 RenderWarning("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505632 return false;
5633 }
[email protected]c6aef902012-02-14 03:31:425634
5635 // true if any enabled, used divisor is zero
5636 bool divisor0 = false;
[email protected]f39f4b3f2010-05-12 17:04:085637 // Validate all attribs currently enabled. If they are used by the current
5638 // program then check that they have enough elements to handle the draw call.
5639 // If they are not used by the current program check that they have a buffer
5640 // assigned.
5641 const VertexAttribManager::VertexAttribInfoList& infos =
[email protected]e259eb412012-10-13 05:47:245642 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos();
[email protected]f39f4b3f2010-05-12 17:04:085643 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
[email protected]8fbedc02010-11-18 18:43:405644 infos.begin(); it != infos.end(); ++it) {
[email protected]f39f4b3f2010-05-12 17:04:085645 const VertexAttribManager::VertexAttribInfo* info = *it;
5646 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245647 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]f39f4b3f2010-05-12 17:04:085648 if (attrib_info) {
[email protected]c6aef902012-02-14 03:31:425649 divisor0 |= (info->divisor() == 0);
5650 GLuint count = info->MaxVertexAccessed(primcount, max_vertex_accessed);
[email protected]f39f4b3f2010-05-12 17:04:085651 // This attrib is used in the current program.
[email protected]c6aef902012-02-14 03:31:425652 if (!info->CanAccess(count)) {
[email protected]0f8afe82012-05-14 23:43:015653 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435654 GL_INVALID_OPERATION, function_name,
[email protected]0f8afe82012-05-14 23:43:015655 (std::string(
[email protected]ad84a3a2012-06-08 21:42:435656 "attempt to access out of range vertices in attribute ") +
5657 base::IntToString(info->index())).c_str());
[email protected]f39f4b3f2010-05-12 17:04:085658 return false;
5659 }
5660 } else {
5661 // This attrib is not used in the current program.
[email protected]a0b78dc2011-11-11 10:43:105662 if (!info->buffer()) {
[email protected]f39f4b3f2010-05-12 17:04:085663 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435664 GL_INVALID_OPERATION, function_name,
[email protected]0f8afe82012-05-14 23:43:015665 (std::string(
[email protected]ad84a3a2012-06-08 21:42:435666 "attempt to render with no buffer attached to "
[email protected]0f8afe82012-05-14 23:43:015667 "enabled attribute ") +
5668 base::IntToString(info->index())).c_str());
[email protected]f39f4b3f2010-05-12 17:04:085669 return false;
5670 }
[email protected]1d32bc82010-01-13 22:06:465671 }
[email protected]07f54fcc2009-12-22 02:46:305672 }
[email protected]c6aef902012-02-14 03:31:425673
5674 if (primcount && !divisor0) {
5675 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435676 GL_INVALID_OPERATION, function_name,
5677 "attempt instanced render with all attributes having "
[email protected]c6aef902012-02-14 03:31:425678 "non-zero divisors");
5679 return false;
5680 }
5681
[email protected]3916c97e2010-02-25 03:20:505682 return true;
[email protected]b1122982010-05-17 23:04:245683}
5684
[email protected]c13e1da62011-09-09 21:48:305685bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435686 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305687 DCHECK(simulated);
5688 *simulated = false;
5689
[email protected]876f6fee2010-08-02 23:10:325690 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305691 return true;
[email protected]876f6fee2010-08-02 23:10:325692
[email protected]b1122982010-05-17 23:04:245693 const VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:245694 state_.vertex_attrib_manager->GetVertexAttribInfo(0);
[email protected]b1122982010-05-17 23:04:245695 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245696 bool attrib_0_used =
5697 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]fc753442011-02-04 19:49:495698 if (info->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305699 return true;
[email protected]b1122982010-05-17 23:04:245700 }
5701
[email protected]b1122982010-05-17 23:04:245702 // Make a buffer with a single repeated vec4 value enough to
5703 // simulate the constant value that is supposed to be here.
5704 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305705 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475706 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305707
5708 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475709 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305710 size_needed > 0x7FFFFFFFU) {
[email protected]ad84a3a2012-06-08 21:42:435711 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305712 return false;
5713 }
5714
[email protected]0f8afe82012-05-14 23:43:015715 PerformanceWarning(
5716 "Attribute 0 is disabled. This has signficant performance penalty");
5717
[email protected]c13e1da62011-09-09 21:48:305718 CopyRealGLErrorsToWrapper();
5719 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5720
[email protected]8f0b86c2f2012-04-10 05:48:285721 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5722 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495723 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305724 GLenum error = glGetError();
5725 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435726 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305727 return false;
5728 }
[email protected]fc753442011-02-04 19:49:495729 }
[email protected]af6380962012-11-29 23:24:135730
5731 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:285732 if (new_buffer ||
5733 (attrib_0_used &&
5734 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:135735 (value.v[0] != attrib_0_value_.v[0] ||
5736 value.v[1] != attrib_0_value_.v[1] ||
5737 value.v[2] != attrib_0_value_.v[2] ||
5738 value.v[3] != attrib_0_value_.v[3])))) {
5739 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:495740 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
5741 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:135742 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:245743 attrib_0_size_ = size_needed;
5744 }
5745
5746 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
5747
[email protected]c6aef902012-02-14 03:31:425748 if (info->divisor())
5749 glVertexAttribDivisorANGLE(0, 0);
5750
[email protected]c13e1da62011-09-09 21:48:305751 *simulated = true;
[email protected]b1122982010-05-17 23:04:245752 return true;
[email protected]b1122982010-05-17 23:04:245753}
5754
[email protected]43410e92012-04-20 17:06:285755void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib) {
[email protected]b1122982010-05-17 23:04:245756 const VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:245757 state_.vertex_attrib_manager->GetVertexAttribInfo(attrib);
[email protected]b1122982010-05-17 23:04:245758 const void* ptr = reinterpret_cast<const void*>(info->offset());
5759 BufferManager::BufferInfo* buffer_info = info->buffer();
5760 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0);
5761 glVertexAttribPointer(
[email protected]43410e92012-04-20 17:06:285762 attrib, info->size(), info->type(), info->normalized(), info->gl_stride(),
[email protected]b1122982010-05-17 23:04:245763 ptr);
[email protected]c6aef902012-02-14 03:31:425764 if (info->divisor())
[email protected]43410e92012-04-20 17:06:285765 glVertexAttribDivisorANGLE(attrib, info->divisor());
[email protected]e259eb412012-10-13 05:47:245766 glBindBuffer(
5767 GL_ARRAY_BUFFER,
5768 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:285769
[email protected]265f8992012-07-20 01:03:145770 // Never touch vertex attribute 0's state (in particular, never
5771 // disable it) when running on desktop GL because it will never be
5772 // re-enabled.
5773 if (attrib != 0 ||
5774 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
5775 if (info->enabled()) {
5776 glEnableVertexAttribArray(attrib);
5777 } else {
5778 glDisableVertexAttribArray(attrib);
5779 }
[email protected]43410e92012-04-20 17:06:285780 }
[email protected]b1122982010-05-17 23:04:245781}
[email protected]07f54fcc2009-12-22 02:46:305782
[email protected]8fbedc02010-11-18 18:43:405783bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:435784 const char* function_name,
[email protected]c6aef902012-02-14 03:31:425785 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:405786 DCHECK(simulated);
5787 *simulated = false;
5788 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
5789 return true;
5790
[email protected]e259eb412012-10-13 05:47:245791 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:405792 return true;
5793 }
5794
[email protected]0f8afe82012-05-14 23:43:015795 PerformanceWarning(
5796 "GL_FIXED attributes have a signficant performance penalty");
5797
[email protected]8fbedc02010-11-18 18:43:405798 // NOTE: we could be smart and try to check if a buffer is used
5799 // twice in 2 different attribs, find the overlapping parts and therefore
5800 // duplicate the minimum amount of data but this whole code path is not meant
5801 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
5802 // tests so we just add to the buffer attrib used.
5803
[email protected]c13e1da62011-09-09 21:48:305804 GLuint elements_needed = 0;
[email protected]8fbedc02010-11-18 18:43:405805 const VertexAttribManager::VertexAttribInfoList& infos =
[email protected]e259eb412012-10-13 05:47:245806 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos();
[email protected]8fbedc02010-11-18 18:43:405807 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
5808 infos.begin(); it != infos.end(); ++it) {
5809 const VertexAttribManager::VertexAttribInfo* info = *it;
5810 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245811 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]c6aef902012-02-14 03:31:425812 GLuint max_accessed = info->MaxVertexAccessed(primcount,
5813 max_vertex_accessed);
5814 GLuint num_vertices = max_accessed + 1;
5815 if (num_vertices == 0) {
[email protected]ad84a3a2012-06-08 21:42:435816 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425817 return false;
5818 }
[email protected]8fbedc02010-11-18 18:43:405819 if (attrib_info &&
[email protected]c6aef902012-02-14 03:31:425820 info->CanAccess(max_accessed) &&
[email protected]8fbedc02010-11-18 18:43:405821 info->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:475822 uint32 elements_used = 0;
5823 if (!SafeMultiplyUint32(num_vertices, info->size(), &elements_used) ||
5824 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ad84a3a2012-06-08 21:42:435825 SetGLError(
5826 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405827 return false;
5828 }
5829 }
5830 }
5831
[email protected]3aad1a32012-09-07 20:54:475832 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
5833 uint32 size_needed = 0;
5834 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305835 size_needed > 0x7FFFFFFFU) {
[email protected]ad84a3a2012-06-08 21:42:435836 SetGLError(GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405837 return false;
5838 }
5839
[email protected]c13e1da62011-09-09 21:48:305840 CopyRealGLErrorsToWrapper();
[email protected]8fbedc02010-11-18 18:43:405841
5842 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:305843 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:405844 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305845 GLenum error = glGetError();
5846 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435847 SetGLError(
5848 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:305849 return false;
5850 }
[email protected]8fbedc02010-11-18 18:43:405851 }
5852
5853 // Copy the elements and convert to float
5854 GLintptr offset = 0;
5855 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
5856 infos.begin(); it != infos.end(); ++it) {
5857 const VertexAttribManager::VertexAttribInfo* info = *it;
5858 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245859 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]c6aef902012-02-14 03:31:425860 GLuint max_accessed = info->MaxVertexAccessed(primcount,
5861 max_vertex_accessed);
5862 GLuint num_vertices = max_accessed + 1;
5863 if (num_vertices == 0) {
[email protected]ad84a3a2012-06-08 21:42:435864 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425865 return false;
5866 }
[email protected]8fbedc02010-11-18 18:43:405867 if (attrib_info &&
[email protected]c6aef902012-02-14 03:31:425868 info->CanAccess(max_accessed) &&
[email protected]8fbedc02010-11-18 18:43:405869 info->type() == GL_FIXED) {
5870 int num_elements = info->size() * kSizeOfFloat;
5871 int size = num_elements * num_vertices;
5872 scoped_array<float> data(new float[size]);
5873 const int32* src = reinterpret_cast<const int32 *>(
5874 info->buffer()->GetRange(info->offset(), size));
5875 const int32* end = src + num_elements;
5876 float* dst = data.get();
5877 while (src != end) {
5878 *dst++ = static_cast<float>(*src++) / 65536.0f;
5879 }
5880 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
5881 glVertexAttribPointer(
5882 info->index(), info->size(), GL_FLOAT, false, 0,
5883 reinterpret_cast<GLvoid*>(offset));
5884 offset += size;
5885 }
5886 }
5887 *simulated = true;
5888 return true;
5889}
5890
5891void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
5892 // There's no need to call glVertexAttribPointer because we shadow all the
5893 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:245894 glBindBuffer(
5895 GL_ARRAY_BUFFER,
5896 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]8fbedc02010-11-18 18:43:405897}
5898
[email protected]ad84a3a2012-06-08 21:42:435899error::Error GLES2DecoderImpl::DoDrawArrays(
5900 const char* function_name,
5901 bool instanced,
5902 GLenum mode,
5903 GLint first,
5904 GLsizei count,
5905 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:085906 if (ShouldDeferDraws())
5907 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:435908 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]f80e6e12012-08-31 00:43:535909 SetGLErrorInvalidEnum(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:435910 return error::kNoError;
5911 }
5912 if (count < 0) {
[email protected]ad84a3a2012-06-08 21:42:435913 SetGLError(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:435914 return error::kNoError;
5915 }
[email protected]c6aef902012-02-14 03:31:425916 if (primcount < 0) {
[email protected]ad84a3a2012-06-08 21:42:435917 SetGLError(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:425918 return error::kNoError;
5919 }
[email protected]ad84a3a2012-06-08 21:42:435920 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:435921 return error::kNoError;
5922 }
5923 // We have to check this here because the prototype for glDrawArrays
5924 // is GLint not GLsizei.
5925 if (first < 0) {
[email protected]ad84a3a2012-06-08 21:42:435926 SetGLError(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:435927 return error::kNoError;
5928 }
5929
[email protected]c6aef902012-02-14 03:31:425930 if (count == 0 || (instanced && primcount == 0)) {
[email protected]0f8afe82012-05-14 23:43:015931 RenderWarning("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:435932 return error::kNoError;
5933 }
5934
5935 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:435936 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:205937 if (!ClearUnclearedTextures()) {
[email protected]ad84a3a2012-06-08 21:42:435938 SetGLError(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:205939 return error::kNoError;
5940 }
[email protected]c13e1da62011-09-09 21:48:305941 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:435942 if (!SimulateAttrib0(
5943 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:305944 return error::kNoError;
5945 }
[email protected]38d139d2011-07-14 00:38:435946 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:435947 if (SimulateFixedAttribs(
5948 function_name, max_vertex_accessed, &simulated_fixed_attribs,
5949 primcount)) {
[email protected]38d139d2011-07-14 00:38:435950 bool textures_set = SetBlackTextureForNonRenderableTextures();
5951 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:425952 if (!instanced) {
5953 glDrawArrays(mode, first, count);
5954 } else {
5955 glDrawArraysInstancedANGLE(mode, first, count, primcount);
5956 }
[email protected]22e3f552012-03-13 01:54:195957 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:435958 if (textures_set) {
5959 RestoreStateForNonRenderableTextures();
5960 }
5961 if (simulated_fixed_attribs) {
5962 RestoreStateForSimulatedFixedAttribs();
5963 }
5964 }
5965 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:285966 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:435967 }
[email protected]38d139d2011-07-14 00:38:435968 }
5969 return error::kNoError;
5970}
5971
[email protected]c6aef902012-02-14 03:31:425972error::Error GLES2DecoderImpl::HandleDrawArrays(
5973 uint32 immediate_data_size, const gles2::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:435974 return DoDrawArrays("glDrawArrays",
5975 false,
[email protected]c6aef902012-02-14 03:31:425976 static_cast<GLenum>(c.mode),
5977 static_cast<GLint>(c.first),
5978 static_cast<GLsizei>(c.count),
5979 0);
5980}
5981
5982error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
5983 uint32 immediate_data_size, const gles2::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:155984 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:425985 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435986 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:425987 return error::kNoError;
5988 }
[email protected]ad84a3a2012-06-08 21:42:435989 return DoDrawArrays("glDrawArraysIntancedANGLE",
5990 true,
[email protected]c6aef902012-02-14 03:31:425991 static_cast<GLenum>(c.mode),
5992 static_cast<GLint>(c.first),
5993 static_cast<GLsizei>(c.count),
5994 static_cast<GLsizei>(c.primcount));
5995}
5996
[email protected]ad84a3a2012-06-08 21:42:435997error::Error GLES2DecoderImpl::DoDrawElements(
5998 const char* function_name,
5999 bool instanced,
6000 GLenum mode,
6001 GLsizei count,
6002 GLenum type,
6003 int32 offset,
6004 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086005 if (ShouldDeferDraws())
6006 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:246007 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]8eee29c2010-04-29 03:38:296008 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436009 function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296010 return error::kNoError;
6011 }
6012
[email protected]8eee29c2010-04-29 03:38:296013 if (count < 0) {
[email protected]ad84a3a2012-06-08 21:42:436014 SetGLError(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296015 return error::kNoError;
6016 }
6017 if (offset < 0) {
[email protected]ad84a3a2012-06-08 21:42:436018 SetGLError(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296019 return error::kNoError;
6020 }
[email protected]9438b012010-06-15 22:55:056021 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]f80e6e12012-08-31 00:43:536022 SetGLErrorInvalidEnum(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296023 return error::kNoError;
6024 }
[email protected]9438b012010-06-15 22:55:056025 if (!validators_->index_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536026 SetGLErrorInvalidEnum(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296027 return error::kNoError;
6028 }
[email protected]c6aef902012-02-14 03:31:426029 if (primcount < 0) {
[email protected]ad84a3a2012-06-08 21:42:436030 SetGLError(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426031 return error::kNoError;
6032 }
[email protected]8eee29c2010-04-29 03:38:296033
[email protected]ad84a3a2012-06-08 21:42:436034 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276035 return error::kNoError;
6036 }
6037
[email protected]c6aef902012-02-14 03:31:426038 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316039 return error::kNoError;
6040 }
6041
[email protected]8eee29c2010-04-29 03:38:296042 GLuint max_vertex_accessed;
[email protected]b04e24c2013-01-08 18:35:256043 if (!state_.vertex_attrib_manager->element_array_buffer()->
6044 GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) {
[email protected]8eee29c2010-04-29 03:38:296045 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436046 function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296047 return error::kNoError;
6048 }
6049
[email protected]ad84a3a2012-06-08 21:42:436050 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206051 if (!ClearUnclearedTextures()) {
[email protected]ad84a3a2012-06-08 21:42:436052 SetGLError(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206053 return error::kNoError;
6054 }
[email protected]c13e1da62011-09-09 21:48:306055 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436056 if (!SimulateAttrib0(
6057 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306058 return error::kNoError;
6059 }
[email protected]8fbedc02010-11-18 18:43:406060 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436061 if (SimulateFixedAttribs(
6062 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6063 primcount)) {
[email protected]8fbedc02010-11-18 18:43:406064 bool textures_set = SetBlackTextureForNonRenderableTextures();
[email protected]297ca1c2011-06-20 23:08:466065 ApplyDirtyState();
[email protected]8fbedc02010-11-18 18:43:406066 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]c6aef902012-02-14 03:31:426067 if (!instanced) {
6068 glDrawElements(mode, count, type, indices);
6069 } else {
6070 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6071 }
[email protected]22e3f552012-03-13 01:54:196072 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406073 if (textures_set) {
6074 RestoreStateForNonRenderableTextures();
6075 }
6076 if (simulated_fixed_attribs) {
6077 RestoreStateForSimulatedFixedAttribs();
6078 }
[email protected]ba3176a2009-12-16 18:19:466079 }
[email protected]b1122982010-05-17 23:04:246080 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286081 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246082 }
[email protected]96449d2c2009-11-25 00:01:326083 }
[email protected]f7a64ee2010-02-01 22:24:146084 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326085}
6086
[email protected]c6aef902012-02-14 03:31:426087error::Error GLES2DecoderImpl::HandleDrawElements(
6088 uint32 immediate_data_size, const gles2::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436089 return DoDrawElements("glDrawElements",
6090 false,
[email protected]c6aef902012-02-14 03:31:426091 static_cast<GLenum>(c.mode),
6092 static_cast<GLsizei>(c.count),
6093 static_cast<GLenum>(c.type),
6094 static_cast<int32>(c.index_offset),
6095 0);
6096}
6097
6098error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
6099 uint32 immediate_data_size, const gles2::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156100 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:426101 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436102 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426103 return error::kNoError;
6104 }
[email protected]ad84a3a2012-06-08 21:42:436105 return DoDrawElements("glDrawElementsInstancedANGLE",
6106 true,
[email protected]c6aef902012-02-14 03:31:426107 static_cast<GLenum>(c.mode),
6108 static_cast<GLsizei>(c.count),
6109 static_cast<GLenum>(c.type),
6110 static_cast<int32>(c.index_offset),
6111 static_cast<GLsizei>(c.primcount));
6112}
6113
[email protected]269200b12010-11-18 22:53:066114GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236115 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6116 GLuint max_vertex_accessed = 0;
6117 BufferManager::BufferInfo* info = GetBufferInfo(buffer_id);
[email protected]8eee29c2010-04-29 03:38:296118 if (!info) {
[email protected]ae51d192010-04-27 00:48:036119 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]8eee29c2010-04-29 03:38:296120 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436121 "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236122 } else {
6123 if (!info->GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036124 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]269200b12010-11-18 22:53:066125 SetGLError(
6126 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436127 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236128 }
6129 }
6130 return max_vertex_accessed;
6131}
6132
[email protected]96449d2c2009-11-25 00:01:326133// Calls glShaderSource for the various versions of the ShaderSource command.
6134// Assumes that data / data_size points to a piece of memory that is in range
6135// of whatever context it came from (shared memory, immediate memory, bucket
6136// memory.)
[email protected]45bf5152010-02-12 00:11:316137error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036138 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576139 std::string str(data, data + data_size);
[email protected]6b8cf1a2010-05-06 16:13:586140 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6141 client_id, "glShaderSource");
[email protected]45bf5152010-02-12 00:11:316142 if (!info) {
[email protected]45bf5152010-02-12 00:11:316143 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326144 }
[email protected]45bf5152010-02-12 00:11:316145 // Note: We don't actually call glShaderSource here. We wait until
6146 // the call to glCompileShader.
[email protected]258a3313f2011-10-18 20:13:576147 info->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146148 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326149}
6150
[email protected]f7a64ee2010-02-01 22:24:146151error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]b9849abf2009-11-25 19:13:196152 uint32 immediate_data_size, const gles2::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326153 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316154 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326155 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466156 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146157 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326158 }
[email protected]ae51d192010-04-27 00:48:036159 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326160}
6161
[email protected]f7a64ee2010-02-01 22:24:146162error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]b9849abf2009-11-25 19:13:196163 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:326164 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316165 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:306166 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:466167 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146168 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326169 }
[email protected]ae51d192010-04-27 00:48:036170 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:316171}
6172
[email protected]558847a2010-03-24 07:02:546173error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
6174 uint32 immediate_data_size, const gles2::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546175 Bucket* bucket = GetBucket(c.data_bucket_id);
6176 if (!bucket || bucket->size() == 0) {
6177 return error::kInvalidArguments;
6178 }
6179 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036180 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546181 bucket->size() - 1);
6182}
6183
[email protected]ae51d192010-04-27 00:48:036184void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386185 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]6b8cf1a2010-05-06 16:13:586186 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6187 client_id, "glCompileShader");
[email protected]45bf5152010-02-12 00:11:316188 if (!info) {
[email protected]45bf5152010-02-12 00:11:316189 return;
6190 }
[email protected]f57bb282010-11-12 00:51:346191 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186192 if (use_shader_translator_) {
[email protected]f57bb282010-11-12 00:51:346193 translator = info->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456194 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416195 }
[email protected]de17df392010-04-23 21:09:416196
[email protected]65dfc602012-07-23 20:39:396197 program_manager()->DoCompileShader(info, translator, feature_info_);
[email protected]45bf5152010-02-12 00:11:316198};
6199
[email protected]ddd968b82010-03-02 00:44:296200void GLES2DecoderImpl::DoGetShaderiv(
6201 GLuint shader, GLenum pname, GLint* params) {
[email protected]6b8cf1a2010-05-06 16:13:586202 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6203 shader, "glGetShaderiv");
[email protected]ddd968b82010-03-02 00:44:296204 if (!info) {
[email protected]ddd968b82010-03-02 00:44:296205 return;
6206 }
[email protected]8f1ccdac2010-05-19 21:01:486207 switch (pname) {
6208 case GL_SHADER_SOURCE_LENGTH:
[email protected]df6cf1ad2011-01-29 01:20:526209 *params = info->source() ? info->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486210 return;
6211 case GL_COMPILE_STATUS:
[email protected]062c38b2012-01-18 03:25:106212 *params = compile_shader_always_succeeds_ ? true : info->IsValid();
[email protected]e5186162010-06-14 18:54:416213 return;
[email protected]8f1ccdac2010-05-19 21:01:486214 case GL_INFO_LOG_LENGTH:
[email protected]df6cf1ad2011-01-29 01:20:526215 *params = info->log_info() ? info->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416216 return;
[email protected]d6a53e42011-10-05 00:09:366217 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]c447acd2012-07-23 23:48:416218 ForceCompileShaderIfPending(info);
[email protected]d6a53e42011-10-05 00:09:366219 *params = info->translated_source() ?
6220 info->translated_source()->size() + 1 : 0;
6221 return;
[email protected]8f1ccdac2010-05-19 21:01:486222 default:
6223 break;
[email protected]ddd968b82010-03-02 00:44:296224 }
[email protected]8f1ccdac2010-05-19 21:01:486225 glGetShaderiv(info->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296226}
6227
[email protected]ae51d192010-04-27 00:48:036228error::Error GLES2DecoderImpl::HandleGetShaderSource(
6229 uint32 immediate_data_size, const gles2::GetShaderSource& c) {
6230 GLuint shader = c.shader;
[email protected]ae51d192010-04-27 00:48:036231 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6232 Bucket* bucket = CreateBucket(bucket_id);
[email protected]6b8cf1a2010-05-06 16:13:586233 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6234 shader, "glGetShaderSource");
[email protected]df6cf1ad2011-01-29 01:20:526235 if (!info || !info->source()) {
[email protected]8eee29c2010-04-29 03:38:296236 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296237 return error::kNoError;
6238 }
[email protected]df6cf1ad2011-01-29 01:20:526239 bucket->SetFromString(info->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036240 return error::kNoError;
6241}
6242
[email protected]d6a53e42011-10-05 00:09:366243error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6244 uint32 immediate_data_size,
6245 const gles2::GetTranslatedShaderSourceANGLE& c) {
6246 GLuint shader = c.shader;
6247
6248 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6249 Bucket* bucket = CreateBucket(bucket_id);
6250 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6251 shader, "glTranslatedGetShaderSourceANGLE");
6252 if (!info) {
6253 bucket->SetSize(0);
6254 return error::kNoError;
6255 }
[email protected]c447acd2012-07-23 23:48:416256 ForceCompileShaderIfPending(info);
[email protected]d6a53e42011-10-05 00:09:366257
6258 bucket->SetFromString(info->translated_source() ?
6259 info->translated_source()->c_str() : NULL);
6260 return error::kNoError;
6261}
6262
[email protected]ae51d192010-04-27 00:48:036263error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
6264 uint32 immediate_data_size, const gles2::GetProgramInfoLog& c) {
6265 GLuint program = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586266 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6267 Bucket* bucket = CreateBucket(bucket_id);
6268 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6269 program, "glGetProgramInfoLog");
[email protected]df6cf1ad2011-01-29 01:20:526270 if (!info || !info->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466271 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036272 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316273 }
[email protected]df6cf1ad2011-01-29 01:20:526274 bucket->SetFromString(info->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036275 return error::kNoError;
6276}
6277
6278error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
6279 uint32 immediate_data_size, const gles2::GetShaderInfoLog& c) {
6280 GLuint shader = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586281 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6282 Bucket* bucket = CreateBucket(bucket_id);
6283 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6284 shader, "glGetShaderInfoLog");
[email protected]df6cf1ad2011-01-29 01:20:526285 if (!info || !info->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466286 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036287 return error::kNoError;
6288 }
[email protected]df6cf1ad2011-01-29 01:20:526289 bucket->SetFromString(info->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036290 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326291}
6292
[email protected]d058bca2012-11-26 10:27:266293bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6294 return state_.GetEnabled(cap);
6295}
6296
[email protected]1958e0e2010-04-22 05:17:156297bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106298 const BufferManager::BufferInfo* buffer = GetBufferInfo(client_id);
6299 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156300}
6301
6302bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106303 const FramebufferManager::FramebufferInfo* framebuffer =
[email protected]06c8b082011-01-05 18:00:366304 GetFramebufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:106305 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156306}
6307
6308bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366309 // IsProgram is true for programs as soon as they are created, until they are
6310 // deleted and no longer in use.
[email protected]a0b78dc2011-11-11 10:43:106311 const ProgramManager::ProgramInfo* program = GetProgramInfo(client_id);
6312 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156313}
6314
6315bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106316 const RenderbufferManager::RenderbufferInfo* renderbuffer =
[email protected]06c8b082011-01-05 18:00:366317 GetRenderbufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:106318 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156319}
6320
6321bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366322 // IsShader is true for shaders as soon as they are created, until they
6323 // are deleted and not attached to any programs.
[email protected]a0b78dc2011-11-11 10:43:106324 const ShaderManager::ShaderInfo* shader = GetShaderInfo(client_id);
6325 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156326}
6327
6328bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106329 const TextureManager::TextureInfo* texture = GetTextureInfo(client_id);
6330 return texture && texture->IsValid() && !texture->IsDeleted();
[email protected]ae51d192010-04-27 00:48:036331}
6332
6333void GLES2DecoderImpl::DoAttachShader(
6334 GLuint program_client_id, GLint shader_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:586335 ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader(
6336 program_client_id, "glAttachShader");
[email protected]ae51d192010-04-27 00:48:036337 if (!program_info) {
[email protected]ae51d192010-04-27 00:48:036338 return;
[email protected]1958e0e2010-04-22 05:17:156339 }
[email protected]6b8cf1a2010-05-06 16:13:586340 ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram(
6341 shader_client_id, "glAttachShader");
[email protected]ae51d192010-04-27 00:48:036342 if (!shader_info) {
[email protected]ae51d192010-04-27 00:48:036343 return;
6344 }
[email protected]ca488e12010-12-13 20:06:146345 if (!program_info->AttachShader(shader_manager(), shader_info)) {
[email protected]fb96c8e2010-08-12 04:10:316346 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436347 "glAttachShader", "can not attach more than"
[email protected]fb96c8e2010-08-12 04:10:316348 " one shader of the same type.");
6349 return;
6350 }
[email protected]ae51d192010-04-27 00:48:036351 glAttachShader(program_info->service_id(), shader_info->service_id());
6352}
6353
6354void GLES2DecoderImpl::DoDetachShader(
6355 GLuint program_client_id, GLint shader_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:586356 ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader(
6357 program_client_id, "glDetachShader");
[email protected]ae51d192010-04-27 00:48:036358 if (!program_info) {
[email protected]ae51d192010-04-27 00:48:036359 return;
6360 }
[email protected]6b8cf1a2010-05-06 16:13:586361 ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram(
6362 shader_client_id, "glDetachShader");
[email protected]ae51d192010-04-27 00:48:036363 if (!shader_info) {
[email protected]ae51d192010-04-27 00:48:036364 return;
6365 }
[email protected]9a0ccd42011-03-16 23:58:226366 if (!program_info->DetachShader(shader_manager(), shader_info)) {
6367 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436368 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226369 return;
6370 }
[email protected]ae51d192010-04-27 00:48:036371 glDetachShader(program_info->service_id(), shader_info->service_id());
6372}
6373
6374void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:586375 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6376 program_client_id, "glValidateProgram");
[email protected]ae51d192010-04-27 00:48:036377 if (!info) {
[email protected]ae51d192010-04-27 00:48:036378 return;
6379 }
[email protected]d685a682011-04-29 16:19:576380 info->Validate();
[email protected]1958e0e2010-04-22 05:17:156381}
6382
[email protected]b1122982010-05-17 23:04:246383void GLES2DecoderImpl::DoGetVertexAttribfv(
6384 GLuint index, GLenum pname, GLfloat* params) {
6385 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246386 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246387 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436388 SetGLError(GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]b1122982010-05-17 23:04:246389 return;
6390 }
6391 switch (pname) {
6392 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
6393 BufferManager::BufferInfo* buffer = info->buffer();
6394 if (buffer && !buffer->IsDeleted()) {
6395 GLuint client_id;
6396 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6397 *params = static_cast<GLfloat>(client_id);
6398 }
6399 break;
6400 }
6401 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
6402 *params = static_cast<GLfloat>(info->enabled());
6403 break;
6404 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
6405 *params = static_cast<GLfloat>(info->size());
6406 break;
6407 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
6408 *params = static_cast<GLfloat>(info->gl_stride());
6409 break;
6410 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
6411 *params = static_cast<GLfloat>(info->type());
6412 break;
6413 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
6414 *params = static_cast<GLfloat>(info->normalized());
6415 break;
[email protected]af6380962012-11-29 23:24:136416 case GL_CURRENT_VERTEX_ATTRIB: {
6417 const Vec4& value = state_.attrib_values[index];
6418 params[0] = value.v[0];
6419 params[1] = value.v[1];
6420 params[2] = value.v[2];
6421 params[3] = value.v[3];
[email protected]b1122982010-05-17 23:04:246422 break;
[email protected]af6380962012-11-29 23:24:136423 }
[email protected]c6aef902012-02-14 03:31:426424 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
6425 *params = static_cast<GLfloat>(info->divisor());
6426 break;
[email protected]b1122982010-05-17 23:04:246427 default:
6428 NOTREACHED();
6429 break;
6430 }
6431}
6432
6433void GLES2DecoderImpl::DoGetVertexAttribiv(
6434 GLuint index, GLenum pname, GLint* params) {
6435 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246436 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246437 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436438 SetGLError(GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]b1122982010-05-17 23:04:246439 return;
6440 }
6441 switch (pname) {
6442 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
6443 BufferManager::BufferInfo* buffer = info->buffer();
6444 if (buffer && !buffer->IsDeleted()) {
6445 GLuint client_id;
6446 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6447 *params = client_id;
6448 }
6449 break;
6450 }
6451 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
6452 *params = info->enabled();
6453 break;
6454 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
6455 *params = info->size();
6456 break;
6457 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
6458 *params = info->gl_stride();
6459 break;
6460 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
6461 *params = info->type();
6462 break;
6463 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
6464 *params = static_cast<GLint>(info->normalized());
6465 break;
[email protected]c6aef902012-02-14 03:31:426466 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
6467 *params = info->divisor();
6468 break;
[email protected]af6380962012-11-29 23:24:136469 case GL_CURRENT_VERTEX_ATTRIB: {
6470 const Vec4& value = state_.attrib_values[index];
6471 params[0] = static_cast<GLint>(value.v[0]);
6472 params[1] = static_cast<GLint>(value.v[1]);
6473 params[2] = static_cast<GLint>(value.v[2]);
6474 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246475 break;
[email protected]af6380962012-11-29 23:24:136476 }
[email protected]b1122982010-05-17 23:04:246477 default:
6478 NOTREACHED();
6479 break;
6480 }
6481}
6482
[email protected]af6380962012-11-29 23:24:136483bool GLES2DecoderImpl::SetVertexAttribValue(
6484 const char* function_name, GLuint index, const GLfloat* value) {
6485 if (index >= state_.attrib_values.size()) {
6486 SetGLError(GL_INVALID_VALUE, function_name, "index out of range");
6487 return false;
[email protected]b1122982010-05-17 23:04:246488 }
[email protected]af6380962012-11-29 23:24:136489 Vec4& v = state_.attrib_values[index];
6490 v.v[0] = value[0];
6491 v.v[1] = value[1];
6492 v.v[2] = value[2];
6493 v.v[3] = value[3];
6494 return true;
6495}
6496
6497void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6498 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6499 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6500 glVertexAttrib1f(index, v0);
6501 }
[email protected]b1122982010-05-17 23:04:246502}
6503
6504void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136505 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6506 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6507 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246508 }
[email protected]b1122982010-05-17 23:04:246509}
6510
6511void GLES2DecoderImpl::DoVertexAttrib3f(
6512 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136513 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6514 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6515 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246516 }
[email protected]b1122982010-05-17 23:04:246517}
6518
6519void GLES2DecoderImpl::DoVertexAttrib4f(
6520 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136521 GLfloat v[4] = { v0, v1, v2, v3, };
6522 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6523 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246524 }
[email protected]b1122982010-05-17 23:04:246525}
6526
6527void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136528 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6529 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6530 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246531 }
[email protected]b1122982010-05-17 23:04:246532}
6533
6534void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136535 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6536 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6537 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246538 }
[email protected]b1122982010-05-17 23:04:246539}
6540
6541void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136542 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6543 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6544 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246545 }
[email protected]b1122982010-05-17 23:04:246546}
6547
6548void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136549 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6550 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246551 }
[email protected]b1122982010-05-17 23:04:246552}
6553
[email protected]f7a64ee2010-02-01 22:24:146554error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]b9849abf2009-11-25 19:13:196555 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466556
[email protected]e259eb412012-10-13 05:47:246557 if (!state_.bound_array_buffer || state_.bound_array_buffer->IsDeleted()) {
6558 if (state_.vertex_attrib_manager == default_vertex_attrib_manager_) {
[email protected]944b62f32012-09-27 02:20:466559 SetGLError(GL_INVALID_VALUE,
6560 "glVertexAttribPointer", "no array buffer bound");
6561 return error::kNoError;
6562 } else if (c.offset != 0) {
6563 SetGLError(GL_INVALID_VALUE,
6564 "glVertexAttribPointer", "client side arrays are not allowed");
6565 return error::kNoError;
6566 }
[email protected]96449d2c2009-11-25 00:01:326567 }
[email protected]8eee29c2010-04-29 03:38:296568
6569 GLuint indx = c.indx;
6570 GLint size = c.size;
6571 GLenum type = c.type;
6572 GLboolean normalized = c.normalized;
6573 GLsizei stride = c.stride;
6574 GLsizei offset = c.offset;
6575 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056576 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536577 SetGLErrorInvalidEnum("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296578 return error::kNoError;
6579 }
[email protected]9438b012010-06-15 22:55:056580 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ff81c192011-01-07 23:04:316581 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436582 "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296583 return error::kNoError;
6584 }
6585 if (indx >= group_->max_vertex_attribs()) {
[email protected]ad84a3a2012-06-08 21:42:436586 SetGLError(GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296587 return error::kNoError;
6588 }
6589 if (stride < 0) {
6590 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436591 "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296592 return error::kNoError;
6593 }
6594 if (stride > 255) {
6595 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436596 "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296597 return error::kNoError;
6598 }
6599 if (offset < 0) {
6600 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436601 "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296602 return error::kNoError;
6603 }
6604 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316605 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296606 if (offset % component_size > 0) {
[email protected]ff81c192011-01-07 23:04:316607 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436608 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316609 return error::kNoError;
6610 }
6611 if (stride % component_size > 0) {
6612 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436613 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296614 return error::kNoError;
6615 }
[email protected]e259eb412012-10-13 05:47:246616 state_.vertex_attrib_manager->SetAttribInfo(
[email protected]8fbedc02010-11-18 18:43:406617 indx,
[email protected]e259eb412012-10-13 05:47:246618 state_.bound_array_buffer,
[email protected]8eee29c2010-04-29 03:38:296619 size,
6620 type,
[email protected]b1122982010-05-17 23:04:246621 normalized,
6622 stride,
6623 stride != 0 ? stride : component_size * size,
[email protected]8eee29c2010-04-29 03:38:296624 offset);
[email protected]8fbedc02010-11-18 18:43:406625 if (type != GL_FIXED) {
6626 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6627 }
[email protected]f7a64ee2010-02-01 22:24:146628 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326629}
6630
[email protected]43410e92012-04-20 17:06:286631void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6632 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246633 state_.viewport_x = x;
6634 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026635 state_.viewport_width = std::min(width, viewport_max_width_);
6636 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286637 glViewport(x, y, width, height);
6638}
6639
[email protected]c6aef902012-02-14 03:31:426640error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
6641 uint32 immediate_data_size, const gles2::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156642 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:426643 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436644 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426645 }
6646 GLuint index = c.index;
6647 GLuint divisor = c.divisor;
6648 if (index >= group_->max_vertex_attribs()) {
6649 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436650 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426651 return error::kNoError;
6652 }
6653
[email protected]e259eb412012-10-13 05:47:246654 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426655 index,
6656 divisor);
6657 glVertexAttribDivisorANGLE(index, divisor);
6658 return error::kNoError;
6659}
6660
[email protected]f7a64ee2010-02-01 22:24:146661error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]b9849abf2009-11-25 19:13:196662 uint32 immediate_data_size, const gles2::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:446663 if (ShouldDeferReads())
6664 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:316665 GLint x = c.x;
6666 GLint y = c.y;
6667 GLsizei width = c.width;
6668 GLsizei height = c.height;
6669 GLenum format = c.format;
6670 GLenum type = c.type;
[email protected]57f223832010-03-19 01:57:566671 if (width < 0 || height < 0) {
[email protected]ad84a3a2012-06-08 21:42:436672 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566673 return error::kNoError;
6674 }
[email protected]a51788e2010-02-24 21:54:256675 typedef gles2::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186676 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346677 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246678 width, height, format, type, state_.pack_alignment, &pixels_size,
6679 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186680 return error::kOutOfBounds;
6681 }
[email protected]612d2f82009-12-08 20:49:316682 void* pixels = GetSharedMemoryAs<void*>(
6683 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]a51788e2010-02-24 21:54:256684 Result* result = GetSharedMemoryAs<Result*>(
6685 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6686 if (!pixels || !result) {
[email protected]f7a64ee2010-02-01 22:24:146687 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466688 }
[email protected]a51788e2010-02-24 21:54:256689
[email protected]9438b012010-06-15 22:55:056690 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:536691 SetGLErrorInvalidEnum("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296692 return error::kNoError;
6693 }
[email protected]9438b012010-06-15 22:55:056694 if (!validators_->pixel_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536695 SetGLErrorInvalidEnum("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:126696 return error::kNoError;
6697 }
[email protected]57f223832010-03-19 01:57:566698 if (width == 0 || height == 0) {
6699 return error::kNoError;
6700 }
6701
[email protected]57f223832010-03-19 01:57:566702 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:306703 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:566704
[email protected]3aad1a32012-09-07 20:54:476705 int32 max_x;
6706 int32 max_y;
6707 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ad84a3a2012-06-08 21:42:436708 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:146709 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:316710 }
[email protected]57f223832010-03-19 01:57:566711
[email protected]0d6bfdc2011-11-02 01:32:206712 if (!CheckBoundFramebuffersValid("glReadPixels")) {
6713 return error::kNoError;
6714 }
6715
[email protected]a0b78dc2011-11-11 10:43:106716 CopyRealGLErrorsToWrapper();
6717
6718 ScopedResolvedFrameBufferBinder binder(this, false, true);
6719
[email protected]d37231fa2010-04-09 21:16:026720 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:566721 // The user requested an out of range area. Get the results 1 line
6722 // at a time.
6723 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346724 uint32 unpadded_row_size;
6725 uint32 padded_row_size;
6726 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246727 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346728 &unpadded_row_size, &padded_row_size)) {
[email protected]ad84a3a2012-06-08 21:42:436729 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566730 return error::kNoError;
6731 }
6732
6733 GLint dest_x_offset = std::max(-x, 0);
6734 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:346735 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246736 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
6737 NULL, NULL)) {
[email protected]ad84a3a2012-06-08 21:42:436738 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566739 return error::kNoError;
6740 }
6741
6742 // Copy each row into the larger dest rect.
6743 int8* dst = static_cast<int8*>(pixels);
6744 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:026745 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:566746 GLint read_width = read_end_x - read_x;
6747 for (GLint yy = 0; yy < height; ++yy) {
6748 GLint ry = y + yy;
6749
6750 // Clear the row.
6751 memset(dst, 0, unpadded_row_size);
6752
6753 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:026754 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:566755 glReadPixels(
6756 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6757 }
6758 dst += padded_row_size;
6759 }
6760 } else {
6761 glReadPixels(x, y, width, height, format, type, pixels);
6762 }
[email protected]1002c2d2011-06-28 22:39:046763 GLenum error = PeekGLError();
[email protected]a51788e2010-02-24 21:54:256764 if (error == GL_NO_ERROR) {
6765 *result = true;
[email protected]4848b9f82011-03-10 18:37:566766
6767 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6768 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
[email protected]84eb4252012-06-29 22:56:446769 if ((channels_exist & 0x0008) == 0 &&
[email protected]62e155e2012-10-23 22:43:156770 workarounds().clear_alpha_in_readpixels) {
[email protected]4848b9f82011-03-10 18:37:566771 // Set the alpha to 255 because some drivers are buggy in this regard.
6772 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346773
6774 uint32 unpadded_row_size;
6775 uint32 padded_row_size;
6776 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246777 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346778 &unpadded_row_size, &padded_row_size)) {
[email protected]ad84a3a2012-06-08 21:42:436779 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]4848b9f82011-03-10 18:37:566780 return error::kNoError;
6781 }
6782 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6783 // of this implementation.
6784 if (type != GL_UNSIGNED_BYTE) {
[email protected]ad84a3a2012-06-08 21:42:436785 SetGLError(
6786 GL_INVALID_OPERATION, "glReadPixels",
6787 "unsupported readPixel format");
[email protected]4848b9f82011-03-10 18:37:566788 return error::kNoError;
6789 }
6790 switch (format) {
6791 case GL_RGBA:
[email protected]297ca1c2011-06-20 23:08:466792 case GL_BGRA_EXT:
[email protected]4848b9f82011-03-10 18:37:566793 case GL_ALPHA: {
6794 int offset = (format == GL_ALPHA) ? 0 : 3;
6795 int step = (format == GL_ALPHA) ? 1 : 4;
6796 uint8* dst = static_cast<uint8*>(pixels) + offset;
6797 for (GLint yy = 0; yy < height; ++yy) {
6798 uint8* end = dst + unpadded_row_size;
6799 for (uint8* d = dst; d < end; d += step) {
6800 *d = 255;
6801 }
6802 dst += padded_row_size;
6803 }
6804 break;
6805 }
6806 default:
6807 break;
6808 }
6809 }
[email protected]a51788e2010-02-24 21:54:256810 }
[email protected]4848b9f82011-03-10 18:37:566811
[email protected]f7a64ee2010-02-01 22:24:146812 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326813}
6814
[email protected]f7a64ee2010-02-01 22:24:146815error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]b9849abf2009-11-25 19:13:196816 uint32 immediate_data_size, const gles2::PixelStorei& c) {
6817 GLenum pname = c.pname;
6818 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:056819 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]f80e6e12012-08-31 00:43:536820 SetGLErrorInvalidEnum("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:126821 return error::kNoError;
6822 }
[email protected]222471d2011-11-30 18:06:396823 switch (pname) {
6824 case GL_PACK_ALIGNMENT:
6825 case GL_UNPACK_ALIGNMENT:
6826 if (!validators_->pixel_store_alignment.IsValid(param)) {
6827 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436828 "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:396829 return error::kNoError;
6830 }
[email protected]164d6d52012-05-05 00:55:036831 break;
[email protected]0a1e9ad2012-05-04 21:13:036832 case GL_UNPACK_FLIP_Y_CHROMIUM:
6833 unpack_flip_y_ = (param != 0);
6834 return error::kNoError;
6835 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
6836 unpack_premultiply_alpha_ = (param != 0);
6837 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:176838 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
6839 unpack_unpremultiply_alpha_ = (param != 0);
6840 return error::kNoError;
[email protected]222471d2011-11-30 18:06:396841 default:
6842 break;
[email protected]b9849abf2009-11-25 19:13:196843 }
6844 glPixelStorei(pname, param);
6845 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:436846 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246847 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436848 break;
6849 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:426850 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:436851 break;
6852 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246853 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436854 break;
6855 default:
6856 // Validation should have prevented us from getting here.
6857 NOTREACHED();
6858 break;
[email protected]b9849abf2009-11-25 19:13:196859 }
[email protected]f7a64ee2010-02-01 22:24:146860 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196861}
6862
[email protected]1c75a3702011-11-11 14:15:286863error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
6864 uint32 immediate_data_size, const gles2::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:386865 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:456866 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]1c75a3702011-11-11 14:15:286867 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436868 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:286869 return error::kNoError;
6870 }
[email protected]7794d512012-04-17 20:36:496871 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:286872 return error::kNoError;
[email protected]7794d512012-04-17 20:36:496873 } else {
6874 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:286875 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:496876 }
[email protected]1c75a3702011-11-11 14:15:286877}
6878
[email protected]558847a2010-03-24 07:02:546879error::Error GLES2DecoderImpl::GetAttribLocationHelper(
6880 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6881 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576882 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ad84a3a2012-06-08 21:42:436883 SetGLError(GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576884 return error::kNoError;
6885 }
[email protected]6b8cf1a2010-05-06 16:13:586886 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6887 client_id, "glGetAttribLocation");
[email protected]ae51d192010-04-27 00:48:036888 if (!info) {
[email protected]f7a64ee2010-02-01 22:24:146889 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196890 }
[email protected]ae51d192010-04-27 00:48:036891 if (!info->IsValid()) {
[email protected]ad84a3a2012-06-08 21:42:436892 SetGLError(
6893 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256894 return error::kNoError;
6895 }
[email protected]b9849abf2009-11-25 19:13:196896 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:546897 location_shm_id, location_shm_offset, sizeof(GLint));
6898 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:146899 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196900 }
[email protected]558847a2010-03-24 07:02:546901 // Require the client to init this incase the context is lost and we are no
6902 // longer executing commands.
6903 if (*location != -1) {
6904 return error::kGenericError;
6905 }
[email protected]0bfd9882010-02-05 23:02:256906 *location = info->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:146907 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196908}
6909
[email protected]558847a2010-03-24 07:02:546910error::Error GLES2DecoderImpl::HandleGetAttribLocation(
6911 uint32 immediate_data_size, const gles2::GetAttribLocation& c) {
6912 uint32 name_size = c.data_size;
6913 const char* name = GetSharedMemoryAs<const char*>(
6914 c.name_shm_id, c.name_shm_offset, name_size);
6915 if (!name) {
6916 return error::kOutOfBounds;
6917 }
6918 String name_str(name, name_size);
6919 return GetAttribLocationHelper(
6920 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6921}
6922
[email protected]f7a64ee2010-02-01 22:24:146923error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]b9849abf2009-11-25 19:13:196924 uint32 immediate_data_size, const gles2::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:546925 uint32 name_size = c.data_size;
6926 const char* name = GetImmediateDataAs<const char*>(
6927 c, name_size, immediate_data_size);
6928 if (!name) {
6929 return error::kOutOfBounds;
6930 }
6931 String name_str(name, name_size);
6932 return GetAttribLocationHelper(
6933 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6934}
6935
6936error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
6937 uint32 immediate_data_size, const gles2::GetAttribLocationBucket& c) {
6938 Bucket* bucket = GetBucket(c.name_bucket_id);
6939 if (!bucket) {
6940 return error::kInvalidArguments;
6941 }
6942 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:186943 if (!bucket->GetAsString(&name_str)) {
6944 return error::kInvalidArguments;
6945 }
[email protected]558847a2010-03-24 07:02:546946 return GetAttribLocationHelper(
6947 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6948}
6949
6950error::Error GLES2DecoderImpl::GetUniformLocationHelper(
6951 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6952 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576953 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ad84a3a2012-06-08 21:42:436954 SetGLError(GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576955 return error::kNoError;
6956 }
[email protected]6b8cf1a2010-05-06 16:13:586957 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6958 client_id, "glUniformLocation");
[email protected]ae51d192010-04-27 00:48:036959 if (!info) {
[email protected]f7a64ee2010-02-01 22:24:146960 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196961 }
[email protected]ae51d192010-04-27 00:48:036962 if (!info->IsValid()) {
[email protected]ad84a3a2012-06-08 21:42:436963 SetGLError(
6964 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256965 return error::kNoError;
6966 }
[email protected]b9849abf2009-11-25 19:13:196967 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:546968 location_shm_id, location_shm_offset, sizeof(GLint));
6969 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:146970 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196971 }
[email protected]558847a2010-03-24 07:02:546972 // Require the client to init this incase the context is lost an we are no
6973 // longer executing commands.
6974 if (*location != -1) {
6975 return error::kGenericError;
6976 }
[email protected]2be6abf32012-06-26 00:28:336977 *location = info->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:146978 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196979}
6980
[email protected]f7a64ee2010-02-01 22:24:146981error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]b9849abf2009-11-25 19:13:196982 uint32 immediate_data_size, const gles2::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:196983 uint32 name_size = c.data_size;
6984 const char* name = GetSharedMemoryAs<const char*>(
6985 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:546986 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:146987 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196988 }
6989 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:546990 return GetUniformLocationHelper(
6991 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:196992}
6993
[email protected]f7a64ee2010-02-01 22:24:146994error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]b9849abf2009-11-25 19:13:196995 uint32 immediate_data_size, const gles2::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:196996 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:306997 const char* name = GetImmediateDataAs<const char*>(
6998 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:546999 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147000 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197001 }
7002 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547003 return GetUniformLocationHelper(
7004 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7005}
7006
7007error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
7008 uint32 immediate_data_size, const gles2::GetUniformLocationBucket& c) {
7009 Bucket* bucket = GetBucket(c.name_bucket_id);
7010 if (!bucket) {
7011 return error::kInvalidArguments;
7012 }
7013 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187014 if (!bucket->GetAsString(&name_str)) {
7015 return error::kInvalidArguments;
7016 }
[email protected]558847a2010-03-24 07:02:547017 return GetUniformLocationHelper(
7018 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197019}
7020
[email protected]ddd968b82010-03-02 00:44:297021error::Error GLES2DecoderImpl::HandleGetString(
7022 uint32 immediate_data_size, const gles2::GetString& c) {
7023 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057024 if (!validators_->string_type.IsValid(name)) {
[email protected]f80e6e12012-08-31 00:43:537025 SetGLErrorInvalidEnum("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297026 return error::kNoError;
7027 }
[email protected]1958e0e2010-04-22 05:17:157028 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
7029 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:047030 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157031 switch (name) {
7032 case GL_VERSION:
7033 str = "OpenGL ES 2.0 Chromium";
7034 break;
7035 case GL_SHADING_LANGUAGE_VERSION:
7036 str = "OpenGL ES GLSL ES 1.0 Chromium";
7037 break;
[email protected]32939602012-05-09 06:25:167038 case GL_RENDERER:
7039 str = "Chromium";
7040 break;
7041 case GL_VENDOR:
7042 str = "Chromium";
7043 break;
[email protected]1958e0e2010-04-22 05:17:157044 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047045 {
7046 // For WebGL contexts, strip out the OES derivatives extension if it has
7047 // not been enabled.
7048 if (force_webgl_glsl_validation_ &&
7049 !derivatives_explicitly_enabled_) {
7050 extensions = feature_info_->extensions();
7051 size_t offset = extensions.find(kOESDerivativeExtension);
7052 if (std::string::npos != offset) {
7053 extensions.replace(offset,
7054 offset + arraysize(kOESDerivativeExtension),
7055 std::string());
7056 }
[email protected]f0d74742011-10-03 16:31:047057 } else {
[email protected]6f5fac9d12012-06-26 21:02:457058 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047059 }
[email protected]6f5fac9d12012-06-26 21:02:457060 std::string surface_extensions = surface_->GetExtensions();
7061 if (!surface_extensions.empty())
7062 extensions += " " + surface_extensions;
7063 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047064 }
[email protected]1958e0e2010-04-22 05:17:157065 break;
7066 default:
7067 str = gl_str;
7068 break;
7069 }
[email protected]ddd968b82010-03-02 00:44:297070 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157071 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297072 return error::kNoError;
7073}
7074
[email protected]0c86dbf2010-03-05 08:14:117075void GLES2DecoderImpl::DoBufferData(
[email protected]b9363b22010-06-09 22:06:157076 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
[email protected]9438b012010-06-15 22:55:057077 if (!validators_->buffer_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:537078 SetGLErrorInvalidEnum("glBufferData", target, "target");
[email protected]8eee29c2010-04-29 03:38:297079 return;
7080 }
[email protected]9438b012010-06-15 22:55:057081 if (!validators_->buffer_usage.IsValid(usage)) {
[email protected]f80e6e12012-08-31 00:43:537082 SetGLErrorInvalidEnum("glBufferData", usage, "usage");
[email protected]0c86dbf2010-03-05 08:14:117083 return;
[email protected]3b6ec202010-03-05 05:16:237084 }
7085 if (size < 0) {
[email protected]ad84a3a2012-06-08 21:42:437086 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0");
[email protected]037896bd2010-04-21 19:07:287087 return;
[email protected]3b6ec202010-03-05 05:16:237088 }
7089 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target);
7090 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:437091 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287092 return;
[email protected]3b6ec202010-03-05 05:16:237093 }
7094 // Clear the buffer to 0 if no initial data was passed in.
7095 scoped_array<int8> zero;
7096 if (!data) {
7097 zero.reset(new int8[size]);
7098 memset(zero.get(), 0, size);
7099 data = zero.get();
7100 }
[email protected]473c01ccb2011-06-07 01:33:307101
[email protected]3b6ec202010-03-05 05:16:237102 CopyRealGLErrorsToWrapper();
7103 glBufferData(target, size, data, usage);
[email protected]1002c2d2011-06-28 22:39:047104 GLenum error = PeekGLError();
7105 if (error == GL_NO_ERROR) {
[email protected]473c01ccb2011-06-07 01:33:307106 buffer_manager()->SetInfo(info, size, usage);
[email protected]0c86dbf2010-03-05 08:14:117107 info->SetRange(0, size, data);
[email protected]a39370652012-09-25 21:52:137108 } else {
7109 buffer_manager()->SetInfo(info, 0, usage);
[email protected]3b6ec202010-03-05 05:16:237110 }
[email protected]0c86dbf2010-03-05 08:14:117111}
7112
7113error::Error GLES2DecoderImpl::HandleBufferData(
7114 uint32 immediate_data_size, const gles2::BufferData& c) {
7115 GLenum target = static_cast<GLenum>(c.target);
7116 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
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 GLenum usage = static_cast<GLenum>(c.usage);
7120 const void* data = NULL;
7121 if (data_shm_id != 0 || data_shm_offset != 0) {
7122 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7123 if (!data) {
7124 return error::kOutOfBounds;
7125 }
7126 }
7127 DoBufferData(target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147128 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197129}
7130
[email protected]f7a64ee2010-02-01 22:24:147131error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]b9849abf2009-11-25 19:13:197132 uint32 immediate_data_size, const gles2::BufferDataImmediate& c) {
7133 GLenum target = static_cast<GLenum>(c.target);
7134 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:307135 const void* data = GetImmediateDataAs<const void*>(
7136 c, size, immediate_data_size);
7137 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147138 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:307139 }
[email protected]b9849abf2009-11-25 19:13:197140 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0c86dbf2010-03-05 08:14:117141 DoBufferData(target, size, data, usage);
7142 return error::kNoError;
7143}
7144
7145void GLES2DecoderImpl::DoBufferSubData(
7146 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]3916c97e2010-02-25 03:20:507147 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477148 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:437149 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287150 return;
[email protected]a93bb842010-02-16 23:03:477151 }
[email protected]0c86dbf2010-03-05 08:14:117152 if (!info->SetRange(offset, size, data)) {
[email protected]ad84a3a2012-06-08 21:42:437153 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range");
[email protected]473c01ccb2011-06-07 01:33:307154 return;
[email protected]07f54fcc2009-12-22 02:46:307155 }
[email protected]473c01ccb2011-06-07 01:33:307156 glBufferSubData(target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197157}
7158
[email protected]0d6bfdc2011-11-02 01:32:207159bool GLES2DecoderImpl::ClearLevel(
7160 unsigned service_id,
7161 unsigned bind_target,
7162 unsigned target,
7163 int level,
7164 unsigned format,
7165 unsigned type,
7166 int width,
[email protected]4502e6492011-12-14 19:39:157167 int height,
7168 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007169 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7170 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7171 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7172 // on depth formats.
7173 GLuint fb = 0;
7174 glGenFramebuffersEXT(1, &fb);
7175 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7176
7177 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7178 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7179 GL_DEPTH_ATTACHMENT;
7180
7181 glFramebufferTexture2DEXT(
7182 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7183 // ANGLE promises a depth only attachment ok.
7184 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7185 GL_FRAMEBUFFER_COMPLETE) {
7186 return false;
7187 }
7188 glClearStencil(0);
7189 glStencilMask(-1);
7190 glClearDepth(1.0f);
7191 glDepthMask(true);
7192 glDisable(GL_SCISSOR_TEST);
7193 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7194
7195 RestoreClearState();
7196
7197 glDeleteFramebuffersEXT(1, &fb);
7198 FramebufferManager::FramebufferInfo* framebuffer =
7199 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7200 GLuint fb_service_id =
7201 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7202 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7203 return true;
7204 }
7205
[email protected]45d15a62012-04-18 14:33:177206 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7207
7208 uint32 size;
7209 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347210 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247211 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177212 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207213 return false;
7214 }
[email protected]45d15a62012-04-18 14:33:177215
[email protected]a5d3dad2012-05-26 04:34:447216 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7217
[email protected]45d15a62012-04-18 14:33:177218 int tile_height;
7219
7220 if (size > kMaxZeroSize) {
7221 if (kMaxZeroSize < padded_row_size) {
7222 // That'd be an awfully large texture.
7223 return false;
7224 }
7225 // We should never have a large total size with a zero row size.
7226 DCHECK_GT(padded_row_size, 0U);
7227 tile_height = kMaxZeroSize / padded_row_size;
7228 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247229 width, tile_height, format, type, state_.unpack_alignment, &size,
7230 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177231 return false;
7232 }
[email protected]4502e6492011-12-14 19:39:157233 } else {
[email protected]45d15a62012-04-18 14:33:177234 tile_height = height;
7235 }
7236
7237 // Assumes the size has already been checked.
7238 scoped_array<char> zero(new char[size]);
7239 memset(zero.get(), 0, size);
7240 glBindTexture(bind_target, service_id);
7241
7242 GLint y = 0;
7243 while (y < height) {
7244 GLint h = y + tile_height > height ? height - y : tile_height;
7245 if (is_texture_immutable || h != height) {
7246 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7247 } else {
7248 WrappedTexImage2D(
7249 target, level, format, width, h, 0, format, type, zero.get());
7250 }
7251 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157252 }
[email protected]0d6bfdc2011-11-02 01:32:207253 TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target);
7254 glBindTexture(bind_target, info ? info->service_id() : 0);
7255 return true;
7256}
7257
[email protected]ad84a3a2012-06-08 21:42:437258namespace {
7259
7260const int kS3TCBlockWidth = 4;
7261const int kS3TCBlockHeight = 4;
7262const int kS3TCDXT1BlockSize = 8;
7263const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077264const int kETC1BlockWidth = 4;
7265const int kETC1BlockHeight = 4;
7266const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437267
7268bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517269 return (size == 1) ||
7270 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437271}
7272
7273} // anonymous namespace.
7274
7275bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7276 const char* function_name,
7277 GLsizei width, GLsizei height, GLenum format, size_t size) {
7278 unsigned int bytes_required = 0;
7279
7280 switch (format) {
7281 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7282 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7283 int num_blocks_across =
7284 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7285 int num_blocks_down =
7286 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7287 int num_blocks = num_blocks_across * num_blocks_down;
7288 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7289 break;
7290 }
7291 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7292 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7293 int num_blocks_across =
7294 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7295 int num_blocks_down =
7296 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7297 int num_blocks = num_blocks_across * num_blocks_down;
7298 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7299 break;
7300 }
[email protected]2d3765b2012-10-03 00:31:077301 case GL_ETC1_RGB8_OES: {
7302 int num_blocks_across =
7303 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7304 int num_blocks_down =
7305 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7306 int num_blocks = num_blocks_across * num_blocks_down;
7307 bytes_required = num_blocks * kETC1BlockSize;
7308 break;
7309 }
[email protected]ad84a3a2012-06-08 21:42:437310 default:
[email protected]f80e6e12012-08-31 00:43:537311 SetGLErrorInvalidEnum(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437312 return false;
7313 }
7314
7315 if (size != bytes_required) {
7316 SetGLError(
7317 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7318 return false;
7319 }
7320
7321 return true;
7322}
7323
7324bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7325 const char* function_name,
7326 GLint level, GLsizei width, GLsizei height, GLenum format) {
7327 switch (format) {
7328 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7329 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7330 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7331 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7332 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
7333 SetGLError(
7334 GL_INVALID_OPERATION, function_name,
7335 "width or height invalid for level");
7336 return false;
7337 }
7338 return true;
7339 }
[email protected]2d3765b2012-10-03 00:31:077340 case GL_ETC1_RGB8_OES:
7341 if (width <= 0 || height <= 0) {
7342 SetGLError(
7343 GL_INVALID_OPERATION, function_name,
7344 "width or height invalid for level");
7345 return false;
7346 }
7347 return true;
[email protected]ad84a3a2012-06-08 21:42:437348 default:
7349 return false;
7350 }
7351}
7352
7353bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7354 const char* function_name,
7355 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7356 GLsizei width, GLsizei height, GLenum format,
7357 TextureManager::TextureInfo* texture) {
7358 if (xoffset < 0 || yoffset < 0) {
7359 SetGLError(
7360 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7361 return false;
7362 }
7363
7364 switch (format) {
7365 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7366 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7367 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7368 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7369 const int kBlockWidth = 4;
7370 const int kBlockHeight = 4;
7371 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
7372 SetGLError(
7373 GL_INVALID_OPERATION, function_name,
7374 "xoffset or yoffset not multiple of 4");
7375 return false;
7376 }
7377 GLsizei tex_width = 0;
7378 GLsizei tex_height = 0;
7379 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7380 width - xoffset > tex_width ||
7381 height - yoffset > tex_height) {
7382 SetGLError(
7383 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7384 return false;
7385 }
7386 return ValidateCompressedTexDimensions(
7387 function_name, level, width, height, format);
7388 }
[email protected]2d3765b2012-10-03 00:31:077389 case GL_ETC1_RGB8_OES: {
7390 SetGLError(
7391 GL_INVALID_OPERATION, function_name,
7392 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7393 return false;
7394 }
[email protected]ad84a3a2012-06-08 21:42:437395 default:
7396 return false;
7397 }
7398}
7399
[email protected]a93bb842010-02-16 23:03:477400error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7401 GLenum target,
7402 GLint level,
7403 GLenum internal_format,
7404 GLsizei width,
7405 GLsizei height,
7406 GLint border,
7407 GLsizei image_size,
7408 const void* data) {
[email protected]a93bb842010-02-16 23:03:477409 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057410 if (!validators_->texture_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:537411 SetGLErrorInvalidEnum("glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297412 return error::kNoError;
7413 }
[email protected]9438b012010-06-15 22:55:057414 if (!validators_->compressed_texture_format.IsValid(
7415 internal_format)) {
[email protected]f80e6e12012-08-31 00:43:537416 SetGLErrorInvalidEnum(
7417 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477418 return error::kNoError;
7419 }
[email protected]80eb6b52012-01-19 00:14:417420 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477421 border != 0) {
[email protected]8eee29c2010-04-29 03:38:297422 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437423 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477424 return error::kNoError;
7425 }
[email protected]3916c97e2010-02-25 03:20:507426 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477427 if (!info) {
[email protected]8eee29c2010-04-29 03:38:297428 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437429 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477430 return error::kNoError;
7431 }
[email protected]97dc7cbe2011-12-06 17:26:177432 if (info->IsImmutable()) {
7433 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437434 "glCompressedTexImage2D", "texture is immutable");
7435 return error::kNoError;
7436 }
7437
7438 if (!ValidateCompressedTexDimensions(
7439 "glCompressedTexImage2D", level, width, height, internal_format) ||
7440 !ValidateCompressedTexFuncData(
7441 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177442 return error::kNoError;
7443 }
[email protected]968351b2011-12-20 08:26:517444
7445 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427446 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517447 // TODO(gman): If textures tracked which framebuffers they were attached to
7448 // we could just mark those framebuffers as not complete.
7449 framebuffer_manager()->IncFramebufferStateChangeCount();
7450 }
7451
[email protected]a93bb842010-02-16 23:03:477452 scoped_array<int8> zero;
7453 if (!data) {
7454 zero.reset(new int8[image_size]);
7455 memset(zero.get(), 0, image_size);
7456 data = zero.get();
7457 }
[email protected]cadde4a2010-07-31 17:10:437458 CopyRealGLErrorsToWrapper();
[email protected]a93bb842010-02-16 23:03:477459 glCompressedTexImage2D(
7460 target, level, internal_format, width, height, border, image_size, data);
[email protected]1002c2d2011-06-28 22:39:047461 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437462 if (error == GL_NO_ERROR) {
7463 texture_manager()->SetLevelInfo(
[email protected]0d6bfdc2011-11-02 01:32:207464 info, target, level, internal_format, width, height, 1, border, 0, 0,
7465 true);
[email protected]cadde4a2010-07-31 17:10:437466 }
[email protected]a93bb842010-02-16 23:03:477467 return error::kNoError;
7468}
7469
[email protected]f7a64ee2010-02-01 22:24:147470error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197471 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) {
7472 GLenum target = static_cast<GLenum>(c.target);
7473 GLint level = static_cast<GLint>(c.level);
7474 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7475 GLsizei width = static_cast<GLsizei>(c.width);
7476 GLsizei height = static_cast<GLsizei>(c.height);
7477 GLint border = static_cast<GLint>(c.border);
7478 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7479 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7480 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7481 const void* data = NULL;
7482 if (data_shm_id != 0 || data_shm_offset != 0) {
7483 data = GetSharedMemoryAs<const void*>(
7484 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467485 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147486 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197487 }
7488 }
[email protected]a93bb842010-02-16 23:03:477489 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197490 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197491}
7492
[email protected]f7a64ee2010-02-01 22:24:147493error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]b9849abf2009-11-25 19:13:197494 uint32 immediate_data_size, const gles2::CompressedTexImage2DImmediate& c) {
7495 GLenum target = static_cast<GLenum>(c.target);
7496 GLint level = static_cast<GLint>(c.level);
7497 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7498 GLsizei width = static_cast<GLsizei>(c.width);
7499 GLsizei height = static_cast<GLsizei>(c.height);
7500 GLint border = static_cast<GLint>(c.border);
7501 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307502 const void* data = GetImmediateDataAs<const void*>(
7503 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467504 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147505 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467506 }
[email protected]a93bb842010-02-16 23:03:477507 return DoCompressedTexImage2D(
7508 target, level, internal_format, width, height, border, image_size, data);
7509}
7510
[email protected]b6140d02010-05-17 14:47:167511error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
7512 uint32 immediate_data_size, const gles2::CompressedTexImage2DBucket& c) {
7513 GLenum target = static_cast<GLenum>(c.target);
7514 GLint level = static_cast<GLint>(c.level);
7515 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7516 GLsizei width = static_cast<GLsizei>(c.width);
7517 GLsizei height = static_cast<GLsizei>(c.height);
7518 GLint border = static_cast<GLint>(c.border);
7519 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287520 if (!bucket) {
7521 return error::kInvalidArguments;
7522 }
7523 uint32 data_size = bucket->size();
7524 GLsizei imageSize = data_size;
7525 const void* data = bucket->GetData(0, data_size);
7526 if (!data) {
7527 return error::kInvalidArguments;
7528 }
[email protected]b6140d02010-05-17 14:47:167529 return DoCompressedTexImage2D(
7530 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287531 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167532}
7533
7534error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7535 uint32 immediate_data_size,
7536 const gles2::CompressedTexSubImage2DBucket& c) {
7537 GLenum target = static_cast<GLenum>(c.target);
7538 GLint level = static_cast<GLint>(c.level);
7539 GLint xoffset = static_cast<GLint>(c.xoffset);
7540 GLint yoffset = static_cast<GLint>(c.yoffset);
7541 GLsizei width = static_cast<GLsizei>(c.width);
7542 GLsizei height = static_cast<GLsizei>(c.height);
7543 GLenum format = static_cast<GLenum>(c.format);
7544 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287545 if (!bucket) {
7546 return error::kInvalidArguments;
7547 }
[email protected]b6140d02010-05-17 14:47:167548 uint32 data_size = bucket->size();
7549 GLsizei imageSize = data_size;
7550 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287551 if (!data) {
7552 return error::kInvalidArguments;
7553 }
[email protected]9438b012010-06-15 22:55:057554 if (!validators_->texture_target.IsValid(target)) {
[email protected]b6140d02010-05-17 14:47:167555 SetGLError(
[email protected]f80e6e12012-08-31 00:43:537556 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167557 return error::kNoError;
7558 }
[email protected]9438b012010-06-15 22:55:057559 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:537560 SetGLErrorInvalidEnum("glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057561 return error::kNoError;
7562 }
[email protected]b6140d02010-05-17 14:47:167563 if (width < 0) {
[email protected]ad84a3a2012-06-08 21:42:437564 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167565 return error::kNoError;
7566 }
7567 if (height < 0) {
[email protected]ad84a3a2012-06-08 21:42:437568 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167569 return error::kNoError;
7570 }
7571 if (imageSize < 0) {
[email protected]ad84a3a2012-06-08 21:42:437572 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167573 return error::kNoError;
7574 }
[email protected]cadde4a2010-07-31 17:10:437575 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167576 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7577 return error::kNoError;
7578}
7579
[email protected]81375742012-06-08 00:04:007580bool GLES2DecoderImpl::ValidateTextureParameters(
7581 const char* function_name,
7582 GLenum target, GLenum format, GLenum type, GLint level) {
7583 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
[email protected]ad84a3a2012-06-08 21:42:437584 SetGLError(GL_INVALID_OPERATION, function_name,
7585 (std::string("invalid type ") +
[email protected]81375742012-06-08 00:04:007586 GLES2Util::GetStringEnum(type) + " for format " +
7587 GLES2Util::GetStringEnum(format)).c_str());
7588 return false;
7589 }
7590
7591 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7592 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
[email protected]ad84a3a2012-06-08 21:42:437593 SetGLError(GL_INVALID_OPERATION, function_name,
7594 (std::string("invalid type ") +
[email protected]81375742012-06-08 00:04:007595 GLES2Util::GetStringEnum(type) + " for format " +
7596 GLES2Util::GetStringEnum(format)).c_str());
7597 return false;
7598 }
7599 return true;
7600}
7601
[email protected]f598f422012-12-07 08:30:037602bool GLES2DecoderImpl::ValidateTexImage2D(
7603 const char* function_name,
7604 GLenum target,
7605 GLint level,
7606 GLenum internal_format,
7607 GLsizei width,
7608 GLsizei height,
7609 GLint border,
7610 GLenum format,
7611 GLenum type,
7612 const void* pixels,
7613 uint32 pixels_size) {
[email protected]9438b012010-06-15 22:55:057614 if (!validators_->texture_target.IsValid(target)) {
[email protected]f598f422012-12-07 08:30:037615 SetGLErrorInvalidEnum(function_name, target, "target");
7616 return false;
[email protected]8eee29c2010-04-29 03:38:297617 }
[email protected]9438b012010-06-15 22:55:057618 if (!validators_->texture_format.IsValid(internal_format)) {
[email protected]f598f422012-12-07 08:30:037619 SetGLErrorInvalidEnum(function_name, internal_format, "internal_format");
7620 return false;
[email protected]8eee29c2010-04-29 03:38:297621 }
[email protected]9438b012010-06-15 22:55:057622 if (!validators_->texture_format.IsValid(format)) {
[email protected]f598f422012-12-07 08:30:037623 SetGLErrorInvalidEnum(function_name, format, "format");
7624 return false;
[email protected]8eee29c2010-04-29 03:38:297625 }
[email protected]9438b012010-06-15 22:55:057626 if (!validators_->pixel_type.IsValid(type)) {
[email protected]f598f422012-12-07 08:30:037627 SetGLErrorInvalidEnum(function_name, type, "type");
7628 return false;
[email protected]b9849abf2009-11-25 19:13:197629 }
[email protected]7b92c412010-07-20 17:48:257630 if (format != internal_format) {
[email protected]ad84a3a2012-06-08 21:42:437631 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037632 function_name, "format != internalFormat");
7633 return false;
[email protected]7b92c412010-07-20 17:48:257634 }
[email protected]f598f422012-12-07 08:30:037635 if (!ValidateTextureParameters(function_name, target, format, type, level)) {
7636 return false;
[email protected]81375742012-06-08 00:04:007637 }
[email protected]80eb6b52012-01-19 00:14:417638 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477639 border != 0) {
[email protected]f598f422012-12-07 08:30:037640 SetGLError(GL_INVALID_VALUE, function_name, "dimensions out of range");
7641 return false;
[email protected]a93bb842010-02-16 23:03:477642 }
[email protected]81375742012-06-08 00:04:007643 if ((GLES2Util::GetChannelsForFormat(format) &
7644 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
7645 SetGLError(
7646 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037647 function_name, "can not supply data for depth or stencil textures");
7648 return false;
[email protected]81375742012-06-08 00:04:007649 }
[email protected]3916c97e2010-02-25 03:20:507650 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477651 if (!info) {
[email protected]8eee29c2010-04-29 03:38:297652 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037653 function_name, "unknown texture for target");
7654 return false;
[email protected]a93bb842010-02-16 23:03:477655 }
[email protected]97dc7cbe2011-12-06 17:26:177656 if (info->IsImmutable()) {
7657 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037658 function_name, "texture is immutable");
7659 return false;
[email protected]97dc7cbe2011-12-06 17:26:177660 }
[email protected]f598f422012-12-07 08:30:037661 return true;
7662}
[email protected]97dc7cbe2011-12-06 17:26:177663
[email protected]f598f422012-12-07 08:30:037664void GLES2DecoderImpl::DoTexImage2D(
7665 GLenum target,
7666 GLint level,
7667 GLenum internal_format,
7668 GLsizei width,
7669 GLsizei height,
7670 GLint border,
7671 GLenum format,
7672 GLenum type,
7673 const void* pixels,
7674 uint32 pixels_size) {
7675 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format,
7676 width, height, border, format, type, pixels, pixels_size)) {
7677 return;
7678 }
7679 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]0226c112011-07-22 03:25:077680 GLsizei tex_width = 0;
7681 GLsizei tex_height = 0;
7682 GLenum tex_type = 0;
7683 GLenum tex_format = 0;
7684 bool level_is_same =
7685 info->GetLevelSize(target, level, &tex_width, &tex_height) &&
7686 info->GetLevelType(target, level, &tex_type, &tex_format) &&
7687 width == tex_width && height == tex_height &&
7688 type == tex_type && format == tex_format;
7689
7690 if (level_is_same && !pixels) {
[email protected]1bed6222011-12-21 11:21:397691 // Just set the level info but mark the texture as uncleared.
7692 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417693 info,
[email protected]1bed6222011-12-21 11:21:397694 target, level, internal_format, width, height, 1, border, format, type,
7695 false);
[email protected]ea72ed222011-08-17 18:58:437696 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037697 return;
[email protected]0226c112011-07-22 03:25:077698 }
7699
[email protected]297ca1c2011-06-20 23:08:467700 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427701 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517702 // TODO(gman): If textures tracked which framebuffers they were attached to
7703 // we could just mark those framebuffers as not complete.
7704 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:467705 }
7706
[email protected]1bed6222011-12-21 11:21:397707 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) {
[email protected]0226c112011-07-22 03:25:077708 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
[email protected]60f22d32012-12-12 00:31:587709 texture_manager()->SetLevelCleared(info, target, level, true);
[email protected]0226c112011-07-22 03:25:077710 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037711 return;
[email protected]7488d962010-07-16 02:41:587712 }
[email protected]876f6fee2010-08-02 23:10:327713
[email protected]cadde4a2010-07-31 17:10:437714 CopyRealGLErrorsToWrapper();
[email protected]473c01ccb2011-06-07 01:33:307715 WrappedTexImage2D(
7716 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477717 pixels);
[email protected]1002c2d2011-06-28 22:39:047718 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437719 if (error == GL_NO_ERROR) {
[email protected]0d6bfdc2011-11-02 01:32:207720 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417721 info,
[email protected]0d6bfdc2011-11-02 01:32:207722 target, level, internal_format, width, height, 1, border, format, type,
7723 pixels != NULL);
[email protected]b493ee622011-04-13 23:52:007724 tex_image_2d_failed_ = false;
[email protected]cadde4a2010-07-31 17:10:437725 }
[email protected]f598f422012-12-07 08:30:037726 return;
[email protected]b9849abf2009-11-25 19:13:197727}
7728
[email protected]f7a64ee2010-02-01 22:24:147729error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197730 uint32 immediate_data_size, const gles2::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387731 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]b493ee622011-04-13 23:52:007732 tex_image_2d_failed_ = true;
[email protected]b9849abf2009-11-25 19:13:197733 GLenum target = static_cast<GLenum>(c.target);
7734 GLint level = static_cast<GLint>(c.level);
7735 GLint internal_format = static_cast<GLint>(c.internalformat);
7736 GLsizei width = static_cast<GLsizei>(c.width);
7737 GLsizei height = static_cast<GLsizei>(c.height);
7738 GLint border = static_cast<GLint>(c.border);
7739 GLenum format = static_cast<GLenum>(c.format);
7740 GLenum type = static_cast<GLenum>(c.type);
7741 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7742 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187743 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347744 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247745 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347746 NULL)) {
[email protected]a76b0052010-03-05 00:33:187747 return error::kOutOfBounds;
7748 }
[email protected]b9849abf2009-11-25 19:13:197749 const void* pixels = NULL;
7750 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7751 pixels = GetSharedMemoryAs<const void*>(
7752 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467753 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147754 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197755 }
7756 }
[email protected]f598f422012-12-07 08:30:037757
7758 DoTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197759 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477760 pixels, pixels_size);
[email protected]f598f422012-12-07 08:30:037761 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197762}
7763
[email protected]f7a64ee2010-02-01 22:24:147764error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]b9849abf2009-11-25 19:13:197765 uint32 immediate_data_size, const gles2::TexImage2DImmediate& c) {
7766 GLenum target = static_cast<GLenum>(c.target);
7767 GLint level = static_cast<GLint>(c.level);
[email protected]ba3176a2009-12-16 18:19:467768 GLint internal_format = static_cast<GLint>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197769 GLsizei width = static_cast<GLsizei>(c.width);
7770 GLsizei height = static_cast<GLsizei>(c.height);
7771 GLint border = static_cast<GLint>(c.border);
7772 GLenum format = static_cast<GLenum>(c.format);
7773 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:187774 uint32 size;
[email protected]3458a64a2012-04-10 17:39:347775 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247776 width, height, format, type, state_.unpack_alignment, &size,
7777 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187778 return error::kOutOfBounds;
7779 }
[email protected]07f54fcc2009-12-22 02:46:307780 const void* pixels = GetImmediateDataAs<const void*>(
7781 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467782 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147783 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467784 }
[email protected]a93bb842010-02-16 23:03:477785 DoTexImage2D(
[email protected]ba3176a2009-12-16 18:19:467786 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477787 pixels, size);
[email protected]f7a64ee2010-02-01 22:24:147788 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327789}
7790
[email protected]cadde4a2010-07-31 17:10:437791void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7792 GLenum target,
7793 GLint level,
7794 GLint xoffset,
7795 GLint yoffset,
7796 GLsizei width,
7797 GLsizei height,
7798 GLenum format,
7799 GLsizei image_size,
7800 const void * data) {
7801 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7802 if (!info) {
7803 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437804 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437805 return;
7806 }
7807 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527808 GLenum internal_format = 0;
7809 if (!info->GetLevelType(target, level, &type, &internal_format)) {
7810 SetGLError(
7811 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437812 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527813 return;
7814 }
7815 if (internal_format != format) {
7816 SetGLError(
7817 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437818 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527819 return;
7820 }
7821 if (!info->ValidForTexture(
7822 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]cadde4a2010-07-31 17:10:437823 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437824 "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437825 return;
7826 }
[email protected]ad84a3a2012-06-08 21:42:437827
7828 if (!ValidateCompressedTexFuncData(
7829 "glCompressedTexSubImage2D", width, height, format, image_size) ||
7830 !ValidateCompressedTexSubDimensions(
7831 "glCompressedTexSubImage2D",
7832 target, level, xoffset, yoffset, width, height, format, info)) {
7833 return;
7834 }
7835
7836
[email protected]0d6bfdc2011-11-02 01:32:207837 // Note: There is no need to deal with texture cleared tracking here
7838 // because the validation above means you can only get here if the level
7839 // is already a matching compressed format and in that case
7840 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:437841 glCompressedTexSubImage2D(
7842 target, level, xoffset, yoffset, width, height, format, image_size, data);
7843}
7844
[email protected]6e288612010-12-21 20:45:037845static void Clip(
7846 GLint start, GLint range, GLint sourceRange,
7847 GLint* out_start, GLint* out_range) {
7848 DCHECK(out_start);
7849 DCHECK(out_range);
7850 if (start < 0) {
7851 range += start;
7852 start = 0;
7853 }
7854 GLint end = start + range;
7855 if (end > sourceRange) {
7856 range -= end - sourceRange;
7857 }
7858 *out_start = start;
7859 *out_range = range;
7860}
7861
[email protected]cadde4a2010-07-31 17:10:437862void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:447863 GLenum target,
7864 GLint level,
7865 GLenum internal_format,
7866 GLint x,
7867 GLint y,
7868 GLsizei width,
7869 GLsizei height,
7870 GLint border) {
[email protected]09e17272012-11-30 10:30:447871 DCHECK(!ShouldDeferReads());
[email protected]cadde4a2010-07-31 17:10:437872 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7873 if (!info) {
7874 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437875 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437876 return;
7877 }
[email protected]97dc7cbe2011-12-06 17:26:177878 if (info->IsImmutable()) {
7879 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437880 "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:177881 }
[email protected]80eb6b52012-01-19 00:14:417882 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:187883 border != 0) {
[email protected]ad84a3a2012-06-08 21:42:437884 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:187885 return;
7886 }
[email protected]81375742012-06-08 00:04:007887 if (!ValidateTextureParameters(
7888 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
7889 return;
7890 }
[email protected]f5719fb2010-08-04 18:27:187891
[email protected]9edc6b22010-12-23 02:00:267892 // Check we have compatible formats.
7893 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7894 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7895 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
7896
7897 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ad84a3a2012-06-08 21:42:437898 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:267899 return;
7900 }
7901
[email protected]81375742012-06-08 00:04:007902 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
7903 SetGLError(
7904 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437905 "glCopyImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:007906 return;
7907 }
7908
[email protected]a0b78dc2011-11-11 10:43:107909 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
7910 return;
7911 }
7912
[email protected]cadde4a2010-07-31 17:10:437913 CopyRealGLErrorsToWrapper();
[email protected]de26b3c2011-08-03 21:54:277914 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:037915 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:267916
[email protected]297ca1c2011-06-20 23:08:467917 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427918 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517919 // TODO(gman): If textures tracked which framebuffers they were attached to
7920 // we could just mark those framebuffers as not complete.
7921 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:467922 }
7923
[email protected]9edc6b22010-12-23 02:00:267924 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:037925 GLint copyX = 0;
7926 GLint copyY = 0;
7927 GLint copyWidth = 0;
7928 GLint copyHeight = 0;
7929 Clip(x, width, size.width(), &copyX, &copyWidth);
7930 Clip(y, height, size.height(), &copyY, &copyHeight);
7931
7932 if (copyX != x ||
7933 copyY != y ||
7934 copyWidth != width ||
7935 copyHeight != height) {
7936 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:207937 if (!ClearLevel(
7938 info->service_id(), info->target(),
[email protected]4502e6492011-12-14 19:39:157939 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
7940 info->IsImmutable())) {
[email protected]ad84a3a2012-06-08 21:42:437941 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:037942 return;
7943 }
[email protected]6e288612010-12-21 20:45:037944 if (copyHeight > 0 && copyWidth > 0) {
7945 GLint dx = copyX - x;
7946 GLint dy = copyY - y;
7947 GLint destX = dx;
7948 GLint destY = dy;
7949 glCopyTexSubImage2D(target, level,
7950 destX, destY, copyX, copyY,
7951 copyWidth, copyHeight);
7952 }
7953 } else {
7954 glCopyTexImage2D(target, level, internal_format,
7955 copyX, copyY, copyWidth, copyHeight, border);
7956 }
[email protected]1002c2d2011-06-28 22:39:047957 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437958 if (error == GL_NO_ERROR) {
7959 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417960 info, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:207961 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:437962 }
7963}
7964
7965void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:447966 GLenum target,
7967 GLint level,
7968 GLint xoffset,
7969 GLint yoffset,
7970 GLint x,
7971 GLint y,
7972 GLsizei width,
7973 GLsizei height) {
[email protected]09e17272012-11-30 10:30:447974 DCHECK(!ShouldDeferReads());
[email protected]cadde4a2010-07-31 17:10:437975 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7976 if (!info) {
7977 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437978 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437979 return;
7980 }
7981 GLenum type = 0;
7982 GLenum format = 0;
7983 if (!info->GetLevelType(target, level, &type, &format) ||
7984 !info->ValidForTexture(
7985 target, level, xoffset, yoffset, width, height, format, type)) {
7986 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437987 "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437988 return;
7989 }
[email protected]32145a92012-12-17 09:01:597990 if (info->AsyncTransferIsInProgress()) {
7991 SetGLError(GL_INVALID_OPERATION,
7992 "glCopyTexSubImage2D", "async upload pending for texture");
7993 return;
7994 }
[email protected]9edc6b22010-12-23 02:00:267995
7996 // Check we have compatible formats.
7997 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7998 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7999 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8000
[email protected]2d3765b2012-10-03 00:31:078001 if (!channels_needed ||
8002 (channels_needed & channels_exist) != channels_needed) {
[email protected]9edc6b22010-12-23 02:00:268003 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:438004 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268005 return;
8006 }
8007
[email protected]81375742012-06-08 00:04:008008 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
8009 SetGLError(
8010 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438011 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008012 return;
8013 }
8014
[email protected]a0b78dc2011-11-11 10:43:108015 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8016 return;
8017 }
8018
[email protected]de26b3c2011-08-03 21:54:278019 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038020 gfx::Size size = GetBoundReadFrameBufferSize();
8021 GLint copyX = 0;
8022 GLint copyY = 0;
8023 GLint copyWidth = 0;
8024 GLint copyHeight = 0;
8025 Clip(x, width, size.width(), &copyX, &copyWidth);
8026 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208027
8028 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
[email protected]ad84a3a2012-06-08 21:42:438029 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208030 return;
8031 }
8032
[email protected]6e288612010-12-21 20:45:038033 if (copyX != x ||
8034 copyY != y ||
8035 copyWidth != width ||
8036 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208037 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038038 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348039 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248040 width, height, format, type, state_.unpack_alignment, &pixels_size,
8041 NULL, NULL)) {
[email protected]ad84a3a2012-06-08 21:42:438042 SetGLError(
8043 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038044 return;
8045 }
8046 scoped_array<char> zero(new char[pixels_size]);
8047 memset(zero.get(), 0, pixels_size);
8048 glTexSubImage2D(
8049 target, level, xoffset, yoffset, width, height,
8050 format, type, zero.get());
8051 }
[email protected]0d6bfdc2011-11-02 01:32:208052
[email protected]6e288612010-12-21 20:45:038053 if (copyHeight > 0 && copyWidth > 0) {
8054 GLint dx = copyX - x;
8055 GLint dy = copyY - y;
8056 GLint destX = xoffset + dx;
8057 GLint destY = yoffset + dy;
8058 glCopyTexSubImage2D(target, level,
8059 destX, destY, copyX, copyY,
8060 copyWidth, copyHeight);
8061 }
[email protected]cadde4a2010-07-31 17:10:438062}
8063
[email protected]f598f422012-12-07 08:30:038064bool GLES2DecoderImpl::ValidateTexSubImage2D(
8065 error::Error* error,
8066 const char* function_name,
8067 GLenum target,
8068 GLint level,
8069 GLint xoffset,
8070 GLint yoffset,
8071 GLsizei width,
8072 GLsizei height,
8073 GLenum format,
8074 GLenum type,
8075 const void * data) {
8076 (*error) = error::kNoError;
8077 if (!validators_->texture_target.IsValid(target)) {
8078 SetGLErrorInvalidEnum(function_name, target, "target");
8079 return false;
8080 }
8081 if (width < 0) {
8082 SetGLError(GL_INVALID_VALUE, function_name, "width < 0");
8083 return false;
8084 }
8085 if (height < 0) {
8086 SetGLError(GL_INVALID_VALUE, function_name, "height < 0");
8087 return false;
8088 }
8089 if (!validators_->texture_format.IsValid(format)) {
8090 SetGLErrorInvalidEnum(function_name, format, "format");
8091 return false;
8092 }
8093 if (!validators_->pixel_type.IsValid(type)) {
8094 SetGLErrorInvalidEnum(function_name, type, "type");
8095 return false;
8096 }
[email protected]cadde4a2010-07-31 17:10:438097 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
8098 if (!info) {
8099 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038100 function_name, "unknown texture for target");
8101 return false;
[email protected]cadde4a2010-07-31 17:10:438102 }
[email protected]df6cf1ad2011-01-29 01:20:528103 GLenum current_type = 0;
8104 GLenum internal_format = 0;
8105 if (!info->GetLevelType(target, level, &current_type, &internal_format)) {
8106 SetGLError(
[email protected]f598f422012-12-07 08:30:038107 GL_INVALID_OPERATION, function_name, "level does not exist.");
8108 return false;
[email protected]df6cf1ad2011-01-29 01:20:528109 }
8110 if (format != internal_format) {
8111 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038112 function_name, "format does not match internal format.");
8113 return false;
[email protected]df6cf1ad2011-01-29 01:20:528114 }
8115 if (type != current_type) {
8116 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038117 function_name, "type does not match type of texture.");
8118 return false;
[email protected]df6cf1ad2011-01-29 01:20:528119 }
[email protected]32145a92012-12-17 09:01:598120 if (info->AsyncTransferIsInProgress()) {
8121 SetGLError(GL_INVALID_OPERATION,
8122 function_name, "async upload pending for texture");
8123 return false;
8124 }
[email protected]cadde4a2010-07-31 17:10:438125 if (!info->ValidForTexture(
8126 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]f598f422012-12-07 08:30:038127 SetGLError(GL_INVALID_VALUE, function_name, "bad dimensions.");
8128 return false;
[email protected]cadde4a2010-07-31 17:10:438129 }
[email protected]81375742012-06-08 00:04:008130 if ((GLES2Util::GetChannelsForFormat(format) &
8131 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
8132 SetGLError(
8133 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038134 function_name, "can not supply data for depth or stencil textures");
8135 return false;
[email protected]81375742012-06-08 00:04:008136 }
[email protected]f598f422012-12-07 08:30:038137 if (data == NULL) {
8138 (*error) = error::kOutOfBounds;
8139 return false;
8140 }
8141 return true;
8142}
[email protected]81375742012-06-08 00:04:008143
[email protected]f598f422012-12-07 08:30:038144error::Error GLES2DecoderImpl::DoTexSubImage2D(
8145 GLenum target,
8146 GLint level,
8147 GLint xoffset,
8148 GLint yoffset,
8149 GLsizei width,
8150 GLsizei height,
8151 GLenum format,
8152 GLenum type,
8153 const void * data) {
8154 error::Error error = error::kNoError;
8155 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8156 xoffset, yoffset, width, height, format, type, data)) {
8157 return error;
8158 }
8159 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]4502e6492011-12-14 19:39:158160 GLsizei tex_width = 0;
8161 GLsizei tex_height = 0;
8162 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height);
8163 DCHECK(ok);
8164 if (xoffset != 0 || yoffset != 0 ||
8165 width != tex_width || height != tex_height) {
8166 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
[email protected]ad84a3a2012-06-08 21:42:438167 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038168 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308169 }
[email protected]63b465922012-09-06 02:04:528170 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158171 glTexSubImage2D(
8172 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038173 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208174 }
[email protected]4502e6492011-12-14 19:39:158175
8176 if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) {
[email protected]63b465922012-09-06 02:04:528177 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158178 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8179 // same as internal_foramt. If that changes we'll need to look them up.
8180 WrappedTexImage2D(
8181 target, level, format, width, height, 0, format, type, data);
8182 } else {
[email protected]63b465922012-09-06 02:04:528183 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158184 glTexSubImage2D(
8185 target, level, xoffset, yoffset, width, height, format, type, data);
8186 }
[email protected]60f22d32012-12-12 00:31:588187 texture_manager()->SetLevelCleared(info, target, level, true);
[email protected]f598f422012-12-07 08:30:038188 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438189}
8190
[email protected]b493ee622011-04-13 23:52:008191error::Error GLES2DecoderImpl::HandleTexSubImage2D(
8192 uint32 immediate_data_size, const gles2::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388193 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008194 GLboolean internal = static_cast<GLboolean>(c.internal);
8195 if (internal == GL_TRUE && tex_image_2d_failed_)
8196 return error::kNoError;
8197
8198 GLenum target = static_cast<GLenum>(c.target);
8199 GLint level = static_cast<GLint>(c.level);
8200 GLint xoffset = static_cast<GLint>(c.xoffset);
8201 GLint yoffset = static_cast<GLint>(c.yoffset);
8202 GLsizei width = static_cast<GLsizei>(c.width);
8203 GLsizei height = static_cast<GLsizei>(c.height);
8204 GLenum format = static_cast<GLenum>(c.format);
8205 GLenum type = static_cast<GLenum>(c.type);
8206 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348207 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248208 width, height, format, type, state_.unpack_alignment, &data_size,
8209 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008210 return error::kOutOfBounds;
8211 }
8212 const void* pixels = GetSharedMemoryAs<const void*>(
8213 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038214 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008215 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008216}
8217
8218error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
8219 uint32 immediate_data_size, const gles2::TexSubImage2DImmediate& c) {
8220 GLboolean internal = static_cast<GLboolean>(c.internal);
8221 if (internal == GL_TRUE && tex_image_2d_failed_)
8222 return error::kNoError;
8223
8224 GLenum target = static_cast<GLenum>(c.target);
8225 GLint level = static_cast<GLint>(c.level);
8226 GLint xoffset = static_cast<GLint>(c.xoffset);
8227 GLint yoffset = static_cast<GLint>(c.yoffset);
8228 GLsizei width = static_cast<GLsizei>(c.width);
8229 GLsizei height = static_cast<GLsizei>(c.height);
8230 GLenum format = static_cast<GLenum>(c.format);
8231 GLenum type = static_cast<GLenum>(c.type);
8232 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348233 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248234 width, height, format, type, state_.unpack_alignment, &data_size,
8235 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008236 return error::kOutOfBounds;
8237 }
8238 const void* pixels = GetImmediateDataAs<const void*>(
8239 c, data_size, immediate_data_size);
[email protected]f598f422012-12-07 08:30:038240 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008241 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008242}
8243
[email protected]f7a64ee2010-02-01 22:24:148244error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]b9849abf2009-11-25 19:13:198245 uint32 immediate_data_size, const gles2::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368246 GLuint index = static_cast<GLuint>(c.index);
8247 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]0bfd9882010-02-05 23:02:258248 typedef gles2::GetVertexAttribPointerv::Result Result;
8249 Result* result = GetSharedMemoryAs<Result*>(
8250 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368251 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148252 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368253 }
[email protected]07d0cc82010-02-17 04:51:408254 // Check that the client initialized the result.
8255 if (result->size != 0) {
8256 return error::kInvalidArguments;
8257 }
[email protected]9438b012010-06-15 22:55:058258 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]f80e6e12012-08-31 00:43:538259 SetGLErrorInvalidEnum("glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148260 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368261 }
[email protected]3916c97e2010-02-25 03:20:508262 if (index >= group_->max_vertex_attribs()) {
[email protected]8eee29c2010-04-29 03:38:298263 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438264 "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148265 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368266 }
[email protected]0bfd9882010-02-05 23:02:258267 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088268 *result->GetData() =
[email protected]e259eb412012-10-13 05:47:248269 state_.vertex_attrib_manager->GetVertexAttribInfo(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148270 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328271}
8272
[email protected]f7b85372010-02-03 01:11:378273bool GLES2DecoderImpl::GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128274 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378275 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128276 error::Error* error, GLint* real_location,
8277 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108278 DCHECK(error);
8279 DCHECK(service_id);
8280 DCHECK(result_pointer);
8281 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128282 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378283 *error = error::kNoError;
8284 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258285 SizedResult<GLint>* result;
8286 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8287 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8288 if (!result) {
[email protected]f7b85372010-02-03 01:11:378289 *error = error::kOutOfBounds;
8290 return false;
8291 }
[email protected]0bfd9882010-02-05 23:02:258292 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378293 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258294 result->SetNumResults(0);
[email protected]6b8cf1a2010-05-06 16:13:588295 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8296 program, "glGetUniform");
[email protected]f7b85372010-02-03 01:11:378297 if (!info) {
[email protected]ae51d192010-04-27 00:48:038298 return false;
8299 }
8300 if (!info->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378301 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ad84a3a2012-06-08 21:42:438302 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378303 return false;
8304 }
[email protected]ae51d192010-04-27 00:48:038305 *service_id = info->service_id();
[email protected]43c2f1f2011-03-25 18:35:368306 GLint array_index = -1;
8307 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]1b0a6752012-02-22 03:44:128308 info->GetUniformInfoByFakeLocation(
8309 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368310 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378311 // No such location.
[email protected]ad84a3a2012-06-08 21:42:438312 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378313 return false;
8314 }
[email protected]43c2f1f2011-03-25 18:35:368315 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508316 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378317 if (size == 0) {
[email protected]ad84a3a2012-06-08 21:42:438318 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378319 return false;
8320 }
[email protected]0bfd9882010-02-05 23:02:258321 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8322 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8323 if (!result) {
[email protected]f7b85372010-02-03 01:11:378324 *error = error::kOutOfBounds;
8325 return false;
8326 }
[email protected]0bfd9882010-02-05 23:02:258327 result->size = size;
[email protected]939e7362010-05-13 20:49:108328 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378329 return true;
8330}
8331
[email protected]f7a64ee2010-02-01 22:24:148332error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]b9849abf2009-11-25 19:13:198333 uint32 immediate_data_size, const gles2::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378334 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338335 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378336 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108337 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128338 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378339 Error error;
[email protected]0bfd9882010-02-05 23:02:258340 void* result;
[email protected]f7b85372010-02-03 01:11:378341 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128342 program, fake_location, c.params_shm_id, c.params_shm_offset,
8343 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258344 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128345 service_id, real_location,
[email protected]0bfd9882010-02-05 23:02:258346 static_cast<gles2::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378347 }
8348 return error;
[email protected]96449d2c2009-11-25 00:01:328349}
8350
[email protected]f7a64ee2010-02-01 22:24:148351error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]b9849abf2009-11-25 19:13:198352 uint32 immediate_data_size, const gles2::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378353 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338354 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378355 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128356 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378357 Error error;
[email protected]0bfd9882010-02-05 23:02:258358 typedef gles2::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108359 Result* result;
8360 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378361 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128362 program, fake_location, c.params_shm_id, c.params_shm_offset,
8363 &error, &real_location, &service_id,
8364 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108365 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8366 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8367 GLsizei num_values = result->GetNumResults();
8368 scoped_array<GLint> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128369 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108370 GLfloat* dst = result->GetData();
8371 for (GLsizei ii = 0; ii < num_values; ++ii) {
8372 dst[ii] = (temp[ii] != 0);
8373 }
8374 } else {
[email protected]1b0a6752012-02-22 03:44:128375 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108376 }
[email protected]f7b85372010-02-03 01:11:378377 }
8378 return error;
[email protected]96449d2c2009-11-25 00:01:328379}
8380
[email protected]f7a64ee2010-02-01 22:24:148381error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]b9849abf2009-11-25 19:13:198382 uint32 immediate_data_size, const gles2::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258383 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8384 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
8385 typedef gles2::GetShaderPrecisionFormat::Result Result;
8386 Result* result = GetSharedMemoryAs<Result*>(
8387 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8388 if (!result) {
8389 return error::kOutOfBounds;
8390 }
[email protected]07d0cc82010-02-17 04:51:408391 // Check that the client initialized the result.
8392 if (result->success != 0) {
8393 return error::kInvalidArguments;
8394 }
[email protected]9438b012010-06-15 22:55:058395 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]f80e6e12012-08-31 00:43:538396 SetGLErrorInvalidEnum(
8397 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298398 return error::kNoError;
8399 }
[email protected]9438b012010-06-15 22:55:058400 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]f80e6e12012-08-31 00:43:538401 SetGLErrorInvalidEnum(
8402 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298403 return error::kNoError;
8404 }
8405
8406 result->success = 1; // true
8407 switch (precision_type) {
8408 case GL_LOW_INT:
8409 case GL_MEDIUM_INT:
8410 case GL_HIGH_INT:
[email protected]0a34b582012-04-09 22:42:568411 // These values are for a 32-bit twos-complement integer format.
8412 result->min_range = 31;
8413 result->max_range = 30;
[email protected]8eee29c2010-04-29 03:38:298414 result->precision = 0;
[email protected]4e8a5b122010-05-08 22:00:108415 break;
[email protected]8eee29c2010-04-29 03:38:298416 case GL_LOW_FLOAT:
8417 case GL_MEDIUM_FLOAT:
8418 case GL_HIGH_FLOAT:
[email protected]0a34b582012-04-09 22:42:568419 // These values are for an IEEE single-precision floating-point format.
8420 result->min_range = 127;
8421 result->max_range = 127;
8422 result->precision = 23;
[email protected]8eee29c2010-04-29 03:38:298423 break;
8424 default:
8425 NOTREACHED();
8426 break;
[email protected]0bfd9882010-02-05 23:02:258427 }
[email protected]f7a64ee2010-02-01 22:24:148428 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328429}
8430
[email protected]f7a64ee2010-02-01 22:24:148431error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]b9849abf2009-11-25 19:13:198432 uint32 immediate_data_size, const gles2::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258433 uint32 result_size = c.result_size;
[email protected]6b8cf1a2010-05-06 16:13:588434 GLuint program = static_cast<GLuint>(c.program);
8435 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8436 program, "glGetAttachedShaders");
[email protected]ae51d192010-04-27 00:48:038437 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258438 return error::kNoError;
8439 }
8440 typedef gles2::GetAttachedShaders::Result Result;
8441 uint32 max_count = Result::ComputeMaxResults(result_size);
8442 Result* result = GetSharedMemoryAs<Result*>(
8443 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8444 if (!result) {
8445 return error::kOutOfBounds;
8446 }
[email protected]07d0cc82010-02-17 04:51:408447 // Check that the client initialized the result.
8448 if (result->size != 0) {
8449 return error::kInvalidArguments;
8450 }
[email protected]0bfd9882010-02-05 23:02:258451 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038452 glGetAttachedShaders(
8453 info->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258454 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038455 if (!shader_manager()->GetClientId(result->GetData()[ii],
8456 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258457 NOTREACHED();
8458 return error::kGenericError;
8459 }
8460 }
8461 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148462 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328463}
8464
[email protected]f7a64ee2010-02-01 22:24:148465error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]b9849abf2009-11-25 19:13:198466 uint32 immediate_data_size, const gles2::GetActiveUniform& c) {
[email protected]0bfd9882010-02-05 23:02:258467 GLuint program = c.program;
8468 GLuint index = c.index;
8469 uint32 name_bucket_id = c.name_bucket_id;
[email protected]0bfd9882010-02-05 23:02:258470 typedef gles2::GetActiveUniform::Result Result;
8471 Result* result = GetSharedMemoryAs<Result*>(
8472 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8473 if (!result) {
8474 return error::kOutOfBounds;
8475 }
[email protected]07d0cc82010-02-17 04:51:408476 // Check that the client initialized the result.
8477 if (result->success != 0) {
8478 return error::kInvalidArguments;
8479 }
[email protected]6b8cf1a2010-05-06 16:13:588480 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8481 program, "glGetActiveUniform");
[email protected]ae51d192010-04-27 00:48:038482 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258483 return error::kNoError;
8484 }
8485 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
8486 info->GetUniformInfo(index);
8487 if (!uniform_info) {
[email protected]ad84a3a2012-06-08 21:42:438488 SetGLError(GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258489 return error::kNoError;
8490 }
8491 result->success = 1; // true.
8492 result->size = uniform_info->size;
8493 result->type = uniform_info->type;
8494 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298495 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148496 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328497}
8498
[email protected]f7a64ee2010-02-01 22:24:148499error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]b9849abf2009-11-25 19:13:198500 uint32 immediate_data_size, const gles2::GetActiveAttrib& c) {
[email protected]0bfd9882010-02-05 23:02:258501 GLuint program = c.program;
8502 GLuint index = c.index;
8503 uint32 name_bucket_id = c.name_bucket_id;
[email protected]0bfd9882010-02-05 23:02:258504 typedef gles2::GetActiveAttrib::Result Result;
8505 Result* result = GetSharedMemoryAs<Result*>(
8506 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8507 if (!result) {
8508 return error::kOutOfBounds;
8509 }
[email protected]07d0cc82010-02-17 04:51:408510 // Check that the client initialized the result.
8511 if (result->success != 0) {
8512 return error::kInvalidArguments;
8513 }
[email protected]6b8cf1a2010-05-06 16:13:588514 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8515 program, "glGetActiveAttrib");
[email protected]ae51d192010-04-27 00:48:038516 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258517 return error::kNoError;
8518 }
8519 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
8520 info->GetAttribInfo(index);
8521 if (!attrib_info) {
[email protected]ad84a3a2012-06-08 21:42:438522 SetGLError(GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258523 return error::kNoError;
8524 }
8525 result->success = 1; // true.
8526 result->size = attrib_info->size;
8527 result->type = attrib_info->type;
8528 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298529 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148530 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328531}
8532
[email protected]b273e432010-04-12 17:23:588533error::Error GLES2DecoderImpl::HandleShaderBinary(
8534 uint32 immediate_data_size, const gles2::ShaderBinary& c) {
8535#if 1 // No binary shader support.
[email protected]ad84a3a2012-06-08 21:42:438536 SetGLError(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588537 return error::kNoError;
8538#else
8539 GLsizei n = static_cast<GLsizei>(c.n);
8540 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:438541 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588542 return error::kNoError;
8543 }
8544 GLsizei length = static_cast<GLsizei>(c.length);
8545 if (length < 0) {
[email protected]ad84a3a2012-06-08 21:42:438546 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588547 return error::kNoError;
8548 }
8549 uint32 data_size;
8550 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8551 return error::kOutOfBounds;
8552 }
8553 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8554 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8555 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8556 const void* binary = GetSharedMemoryAs<const void*>(
8557 c.binary_shm_id, c.binary_shm_offset, length);
8558 if (shaders == NULL || binary == NULL) {
8559 return error::kOutOfBounds;
8560 }
8561 scoped_array<GLuint> service_ids(new GLuint[n]);
8562 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ae51d192010-04-27 00:48:038563 ShaderManager::ShaderInfo* info = GetShaderInfo(shaders[ii]);
8564 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:438565 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588566 return error::kNoError;
8567 }
[email protected]ae51d192010-04-27 00:48:038568 service_ids[ii] = info->service_id();
[email protected]b273e432010-04-12 17:23:588569 }
8570 // TODO(gman): call glShaderBinary
8571 return error::kNoError;
8572#endif
8573}
8574
[email protected]6217d392010-03-25 22:08:358575error::Error GLES2DecoderImpl::HandleSwapBuffers(
8576 uint32 immediate_data_size, const gles2::SwapBuffers& c) {
[email protected]64ace852011-05-19 21:49:498577 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088578 if (!is_offscreen && surface_->DeferSwapBuffers()) {
8579 return error::kDeferCommandUntilLater;
8580 }
8581
[email protected]64ace852011-05-19 21:49:498582 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428583 // TRACE_EVENT for gpu tests:
8584 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
8585 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8586 "width", (is_offscreen ? offscreen_size_.width() :
8587 surface_->GetSize().width()));
[email protected]64ace852011-05-19 21:49:498588 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleSwapBuffers",
8589 "offscreen", is_offscreen,
8590 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358591 // If offscreen then don't actually SwapBuffers to the display. Just copy
8592 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498593 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318594 TRACE_EVENT2("gpu", "Offscreen",
8595 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538596 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8597 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8598 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8599 // fix this.
[email protected]62e155e2012-10-23 22:43:158600 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538601 offscreen_saved_frame_buffer_->Create();
8602 glFinish();
8603 }
8604
8605 // Allocate the offscreen saved color texture.
8606 DCHECK(offscreen_saved_color_format_);
8607 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098608 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538609
8610 offscreen_saved_frame_buffer_->AttachRenderTexture(
8611 offscreen_saved_color_texture_.get());
8612 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8613 GL_FRAMEBUFFER_COMPLETE) {
8614 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8615 << "because offscreen saved FBO was incomplete.";
8616 return error::kLostContext;
8617 }
8618
[email protected]1fb8c482011-08-31 01:01:538619 // Clear the offscreen color texture.
8620 // TODO(piman): Is this still necessary?
8621 {
8622 ScopedFrameBufferBinder binder(this,
8623 offscreen_saved_frame_buffer_->id());
8624 glClearColor(0, 0, 0, 0);
8625 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8626 glDisable(GL_SCISSOR_TEST);
8627 glClear(GL_COLOR_BUFFER_BIT);
8628 RestoreClearState();
8629 }
8630
8631 UpdateParentTextureInfo();
8632 }
8633
[email protected]6217d392010-03-25 22:08:358634 ScopedGLErrorSuppressor suppressor(this);
8635
[email protected]34ff8b0c2010-10-01 20:06:028636 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138637 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278638 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]89d6ed02011-04-20 00:23:238639 return error::kNoError;
[email protected]b86b14982010-10-11 18:45:488640 } else {
[email protected]069944672012-04-25 20:52:238641 ScopedFrameBufferBinder binder(this,
8642 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138643
[email protected]069944672012-04-25 20:52:238644 if (offscreen_target_buffer_preserved_) {
8645 // Copy the target frame buffer to the saved offscreen texture.
8646 offscreen_saved_color_texture_->Copy(
8647 offscreen_saved_color_texture_->size(),
8648 offscreen_saved_color_format_);
8649 } else {
8650 // Flip the textures in the parent context via the texture manager.
8651 if (!!offscreen_saved_color_texture_info_.get())
8652 offscreen_saved_color_texture_info_->
8653 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568654
[email protected]069944672012-04-25 20:52:238655 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8656 offscreen_target_frame_buffer_->AttachRenderTexture(
8657 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488658 }
[email protected]069944672012-04-25 20:52:238659
8660 // Ensure the side effects of the copy are visible to the parent
8661 // context. There is no need to do this for ANGLE because it uses a
8662 // single D3D device for all contexts.
8663 if (!IsAngle())
8664 glFlush();
[email protected]89d6ed02011-04-20 00:23:238665 return error::kNoError;
[email protected]0c8c9d22010-06-25 17:36:398666 }
[email protected]6217d392010-03-25 22:08:358667 } else {
[email protected]111975c62012-09-06 01:37:318668 TRACE_EVENT2("gpu", "Onscreen",
8669 "width", surface_->GetSize().width(),
8670 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158671 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018672 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]5259ead82010-09-10 18:02:028673 return error::kLostContext;
[email protected]d0498742010-09-20 20:27:018674 }
[email protected]6217d392010-03-25 22:08:358675 }
8676
[email protected]89d6ed02011-04-20 00:23:238677 return error::kNoError;
[email protected]6217d392010-03-25 22:08:358678}
8679
[email protected]d4239852011-08-12 04:51:228680error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
8681 uint32 immediate_data_size, const gles2::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188682 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288683 if (!bucket || bucket->size() == 0) {
8684 return error::kInvalidArguments;
8685 }
[email protected]d4239852011-08-12 04:51:228686 typedef gles2::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188687 Result* result = GetSharedMemoryAs<Result*>(
8688 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8689 if (!result) {
8690 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108691 }
[email protected]b1d2dcb2010-05-17 19:24:188692 // Check that the client initialized the result.
8693 if (*result != 0) {
8694 return error::kInvalidArguments;
8695 }
8696 std::string feature_str;
8697 if (!bucket->GetAsString(&feature_str)) {
8698 return error::kInvalidArguments;
8699 }
8700
8701 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228702 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188703 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228704 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408705 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8706 // TODO(gman): decide how to remove the need for this const_cast.
8707 // I could make validators_ non const but that seems bad as this is the only
8708 // place it is needed. I could make some special friend class of validators
8709 // just to allow this to set them. That seems silly. I could refactor this
8710 // code to use the extension mechanism or the initialization attributes to
8711 // turn this feature on. Given that the only real point of this is to make
8712 // the conformance tests pass and given that there is lots of real work that
8713 // needs to be done it seems like refactoring for one to one of those
8714 // methods is a very low priority.
8715 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048716 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8717 force_webgl_glsl_validation_ = true;
8718 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188719 } else {
8720 return error::kNoError;
8721 }
8722
8723 *result = 1; // true.
8724 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108725}
8726
[email protected]c2f8c8402010-12-06 18:07:248727error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8728 uint32 immediate_data_size,
8729 const gles2::GetRequestableExtensionsCHROMIUM& c) {
8730 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]80eb6b52012-01-19 00:14:418731 FeatureInfo::Ref info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:298732 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:248733 bucket->SetFromString(info->extensions().c_str());
8734 return error::kNoError;
8735}
8736
8737error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
8738 uint32 immediate_data_size, const gles2::RequestExtensionCHROMIUM& c) {
8739 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288740 if (!bucket || bucket->size() == 0) {
8741 return error::kInvalidArguments;
8742 }
[email protected]c2f8c8402010-12-06 18:07:248743 std::string feature_str;
8744 if (!bucket->GetAsString(&feature_str)) {
8745 return error::kInvalidArguments;
8746 }
8747
[email protected]4b7eba92013-01-08 02:23:568748 bool desire_webgl_glsl_validation =
8749 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
8750 bool desire_standard_derivatives = false;
8751 if (force_webgl_glsl_validation_) {
8752 desire_standard_derivatives =
8753 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:048754 }
8755
[email protected]4b7eba92013-01-08 02:23:568756 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
8757 desire_standard_derivatives != derivatives_explicitly_enabled_) {
8758 force_webgl_glsl_validation_ = desire_webgl_glsl_validation;
8759 derivatives_explicitly_enabled_ = desire_standard_derivatives;
[email protected]c2f8c8402010-12-06 18:07:248760 InitializeShaderTranslator();
8761 }
8762
[email protected]302ce6d2011-07-07 23:28:118763 UpdateCapabilities();
8764
[email protected]c2f8c8402010-12-06 18:07:248765 return error::kNoError;
8766}
8767
[email protected]372e0412011-06-28 16:08:568768error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
8769 uint32 immediate_data_size, const gles2::GetMultipleIntegervCHROMIUM& c) {
8770 GLuint count = c.count;
8771 uint32 pnames_size;
8772 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8773 return error::kOutOfBounds;
8774 }
8775 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8776 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8777 if (pnames == NULL) {
8778 return error::kOutOfBounds;
8779 }
8780
8781 // We have to copy them since we use them twice so the client
8782 // can't change them between the time we validate them and the time we use
8783 // them.
8784 scoped_array<GLenum> enums(new GLenum[count]);
8785 memcpy(enums.get(), pnames, pnames_size);
8786
8787 // Count up the space needed for the result.
8788 uint32 num_results = 0;
8789 for (GLuint ii = 0; ii < count; ++ii) {
8790 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8791 if (num == 0) {
[email protected]f80e6e12012-08-31 00:43:538792 SetGLErrorInvalidEnum("glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568793 return error::kNoError;
8794 }
8795 // Num will never be more than 4.
8796 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478797 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568798 return error::kOutOfBounds;
8799 }
8800 }
8801
8802 uint32 result_size = 0;
8803 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8804 return error::kOutOfBounds;
8805 }
8806
8807 if (result_size != static_cast<uint32>(c.size)) {
8808 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438809 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:568810 return error::kNoError;
8811 }
8812
8813 GLint* results = GetSharedMemoryAs<GLint*>(
8814 c.results_shm_id, c.results_shm_offset, result_size);
8815 if (results == NULL) {
8816 return error::kOutOfBounds;
8817 }
8818
8819 // Check the results have been cleared in case the context was lost.
8820 for (uint32 ii = 0; ii < num_results; ++ii) {
8821 if (results[ii]) {
8822 return error::kInvalidArguments;
8823 }
8824 }
8825
8826 // Get each result.
8827 GLint* start = results;
8828 for (GLuint ii = 0; ii < count; ++ii) {
8829 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:268830 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:538831 !GetHelper(enums[ii], results, &num_written)) {
[email protected]372e0412011-06-28 16:08:568832 glGetIntegerv(enums[ii], results);
8833 }
8834 results += num_written;
8835 }
8836
8837 // Just to verify. Should this be a DCHECK?
8838 if (static_cast<uint32>(results - start) != num_results) {
8839 return error::kOutOfBounds;
8840 }
8841
8842 return error::kNoError;
8843}
8844
[email protected]2318d342011-07-11 22:27:428845error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
8846 uint32 immediate_data_size, const gles2::GetProgramInfoCHROMIUM& c) {
8847 GLuint program = static_cast<GLuint>(c.program);
8848 uint32 bucket_id = c.bucket_id;
8849 Bucket* bucket = CreateBucket(bucket_id);
8850 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
8851 ProgramManager::ProgramInfo* info = NULL;
[email protected]9a14ae612011-08-08 17:51:468852 info = GetProgramInfo(program);
8853 if (!info || !info->IsValid()) {
8854 return error::kNoError;
[email protected]2318d342011-07-11 22:27:428855 }
[email protected]5d4c6b22012-02-07 08:22:288856 info->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:428857 return error::kNoError;
8858}
8859
[email protected]38d139d2011-07-14 00:38:438860error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
8861 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:438862 case GL_NO_ERROR:
8863 // TODO(kbr): improve the precision of the error code in this case.
8864 // Consider delegating to context for error code if MakeCurrent fails.
8865 return error::kUnknown;
8866 case GL_GUILTY_CONTEXT_RESET_ARB:
8867 return error::kGuilty;
8868 case GL_INNOCENT_CONTEXT_RESET_ARB:
8869 return error::kInnocent;
8870 case GL_UNKNOWN_CONTEXT_RESET_ARB:
8871 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:438872 }
8873
8874 NOTREACHED();
8875 return error::kUnknown;
8876}
8877
8878bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:098879 if (reset_status_ != GL_NO_ERROR) {
8880 return true;
8881 }
[email protected]706b69f2012-07-27 04:59:308882 if (context_->WasAllocatedUsingRobustnessExtension()) {
8883 GLenum status = GL_NO_ERROR;
8884 if (has_robustness_extension_)
8885 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:438886 if (status != GL_NO_ERROR) {
8887 // The graphics card was reset. Signal a lost context to the application.
8888 reset_status_ = status;
8889 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:098890 << " context lost via ARB/EXT_robustness. Reset status = "
8891 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:438892 return true;
8893 }
8894 }
8895 return false;
8896}
8897
[email protected]c4485aad62012-12-17 10:19:098898void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
8899 // Only loses the context once.
8900 if (reset_status_ != GL_NO_ERROR) {
8901 return;
8902 }
8903
8904 // Marks this context as lost.
8905 reset_status_ = reset_status;
8906 current_decoder_error_ = error::kLostContext;
8907
8908 // Loses the parent's context.
8909 if (parent_) {
8910 parent_->LoseContext(reset_status);
8911 }
8912
8913 // Loses any child contexts.
8914 for (ChildList::iterator it = children_.begin();
8915 it != children_.end();
8916 ++it) {
8917 (*it)->LoseContext(reset_status);
8918 }
8919}
8920
8921error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
8922 uint32 immediate_data_size, const gles2::LoseContextCHROMIUM& c) {
8923 GLenum current = static_cast<GLenum>(c.current);
8924 GLenum other = static_cast<GLenum>(c.other);
8925 if (!validators_->reset_status.IsValid(current)) {
8926 SetGLErrorInvalidEnum("glLoseContextCHROMIUM", current, "current");
8927 }
8928 if (!validators_->reset_status.IsValid(other)) {
8929 SetGLErrorInvalidEnum("glLoseContextCHROMIUM", other, "other");
8930 }
8931 group_->LoseContexts(other);
8932 reset_status_ = current;
8933 current_decoder_error_ = error::kLostContext;
8934 return error::kLostContext;
8935}
8936
[email protected]882ba1e22012-03-08 19:02:538937bool GLES2DecoderImpl::GenQueriesEXTHelper(
8938 GLsizei n, const GLuint* client_ids) {
8939 for (GLsizei ii = 0; ii < n; ++ii) {
8940 if (query_manager_->GetQuery(client_ids[ii])) {
8941 return false;
8942 }
8943 }
[email protected]c45f1972012-03-14 07:27:368944 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:538945 return true;
8946}
8947
8948void GLES2DecoderImpl::DeleteQueriesEXTHelper(
8949 GLsizei n, const GLuint* client_ids) {
8950 for (GLsizei ii = 0; ii < n; ++ii) {
8951 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
8952 if (query && !query->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:248953 if (query == state_.current_query) {
8954 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:538955 }
[email protected]c45f1972012-03-14 07:27:368956 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:538957 query_manager_->RemoveQuery(client_ids[ii]);
8958 }
8959 }
8960}
8961
[email protected]22e3f552012-03-13 01:54:198962bool GLES2DecoderImpl::ProcessPendingQueries() {
8963 if (query_manager_.get() == NULL) {
8964 return false;
8965 }
[email protected]c45f1972012-03-14 07:27:368966 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:198967 current_decoder_error_ = error::kOutOfBounds;
8968 }
8969 return query_manager_->HavePendingQueries();
8970}
8971
[email protected]882ba1e22012-03-08 19:02:538972error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
8973 uint32 immediate_data_size, const gles2::BeginQueryEXT& c) {
8974 GLenum target = static_cast<GLenum>(c.target);
8975 GLuint client_id = static_cast<GLuint>(c.id);
8976 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
8977 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
8978
[email protected]c45f1972012-03-14 07:27:368979 switch (target) {
8980 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:558981 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]0713f43d2012-12-14 22:41:308982 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:368983 break;
8984 default:
[email protected]62e155e2012-10-23 22:43:158985 if (!features().occlusion_query_boolean) {
[email protected]ad84a3a2012-06-08 21:42:438986 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "not enabled");
[email protected]c45f1972012-03-14 07:27:368987 return error::kNoError;
8988 }
8989 break;
[email protected]882ba1e22012-03-08 19:02:538990 }
8991
[email protected]e259eb412012-10-13 05:47:248992 if (state_.current_query) {
[email protected]882ba1e22012-03-08 19:02:538993 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:438994 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:538995 return error::kNoError;
8996 }
8997
8998 if (client_id == 0) {
[email protected]ad84a3a2012-06-08 21:42:438999 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539000 return error::kNoError;
9001 }
9002
9003 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9004 if (!query) {
[email protected]c45f1972012-03-14 07:27:369005 // TODO(gman): Decide if we need this check.
9006 //
[email protected]882ba1e22012-03-08 19:02:539007 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369008 //
9009 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9010 // for all Query ids but from the POV of the command buffer service maybe
9011 // you don't.
9012 //
9013 // The client can enforce this. I don't think the service cares.
9014 //
9015 // IdAllocatorInterface* id_allocator =
9016 // group_->GetIdAllocator(id_namespaces::kQueries);
9017 // if (!id_allocator->InUse(client_id)) {
9018 // SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439019 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369020 // return error::kNoError;
9021 // }
9022 query = query_manager_->CreateQuery(
9023 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539024 }
9025
[email protected]c45f1972012-03-14 07:27:369026 if (query->target() != target) {
[email protected]ad84a3a2012-06-08 21:42:439027 SetGLError(
9028 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539029 return error::kNoError;
9030 } else if (query->shm_id() != sync_shm_id ||
9031 query->shm_offset() != sync_shm_offset) {
9032 DLOG(ERROR) << "Shared memory used by query not the same as before";
9033 return error::kInvalidArguments;
9034 }
9035
[email protected]c45f1972012-03-14 07:27:369036 if (!query_manager_->BeginQuery(query)) {
9037 return error::kOutOfBounds;
9038 }
[email protected]882ba1e22012-03-08 19:02:539039
[email protected]e259eb412012-10-13 05:47:249040 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539041 return error::kNoError;
9042}
9043
9044error::Error GLES2DecoderImpl::HandleEndQueryEXT(
9045 uint32 immediate_data_size, const gles2::EndQueryEXT& c) {
9046 GLenum target = static_cast<GLenum>(c.target);
9047 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9048
[email protected]e259eb412012-10-13 05:47:249049 if (!state_.current_query) {
[email protected]ad84a3a2012-06-08 21:42:439050 SetGLError(GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539051 return error::kNoError;
9052 }
[email protected]e259eb412012-10-13 05:47:249053 if (state_.current_query->target() != target) {
[email protected]882ba1e22012-03-08 19:02:539054 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439055 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539056 return error::kNoError;
9057 }
[email protected]882ba1e22012-03-08 19:02:539058
[email protected]e259eb412012-10-13 05:47:249059 if (!query_manager_->EndQuery(state_.current_query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369060 return error::kOutOfBounds;
9061 }
9062
[email protected]e259eb412012-10-13 05:47:249063 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539064 return error::kNoError;
9065}
9066
[email protected]944b62f32012-09-27 02:20:469067bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9068 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469069 for (GLsizei ii = 0; ii < n; ++ii) {
9070 if (GetVertexAttribManager(client_ids[ii])) {
9071 return false;
9072 }
9073 }
[email protected]ab4fd7282012-10-12 16:25:579074
[email protected]62e155e2012-10-23 22:43:159075 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579076 // Emulated VAO
9077 for (GLsizei ii = 0; ii < n; ++ii) {
9078 CreateVertexAttribManager(client_ids[ii], 0);
9079 }
9080 } else {
9081 scoped_array<GLuint> service_ids(new GLuint[n]);
9082
9083 glGenVertexArraysOES(n, service_ids.get());
9084 for (GLsizei ii = 0; ii < n; ++ii) {
9085 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9086 }
[email protected]944b62f32012-09-27 02:20:469087 }
[email protected]ab4fd7282012-10-12 16:25:579088
[email protected]944b62f32012-09-27 02:20:469089 return true;
9090}
9091
9092void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9093 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469094 for (GLsizei ii = 0; ii < n; ++ii) {
9095 VertexAttribManager* vao =
9096 GetVertexAttribManager(client_ids[ii]);
9097 if (vao && !vao->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249098 if (state_.vertex_attrib_manager == vao) {
9099 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469100 }
9101 RemoveVertexAttribManager(client_ids[ii]);
9102 }
9103 }
9104}
9105
9106void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469107 VertexAttribManager* vao = NULL;
9108 GLuint service_id = 0;
9109 if (client_id != 0) {
9110 vao = GetVertexAttribManager(client_id);
9111 if (!vao) {
9112 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9113 // only allows names that have been previously generated. As such, we do
9114 // not generate new names here.
9115 SetGLError(GL_INVALID_OPERATION,
9116 "glBindVertexArrayOES", ""
9117 "bad vertex array id.");
9118 current_decoder_error_ = error::kNoError;
9119 return;
9120 } else {
9121 service_id = vao->service_id();
9122 }
[email protected]944b62f32012-09-27 02:20:469123 } else {
[email protected]ab4fd7282012-10-12 16:25:579124 vao = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469125 }
9126
[email protected]ab4fd7282012-10-12 16:25:579127 // Only set the VAO state if it's changed
[email protected]e259eb412012-10-13 05:47:249128 if (state_.vertex_attrib_manager != vao) {
9129 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159130 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579131 EmulateVertexArrayState();
9132 } else {
9133 glBindVertexArrayOES(service_id);
9134 }
9135 }
9136}
9137
9138// Used when OES_vertex_array_object isn't natively supported
9139void GLES2DecoderImpl::EmulateVertexArrayState() {
9140 // Setup the Vertex attribute state
9141 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9142 RestoreStateForAttrib(vv);
9143 }
9144
9145 // Setup the element buffer
9146 BufferManager::BufferInfo* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249147 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579148 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9149 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469150}
9151
9152bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469153 const VertexAttribManager* vao =
9154 GetVertexAttribManager(client_id);
9155 return vao && vao->IsValid() && !vao->IsDeleted();
9156}
9157
[email protected]b0af4f52011-09-28 22:04:429158error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9159 uint32 immediate_data_size,
9160 const gles2::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159161 if (!features().chromium_stream_texture) {
[email protected]b0af4f52011-09-28 22:04:429162 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439163 "glOpenStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429164 "not supported.");
9165 return error::kNoError;
9166 }
9167
9168 uint32 client_id = c.client_id;
9169 typedef gles2::CreateStreamTextureCHROMIUM::Result Result;
9170 Result* result = GetSharedMemoryAs<Result*>(
9171 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9172
[email protected]e5081262012-01-05 23:09:039173 if (!result)
9174 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429175 *result = GL_ZERO;
9176 TextureManager::TextureInfo* info =
9177 texture_manager()->GetTextureInfo(client_id);
9178 if (!info) {
9179 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439180 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429181 "bad texture id.");
9182 return error::kNoError;
9183 }
9184
9185 if (info->IsStreamTexture()) {
9186 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439187 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429188 "is already a stream texture.");
9189 return error::kNoError;
9190 }
9191
9192 if (info->target() && info->target() != GL_TEXTURE_EXTERNAL_OES) {
9193 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439194 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429195 "is already bound to incompatible target.");
9196 return error::kNoError;
9197 }
9198
9199 if (!stream_texture_manager_)
9200 return error::kInvalidArguments;
9201
9202 GLuint object_id = stream_texture_manager_->CreateStreamTexture(
9203 info->service_id(), client_id);
9204
9205 if (object_id) {
9206 info->SetStreamTexture(true);
9207 } else {
9208 SetGLError(GL_OUT_OF_MEMORY,
[email protected]ad84a3a2012-06-08 21:42:439209 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429210 "failed to create platform texture.");
9211 }
9212
9213 *result = object_id;
9214 return error::kNoError;
9215}
9216
9217error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9218 uint32 immediate_data_size,
9219 const gles2::DestroyStreamTextureCHROMIUM& c) {
9220 GLuint client_id = c.texture;
9221 TextureManager::TextureInfo* info =
9222 texture_manager()->GetTextureInfo(client_id);
9223 if (info && info->IsStreamTexture()) {
9224 if (!stream_texture_manager_)
9225 return error::kInvalidArguments;
9226
9227 stream_texture_manager_->DestroyStreamTexture(info->service_id());
9228 info->SetStreamTexture(false);
[email protected]b0af4f52011-09-28 22:04:429229 } else {
9230 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439231 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429232 }
9233
9234 return error::kNoError;
9235}
9236
[email protected]e51bdf32011-11-23 22:21:469237#if defined(OS_MACOSX)
9238void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9239 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9240 texture_id);
9241 if (it != texture_to_io_surface_map_.end()) {
9242 // Found a previous IOSurface bound to this texture; release it.
9243 CFTypeRef surface = it->second;
9244 CFRelease(surface);
9245 texture_to_io_surface_map_.erase(it);
9246 }
9247}
9248#endif
9249
9250void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9251 GLenum target, GLsizei width, GLsizei height,
9252 GLuint io_surface_id, GLuint plane) {
9253#if defined(OS_MACOSX)
9254 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ad84a3a2012-06-08 21:42:439255 SetGLError(
9256 GL_INVALID_OPERATION,
9257 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469258 return;
9259 }
9260
9261 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9262 if (!surface_support) {
9263 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439264 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469265 return;
9266 }
9267
9268 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9269 // This might be supported in the future, and if we could require
9270 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9271 // could delete a lot of code. For now, perform strict validation so we
9272 // know what's going on.
9273 SetGLError(
9274 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439275 "glTexImageIOSurface2DCHROMIUM",
9276 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469277 return;
9278 }
9279
[email protected]09d50362012-10-18 20:54:379280 // Default target might be conceptually valid, but disallow it to avoid
9281 // accidents.
9282 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9283 target);
[email protected]e51bdf32011-11-23 22:21:469284 if (!info) {
9285 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439286 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469287 return;
9288 }
[email protected]e51bdf32011-11-23 22:21:469289
9290 // Look up the new IOSurface. Note that because of asynchrony
9291 // between processes this might fail; during live resizing the
9292 // plugin process might allocate and release an IOSurface before
9293 // this process gets a chance to look it up. Hold on to any old
9294 // IOSurface in this case.
9295 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9296 if (!surface) {
[email protected]ad84a3a2012-06-08 21:42:439297 SetGLError(
9298 GL_INVALID_OPERATION,
9299 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469300 return;
9301 }
9302
9303 // Release any IOSurface previously bound to this texture.
9304 ReleaseIOSurfaceForTexture(info->service_id());
9305
9306 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9307 texture_to_io_surface_map_.insert(
9308 std::make_pair(info->service_id(), surface));
9309
9310 CGLContextObj context =
9311 static_cast<CGLContextObj>(context_->GetHandle());
9312
9313 CGLError err = surface_support->CGLTexImageIOSurface2D(
9314 context,
9315 target,
9316 GL_RGBA,
9317 width,
9318 height,
9319 GL_BGRA,
9320 GL_UNSIGNED_INT_8_8_8_8_REV,
9321 surface,
9322 plane);
9323
9324 if (err != kCGLNoError) {
9325 SetGLError(
9326 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439327 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469328 return;
9329 }
9330
9331 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:419332 info, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469333 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9334
9335#else
9336 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439337 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469338#endif
9339}
9340
[email protected]97dc7cbe2011-12-06 17:26:179341static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9342 switch (internalformat) {
9343 case GL_RGB565:
9344 return GL_RGB;
9345 case GL_RGBA4:
9346 return GL_RGBA;
9347 case GL_RGB5_A1:
9348 return GL_RGBA;
9349 case GL_RGB8_OES:
9350 return GL_RGB;
9351 case GL_RGBA8_OES:
9352 return GL_RGBA;
9353 case GL_LUMINANCE8_ALPHA8_EXT:
9354 return GL_LUMINANCE_ALPHA;
9355 case GL_LUMINANCE8_EXT:
9356 return GL_LUMINANCE;
9357 case GL_ALPHA8_EXT:
9358 return GL_ALPHA;
9359 case GL_RGBA32F_EXT:
9360 return GL_RGBA;
9361 case GL_RGB32F_EXT:
9362 return GL_RGB;
9363 case GL_ALPHA32F_EXT:
9364 return GL_ALPHA;
9365 case GL_LUMINANCE32F_EXT:
9366 return GL_LUMINANCE;
9367 case GL_LUMINANCE_ALPHA32F_EXT:
9368 return GL_LUMINANCE_ALPHA;
9369 case GL_RGBA16F_EXT:
9370 return GL_RGBA;
9371 case GL_RGB16F_EXT:
9372 return GL_RGB;
9373 case GL_ALPHA16F_EXT:
9374 return GL_ALPHA;
9375 case GL_LUMINANCE16F_EXT:
9376 return GL_LUMINANCE;
9377 case GL_LUMINANCE_ALPHA16F_EXT:
9378 return GL_LUMINANCE_ALPHA;
9379 case GL_BGRA8_EXT:
9380 return GL_BGRA_EXT;
9381 default:
9382 return GL_NONE;
9383 }
9384}
9385
[email protected]43410e92012-04-20 17:06:289386void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039387 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
9388 GLenum internal_format) {
[email protected]43410e92012-04-20 17:06:289389 TextureManager::TextureInfo* dest_info = GetTextureInfo(dest_id);
9390 TextureManager::TextureInfo* source_info = GetTextureInfo(source_id);
9391
9392 if (!source_info || !dest_info) {
[email protected]ad84a3a2012-06-08 21:42:439393 SetGLError(GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289394 return;
9395 }
9396
9397 if (GL_TEXTURE_2D != target) {
9398 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439399 "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289400 return;
9401 }
9402
[email protected]0a1e9ad2012-05-04 21:13:039403 if (dest_info->target() != GL_TEXTURE_2D ||
9404 source_info->target() != GL_TEXTURE_2D) {
9405 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439406 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039407 return;
9408 }
9409
[email protected]43410e92012-04-20 17:06:289410 int source_width, source_height, dest_width, dest_height;
9411 if (!source_info->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
9412 &source_height)) {
9413 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439414 "glCopyTextureChromium", "source texture has no level 0");
[email protected]43410e92012-04-20 17:06:289415 return;
9416 }
9417
[email protected]43410e92012-04-20 17:06:289418 // Check that this type of texture is allowed.
9419 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
9420 source_height, 1)) {
9421 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439422 "glCopyTextureCHROMIUM", "Bad dimensions");
[email protected]43410e92012-04-20 17:06:289423 return;
9424 }
9425
[email protected]cf6b8f62012-05-25 21:43:379426 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9427 // needed because it takes 10s of milliseconds to initialize.
9428 if (!copy_texture_CHROMIUM_.get()) {
9429 CopyRealGLErrorsToWrapper();
9430 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
9431 copy_texture_CHROMIUM_->Initialize();
9432 RestoreCurrentFramebufferBindings();
9433 if (PeekGLError() != GL_NO_ERROR)
9434 return;
9435 }
9436
[email protected]0a1e9ad2012-05-04 21:13:039437 GLenum dest_type;
9438 GLenum dest_internal_format;
9439 bool dest_level_defined = dest_info->GetLevelSize(GL_TEXTURE_2D, level,
9440 &dest_width,
9441 &dest_height);
[email protected]43410e92012-04-20 17:06:289442
[email protected]0a1e9ad2012-05-04 21:13:039443 if (dest_level_defined) {
9444 dest_info->GetLevelType(GL_TEXTURE_2D, level, &dest_type,
9445 &dest_internal_format);
9446 } else {
9447 GLenum source_internal_format;
9448 source_info->GetLevelType(GL_TEXTURE_2D, 0, &dest_type,
9449 &source_internal_format);
9450 }
9451
9452 // Resize the destination texture to the dimensions of the source texture.
9453 if (!dest_level_defined || dest_width != source_width ||
9454 dest_height != source_height ||
9455 dest_internal_format != internal_format) {
[email protected]43410e92012-04-20 17:06:289456 // Ensure that the glTexImage2D succeeds.
9457 CopyRealGLErrorsToWrapper();
[email protected]0a1e9ad2012-05-04 21:13:039458 glBindTexture(GL_TEXTURE_2D, dest_info->service_id());
[email protected]43410e92012-04-20 17:06:289459 WrappedTexImage2D(
9460 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039461 0, internal_format, dest_type, NULL);
[email protected]43410e92012-04-20 17:06:289462 GLenum error = PeekGLError();
[email protected]0a1e9ad2012-05-04 21:13:039463 if (error != GL_NO_ERROR) {
9464 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289465 return;
[email protected]0a1e9ad2012-05-04 21:13:039466 }
[email protected]43410e92012-04-20 17:06:289467
9468 texture_manager()->SetLevelInfo(
9469 dest_info, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039470 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259471 } else {
[email protected]60f22d32012-12-12 00:31:589472 texture_manager()->SetLevelCleared(dest_info, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289473 }
9474
[email protected]88a61bf2012-10-27 13:00:429475 clear_state_dirty_ = true;
[email protected]0a1e9ad2012-05-04 21:13:039476 glViewport(0, 0, source_width, source_height);
[email protected]43410e92012-04-20 17:06:289477 copy_texture_CHROMIUM_->DoCopyTexture(target, source_info->service_id(),
9478 dest_info->service_id(), level,
9479 unpack_flip_y_,
[email protected]6c75c712012-06-19 15:43:179480 unpack_premultiply_alpha_,
9481 unpack_unpremultiply_alpha_);
[email protected]e259eb412012-10-13 05:47:249482 glViewport(
9483 state_.viewport_x, state_.viewport_y,
9484 state_.viewport_width, state_.viewport_height);
[email protected]43410e92012-04-20 17:06:289485
9486 // Restore all of the state touched by the extension.
[email protected]e259eb412012-10-13 05:47:249487 if (state_.current_program)
9488 glUseProgram(state_.current_program->service_id());
[email protected]43410e92012-04-20 17:06:289489 else
9490 glUseProgram(0);
9491
9492 RestoreCurrentFramebufferBindings();
9493 RestoreCurrentTexture2DBindings();
9494 RestoreStateForAttrib(
9495 CopyTextureCHROMIUMResourceManager::kVertexPositionAttrib);
9496 RestoreStateForAttrib(
9497 CopyTextureCHROMIUMResourceManager::kVertexTextureAttrib);
9498
9499 ApplyDirtyState();
9500}
9501
[email protected]97dc7cbe2011-12-06 17:26:179502static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9503 switch (internalformat) {
9504 case GL_RGB565:
9505 return GL_UNSIGNED_SHORT_5_6_5;
9506 case GL_RGBA4:
9507 return GL_UNSIGNED_SHORT_4_4_4_4;
9508 case GL_RGB5_A1:
9509 return GL_UNSIGNED_SHORT_5_5_5_1;
9510 case GL_RGB8_OES:
9511 return GL_UNSIGNED_BYTE;
9512 case GL_RGBA8_OES:
9513 return GL_UNSIGNED_BYTE;
9514 case GL_LUMINANCE8_ALPHA8_EXT:
9515 return GL_UNSIGNED_BYTE;
9516 case GL_LUMINANCE8_EXT:
9517 return GL_UNSIGNED_BYTE;
9518 case GL_ALPHA8_EXT:
9519 return GL_UNSIGNED_BYTE;
9520 case GL_RGBA32F_EXT:
9521 return GL_FLOAT;
9522 case GL_RGB32F_EXT:
9523 return GL_FLOAT;
9524 case GL_ALPHA32F_EXT:
9525 return GL_FLOAT;
9526 case GL_LUMINANCE32F_EXT:
9527 return GL_FLOAT;
9528 case GL_LUMINANCE_ALPHA32F_EXT:
9529 return GL_FLOAT;
9530 case GL_RGBA16F_EXT:
9531 return GL_HALF_FLOAT_OES;
9532 case GL_RGB16F_EXT:
9533 return GL_HALF_FLOAT_OES;
9534 case GL_ALPHA16F_EXT:
9535 return GL_HALF_FLOAT_OES;
9536 case GL_LUMINANCE16F_EXT:
9537 return GL_HALF_FLOAT_OES;
9538 case GL_LUMINANCE_ALPHA16F_EXT:
9539 return GL_HALF_FLOAT_OES;
9540 case GL_BGRA8_EXT:
9541 return GL_UNSIGNED_BYTE;
9542 default:
9543 return GL_NONE;
9544 }
9545}
9546
9547void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449548 GLenum target,
9549 GLint levels,
9550 GLenum internal_format,
9551 GLsizei width,
9552 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389553 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419554 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179555 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ad84a3a2012-06-08 21:42:439556 SetGLError(
9557 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179558 return;
9559 }
9560 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9561 if (!info) {
9562 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439563 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179564 return;
9565 }
9566 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:429567 clear_state_dirty_ = true;
[email protected]97dc7cbe2011-12-06 17:26:179568 }
9569 if (info->IsImmutable()) {
9570 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439571 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179572 return;
9573 }
9574 CopyRealGLErrorsToWrapper();
[email protected]f0e6a34f2012-01-04 20:53:409575 glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format),
9576 width, height);
[email protected]97dc7cbe2011-12-06 17:26:179577 GLenum error = PeekGLError();
9578 if (error == GL_NO_ERROR) {
9579 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9580 GLenum type = ExtractTypeFromStorageFormat(internal_format);
[email protected]4502e6492011-12-14 19:39:159581 GLsizei level_width = width;
9582 GLsizei level_height = height;
9583 for (int ii = 0; ii < levels; ++ii) {
9584 texture_manager()->SetLevelInfo(
[email protected]e071ea72012-11-26 22:29:599585 info, target, ii, format, level_width, level_height, 1, 0, format,
[email protected]80eb6b52012-01-19 00:14:419586 type, false);
[email protected]4502e6492011-12-14 19:39:159587 level_width = std::max(1, level_width >> 1);
9588 level_height = std::max(1, level_height >> 1);
9589 }
[email protected]97dc7cbe2011-12-06 17:26:179590 info->SetImmutable(true);
9591 }
[email protected]97dc7cbe2011-12-06 17:26:179592}
[email protected]e51bdf32011-11-23 22:21:469593
[email protected]78b514b2012-05-01 21:50:599594error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
9595 uint32 immediate_data_size, const gles2::GenMailboxCHROMIUM& c) {
9596 MailboxName name;
9597 mailbox_manager()->GenerateMailboxName(&name);
9598 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
9599 Bucket* bucket = CreateBucket(bucket_id);
9600
9601 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
9602 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
9603
9604 return error::kNoError;
9605}
9606
9607void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9608 const GLbyte* mailbox) {
9609 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9610 if (!info) {
9611 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439612 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599613 return;
9614 }
9615
9616 TextureDefinition* definition = texture_manager()->Save(info);
9617 if (!definition) {
9618 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439619 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599620 return;
9621 }
9622
9623 if (!group_->mailbox_manager()->ProduceTexture(
9624 target,
9625 *reinterpret_cast<const MailboxName*>(mailbox),
9626 definition,
9627 texture_manager())) {
9628 bool success = texture_manager()->Restore(info, definition);
9629 DCHECK(success);
9630 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439631 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599632 return;
9633 }
9634
9635 BindAndApplyTextureParameters(info);
9636}
9637
9638void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9639 const GLbyte* mailbox) {
9640 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9641 if (!info) {
9642 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439643 "glConsumeTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599644 return;
9645 }
9646
9647 scoped_ptr<TextureDefinition> definition(
9648 group_->mailbox_manager()->ConsumeTexture(
9649 target,
9650 *reinterpret_cast<const MailboxName*>(mailbox)));
9651 if (!definition.get()) {
9652 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439653 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599654 return;
9655 }
9656
9657 if (!texture_manager()->Restore(info, definition.release())) {
9658 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439659 "glConsumeTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599660 return;
9661 }
9662
9663 BindAndApplyTextureParameters(info);
9664}
9665
[email protected]d2a0e1a2012-08-12 02:25:019666void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9667 GLsizei length, const GLchar* marker) {
9668 if (!marker) {
9669 marker = "";
9670 }
9671 debug_marker_manager_.SetMarker(
9672 length ? std::string(marker, length) : std::string(marker));
9673}
9674
9675void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9676 GLsizei length, const GLchar* marker) {
9677 if (!marker) {
9678 marker = "";
9679 }
9680 debug_marker_manager_.PushGroup(
9681 length ? std::string(marker, length) : std::string(marker));
9682}
9683
9684void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9685 debug_marker_manager_.PopGroup();
9686}
9687
[email protected]09d50362012-10-18 20:54:379688void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9689 GLenum target, GLint image_id) {
9690 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9691 if (target != GL_TEXTURE_2D) {
9692 // This might be supported in the future.
9693 SetGLError(
9694 GL_INVALID_OPERATION,
9695 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9696 return;
9697 }
9698
9699 // Default target might be conceptually valid, but disallow it to avoid
9700 // accidents.
9701 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9702 target);
9703 if (!info) {
9704 SetGLError(GL_INVALID_OPERATION,
9705 "glBindTexImage2DCHROMIUM", "no texture bound");
9706 return;
9707 }
9708
9709 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9710 if (!gl_image) {
9711 SetGLError(GL_INVALID_OPERATION,
9712 "glBindTexImage2DCHROMIUM",
9713 "no image found with the given ID");
9714 return;
9715 }
9716
9717 if (!gl_image->BindTexImage()) {
9718 SetGLError(GL_INVALID_OPERATION,
9719 "glBindTexImage2DCHROMIUM",
9720 "fail to bind image with the given ID");
9721 return;
9722 }
9723
9724 gfx::Size size = gl_image->GetSize();
9725 texture_manager()->SetLevelInfo(
9726 info, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
9727 GL_RGBA, GL_UNSIGNED_BYTE, true);
9728 texture_manager()->SetLevelImage(info, target, 0, gl_image);
9729}
9730
9731void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
9732 GLenum target, GLint image_id) {
9733 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
9734 if (target != GL_TEXTURE_2D) {
9735 // This might be supported in the future.
9736 SetGLError(
9737 GL_INVALID_OPERATION,
9738 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9739 return;
9740 }
9741
9742 // Default target might be conceptually valid, but disallow it to avoid
9743 // accidents.
9744 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9745 target);
9746 if (!info) {
9747 SetGLError(GL_INVALID_OPERATION,
9748 "glReleaseTexImage2DCHROMIUM", "no texture bound");
9749 return;
9750 }
9751
9752 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9753 if (!gl_image) {
9754 SetGLError(GL_INVALID_OPERATION,
9755 "glReleaseTexImage2DCHROMIUM",
9756 "no image found with the given ID");
9757 return;
9758 }
9759
9760 // Do nothing when image is not currently bound.
9761 if (info->GetLevelImage(target, 0) != gl_image)
9762 return;
9763
9764 gl_image->ReleaseTexImage();
9765
9766 texture_manager()->SetLevelInfo(
9767 info, target, 0, GL_RGBA, 0, 0, 1, 0,
9768 GL_RGBA, GL_UNSIGNED_BYTE, false);
9769}
[email protected]d2a0e1a2012-08-12 02:25:019770
[email protected]94307712012-11-16 23:26:119771error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
9772 uint32 immediate_data_size, const gles2::TraceBeginCHROMIUM& c) {
9773 Bucket* bucket = GetBucket(c.bucket_id);
9774 if (!bucket || bucket->size() == 0) {
9775 return error::kInvalidArguments;
9776 }
9777 std::string command_name;
9778 if (!bucket->GetAsString(&command_name)) {
9779 return error::kInvalidArguments;
9780 }
9781
9782 linked_ptr<GPUTrace> trace(new GPUTrace(command_name));
9783 trace->EnableStartTrace();
9784 gpu_trace_stack_.push(trace);
9785
9786 return error::kNoError;
9787}
9788
9789void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
9790 if (gpu_trace_stack_.empty()) {
9791 SetGLError(GL_INVALID_OPERATION,
9792 "glTraceEndCHROMIUM", "no trace begin found");
9793 return;
9794 }
9795
9796 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top();
9797 trace->EnableEndTrace();
9798 gpu_trace_stack_.pop();
9799}
9800
[email protected]32145a92012-12-17 09:01:599801bool GLES2DecoderImpl::ValidateAsyncTransfer(
9802 const char* function_name,
9803 TextureManager::TextureInfo* info,
9804 GLenum target,
9805 GLint level,
9806 const void * data) {
9807 // We only support async uploads to 2D textures for now.
9808 if (GL_TEXTURE_2D != target) {
9809 SetGLErrorInvalidEnum(function_name, target, "target");
9810 return false;
9811 }
9812 // We only support uploads to level zero for now.
9813 if (level != 0) {
9814 SetGLError(GL_INVALID_VALUE, function_name, "level != 0");
9815 return false;
9816 }
9817 // A transfer buffer must be bound, even for asyncTexImage2D.
9818 if (data == NULL) {
9819 SetGLError(GL_INVALID_OPERATION, function_name, "buffer == 0");
9820 return false;
9821 }
9822 // We only support one async transfer in progress.
9823 if (!info || info->AsyncTransferIsInProgress()) {
9824 SetGLError(GL_INVALID_OPERATION,
9825 function_name, "transfer already in progress");
9826 return false;
9827 }
9828 return true;
9829}
9830
[email protected]69023942012-11-30 19:57:169831error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
9832 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) {
9833 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:169834 GLenum target = static_cast<GLenum>(c.target);
9835 GLint level = static_cast<GLint>(c.level);
9836 GLint internal_format = static_cast<GLint>(c.internalformat);
9837 GLsizei width = static_cast<GLsizei>(c.width);
9838 GLsizei height = static_cast<GLsizei>(c.height);
9839 GLint border = static_cast<GLint>(c.border);
9840 GLenum format = static_cast<GLenum>(c.format);
9841 GLenum type = static_cast<GLenum>(c.type);
9842 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9843 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
9844 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:599845
9846 // TODO(epenner): Move this and copies of this memory validation
9847 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:169848 if (!GLES2Util::ComputeImageDataSizes(
9849 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
9850 NULL)) {
9851 return error::kOutOfBounds;
9852 }
9853 const void* pixels = NULL;
9854 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9855 pixels = GetSharedMemoryAs<const void*>(
9856 pixels_shm_id, pixels_shm_offset, pixels_size);
9857 if (!pixels) {
9858 return error::kOutOfBounds;
9859 }
9860 }
9861
[email protected]32145a92012-12-17 09:01:599862 // All the normal glTexSubImage2D validation.
9863 if (!ValidateTexImage2D(
9864 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
9865 width, height, border, format, type, pixels, pixels_size)) {
9866 return error::kNoError;
9867 }
9868
9869 // Extra async validation.
9870 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9871 if (!ValidateAsyncTransfer(
9872 "glAsyncTexImage2DCHROMIUM", info, target, level, pixels))
9873 return error::kNoError;
9874
9875 // Don't allow async redefinition of a textures.
9876 if (info->IsDefined()) {
9877 SetGLError(GL_INVALID_OPERATION,
9878 "glAsyncTexImage2DCHROMIUM", "already defined");
9879 return error::kNoError;
9880 }
9881
9882 // We know the memory/size is safe, so get the real shared memory since
9883 // it might need to be duped to prevent use-after-free of the memory.
9884 Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
9885 base::SharedMemory* shared_memory = buffer.shared_memory;
9886 uint32 shm_size = buffer.size;
9887 uint32 shm_data_offset = c.pixels_shm_offset;
9888 uint32 shm_data_size = pixels_size;
9889
9890 // Set up the async state if needed, and make the texture
9891 // immutable so the async state stays valid. The level info
9892 // is set up lazily when the transfer completes.
9893 DCHECK(!info->GetAsyncTransferState());
9894 info->SetAsyncTransferState(
9895 async_pixel_transfer_delegate_->
9896 CreatePixelTransferState(info->service_id()));
9897 info->SetImmutable(true);
9898
9899 // Issue the async call and set up the texture.
9900 GLenum gl_internal_format =
9901 GetTexInternalFormat(internal_format, format, type);
9902 gfx::AsyncTexImage2DParams tex_params = {target, level, gl_internal_format,
9903 width, height, border, format, type};
9904 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
9905 shm_data_offset, shm_data_size};
9906
9907 // Add a pending transfer to the texture manager, which will bind the
9908 // transfer data to the texture and set the level info at the same time,
9909 // after the the transfer is complete.
9910 texture_manager()->AddPendingAsyncPixelTransfer(
9911 info->GetAsyncTransferState()->AsWeakPtr(), info);
9912
9913 async_pixel_transfer_delegate_->AsyncTexImage2D(
9914 info->GetAsyncTransferState(), tex_params, mem_params);
[email protected]f598f422012-12-07 08:30:039915 return error::kNoError;
[email protected]69023942012-11-30 19:57:169916}
9917
9918error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
9919 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) {
9920 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:169921 GLenum target = static_cast<GLenum>(c.target);
9922 GLint level = static_cast<GLint>(c.level);
9923 GLint xoffset = static_cast<GLint>(c.xoffset);
9924 GLint yoffset = static_cast<GLint>(c.yoffset);
9925 GLsizei width = static_cast<GLsizei>(c.width);
9926 GLsizei height = static_cast<GLsizei>(c.height);
9927 GLenum format = static_cast<GLenum>(c.format);
9928 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:599929
9930 // TODO(epenner): Move this and copies of this memory validation
9931 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:169932 uint32 data_size;
9933 if (!GLES2Util::ComputeImageDataSizes(
9934 width, height, format, type, state_.unpack_alignment, &data_size,
9935 NULL, NULL)) {
9936 return error::kOutOfBounds;
9937 }
9938 const void* pixels = GetSharedMemoryAs<const void*>(
9939 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:599940
9941 // All the normal glTexSubImage2D validation.
9942 error::Error error = error::kNoError;
9943 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
9944 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
9945 return error;
[email protected]69023942012-11-30 19:57:169946 }
9947
[email protected]32145a92012-12-17 09:01:599948 // Extra async validation.
9949 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9950 if (!ValidateAsyncTransfer(
9951 "glAsyncTexSubImage2DCHROMIUM", info, target, level, pixels))
9952 return error::kNoError;
9953
9954 // Guarantee async textures are always 'cleared' as follows:
9955 // - AsyncTexImage2D can not redefine an existing texture
9956 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
9957 // - AsyncTexSubImage2D clears synchronously if not already cleared.
9958 // - Textures become immutable after an async call.
9959 // This way we know in all cases that an async texture is always clear.
9960 if (!info->SafeToRenderFrom()) {
9961 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
9962 SetGLError(GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:259963 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:599964 return error::kNoError;
9965 }
9966 }
9967
9968 // We know the memory/size is safe, so get the real shared memory since
9969 // it might need to be duped to prevent use-after-free of the memory.
9970 Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
9971 base::SharedMemory* shared_memory = buffer.shared_memory;
9972 uint32 shm_size = buffer.size;
9973 uint32 shm_data_offset = c.data_shm_offset;
9974 uint32 shm_data_size = data_size;
9975
9976 if (!info->GetAsyncTransferState()) {
9977 // Set up the async state if needed, and make the texture
9978 // immutable so the async state stays valid.
9979 info->SetAsyncTransferState(
9980 async_pixel_transfer_delegate_->
9981 CreatePixelTransferState(info->service_id()));
9982 info->SetImmutable(true);
9983 }
9984
9985 gfx::AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
9986 width, height, format, type};
9987 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
9988 shm_data_offset, shm_data_size};
9989 async_pixel_transfer_delegate_->AsyncTexSubImage2D(
9990 info->GetAsyncTransferState(), tex_params, mem_params);
9991 return error::kNoError;
[email protected]69023942012-11-30 19:57:169992}
9993
[email protected]96449d2c2009-11-25 00:01:329994// Include the auto-generated part of this file. We split this because it means
9995// we can easily edit the non-auto generated parts right here in this file
9996// instead of having to edit some template or the code generator.
9997#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
9998
9999} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510000} // namespace gpu