blob: 710de787a638d219e6928581a5e94147a528210d [file] [log] [blame]
[email protected]529c6672012-01-04 02:18:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]96449d2c2009-11-25 00:01:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8a837bb2010-01-05 00:21:245#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
[email protected]74470702010-01-06 18:51:166
7#include <stdio.h>
8
[email protected]1aef98132010-02-23 18:00:079#include <algorithm>
[email protected]f39f4b3f2010-05-12 17:04:0810#include <list>
[email protected]96449d2c2009-11-25 00:01:3211#include <map>
[email protected]94307712012-11-16 23:26:1112#include <stack>
[email protected]f39f4b3f2010-05-12 17:04:0813#include <string>
14#include <vector>
[email protected]5a6db6c2010-04-22 18:32:0615
[email protected]00eb49a2010-08-12 20:46:5716#include "base/at_exit.h"
[email protected]d353541f2012-05-03 22:45:4117#include "base/atomicops.h"
[email protected]9d37f062011-11-22 01:24:5218#include "base/bind.h"
[email protected]e844ae22012-01-14 03:36:2619#include "base/command_line.h"
[email protected]1078f912011-12-23 13:12:1420#include "base/debug/trace_event.h"
[email protected]e51bdf32011-11-23 22:21:4621#if defined(OS_MACOSX)
22#include "base/mac/scoped_cftyperef.h"
23#endif
[email protected]3b63f8f42011-03-28 01:54:1524#include "base/memory/scoped_ptr.h"
[email protected]0f8afe82012-05-14 23:43:0125#include "base/string_number_conversions.h"
[email protected]445a8762012-12-06 15:43:2126#include "base/stringprintf.h"
[email protected]d37231fa2010-04-09 21:16:0227#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3228#define GLES2_GPU_SERVICE 1
29#include "gpu/command_buffer/common/gles2_cmd_format.h"
30#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]d2a0e1a2012-08-12 02:25:0131#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]066849e32010-05-03 19:14:1032#include "gpu/command_buffer/common/id_allocator.h"
[email protected]3916c97e2010-02-25 03:20:5033#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3234#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5035#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2436#include "gpu/command_buffer/service/context_state.h"
[email protected]915a59a12010-09-30 21:29:1137#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5838#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3239#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2840#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4641#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]e844ae22012-01-14 03:36:2642#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]94307712012-11-16 23:26:1143#include "gpu/command_buffer/service/gpu_trace.h"
[email protected]09d50362012-10-18 20:54:3744#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5945#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2546#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4747#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5348#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5849#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4750#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4551#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0452#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]b0af4f52011-09-28 22:04:4253#include "gpu/command_buffer/service/stream_texture.h"
54#include "gpu/command_buffer/service/stream_texture_manager.h"
[email protected]78b514b2012-05-01 21:50:5955#include "gpu/command_buffer/service/texture_definition.h"
[email protected]a93bb842010-02-16 23:03:4756#include "gpu/command_buffer/service/texture_manager.h"
[email protected]d8ea9772011-07-11 18:11:4357#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]944b62f32012-09-27 02:20:4658#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]32145a92012-12-17 09:01:5959#include "ui/gl/async_pixel_transfer_delegate.h"
[email protected]09d50362012-10-18 20:54:3760#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2761#include "ui/gl/gl_implementation.h"
62#include "ui/gl/gl_surface.h"
[email protected]e51bdf32011-11-23 22:21:4663#if defined(OS_MACOSX)
[email protected]d353541f2012-05-03 22:45:4164#include "ui/surface/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4665#endif
[email protected]de17df392010-04-23 21:09:4166
[email protected]6217d392010-03-25 22:08:3567#if !defined(GL_DEPTH24_STENCIL8)
68#define GL_DEPTH24_STENCIL8 0x88F0
69#endif
70
[email protected]693ca512012-11-13 18:09:1371// TODO(zmo): we can't include "City.h" due to type def conflicts.
72extern uint64 CityHash64(const char*, size_t);
73
[email protected]a7a27ace2009-12-12 00:11:2574namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3275namespace gles2 {
76
[email protected]f0d74742011-10-03 16:31:0477namespace {
[email protected]693ca512012-11-13 18:09:1378
[email protected]f0d74742011-10-03 16:31:0479static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]693ca512012-11-13 18:09:1380
81khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
82 return static_cast<khronos_uint64_t>(
83 CityHash64(name, static_cast<size_t>(len)));
84}
85
[email protected]f0d74742011-10-03 16:31:0486}
87
[email protected]6217d392010-03-25 22:08:3588class GLES2DecoderImpl;
89
[email protected]07f54fcc2009-12-22 02:46:3090// Check that certain assumptions the code makes are true. There are places in
91// the code where shared memory is passed direclty to GL. Example, glUniformiv,
92// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
93// a few others) are 32bits. If they are not 32bits the code will have to change
94// to call those GL functions with service side memory and then copy the results
95// to shared memory, converting the sizes.
96COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
97 GLint_not_same_size_as_uint32);
98COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
99 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37100COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
101 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30102
[email protected]43f28f832010-02-03 02:28:48103// TODO(kbr): the use of this anonymous namespace core dumps the
104// linker on Mac OS X 10.6 when the symbol ordering file is used
105// namespace {
[email protected]96449d2c2009-11-25 00:01:32106
107// Returns the address of the first byte after a struct.
108template <typename T>
109const void* AddressAfterStruct(const T& pod) {
110 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
111}
112
[email protected]07f54fcc2009-12-22 02:46:30113// Returns the address of the frst byte after the struct or NULL if size >
114// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32115template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30116RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
117 uint32 size,
118 uint32 immediate_data_size) {
119 return (size <= immediate_data_size) ?
120 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
121 NULL;
[email protected]96449d2c2009-11-25 00:01:32122}
123
[email protected]07f54fcc2009-12-22 02:46:30124// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18125bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32126 GLuint count,
127 size_t size,
[email protected]a76b0052010-03-05 00:33:18128 unsigned int elements_per_unit,
129 uint32* dst) {
130 uint32 value;
131 if (!SafeMultiplyUint32(count, size, &value)) {
132 return false;
133 }
134 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
135 return false;
136 }
137 *dst = value;
138 return true;
[email protected]96449d2c2009-11-25 00:01:32139}
140
141// A struct to hold info about each command.
142struct CommandInfo {
143 int arg_flags; // How to handle the arguments for this command
144 int arg_count; // How many arguments are expected for this command.
145};
146
147// A table of CommandInfo for all the commands.
148const CommandInfo g_command_info[] = {
149 #define GLES2_CMD_OP(name) { \
150 name::kArgFlags, \
151 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
152
153 GLES2_COMMAND_LIST(GLES2_CMD_OP)
154
155 #undef GLES2_CMD_OP
156};
157
[email protected]258a3313f2011-10-18 20:13:57158// Return true if a character belongs to the ASCII subset as defined in
159// GLSL ES 1.0 spec section 3.1.
160static bool CharacterIsValidForGLES(unsigned char c) {
161 // Printing characters are valid except " $ ` @ \ ' DEL.
162 if (c >= 32 && c <= 126 &&
163 c != '"' &&
164 c != '$' &&
165 c != '`' &&
166 c != '@' &&
167 c != '\\' &&
168 c != '\'') {
169 return true;
170 }
171 // Horizontal tab, line feed, vertical tab, form feed, carriage return
172 // are also valid.
173 if (c >= 9 && c <= 13) {
174 return true;
175 }
176
177 return false;
178}
179
180static bool StringIsValidForGLES(const char* str) {
181 for (; *str; ++str) {
182 if (!CharacterIsValidForGLES(*str)) {
183 return false;
184 }
185 }
186 return true;
187}
188
[email protected]f0e6a34f2012-01-04 20:53:40189static inline GLenum GetTexInternalFormat(GLenum internal_format) {
190 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
191 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT)
192 return GL_RGBA8;
193 }
194 return internal_format;
195}
196
[email protected]32145a92012-12-17 09:01:59197// TODO(epenner): Could the above function be merged into this and removed?
198static inline GLenum GetTexInternalFormat(GLenum internal_format,
199 GLenum format,
200 GLenum type) {
201 GLenum gl_internal_format = GetTexInternalFormat(internal_format);
202
203 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
204 return gl_internal_format;
205
206 if (type == GL_FLOAT) {
207 switch (format) {
208 case GL_RGBA:
209 gl_internal_format = GL_RGBA32F_ARB;
210 break;
211 case GL_RGB:
212 gl_internal_format = GL_RGB32F_ARB;
213 break;
214 case GL_LUMINANCE_ALPHA:
215 gl_internal_format = GL_LUMINANCE_ALPHA32F_ARB;
216 break;
217 case GL_LUMINANCE:
218 gl_internal_format = GL_LUMINANCE32F_ARB;
219 break;
220 case GL_ALPHA:
221 gl_internal_format = GL_ALPHA32F_ARB;
222 break;
223 default:
224 NOTREACHED();
225 break;
226 }
227 } else if (type == GL_HALF_FLOAT_OES) {
228 switch (format) {
229 case GL_RGBA:
230 gl_internal_format = GL_RGBA16F_ARB;
231 break;
232 case GL_RGB:
233 gl_internal_format = GL_RGB16F_ARB;
234 break;
235 case GL_LUMINANCE_ALPHA:
236 gl_internal_format = GL_LUMINANCE_ALPHA16F_ARB;
237 break;
238 case GL_LUMINANCE:
239 gl_internal_format = GL_LUMINANCE16F_ARB;
240 break;
241 case GL_ALPHA:
242 gl_internal_format = GL_ALPHA16F_ARB;
243 break;
244 default:
245 NOTREACHED();
246 break;
247 }
248 }
249 return gl_internal_format;
250}
251
[email protected]297ca1c2011-06-20 23:08:46252static void WrappedTexImage2D(
[email protected]473c01ccb2011-06-07 01:33:30253 GLenum target,
254 GLint level,
255 GLenum internal_format,
256 GLsizei width,
257 GLsizei height,
258 GLint border,
259 GLenum format,
260 GLenum type,
261 const void* pixels) {
[email protected]473c01ccb2011-06-07 01:33:30262 glTexImage2D(
[email protected]32145a92012-12-17 09:01:59263 target, level, GetTexInternalFormat(internal_format, format, type),
264 width, height, border, format, type, pixels);
[email protected]473c01ccb2011-06-07 01:33:30265}
266
[email protected]297ca1c2011-06-20 23:08:46267// Wrapper for glEnable/glDisable that doesn't suck.
268static void EnableDisable(GLenum pname, bool enable) {
269 if (enable) {
270 glEnable(pname);
271 } else {
272 glDisable(pname);
273 }
274}
275
[email protected]6217d392010-03-25 22:08:35276// This class prevents any GL errors that occur when it is in scope from
277// being reported to the client.
278class ScopedGLErrorSuppressor {
279 public:
280 explicit ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder);
281 ~ScopedGLErrorSuppressor();
282 private:
283 GLES2DecoderImpl* decoder_;
284 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
285};
286
287// Temporarily changes a decoder's bound 2D texture and restore it when this
288// object goes out of scope. Also temporarily switches to using active texture
289// unit zero in case the client has changed that to something invalid.
290class ScopedTexture2DBinder {
291 public:
292 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
293 ~ScopedTexture2DBinder();
294
295 private:
296 GLES2DecoderImpl* decoder_;
297 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
298};
299
300// Temporarily changes a decoder's bound render buffer and restore it when this
301// object goes out of scope.
302class ScopedRenderBufferBinder {
303 public:
304 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
305 ~ScopedRenderBufferBinder();
306
307 private:
308 GLES2DecoderImpl* decoder_;
309 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
310};
311
312// Temporarily changes a decoder's bound frame buffer and restore it when this
313// object goes out of scope.
314class ScopedFrameBufferBinder {
315 public:
316 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
317 ~ScopedFrameBufferBinder();
318
319 private:
320 GLES2DecoderImpl* decoder_;
321 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
322};
323
[email protected]34ff8b0c2010-10-01 20:06:02324// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52325// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27326// if it is bound or enforce_internal_framebuffer is true. If internal is
327// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02328class ScopedResolvedFrameBufferBinder {
329 public:
[email protected]e7e38032011-07-26 17:25:25330 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27331 bool enforce_internal_framebuffer,
332 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02333 ~ScopedResolvedFrameBufferBinder();
334
335 private:
336 GLES2DecoderImpl* decoder_;
337 bool resolve_and_bind_;
338 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
339};
340
[email protected]63b465922012-09-06 02:04:52341// This class records texture upload time when in scope.
342class ScopedTextureUploadTimer {
343 public:
344 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder);
345 ~ScopedTextureUploadTimer();
346
347 private:
348 GLES2DecoderImpl* decoder_;
349 base::TimeTicks begin_time_;
350 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer);
351};
352
[email protected]6217d392010-03-25 22:08:35353// Encapsulates an OpenGL texture.
354class Texture {
355 public:
356 explicit Texture(GLES2DecoderImpl* decoder);
357 ~Texture();
358
359 // Create a new render texture.
360 void Create();
361
362 // Set the initial size and format of a render texture or resize it.
[email protected]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);
1130 void DoSampleCoverage (GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281131
[email protected]45bf5152010-02-12 00:11:311132 // Wrapper for glCompileShader.
1133 void DoCompileShader(GLuint shader);
1134
[email protected]269200b12010-11-18 22:53:061135 // Helper for DeleteSharedIdsCHROMIUM commands.
1136 void DoDeleteSharedIdsCHROMIUM(
1137 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101138
[email protected]ae51d192010-04-27 00:48:031139 // Wrapper for glDetachShader
1140 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1141
[email protected]3a2e7c7b2010-08-06 01:12:281142 // Wrapper for glDisable
1143 void DoDisable(GLenum cap);
1144
[email protected]07f54fcc2009-12-22 02:46:301145 // Wrapper for glDisableVertexAttribArray.
1146 void DoDisableVertexAttribArray(GLuint index);
1147
[email protected]60f22d32012-12-12 00:31:581148 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1149 // attachments.
1150 void DoDiscardFramebufferEXT(GLenum target,
1151 GLsizei numAttachments,
1152 const GLenum* attachments);
1153
[email protected]3a2e7c7b2010-08-06 01:12:281154 // Wrapper for glEnable
1155 void DoEnable(GLenum cap);
1156
[email protected]07f54fcc2009-12-22 02:46:301157 // Wrapper for glEnableVertexAttribArray.
1158 void DoEnableVertexAttribArray(GLuint index);
1159
[email protected]882ba1e22012-03-08 19:02:531160 // Wrapper for glFinish.
1161 void DoFinish();
1162
1163 // Wrapper for glFlush.
1164 void DoFlush();
1165
[email protected]36cef8ce2010-03-16 07:34:451166 // Wrapper for glFramebufferRenderbufffer.
1167 void DoFramebufferRenderbuffer(
1168 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1169 GLuint renderbuffer);
1170
1171 // Wrapper for glFramebufferTexture2D.
1172 void DoFramebufferTexture2D(
1173 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1174 GLint level);
1175
[email protected]a93bb842010-02-16 23:03:471176 // Wrapper for glGenerateMipmap
1177 void DoGenerateMipmap(GLenum target);
1178
[email protected]269200b12010-11-18 22:53:061179 // Helper for GenSharedIdsCHROMIUM commands.
1180 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101181 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1182
[email protected]b273e432010-04-12 17:23:581183 // Wrapper for DoGetBooleanv.
1184 void DoGetBooleanv(GLenum pname, GLboolean* params);
1185
1186 // Wrapper for DoGetFloatv.
1187 void DoGetFloatv(GLenum pname, GLfloat* params);
1188
[email protected]36cef8ce2010-03-16 07:34:451189 // Wrapper for glGetFramebufferAttachmentParameteriv.
1190 void DoGetFramebufferAttachmentParameteriv(
1191 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1192
[email protected]a0c3e972010-04-21 00:49:131193 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581194 void DoGetIntegerv(GLenum pname, GLint* params);
1195
[email protected]29a9eb52010-04-13 09:04:231196 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061197 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231198 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1199
[email protected]a0c3e972010-04-21 00:49:131200 // Wrapper for glGetProgramiv.
1201 void DoGetProgramiv(
1202 GLuint program_id, GLenum pname, GLint* params);
1203
[email protected]36cef8ce2010-03-16 07:34:451204 // Wrapper for glRenderbufferParameteriv.
1205 void DoGetRenderbufferParameteriv(
1206 GLenum target, GLenum pname, GLint* params);
1207
[email protected]ddd968b82010-03-02 00:44:291208 // Wrapper for glGetShaderiv
1209 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1210
[email protected]b1122982010-05-17 23:04:241211 // Wrappers for glGetVertexAttrib.
1212 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1213 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1214
[email protected]1958e0e2010-04-22 05:17:151215 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241216 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151217 bool DoIsBuffer(GLuint client_id);
1218 bool DoIsFramebuffer(GLuint client_id);
1219 bool DoIsProgram(GLuint client_id);
1220 bool DoIsRenderbuffer(GLuint client_id);
1221 bool DoIsShader(GLuint client_id);
1222 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461223 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151224
[email protected]07f54fcc2009-12-22 02:46:301225 // Wrapper for glLinkProgram
1226 void DoLinkProgram(GLuint program);
1227
[email protected]269200b12010-11-18 22:53:061228 // Helper for RegisterSharedIdsCHROMIUM.
1229 void DoRegisterSharedIdsCHROMIUM(
1230 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101231
[email protected]36cef8ce2010-03-16 07:34:451232 // Wrapper for glRenderbufferStorage.
1233 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031234 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451235
[email protected]8e3e0662010-08-23 18:46:301236 // Wrapper for glRenderbufferStorageMultisampleEXT.
1237 void DoRenderbufferStorageMultisample(
1238 GLenum target, GLsizei samples, GLenum internalformat,
1239 GLsizei width, GLsizei height);
1240
[email protected]b273e432010-04-12 17:23:581241 // Wrapper for glReleaseShaderCompiler.
1242 void DoReleaseShaderCompiler() { }
1243
[email protected]3916c97e2010-02-25 03:20:501244 // Wrappers for glTexParameter functions.
1245 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1246 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1247 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1248 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1249
1250 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1251 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121252 void DoUniform1i(GLint fake_location, GLint v0);
1253 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1254 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1255 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1256 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101257
1258 // Wrappers for glUniformfv because some drivers don't correctly accept
1259 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121260 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1261 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1262 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1263 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501264
[email protected]43c2f1f2011-03-25 18:35:361265 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121266 GLint fake_location, GLsizei count, GLboolean transpose,
1267 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361268 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121269 GLint fake_location, GLsizei count, GLboolean transpose,
1270 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361271 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121272 GLint fake_location, GLsizei count, GLboolean transpose,
1273 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361274
[email protected]af6380962012-11-29 23:24:131275 bool SetVertexAttribValue(
1276 const char* function_name, GLuint index, const GLfloat* value);
1277
[email protected]b1122982010-05-17 23:04:241278 // Wrappers for glVertexAttrib??
1279 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1280 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1281 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1282 void DoVertexAttrib4f(
1283 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1284 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1285 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1286 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1287 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1288
[email protected]43410e92012-04-20 17:06:281289 // Wrapper for glViewport
1290 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1291
[email protected]07f54fcc2009-12-22 02:46:301292 // Wrapper for glUseProgram
1293 void DoUseProgram(GLuint program);
1294
[email protected]ae51d192010-04-27 00:48:031295 // Wrapper for glValidateProgram.
1296 void DoValidateProgram(GLuint program_client_id);
1297
[email protected]d2a0e1a2012-08-12 02:25:011298 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1299 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1300 void DoPopGroupMarkerEXT(void);
1301
[email protected]4e8a5b122010-05-08 22:00:101302 // Gets the number of values that will be returned by glGetXXX. Returns
1303 // false if pname is unknown.
1304 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1305
[email protected]1002c2d2011-06-28 22:39:041306 // Gets the GLError and stores it in our wrapper. Effectively
1307 // this lets us peek at the error without losing it.
1308 GLenum PeekGLError();
1309
[email protected]07f54fcc2009-12-22 02:46:301310 // Copies the real GL errors to the wrapper. This is so we can
1311 // make sure there are no native GL errors before calling some GL function
1312 // so that on return we know any error generated was for that specific
1313 // command.
1314 void CopyRealGLErrorsToWrapper();
1315
[email protected]6217d392010-03-25 22:08:351316 // Clear all real GL errors. This is to prevent the client from seeing any
1317 // errors caused by GL calls that it was not responsible for issuing.
1318 void ClearRealGLErrors();
1319
[email protected]445a8762012-12-06 15:43:211320 // Generates a GL error for a bad parameter.
1321 void SetGLErrorInvalidParam(
1322 GLenum error,
1323 const char* function_name,
1324 GLenum pname,
1325 GLint param);
1326
[email protected]07f54fcc2009-12-22 02:46:301327 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431328 bool IsDrawValid(
1329 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301330
[email protected]c13e1da62011-09-09 21:48:301331 // Returns true if successful, simulated will be true if attrib0 was
1332 // simulated.
[email protected]c6aef902012-02-14 03:31:421333 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431334 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281335 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241336
[email protected]ef526492010-06-02 23:12:251337 // Returns true if textures were set.
1338 bool SetBlackTextureForNonRenderableTextures();
[email protected]3916c97e2010-02-25 03:20:501339 void RestoreStateForNonRenderableTextures();
1340
[email protected]8fbedc02010-11-18 18:43:401341 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421342 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431343 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421344 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401345 void RestoreStateForSimulatedFixedAttribs();
1346
[email protected]c6aef902012-02-14 03:31:421347 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1348 // cases (primcount is 0 for non-instanced).
1349 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431350 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421351 bool instanced, GLenum mode, GLint first, GLsizei count,
1352 GLsizei primcount);
1353 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431354 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421355 bool instanced, GLenum mode, GLsizei count, GLenum type,
1356 int32 offset, GLsizei primcount);
1357
[email protected]07f54fcc2009-12-22 02:46:301358 // Gets the buffer id for a given target.
[email protected]3916c97e2010-02-25 03:20:501359 BufferManager::BufferInfo* GetBufferInfoForTarget(GLenum target) {
[email protected]07f54fcc2009-12-22 02:46:301360 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
[email protected]944b62f32012-09-27 02:20:461361 if (target == GL_ARRAY_BUFFER) {
[email protected]e259eb412012-10-13 05:47:241362 return state_.bound_array_buffer;
[email protected]944b62f32012-09-27 02:20:461363 } else {
[email protected]e259eb412012-10-13 05:47:241364 return state_.vertex_attrib_manager->element_array_buffer();
[email protected]944b62f32012-09-27 02:20:461365 }
[email protected]07f54fcc2009-12-22 02:46:301366 }
1367
[email protected]a93bb842010-02-16 23:03:471368 // Gets the texture id for a given target.
[email protected]3916c97e2010-02-25 03:20:501369 TextureManager::TextureInfo* GetTextureInfoForTarget(GLenum target) {
[email protected]e259eb412012-10-13 05:47:241370 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:501371 TextureManager::TextureInfo* info = NULL;
[email protected]a93bb842010-02-16 23:03:471372 switch (target) {
1373 case GL_TEXTURE_2D:
[email protected]3916c97e2010-02-25 03:20:501374 info = unit.bound_texture_2d;
1375 break;
[email protected]a93bb842010-02-16 23:03:471376 case GL_TEXTURE_CUBE_MAP:
1377 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1378 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1379 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1380 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1381 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1382 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
[email protected]3916c97e2010-02-25 03:20:501383 info = unit.bound_texture_cube_map;
1384 break;
[email protected]61eeb33f2011-07-26 15:30:311385 case GL_TEXTURE_EXTERNAL_OES:
1386 info = unit.bound_texture_external_oes;
1387 break;
[email protected]e51bdf32011-11-23 22:21:461388 case GL_TEXTURE_RECTANGLE_ARB:
1389 info = unit.bound_texture_rectangle_arb;
1390 break;
[email protected]a93bb842010-02-16 23:03:471391 default:
1392 NOTREACHED();
[email protected]3916c97e2010-02-25 03:20:501393 return NULL;
[email protected]a93bb842010-02-16 23:03:471394 }
[email protected]a0b78dc2011-11-11 10:43:101395 return info;
[email protected]a93bb842010-02-16 23:03:471396 }
1397
[email protected]09d50362012-10-18 20:54:371398 TextureManager::TextureInfo* GetTextureInfoForTargetUnlessDefault(
1399 GLenum target) {
1400 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
1401 if (!info)
1402 return NULL;
1403 if (info == texture_manager()->GetDefaultTextureInfo(target))
1404 return NULL;
1405 return info;
1406 }
1407
[email protected]61eeb33f2011-07-26 15:30:311408 GLenum GetBindTargetForSamplerType(GLenum type) {
1409 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461410 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1411 switch (type) {
1412 case GL_SAMPLER_2D:
1413 return GL_TEXTURE_2D;
1414 case GL_SAMPLER_CUBE:
1415 return GL_TEXTURE_CUBE_MAP;
1416 case GL_SAMPLER_EXTERNAL_OES:
1417 return GL_TEXTURE_EXTERNAL_OES;
1418 case GL_SAMPLER_2D_RECT_ARB:
1419 return GL_TEXTURE_RECTANGLE_ARB;
1420 }
1421
1422 NOTREACHED();
1423 return 0;
[email protected]61eeb33f2011-07-26 15:30:311424 }
1425
[email protected]8e3e0662010-08-23 18:46:301426 // Gets the framebuffer info for a particular target.
1427 FramebufferManager::FramebufferInfo* GetFramebufferInfoForTarget(
1428 GLenum target) {
1429 FramebufferManager::FramebufferInfo* info = NULL;
1430 switch (target) {
1431 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451432 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]e259eb412012-10-13 05:47:241433 info = state_.bound_draw_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301434 break;
[email protected]ebfb73c2012-08-15 02:37:451435 case GL_READ_FRAMEBUFFER_EXT:
[email protected]e259eb412012-10-13 05:47:241436 info = state_.bound_read_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301437 break;
1438 default:
1439 NOTREACHED();
1440 break;
1441 }
[email protected]a0b78dc2011-11-11 10:43:101442 return info;
[email protected]8e3e0662010-08-23 18:46:301443 }
1444
[email protected]0d6bfdc2011-11-02 01:32:201445 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfoForTarget(
1446 GLenum target) {
1447 RenderbufferManager::RenderbufferInfo* info = NULL;
1448 switch (target) {
1449 case GL_RENDERBUFFER:
[email protected]e259eb412012-10-13 05:47:241450 info = state_.bound_renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201451 break;
1452 default:
1453 NOTREACHED();
1454 break;
1455 }
[email protected]a0b78dc2011-11-11 10:43:101456 return info;
[email protected]0d6bfdc2011-11-02 01:32:201457 }
1458
[email protected]f7b85372010-02-03 01:11:371459 // Validates the program and location for a glGetUniform call and returns
1460 // a SizeResult setup to receive the result. Returns true if glGetUniform
1461 // should be called.
1462 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121463 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371464 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121465 error::Error* error, GLint* real_location, GLuint* service_id,
1466 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371467
[email protected]1078f912011-12-23 13:12:141468 // Computes the estimated memory used for the backbuffer and passes it to
1469 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531470 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141471
[email protected]a10b4a02012-11-26 23:09:501472 virtual bool WasContextLost() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091473 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431474
[email protected]e51bdf32011-11-23 22:21:461475#if defined(OS_MACOSX)
1476 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1477#endif
1478
[email protected]81375742012-06-08 00:04:001479 // Validates the combination of texture parameters. For example validates that
1480 // for a given format the specific type, level and targets are valid.
1481 // Synthesizes the correct GL error if invalid. Returns true if valid.
1482 bool ValidateTextureParameters(
1483 const char* function_name,
1484 GLenum target, GLenum format, GLenum type, GLint level);
1485
[email protected]ad84a3a2012-06-08 21:42:431486 bool ValidateCompressedTexDimensions(
1487 const char* function_name,
1488 GLint level, GLsizei width, GLsizei height, GLenum format);
1489 bool ValidateCompressedTexFuncData(
1490 const char* function_name,
1491 GLsizei width, GLsizei height, GLenum format, size_t size);
1492 bool ValidateCompressedTexSubDimensions(
1493 const char* function_name,
1494 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1495 GLsizei width, GLsizei height, GLenum format,
1496 TextureManager::TextureInfo* texture);
1497
[email protected]0f8afe82012-05-14 23:43:011498 void LogMessage(const std::string& msg);
1499 void RenderWarning(const std::string& msg);
1500 void PerformanceWarning(const std::string& msg);
[email protected]d2a0e1a2012-08-12 02:25:011501 const std::string& GetLogPrefix() const;
[email protected]0f8afe82012-05-14 23:43:011502
[email protected]62e155e2012-10-23 22:43:151503 const FeatureInfo::FeatureFlags& features() const {
1504 return feature_info_->feature_flags();
1505 }
1506
1507 const FeatureInfo::Workarounds& workarounds() const {
1508 return feature_info_->workarounds();
1509 }
1510
[email protected]a7266a92012-06-28 02:11:081511 bool ShouldDeferDraws() {
1512 return !offscreen_target_frame_buffer_.get() &&
[email protected]e259eb412012-10-13 05:47:241513 state_.bound_draw_framebuffer == NULL &&
[email protected]a7266a92012-06-28 02:11:081514 surface_->DeferDraws();
1515 }
1516
[email protected]09e17272012-11-30 10:30:441517 bool ShouldDeferReads() {
1518 return !offscreen_target_frame_buffer_.get() &&
1519 state_.bound_read_framebuffer == NULL &&
1520 surface_->DeferDraws();
1521 }
1522
[email protected]c447acd2012-07-23 23:48:411523 void ForceCompileShaderIfPending(ShaderManager::ShaderInfo* info);
1524
[email protected]96449d2c2009-11-25 00:01:321525 // Generate a member function prototype for each command in an automated and
1526 // typesafe way.
1527 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141528 Error Handle ## name( \
[email protected]b9849abf2009-11-25 19:13:191529 uint32 immediate_data_size, \
[email protected]96449d2c2009-11-25 00:01:321530 const gles2::name& args); \
1531
1532 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1533
1534 #undef GLES2_CMD_OP
1535
[email protected]2f2d7042010-04-14 21:45:581536 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381537 scoped_refptr<gfx::GLSurface> surface_;
1538 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021539
[email protected]a3ded6d2010-10-19 06:44:391540 // The ContextGroup for this decoder uses to track resources.
1541 ContextGroup::Ref group_;
1542
[email protected]e259eb412012-10-13 05:47:241543 // All the state for this context.
1544 ContextState state_;
1545
[email protected]6217d392010-03-25 22:08:351546 // A parent decoder can access this decoders saved offscreen frame buffer.
1547 // The parent pointer is reset if the parent is destroyed.
1548 base::WeakPtr<GLES2DecoderImpl> parent_;
1549
[email protected]34ff8b0c2010-10-01 20:06:021550 // Current width and height of the offscreen frame buffer.
1551 gfx::Size offscreen_size_;
1552
[email protected]96449d2c2009-11-25 00:01:321553 // Current GL error bits.
1554 uint32 error_bits_;
1555
[email protected]96449d2c2009-11-25 00:01:321556 // Util to help with GL.
1557 GLES2Util util_;
1558
[email protected]43410e92012-04-20 17:06:281559 // unpack flip y as last set by glPixelStorei
1560 bool unpack_flip_y_;
1561
[email protected]6c75c712012-06-19 15:43:171562 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281563 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171564 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281565
[email protected]944b62f32012-09-27 02:20:461566 // Default vertex attribs manager, used when no VAOs are bound.
1567 VertexAttribManager::Ref default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301568
[email protected]b1122982010-05-17 23:04:241569 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1570 GLuint attrib_0_buffer_id_;
1571
1572 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131573 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241574
[email protected]fc753442011-02-04 19:49:491575 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1576 bool attrib_0_buffer_matches_value_;
1577
[email protected]b1122982010-05-17 23:04:241578 // The size of attrib 0.
1579 GLsizei attrib_0_size_;
1580
[email protected]8fbedc02010-11-18 18:43:401581 // The buffer used to simulate GL_FIXED attribs.
1582 GLuint fixed_attrib_buffer_id_;
1583
1584 // The size of fiixed attrib buffer.
1585 GLsizei fixed_attrib_buffer_size_;
1586
[email protected]3a2e7c7b2010-08-06 01:12:281587 // state saved for clearing so we can clear render buffers and then
1588 // restore to these values.
[email protected]88a61bf2012-10-27 13:00:421589 bool clear_state_dirty_;
[email protected]3a2e7c7b2010-08-06 01:12:281590
[email protected]b9363b22010-06-09 22:06:151591 // The offscreen frame buffer that the client renders to. With EGL, the
1592 // depth and stencil buffers are separate. With regular GL there is a single
1593 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1594 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]6217d392010-03-25 22:08:351595 scoped_ptr<FrameBuffer> offscreen_target_frame_buffer_;
1596 scoped_ptr<Texture> offscreen_target_color_texture_;
[email protected]34ff8b0c2010-10-01 20:06:021597 scoped_ptr<RenderBuffer> offscreen_target_color_render_buffer_;
[email protected]b9363b22010-06-09 22:06:151598 scoped_ptr<RenderBuffer> offscreen_target_depth_render_buffer_;
1599 scoped_ptr<RenderBuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021600 GLenum offscreen_target_color_format_;
1601 GLenum offscreen_target_depth_format_;
1602 GLenum offscreen_target_stencil_format_;
1603 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561604 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351605
[email protected]de26b3c2011-08-03 21:54:271606 // The copy that is saved when SwapBuffers is called.
[email protected]34ff8b0c2010-10-01 20:06:021607 scoped_ptr<FrameBuffer> offscreen_saved_frame_buffer_;
[email protected]6217d392010-03-25 22:08:351608 scoped_ptr<Texture> offscreen_saved_color_texture_;
[email protected]8a61d872012-01-20 12:43:561609 TextureManager::TextureInfo::Ref offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271610
1611 // The copy that is used as the destination for multi-sample resolves.
1612 scoped_ptr<FrameBuffer> offscreen_resolved_frame_buffer_;
1613 scoped_ptr<Texture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051614 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351615
[email protected]882ba1e22012-03-08 19:02:531616 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531617
[email protected]944b62f32012-09-27 02:20:461618 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1619
[email protected]9d37f062011-11-22 01:24:521620 base::Callback<void(gfx::Size)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001621
[email protected]6b6e7ee2011-12-13 08:04:521622 MsgCallback msg_callback_;
[email protected]43f28f832010-02-03 02:28:481623
[email protected]b0af4f52011-09-28 22:04:421624 StreamTextureManager* stream_texture_manager_;
[email protected]32145a92012-12-17 09:01:591625 scoped_ptr<gfx::AsyncPixelTransferDelegate> async_pixel_transfer_delegate_;
[email protected]b0af4f52011-09-28 22:04:421626
[email protected]32fe9aa2011-01-21 23:47:131627 // The format of the back buffer_
1628 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461629 bool back_buffer_has_depth_;
1630 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131631
[email protected]60f22d32012-12-12 00:31:581632 // Backbuffer attachments that are currently undefined.
1633 uint32 backbuffer_needs_clear_bits_;
1634
[email protected]473c01ccb2011-06-07 01:33:301635 bool teximage2d_faster_than_texsubimage2d_;
[email protected]473c01ccb2011-06-07 01:33:301636
[email protected]8eee29c2010-04-29 03:38:291637 // The last error message set.
1638 std::string last_error_;
1639
[email protected]0f8afe82012-05-14 23:43:011640 int log_message_count_;
[email protected]fa20ec82012-05-04 04:02:481641
[email protected]a3a93e7b2010-08-28 00:48:561642 // The current decoder error.
1643 error::Error current_decoder_error_;
1644
[email protected]d2a0e1a2012-08-12 02:25:011645 DebugMarkerManager debug_marker_manager_;
1646 std::string this_in_hex_;
1647
[email protected]b1d2dcb2010-05-17 19:24:181648 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041649 scoped_refptr<ShaderTranslator> vertex_translator_;
1650 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181651
[email protected]e82fb792011-09-22 00:33:291652 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411653
[email protected]915a59a12010-09-30 21:29:111654 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051655 const Validators* validators_;
[email protected]80eb6b52012-01-19 00:14:411656 FeatureInfo::Ref feature_info_;
[email protected]9438b012010-06-15 22:55:051657
[email protected]b493ee622011-04-13 23:52:001658 // This indicates all the following texSubImage2D calls that are part of the
1659 // failed texImage2D call should be ignored.
1660 bool tex_image_2d_failed_;
1661
[email protected]65225772011-05-12 21:10:241662 int frame_number_;
1663
[email protected]706b69f2012-07-27 04:59:301664 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431665 GLenum reset_status_;
1666
[email protected]f0d74742011-10-03 16:31:041667 // These flags are used to override the state of the shared feature_info_
1668 // member. Because the same FeatureInfo instance may be shared among many
1669 // contexts, the assumptions on the availablity of extensions in WebGL
1670 // contexts may be broken. These flags override the shared state to preserve
1671 // WebGL semantics.
1672 bool force_webgl_glsl_validation_;
1673 bool derivatives_explicitly_enabled_;
1674
[email protected]062c38b2012-01-18 03:25:101675 bool compile_shader_always_succeeds_;
1676
[email protected]cae20172012-12-07 00:06:191677 // Log extra info.
1678 bool service_logging_;
1679
[email protected]e51bdf32011-11-23 22:21:461680#if defined(OS_MACOSX)
1681 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1682 TextureToIOSurfaceMap texture_to_io_surface_map_;
1683#endif
1684
[email protected]c826d732012-02-09 04:40:261685 typedef std::vector<GLES2DecoderImpl*> ChildList;
1686 ChildList children_;
1687
[email protected]43410e92012-04-20 17:06:281688 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1689
[email protected]1868a342012-11-07 15:56:021690 // Cached values of the currently assigned viewport dimensions.
1691 GLsizei viewport_max_width_;
1692 GLsizei viewport_max_height_;
1693
[email protected]63b465922012-09-06 02:04:521694 // Command buffer stats.
1695 int texture_upload_count_;
1696 base::TimeDelta total_texture_upload_time_;
1697 base::TimeDelta total_processing_commands_time_;
1698
[email protected]94307712012-11-16 23:26:111699 std::stack<linked_ptr<GPUTrace> > gpu_trace_stack_;
1700
[email protected]96449d2c2009-11-25 00:01:321701 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1702};
1703
[email protected]6217d392010-03-25 22:08:351704ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder)
1705 : decoder_(decoder) {
1706 decoder_->CopyRealGLErrorsToWrapper();
1707}
1708
1709ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
1710 decoder_->ClearRealGLErrors();
1711}
1712
1713ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1714 GLuint id)
1715 : decoder_(decoder) {
1716 ScopedGLErrorSuppressor suppressor(decoder_);
1717
1718 // TODO(apatrick): Check if there are any other states that need to be reset
1719 // before binding a new texture.
1720 glActiveTexture(GL_TEXTURE0);
1721 glBindTexture(GL_TEXTURE_2D, id);
1722}
1723
1724ScopedTexture2DBinder::~ScopedTexture2DBinder() {
1725 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301726 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351727}
1728
1729ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1730 GLuint id)
1731 : decoder_(decoder) {
1732 ScopedGLErrorSuppressor suppressor(decoder_);
1733 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1734}
1735
1736ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
1737 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301738 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351739}
1740
1741ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1742 GLuint id)
1743 : decoder_(decoder) {
1744 ScopedGLErrorSuppressor suppressor(decoder_);
1745 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
1746}
1747
1748ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
1749 ScopedGLErrorSuppressor suppressor(decoder_);
[email protected]8e3e0662010-08-23 18:46:301750 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351751}
1752
[email protected]34ff8b0c2010-10-01 20:06:021753ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271754 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521755 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021756 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1757 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241758 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521759 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021760 if (!resolve_and_bind_)
1761 return;
1762
1763 ScopedGLErrorSuppressor suppressor(decoder_);
1764 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1765 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271766 GLuint targetid;
1767 if (internal) {
1768 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1769 decoder_->offscreen_resolved_frame_buffer_.reset(
1770 new FrameBuffer(decoder_));
1771 decoder_->offscreen_resolved_frame_buffer_->Create();
1772 decoder_->offscreen_resolved_color_texture_.reset(new Texture(decoder_));
1773 decoder_->offscreen_resolved_color_texture_->Create();
1774
1775 DCHECK(decoder_->offscreen_saved_color_format_);
1776 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[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() {
2970 return texture_upload_count_;
2971}
2972
2973base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
2974 return total_texture_upload_time_;
2975}
2976
2977base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
2978 return total_processing_commands_time_;
2979}
2980
[email protected]dc25dda2012-09-27 21:36:302981void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
2982 total_processing_commands_time_ += time;
2983}
2984
[email protected]63c9b052012-05-17 18:27:382985void GLES2DecoderImpl::Destroy(bool have_context) {
2986 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:052987
[email protected]c826d732012-02-09 04:40:262988 ChildList children = children_;
2989 for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
2990 (*it)->SetParent(NULL, 0);
2991 DCHECK(children_.empty());
[email protected]3c644d82011-06-20 19:58:242992 SetParent(NULL, 0);
2993
[email protected]80eb6b52012-01-19 00:14:412994 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:242995 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:462996 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:022997 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:242998 state_.bound_array_buffer = NULL;
2999 state_.current_query = NULL;
3000 state_.current_program = NULL;
3001 state_.bound_read_framebuffer = NULL;
3002 state_.bound_draw_framebuffer = NULL;
3003 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413004
[email protected]eadc96792010-10-27 19:39:393005 if (have_context) {
[email protected]c322e882012-05-23 18:06:183006 if (copy_texture_CHROMIUM_.get()) {
3007 copy_texture_CHROMIUM_->Destroy();
3008 copy_texture_CHROMIUM_.reset();
3009 }
[email protected]43410e92012-04-20 17:06:283010
[email protected]e259eb412012-10-13 05:47:243011 if (state_.current_program) {
3012 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
3013 state_.current_program = NULL;
[email protected]ca488e12010-12-13 20:06:143014 }
3015
[email protected]b1122982010-05-17 23:04:243016 if (attrib_0_buffer_id_) {
3017 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3018 }
[email protected]8fbedc02010-11-18 18:43:403019 if (fixed_attrib_buffer_id_) {
3020 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3021 }
[email protected]b1122982010-05-17 23:04:243022
[email protected]97872062010-11-03 19:07:053023 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543024 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053025 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543026 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053027 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023028 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053029 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153030 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053031 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153032 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053033 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023034 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053035 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543036 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273037 if (offscreen_resolved_frame_buffer_.get())
3038 offscreen_resolved_frame_buffer_->Destroy();
3039 if (offscreen_resolved_color_texture_.get())
3040 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053041 } else {
3042 if (offscreen_target_frame_buffer_.get())
3043 offscreen_target_frame_buffer_->Invalidate();
3044 if (offscreen_target_color_texture_.get())
3045 offscreen_target_color_texture_->Invalidate();
3046 if (offscreen_target_color_render_buffer_.get())
3047 offscreen_target_color_render_buffer_->Invalidate();
3048 if (offscreen_target_depth_render_buffer_.get())
3049 offscreen_target_depth_render_buffer_->Invalidate();
3050 if (offscreen_target_stencil_render_buffer_.get())
3051 offscreen_target_stencil_render_buffer_->Invalidate();
3052 if (offscreen_saved_frame_buffer_.get())
3053 offscreen_saved_frame_buffer_->Invalidate();
3054 if (offscreen_saved_color_texture_.get())
3055 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273056 if (offscreen_resolved_frame_buffer_.get())
3057 offscreen_resolved_frame_buffer_->Invalidate();
3058 if (offscreen_resolved_color_texture_.get())
3059 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023060 }
[email protected]43410e92012-04-20 17:06:283061 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053062
[email protected]882ba1e22012-03-08 19:02:533063 if (query_manager_.get()) {
3064 query_manager_->Destroy(have_context);
3065 query_manager_.reset();
3066 }
3067
[email protected]944b62f32012-09-27 02:20:463068 if (vertex_array_manager_ .get()) {
3069 vertex_array_manager_->Destroy(have_context);
3070 vertex_array_manager_.reset();
3071 }
3072
[email protected]1871a092011-10-10 21:46:423073 if (group_) {
[email protected]c4485aad62012-12-17 10:19:093074 group_->Destroy(this, have_context);
[email protected]1871a092011-10-10 21:46:423075 group_ = NULL;
3076 }
[email protected]3ae019382011-10-05 19:42:413077
[email protected]fe871662011-06-16 20:43:053078 if (context_.get()) {
3079 context_->ReleaseCurrent(NULL);
[email protected]79311e82011-09-20 00:40:503080 context_ = NULL;
[email protected]fe871662011-06-16 20:43:053081 }
[email protected]0fc35742011-04-13 17:57:543082
[email protected]97872062010-11-03 19:07:053083 offscreen_target_frame_buffer_.reset();
3084 offscreen_target_color_texture_.reset();
3085 offscreen_target_color_render_buffer_.reset();
3086 offscreen_target_depth_render_buffer_.reset();
3087 offscreen_target_stencil_render_buffer_.reset();
3088 offscreen_saved_frame_buffer_.reset();
3089 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273090 offscreen_resolved_frame_buffer_.reset();
3091 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463092
3093#if defined(OS_MACOSX)
3094 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3095 it != texture_to_io_surface_map_.end(); ++it) {
3096 CFRelease(it->second);
3097 }
3098 texture_to_io_surface_map_.clear();
3099#endif
[email protected]96449d2c2009-11-25 00:01:323100}
3101
[email protected]63c9b052012-05-17 18:27:383102void GLES2DecoderImpl::SetSurface(
3103 const scoped_refptr<gfx::GLSurface>& surface) {
3104 DCHECK(context_->IsCurrent(NULL));
3105 DCHECK(surface_.get());
3106 surface_ = surface;
3107 RestoreCurrentFramebufferBindings();
3108}
3109
[email protected]3c644d82011-06-20 19:58:243110bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent,
3111 uint32 new_parent_texture_id) {
[email protected]9a5afa432011-07-22 18:16:393112 if (!offscreen_saved_color_texture_.get())
3113 return false;
3114
[email protected]3c644d82011-06-20 19:58:243115 // Remove the saved frame buffer mapping from the parent decoder. The
3116 // parent pointer is a weak pointer so it will be null if the parent has
3117 // already been destroyed.
3118 if (parent_) {
[email protected]c826d732012-02-09 04:40:263119 ChildList::iterator it = std::find(
3120 parent_->children_.begin(),
3121 parent_->children_.end(),
3122 this);
3123 DCHECK(it != parent_->children_.end());
3124 parent_->children_.erase(it);
[email protected]3c644d82011-06-20 19:58:243125 // First check the texture has been mapped into the parent. This might not
3126 // be the case if initialization failed midway through.
3127 GLuint service_id = offscreen_saved_color_texture_->id();
3128 GLuint client_id = 0;
3129 if (parent_->texture_manager()->GetClientId(service_id, &client_id)) {
[email protected]80eb6b52012-01-19 00:14:413130 parent_->texture_manager()->RemoveTextureInfo(client_id);
[email protected]3c644d82011-06-20 19:58:243131 }
3132 }
3133
3134 GLES2DecoderImpl* new_parent_impl = static_cast<GLES2DecoderImpl*>(
3135 new_parent);
3136 if (new_parent_impl) {
[email protected]c826d732012-02-09 04:40:263137#ifndef NDEBUG
3138 ChildList::iterator it = std::find(
3139 new_parent_impl->children_.begin(),
3140 new_parent_impl->children_.end(),
3141 this);
3142 DCHECK(it == new_parent_impl->children_.end());
3143#endif
3144 new_parent_impl->children_.push_back(this);
[email protected]3c644d82011-06-20 19:58:243145 // Map the ID of the saved offscreen texture into the parent so that
3146 // it can reference it.
3147 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]98687862011-07-11 23:31:303148
3149 // Replace texture info when ID is already in use by parent.
3150 if (new_parent_impl->texture_manager()->GetTextureInfo(
[email protected]80eb6b52012-01-19 00:14:413151 new_parent_texture_id))
[email protected]98687862011-07-11 23:31:303152 new_parent_impl->texture_manager()->RemoveTextureInfo(
[email protected]80eb6b52012-01-19 00:14:413153 new_parent_texture_id);
[email protected]98687862011-07-11 23:31:303154
[email protected]8a61d872012-01-20 12:43:563155 offscreen_saved_color_texture_info_ =
[email protected]5f4f2a732011-07-30 00:47:553156 new_parent_impl->CreateTextureInfo(new_parent_texture_id, service_id);
[email protected]8a61d872012-01-20 12:43:563157 offscreen_saved_color_texture_info_->SetNotOwned();
3158 new_parent_impl->texture_manager()->
3159 SetInfoTarget(offscreen_saved_color_texture_info_, GL_TEXTURE_2D);
[email protected]3c644d82011-06-20 19:58:243160
[email protected]ee1e6aa2012-11-29 09:24:103161 parent_ = base::AsWeakPtr<GLES2DecoderImpl>(new_parent_impl);
[email protected]9a5afa432011-07-22 18:16:393162
3163 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243164 } else {
3165 parent_.reset();
[email protected]8a61d872012-01-20 12:43:563166 offscreen_saved_color_texture_info_ = NULL;
[email protected]3c644d82011-06-20 19:58:243167 }
3168
3169 return true;
3170}
3171
[email protected]260ddc4e2012-06-28 00:01:533172size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143173 size_t total = 0;
3174 if (offscreen_target_frame_buffer_.get()) {
3175 if (offscreen_target_color_texture_.get()) {
3176 total += offscreen_target_color_texture_->estimated_size();
3177 }
3178 if (offscreen_target_color_render_buffer_.get()) {
3179 total += offscreen_target_color_render_buffer_->estimated_size();
3180 }
3181 if (offscreen_target_depth_render_buffer_.get()) {
3182 total += offscreen_target_depth_render_buffer_->estimated_size();
3183 }
3184 if (offscreen_target_stencil_render_buffer_.get()) {
3185 total += offscreen_target_stencil_render_buffer_->estimated_size();
3186 }
3187 if (offscreen_saved_color_texture_.get()) {
3188 total += offscreen_saved_color_texture_->estimated_size();
3189 }
3190 if (offscreen_resolved_color_texture_.get()) {
3191 total += offscreen_resolved_color_texture_->estimated_size();
3192 }
3193 } else {
3194 gfx::Size size = surface_->GetSize();
3195 total += size.width() * size.height() *
3196 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3197 }
[email protected]260ddc4e2012-06-28 00:01:533198 return total;
[email protected]1078f912011-12-23 13:12:143199}
3200
[email protected]799b4b22011-08-22 17:09:593201bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3202 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3203 if (!is_offscreen) {
3204 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3205 << " with an onscreen framebuffer.";
3206 return false;
3207 }
3208
3209 if (offscreen_size_ == size)
3210 return true;
3211
3212 offscreen_size_ = size;
3213 int w = offscreen_size_.width();
3214 int h = offscreen_size_.height();
3215 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3216 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3217 << "to allocate storage due to excessive dimensions.";
3218 return false;
3219 }
3220
3221 // Reallocate the offscreen target buffers.
3222 DCHECK(offscreen_target_color_format_);
3223 if (IsOffscreenBufferMultisampled()) {
3224 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3225 offscreen_size_, offscreen_target_color_format_,
3226 offscreen_target_samples_)) {
3227 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3228 << "to allocate storage for offscreen target color buffer.";
3229 return false;
3230 }
3231 } else {
3232 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093233 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593234 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3235 << "to allocate storage for offscreen target color texture.";
3236 return false;
3237 }
3238 }
3239 if (offscreen_target_depth_format_ &&
3240 !offscreen_target_depth_render_buffer_->AllocateStorage(
3241 offscreen_size_, offscreen_target_depth_format_,
3242 offscreen_target_samples_)) {
3243 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3244 << "to allocate storage for offscreen target depth buffer.";
3245 return false;
3246 }
3247 if (offscreen_target_stencil_format_ &&
3248 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3249 offscreen_size_, offscreen_target_stencil_format_,
3250 offscreen_target_samples_)) {
3251 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3252 << "to allocate storage for offscreen target stencil buffer.";
3253 return false;
3254 }
3255
3256 // Attach the offscreen target buffers to the target frame buffer.
3257 if (IsOffscreenBufferMultisampled()) {
3258 offscreen_target_frame_buffer_->AttachRenderBuffer(
3259 GL_COLOR_ATTACHMENT0,
3260 offscreen_target_color_render_buffer_.get());
3261 } else {
3262 offscreen_target_frame_buffer_->AttachRenderTexture(
3263 offscreen_target_color_texture_.get());
3264 }
3265 if (offscreen_target_depth_format_) {
3266 offscreen_target_frame_buffer_->AttachRenderBuffer(
3267 GL_DEPTH_ATTACHMENT,
3268 offscreen_target_depth_render_buffer_.get());
3269 }
3270 const bool packed_depth_stencil =
3271 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3272 if (packed_depth_stencil) {
3273 offscreen_target_frame_buffer_->AttachRenderBuffer(
3274 GL_STENCIL_ATTACHMENT,
3275 offscreen_target_depth_render_buffer_.get());
3276 } else if (offscreen_target_stencil_format_) {
3277 offscreen_target_frame_buffer_->AttachRenderBuffer(
3278 GL_STENCIL_ATTACHMENT,
3279 offscreen_target_stencil_render_buffer_.get());
3280 }
3281
3282 if (offscreen_target_frame_buffer_->CheckStatus() !=
3283 GL_FRAMEBUFFER_COMPLETE) {
3284 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3285 << "because offscreen FBO was incomplete.";
3286 return false;
3287 }
3288
3289 // Clear the target frame buffer.
3290 {
3291 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3292 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3293 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3294 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3295 glClearStencil(0);
3296 glStencilMaskSeparate(GL_FRONT, -1);
3297 glStencilMaskSeparate(GL_BACK, -1);
3298 glClearDepth(0);
3299 glDepthMask(GL_TRUE);
3300 glDisable(GL_SCISSOR_TEST);
3301 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3302 RestoreClearState();
3303 }
[email protected]d85ef76d2011-09-08 22:21:433304
3305 // Destroy the offscreen resolved framebuffers.
3306 if (offscreen_resolved_frame_buffer_.get())
3307 offscreen_resolved_frame_buffer_->Destroy();
3308 if (offscreen_resolved_color_texture_.get())
3309 offscreen_resolved_color_texture_->Destroy();
3310 offscreen_resolved_color_texture_.reset();
3311 offscreen_resolved_frame_buffer_.reset();
3312
[email protected]799b4b22011-08-22 17:09:593313 return true;
[email protected]6217d392010-03-25 22:08:353314}
3315
[email protected]799b4b22011-08-22 17:09:593316error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
3317 uint32 immediate_data_size, const gles2::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443318 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023319 return error::kDeferCommandUntilLater;
3320
[email protected]799b4b22011-08-22 17:09:593321 GLuint width = static_cast<GLuint>(c.width);
3322 GLuint height = static_cast<GLuint>(c.height);
3323 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]a0d989162011-11-22 13:15:073324#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3325 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003326 // Make sure that we are done drawing to the back buffer before resizing.
3327 glFinish();
3328#endif
[email protected]799b4b22011-08-22 17:09:593329 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3330 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493331 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3332 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3333 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593334 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493335 }
[email protected]7ff86b92010-11-25 17:50:003336 }
[email protected]799b4b22011-08-22 17:09:593337
[email protected]9d37f062011-11-22 01:24:523338 if (!resize_callback_.is_null()) {
3339 resize_callback_.Run(gfx::Size(width, height));
[email protected]c777de52011-09-09 23:08:563340 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493341 if (!context_->IsCurrent(surface_.get())) {
3342 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3343 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053344 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493345 }
[email protected]658f7562011-09-09 05:24:053346 }
[email protected]799b4b22011-08-22 17:09:593347
3348 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393349}
3350
[email protected]96449d2c2009-11-25 00:01:323351const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3352 if (command_id > kStartPoint && command_id < kNumCommands) {
3353 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3354 }
3355 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3356}
3357
3358// Decode command with its arguments, and call the corresponding GL function.
3359// Note: args is a pointer to the command buffer. As such, it could be changed
3360// by a (malicious) client at any time, so if validation has to happen, it
3361// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143362error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323363 unsigned int command,
3364 unsigned int arg_count,
3365 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143366 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263367 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003368 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3369 // LOG(INFO), tried VLOG(1), no luck.
[email protected]d2a0e1a2012-08-12 02:25:013370 LOG(ERROR) << "[" << GetLogPrefix() << "]" << "cmd: "
3371 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193372 }
[email protected]96449d2c2009-11-25 00:01:323373 unsigned int command_index = command - kStartPoint - 1;
3374 if (command_index < arraysize(g_command_info)) {
3375 const CommandInfo& info = g_command_info[command_index];
3376 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3377 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3378 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193379 uint32 immediate_data_size =
3380 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323381 switch (command) {
3382 #define GLES2_CMD_OP(name) \
3383 case name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193384 result = Handle ## name( \
3385 immediate_data_size, \
[email protected]96449d2c2009-11-25 00:01:323386 *static_cast<const name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193387 break; \
[email protected]96449d2c2009-11-25 00:01:323388
3389 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323390 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383391 }
3392 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303393 GLenum error;
3394 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]d2a0e1a2012-08-12 02:25:013395 LOG(ERROR) << "[" << GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003396 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3397 << GetCommandName(command);
[email protected]ad84a3a2012-06-08 21:42:433398 SetGLError(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193399 }
[email protected]96449d2c2009-11-25 00:01:323400 }
3401 } else {
[email protected]f7a64ee2010-02-01 22:24:143402 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323403 }
[email protected]b9849abf2009-11-25 19:13:193404 } else {
3405 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323406 }
[email protected]a3a93e7b2010-08-28 00:48:563407 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3408 result = current_decoder_error_;
3409 current_decoder_error_ = error::kNoError;
3410 }
[email protected]b9849abf2009-11-25 19:13:193411 return result;
[email protected]96449d2c2009-11-25 00:01:323412}
3413
[email protected]ae51d192010-04-27 00:48:033414void GLES2DecoderImpl::RemoveBufferInfo(GLuint client_id) {
3415 buffer_manager()->RemoveBufferInfo(client_id);
[email protected]3916c97e2010-02-25 03:20:503416}
3417
[email protected]ae51d192010-04-27 00:48:033418bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
3419 if (GetProgramInfo(client_id)) {
3420 return false;
3421 }
[email protected]96449d2c2009-11-25 00:01:323422 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033423 if (service_id != 0) {
3424 CreateProgramInfo(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323425 }
[email protected]ae51d192010-04-27 00:48:033426 return true;
[email protected]96449d2c2009-11-25 00:01:323427}
3428
[email protected]ae51d192010-04-27 00:48:033429bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
3430 if (GetShaderInfo(client_id)) {
3431 return false;
[email protected]96449d2c2009-11-25 00:01:323432 }
[email protected]ae51d192010-04-27 00:48:033433 GLuint service_id = glCreateShader(type);
3434 if (service_id != 0) {
[email protected]7cea56d92010-04-28 17:21:383435 CreateShaderInfo(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033436 }
3437 return true;
[email protected]96449d2c2009-11-25 00:01:323438}
3439
[email protected]882ba1e22012-03-08 19:02:533440void GLES2DecoderImpl::DoFinish() {
3441 glFinish();
[email protected]22e3f552012-03-13 01:54:193442 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533443}
3444
3445void GLES2DecoderImpl::DoFlush() {
3446 glFlush();
[email protected]22e3f552012-03-13 01:54:193447 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533448}
3449
[email protected]3916c97e2010-02-25 03:20:503450void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453451 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023452 if (texture_index >= state_.texture_units.size()) {
[email protected]f80e6e12012-08-31 00:43:533453 SetGLErrorInvalidEnum(
3454 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503455 return;
3456 }
[email protected]e259eb412012-10-13 05:47:243457 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453458 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503459}
3460
[email protected]051b1372010-04-12 02:42:083461void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]3916c97e2010-02-25 03:20:503462 BufferManager::BufferInfo* info = NULL;
[email protected]051b1372010-04-12 02:42:083463 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033464 if (client_id != 0) {
3465 info = GetBufferInfo(client_id);
3466 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353467 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153468 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3469 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353470 return;
3471 }
3472
[email protected]ae51d192010-04-27 00:48:033473 // It's a new id so make a buffer info for it.
3474 glGenBuffersARB(1, &service_id);
3475 CreateBufferInfo(client_id, service_id);
3476 info = GetBufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573477 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103478 group_->GetIdAllocator(id_namespaces::kBuffers);
3479 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033480 }
[email protected]051b1372010-04-12 02:42:083481 }
[email protected]cae20172012-12-07 00:06:193482 LogClientServiceForInfo(info, client_id, "glBindBuffer");
[email protected]ae51d192010-04-27 00:48:033483 if (info) {
[email protected]4e8a5b122010-05-08 22:00:103484 if (!buffer_manager()->SetTarget(info, target)) {
[email protected]8eee29c2010-04-29 03:38:293485 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433486 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473487 return;
3488 }
[email protected]ae51d192010-04-27 00:48:033489 service_id = info->service_id();
[email protected]a93bb842010-02-16 23:03:473490 }
[email protected]96449d2c2009-11-25 00:01:323491 switch (target) {
3492 case GL_ARRAY_BUFFER:
[email protected]e259eb412012-10-13 05:47:243493 state_.bound_array_buffer = info;
[email protected]96449d2c2009-11-25 00:01:323494 break;
3495 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]e259eb412012-10-13 05:47:243496 state_.vertex_attrib_manager->SetElementArrayBuffer(info);
[email protected]96449d2c2009-11-25 00:01:323497 break;
3498 default:
[email protected]a93bb842010-02-16 23:03:473499 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323500 break;
3501 }
[email protected]051b1372010-04-12 02:42:083502 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323503}
3504
[email protected]297ca1c2011-06-20 23:08:463505bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
3506 return (GLES2Util::GetChannelsForFormat(
3507 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3508}
3509
3510bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]0d6bfdc2011-11-02 01:32:203511 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453512 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203513 if (framebuffer) {
3514 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463515 }
3516 if (offscreen_target_frame_buffer_.get()) {
3517 return offscreen_target_depth_format_ != 0;
3518 }
3519 return back_buffer_has_depth_;
3520}
3521
3522bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]0d6bfdc2011-11-02 01:32:203523 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453524 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203525 if (framebuffer) {
3526 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463527 }
3528 if (offscreen_target_frame_buffer_.get()) {
3529 return offscreen_target_stencil_format_ != 0 ||
3530 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3531 }
3532 return back_buffer_has_stencil_;
3533}
3534
3535void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]88a61bf2012-10-27 13:00:423536 if (clear_state_dirty_) {
[email protected]297ca1c2011-06-20 23:08:463537 glColorMask(
[email protected]e259eb412012-10-13 05:47:243538 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3539 state_.color_mask_alpha &&
3540 BoundFramebufferHasColorAttachmentWithAlpha());
[email protected]297ca1c2011-06-20 23:08:463541 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243542 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223543 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463544 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243545 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423546 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243547 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423548 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223549 EnableDisable(
3550 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3551 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3552 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3553 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]88a61bf2012-10-27 13:00:423554 clear_state_dirty_ = false;
[email protected]297ca1c2011-06-20 23:08:463555 }
3556}
3557
[email protected]78b514b2012-05-01 21:50:593558void GLES2DecoderImpl::BindAndApplyTextureParameters(
3559 TextureManager::TextureInfo* info) {
3560 glBindTexture(info->target(), info->service_id());
3561 glTexParameteri(info->target(), GL_TEXTURE_MIN_FILTER, info->min_filter());
3562 glTexParameteri(info->target(), GL_TEXTURE_MAG_FILTER, info->mag_filter());
3563 glTexParameteri(info->target(), GL_TEXTURE_WRAP_S, info->wrap_s());
3564 glTexParameteri(info->target(), GL_TEXTURE_WRAP_T, info->wrap_t());
3565}
3566
[email protected]1868a342012-11-07 15:56:023567GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]b177ae22011-11-01 03:29:113568 return (offscreen_target_frame_buffer_.get()) ?
3569 offscreen_target_frame_buffer_->id() :
[email protected]1868a342012-11-07 15:56:023570 (surface_ ? surface_->GetBackingFrameBufferObject() : 0);
3571}
3572
3573void GLES2DecoderImpl::RestoreState() const {
3574 state_.RestoreState();
3575
3576 // TODO: Restore multisample bindings
3577 GLuint service_id = state_.bound_draw_framebuffer ?
3578 state_.bound_draw_framebuffer->service_id() :
3579 GetBackbufferServiceId();
3580 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
[email protected]b177ae22011-11-01 03:29:113581}
3582
[email protected]051b1372010-04-12 02:42:083583void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
3584 FramebufferManager::FramebufferInfo* info = NULL;
3585 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033586 if (client_id != 0) {
3587 info = GetFramebufferInfo(client_id);
[email protected]051b1372010-04-12 02:42:083588 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353589 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153590 LOG(ERROR)
3591 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3592 current_decoder_error_ = error::kGenericError;
3593 return;
[email protected]bf5a8d132011-08-16 08:39:353594 }
3595
[email protected]ae51d192010-04-27 00:48:033596 // It's a new id so make a framebuffer info for it.
3597 glGenFramebuffersEXT(1, &service_id);
3598 CreateFramebufferInfo(client_id, service_id);
3599 info = GetFramebufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573600 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103601 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3602 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033603 } else {
3604 service_id = info->service_id();
[email protected]051b1372010-04-12 02:42:083605 }
[email protected]06c8b082011-01-05 18:00:363606 info->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083607 }
[email protected]cae20172012-12-07 00:06:193608 LogClientServiceForInfo(info, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303609
3610 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]e259eb412012-10-13 05:47:243611 state_.bound_draw_framebuffer = info;
[email protected]8e3e0662010-08-23 18:46:303612 }
3613 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]e259eb412012-10-13 05:47:243614 state_.bound_read_framebuffer = info;
[email protected]8e3e0662010-08-23 18:46:303615 }
[email protected]6217d392010-03-25 22:08:353616
[email protected]88a61bf2012-10-27 13:00:423617 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:463618
[email protected]b177ae22011-11-01 03:29:113619 // If we are rendering to the backbuffer get the FBO id for any simulated
3620 // backbuffer.
3621 if (info == NULL) {
3622 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463623 }
[email protected]6217d392010-03-25 22:08:353624
[email protected]051b1372010-04-12 02:42:083625 glBindFramebufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563626}
3627
[email protected]051b1372010-04-12 02:42:083628void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
3629 RenderbufferManager::RenderbufferInfo* info = NULL;
3630 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033631 if (client_id != 0) {
3632 info = GetRenderbufferInfo(client_id);
[email protected]051b1372010-04-12 02:42:083633 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353634 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153635 LOG(ERROR)
3636 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3637 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353638 return;
3639 }
3640
[email protected]ae51d192010-04-27 00:48:033641 // It's a new id so make a renderbuffer info for it.
3642 glGenRenderbuffersEXT(1, &service_id);
3643 CreateRenderbufferInfo(client_id, service_id);
[email protected]066849e32010-05-03 19:14:103644 info = GetRenderbufferInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573645 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103646 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3647 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033648 } else {
3649 service_id = info->service_id();
[email protected]051b1372010-04-12 02:42:083650 }
[email protected]06c8b082011-01-05 18:00:363651 info->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083652 }
[email protected]cae20172012-12-07 00:06:193653 LogClientServiceForInfo(info, client_id, "glBindRenerbuffer");
[email protected]e259eb412012-10-13 05:47:243654 state_.bound_renderbuffer = info;
[email protected]051b1372010-04-12 02:42:083655 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563656}
3657
[email protected]051b1372010-04-12 02:42:083658void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]ae51d192010-04-27 00:48:033659 TextureManager::TextureInfo* info = NULL;
[email protected]051b1372010-04-12 02:42:083660 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033661 if (client_id != 0) {
3662 info = GetTextureInfo(client_id);
3663 if (!info) {
[email protected]bf5a8d132011-08-16 08:39:353664 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153665 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3666 current_decoder_error_ = error::kGenericError;
3667 return;
[email protected]bf5a8d132011-08-16 08:39:353668 }
3669
[email protected]ae51d192010-04-27 00:48:033670 // It's a new id so make a texture info for it.
3671 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413672 DCHECK_NE(0u, service_id);
[email protected]ae51d192010-04-27 00:48:033673 CreateTextureInfo(client_id, service_id);
3674 info = GetTextureInfo(client_id);
[email protected]3b1ecc262011-08-03 22:49:573675 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103676 group_->GetIdAllocator(id_namespaces::kTextures);
3677 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033678 }
3679 } else {
3680 info = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083681 }
[email protected]ae51d192010-04-27 00:48:033682
[email protected]1958e0e2010-04-22 05:17:153683 // Check the texture exists
3684 // Check that we are not trying to bind it to a different target.
[email protected]ae51d192010-04-27 00:48:033685 if (info->target() != 0 && info->target() != target) {
[email protected]8eee29c2010-04-29 03:38:293686 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433687 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153688 return;
3689 }
[email protected]b0af4f52011-09-28 22:04:423690 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
3691 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433692 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423693 return;
3694 }
[email protected]cae20172012-12-07 00:06:193695 LogClientServiceForInfo(info, client_id, "glBindTexture");
[email protected]1958e0e2010-04-22 05:17:153696 if (info->target() == 0) {
[email protected]80eb6b52012-01-19 00:14:413697 texture_manager()->SetInfoTarget(info, target);
[email protected]a93bb842010-02-16 23:03:473698 }
[email protected]ae51d192010-04-27 00:48:033699 glBindTexture(target, info->service_id());
[email protected]32145a92012-12-17 09:01:593700
[email protected]e259eb412012-10-13 05:47:243701 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503702 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473703 switch (target) {
3704 case GL_TEXTURE_2D:
[email protected]3916c97e2010-02-25 03:20:503705 unit.bound_texture_2d = info;
[email protected]a93bb842010-02-16 23:03:473706 break;
3707 case GL_TEXTURE_CUBE_MAP:
[email protected]3916c97e2010-02-25 03:20:503708 unit.bound_texture_cube_map = info;
[email protected]a93bb842010-02-16 23:03:473709 break;
[email protected]61eeb33f2011-07-26 15:30:313710 case GL_TEXTURE_EXTERNAL_OES:
3711 unit.bound_texture_external_oes = info;
[email protected]b0af4f52011-09-28 22:04:423712 if (info->IsStreamTexture()) {
3713 DCHECK(stream_texture_manager_);
3714 StreamTexture* stream_tex =
3715 stream_texture_manager_->LookupStreamTexture(info->service_id());
3716 if (stream_tex)
3717 stream_tex->Update();
3718 }
[email protected]61eeb33f2011-07-26 15:30:313719 break;
[email protected]e51bdf32011-11-23 22:21:463720 case GL_TEXTURE_RECTANGLE_ARB:
3721 unit.bound_texture_rectangle_arb = info;
3722 break;
[email protected]a93bb842010-02-16 23:03:473723 default:
3724 NOTREACHED(); // Validation should prevent us getting here.
3725 break;
3726 }
3727}
3728
[email protected]07f54fcc2009-12-22 02:46:303729void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243730 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123731 if (index != 0 ||
3732 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243733 glDisableVertexAttribArray(index);
3734 }
[email protected]07f54fcc2009-12-22 02:46:303735 } else {
[email protected]8eee29c2010-04-29 03:38:293736 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:433737 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303738 }
3739}
3740
[email protected]60f22d32012-12-12 00:31:583741void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3742 GLsizei numAttachments,
3743 const GLenum* attachments) {
3744 FramebufferManager::FramebufferInfo* framebuffer =
3745 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3746
3747 // Validates the attachments. If one of them fails
3748 // the whole command fails.
3749 for (GLsizei i = 0; i < numAttachments; ++i) {
3750 if ((framebuffer &&
3751 !validators_->attachment.IsValid(attachments[i])) ||
3752 (!framebuffer &&
3753 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
3754 SetGLErrorInvalidEnum("glDiscardFramebufferEXT",
3755 attachments[i],
3756 "attachments");
3757 return;
3758 }
3759 }
3760
3761 // Marks each one of them as not cleared
3762 for (GLsizei i = 0; i < numAttachments; ++i) {
3763 if (framebuffer) {
3764 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3765 texture_manager(),
3766 attachments[i],
3767 false);
3768 } else {
3769 switch (attachments[i]) {
3770 case GL_COLOR_EXT:
3771 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3772 break;
3773 case GL_DEPTH_EXT:
3774 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
3775 case GL_STENCIL_EXT:
3776 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
3777 break;
3778 default:
3779 NOTREACHED();
3780 break;
3781 }
3782 }
3783 }
3784
3785 glDiscardFramebufferEXT(target, numAttachments, attachments);
3786}
3787
[email protected]07f54fcc2009-12-22 02:46:303788void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243789 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:303790 glEnableVertexAttribArray(index);
3791 } else {
[email protected]8eee29c2010-04-29 03:38:293792 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:433793 "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303794 }
3795}
3796
[email protected]a93bb842010-02-16 23:03:473797void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]3916c97e2010-02-25 03:20:503798 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]97dc7cbe2011-12-06 17:26:173799 if (!info ||
[email protected]38c0a972012-05-12 00:48:023800 !texture_manager()->CanGenerateMipmaps(info)) {
[email protected]8eee29c2010-04-29 03:38:293801 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:433802 "glGenerateMipmaps", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:473803 return;
3804 }
[email protected]38c0a972012-05-12 00:48:023805
[email protected]12d95352012-12-14 07:23:543806 if (target == GL_TEXTURE_CUBE_MAP) {
3807 for (int i = 0; i < 6; ++i) {
3808 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
3809 if (!texture_manager()->ClearTextureLevel(this, info, face, 0)) {
3810 SetGLError(GL_OUT_OF_MEMORY, "glGenerateMipmaps", "dimensions too big");
3811 return;
3812 }
3813 }
3814 } else {
3815 if (!texture_manager()->ClearTextureLevel(this, info, target, 0)) {
3816 SetGLError(GL_OUT_OF_MEMORY, "glGenerateMipmaps", "dimensions too big");
3817 return;
3818 }
[email protected]7687479c2012-05-14 23:54:043819 }
3820
[email protected]38c0a972012-05-12 00:48:023821 CopyRealGLErrorsToWrapper();
[email protected]59f3ca02011-03-26 22:24:193822 // Workaround for Mac driver bug. In the large scheme of things setting
3823 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:563824 // hit so there's probably no need to make this conditional. The bug appears
3825 // to be that if the filtering mode is set to something that doesn't require
3826 // mipmaps for rendering, or is never set to something other than the default,
3827 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:153828 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193829 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3830 }
[email protected]a93bb842010-02-16 23:03:473831 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:153832 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193833 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, info->min_filter());
3834 }
[email protected]38c0a972012-05-12 00:48:023835 GLenum error = PeekGLError();
3836 if (error == GL_NO_ERROR) {
3837 texture_manager()->MarkMipmapsGenerated(info);
3838 }
[email protected]a93bb842010-02-16 23:03:473839}
3840
[email protected]b273e432010-04-12 17:23:583841bool GLES2DecoderImpl::GetHelper(
3842 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:583843 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:153844 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
3845 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:433846 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3847 *num_written = 1;
3848 if (params) {
3849 *params = GL_RGBA; // We don't support other formats.
3850 }
3851 return true;
3852 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3853 *num_written = 1;
3854 if (params) {
3855 *params = GL_UNSIGNED_BYTE; // We don't support other types.
3856 }
3857 return true;
3858 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
3859 *num_written = 1;
3860 if (params) {
3861 *params = group_->max_fragment_uniform_vectors();
3862 }
3863 return true;
3864 case GL_MAX_VARYING_VECTORS:
3865 *num_written = 1;
3866 if (params) {
3867 *params = group_->max_varying_vectors();
3868 }
3869 return true;
3870 case GL_MAX_VERTEX_UNIFORM_VECTORS:
3871 *num_written = 1;
3872 if (params) {
3873 *params = group_->max_vertex_uniform_vectors();
3874 }
3875 return true;
[email protected]4e8a5b122010-05-08 22:00:103876 }
[email protected]5cb735d2011-10-13 01:37:233877 }
3878 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:243879 case GL_MAX_VIEWPORT_DIMS:
3880 if (offscreen_target_frame_buffer_.get()) {
3881 *num_written = 2;
3882 if (params) {
3883 params[0] = renderbuffer_manager()->max_renderbuffer_size();
3884 params[1] = renderbuffer_manager()->max_renderbuffer_size();
3885 }
3886 return true;
3887 }
[email protected]5cb735d2011-10-13 01:37:233888 return false;
[email protected]84afefa2011-10-19 21:45:533889 case GL_MAX_SAMPLES:
3890 *num_written = 1;
3891 if (params) {
3892 params[0] = renderbuffer_manager()->max_samples();
3893 }
3894 return true;
3895 case GL_MAX_RENDERBUFFER_SIZE:
3896 *num_written = 1;
3897 if (params) {
3898 params[0] = renderbuffer_manager()->max_renderbuffer_size();
3899 }
3900 return true;
[email protected]5cb735d2011-10-13 01:37:233901 case GL_MAX_TEXTURE_SIZE:
3902 *num_written = 1;
3903 if (params) {
3904 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
3905 }
3906 return true;
3907 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
3908 *num_written = 1;
3909 if (params) {
3910 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
3911 }
3912 return true;
[email protected]297ca1c2011-06-20 23:08:463913 case GL_ALPHA_BITS:
3914 *num_written = 1;
3915 if (params) {
3916 GLint v = 0;
3917 glGetIntegerv(GL_ALPHA_BITS, &v);
3918 params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0;
3919 }
3920 return true;
3921 case GL_DEPTH_BITS:
3922 *num_written = 1;
3923 if (params) {
3924 GLint v = 0;
3925 glGetIntegerv(GL_DEPTH_BITS, &v);
3926 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
3927 }
3928 return true;
3929 case GL_STENCIL_BITS:
3930 *num_written = 1;
3931 if (params) {
3932 GLint v = 0;
3933 glGetIntegerv(GL_STENCIL_BITS, &v);
3934 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
3935 }
3936 return true;
[email protected]656dcaad2010-05-07 17:18:373937 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:113938 *num_written = validators_->compressed_texture_format.GetValues().size();
3939 if (params) {
3940 for (GLint ii = 0; ii < *num_written; ++ii) {
3941 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
3942 }
3943 }
[email protected]656dcaad2010-05-07 17:18:373944 return true;
[email protected]b273e432010-04-12 17:23:583945 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
3946 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103947 if (params) {
[email protected]302ce6d2011-07-07 23:28:113948 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:103949 }
[email protected]b273e432010-04-12 17:23:583950 return true;
3951 case GL_NUM_SHADER_BINARY_FORMATS:
3952 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103953 if (params) {
[email protected]302ce6d2011-07-07 23:28:113954 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:103955 }
[email protected]b273e432010-04-12 17:23:583956 return true;
3957 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:113958 *num_written = validators_->shader_binary_format.GetValues().size();
3959 if (params) {
3960 for (GLint ii = 0; ii < *num_written; ++ii) {
3961 params[ii] = validators_->shader_binary_format.GetValues()[ii];
3962 }
3963 }
3964 return true;
[email protected]b273e432010-04-12 17:23:583965 case GL_SHADER_COMPILER:
3966 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103967 if (params) {
3968 *params = GL_TRUE;
3969 }
[email protected]b273e432010-04-12 17:23:583970 return true;
[email protected]6b8cf1a2010-05-06 16:13:583971 case GL_ARRAY_BUFFER_BINDING:
3972 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103973 if (params) {
[email protected]e259eb412012-10-13 05:47:243974 if (state_.bound_array_buffer) {
[email protected]4e8a5b122010-05-08 22:00:103975 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:243976 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:103977 &client_id);
3978 *params = client_id;
3979 } else {
3980 *params = 0;
3981 }
[email protected]6b8cf1a2010-05-06 16:13:583982 }
3983 return true;
3984 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
3985 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:103986 if (params) {
[email protected]e259eb412012-10-13 05:47:243987 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:103988 GLuint client_id = 0;
3989 buffer_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:243990 state_.vertex_attrib_manager->element_array_buffer(
3991 )->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:103992 *params = client_id;
3993 } else {
3994 *params = 0;
3995 }
[email protected]6b8cf1a2010-05-06 16:13:583996 }
3997 return true;
3998 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:303999 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584000 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104001 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:204002 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454003 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204004 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104005 GLuint client_id = 0;
4006 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204007 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304008 *params = client_id;
4009 } else {
4010 *params = 0;
4011 }
4012 }
4013 return true;
[email protected]ebfb73c2012-08-15 02:37:454014 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304015 *num_written = 1;
4016 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:204017 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454018 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204019 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304020 GLuint client_id = 0;
4021 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204022 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104023 *params = client_id;
4024 } else {
4025 *params = 0;
4026 }
[email protected]6b8cf1a2010-05-06 16:13:584027 }
4028 return true;
4029 case GL_RENDERBUFFER_BINDING:
4030 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104031 if (params) {
[email protected]0d6bfdc2011-11-02 01:32:204032 RenderbufferManager::RenderbufferInfo* renderbuffer =
4033 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4034 if (renderbuffer) {
[email protected]4e8a5b122010-05-08 22:00:104035 GLuint client_id = 0;
4036 renderbuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204037 renderbuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104038 *params = client_id;
4039 } else {
4040 *params = 0;
4041 }
[email protected]6b8cf1a2010-05-06 16:13:584042 }
4043 return true;
4044 case GL_CURRENT_PROGRAM:
4045 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104046 if (params) {
[email protected]e259eb412012-10-13 05:47:244047 if (state_.current_program) {
[email protected]4e8a5b122010-05-08 22:00:104048 GLuint client_id = 0;
4049 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244050 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104051 *params = client_id;
4052 } else {
4053 *params = 0;
4054 }
[email protected]6b8cf1a2010-05-06 16:13:584055 }
4056 return true;
[email protected]bf835842012-11-19 15:21:514057 case GL_VERTEX_ARRAY_BINDING_OES:
4058 *num_written = 1;
4059 if (params) {
4060 if (state_.vertex_attrib_manager != default_vertex_attrib_manager_) {
4061 GLuint client_id = 0;
4062 vertex_array_manager_->GetClientId(
4063 state_.vertex_attrib_manager->service_id(), &client_id);
4064 *params = client_id;
4065 } else {
4066 *params = 0;
4067 }
4068 }
4069 return true;
[email protected]4e8a5b122010-05-08 22:00:104070 case GL_TEXTURE_BINDING_2D:
4071 *num_written = 1;
4072 if (params) {
[email protected]e259eb412012-10-13 05:47:244073 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584074 if (unit.bound_texture_2d) {
4075 GLuint client_id = 0;
4076 texture_manager()->GetClientId(
4077 unit.bound_texture_2d->service_id(), &client_id);
4078 *params = client_id;
4079 } else {
4080 *params = 0;
4081 }
[email protected]6b8cf1a2010-05-06 16:13:584082 }
[email protected]4e8a5b122010-05-08 22:00:104083 return true;
4084 case GL_TEXTURE_BINDING_CUBE_MAP:
4085 *num_written = 1;
4086 if (params) {
[email protected]e259eb412012-10-13 05:47:244087 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584088 if (unit.bound_texture_cube_map) {
4089 GLuint client_id = 0;
4090 texture_manager()->GetClientId(
4091 unit.bound_texture_cube_map->service_id(), &client_id);
4092 *params = client_id;
4093 } else {
4094 *params = 0;
4095 }
[email protected]6b8cf1a2010-05-06 16:13:584096 }
[email protected]4e8a5b122010-05-08 22:00:104097 return true;
[email protected]61eeb33f2011-07-26 15:30:314098 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4099 *num_written = 1;
4100 if (params) {
[email protected]e259eb412012-10-13 05:47:244101 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]61eeb33f2011-07-26 15:30:314102 if (unit.bound_texture_external_oes) {
4103 GLuint client_id = 0;
4104 texture_manager()->GetClientId(
4105 unit.bound_texture_external_oes->service_id(), &client_id);
4106 *params = client_id;
4107 } else {
4108 *params = 0;
4109 }
4110 }
4111 return true;
[email protected]e51bdf32011-11-23 22:21:464112 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4113 *num_written = 1;
4114 if (params) {
[email protected]e259eb412012-10-13 05:47:244115 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]e51bdf32011-11-23 22:21:464116 if (unit.bound_texture_rectangle_arb) {
4117 GLuint client_id = 0;
4118 texture_manager()->GetClientId(
4119 unit.bound_texture_rectangle_arb->service_id(), &client_id);
4120 *params = client_id;
4121 } else {
4122 *params = 0;
4123 }
4124 }
4125 return true;
[email protected]6c75c712012-06-19 15:43:174126 case GL_UNPACK_FLIP_Y_CHROMIUM:
4127 *num_written = 1;
4128 if (params) {
4129 params[0] = unpack_flip_y_;
4130 }
4131 return true;
4132 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4133 *num_written = 1;
4134 if (params) {
4135 params[0] = unpack_premultiply_alpha_;
4136 }
4137 return true;
4138 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4139 *num_written = 1;
4140 if (params) {
4141 params[0] = unpack_unpremultiply_alpha_;
4142 }
4143 return true;
[email protected]b273e432010-04-12 17:23:584144 default:
[email protected]4e8a5b122010-05-08 22:00:104145 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534146 return false;
[email protected]b273e432010-04-12 17:23:584147 }
4148}
4149
[email protected]4e8a5b122010-05-08 22:00:104150bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4151 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264152 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534153 return true;
4154 }
[email protected]4e8a5b122010-05-08 22:00:104155 return GetHelper(pname, NULL, num_values);
4156}
4157
[email protected]b273e432010-04-12 17:23:584158void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4159 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104160 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534161 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]4e8a5b122010-05-08 22:00:104162 scoped_array<GLint> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264163 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534164 GetHelper(pname, values.get(), &num_written);
4165 }
[email protected]b273e432010-04-12 17:23:584166 for (GLsizei ii = 0; ii < num_written; ++ii) {
4167 params[ii] = static_cast<GLboolean>(values[ii]);
4168 }
4169 } else {
4170 glGetBooleanv(pname, params);
4171 }
4172}
4173
4174void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4175 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104176 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264177 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534178 if (GetHelper(pname, NULL, &num_written)) {
4179 scoped_array<GLint> values(new GLint[num_written]);
4180 GetHelper(pname, values.get(), &num_written);
4181 for (GLsizei ii = 0; ii < num_written; ++ii) {
4182 params[ii] = static_cast<GLfloat>(values[ii]);
4183 }
4184 } else {
4185 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584186 }
[email protected]b273e432010-04-12 17:23:584187 }
4188}
4189
4190void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4191 DCHECK(params);
4192 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264193 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534194 !GetHelper(pname, params, &num_written)) {
[email protected]b273e432010-04-12 17:23:584195 glGetIntegerv(pname, params);
4196 }
4197}
4198
[email protected]a0c3e972010-04-21 00:49:134199void GLES2DecoderImpl::DoGetProgramiv(
4200 GLuint program_id, GLenum pname, GLint* params) {
[email protected]6b8cf1a2010-05-06 16:13:584201 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4202 program_id, "glGetProgramiv");
[email protected]a0c3e972010-04-21 00:49:134203 if (!info) {
[email protected]a0c3e972010-04-21 00:49:134204 return;
4205 }
4206 info->GetProgramiv(pname, params);
4207}
4208
[email protected]258a3313f2011-10-18 20:13:574209void GLES2DecoderImpl::DoBindAttribLocation(
4210 GLuint program, GLuint index, const char* name) {
4211 if (!StringIsValidForGLES(name)) {
[email protected]ad84a3a2012-06-08 21:42:434212 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574213 return;
4214 }
[email protected]68dcb1f2012-04-07 00:14:564215 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ad84a3a2012-06-08 21:42:434216 SetGLError(GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564217 return;
4218 }
4219 if (index >= group_->max_vertex_attribs()) {
[email protected]ad84a3a2012-06-08 21:42:434220 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564221 return;
4222 }
[email protected]6b8cf1a2010-05-06 16:13:584223 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4224 program, "glBindAttribLocation");
[email protected]ae51d192010-04-27 00:48:034225 if (!info) {
[email protected]258a3313f2011-10-18 20:13:574226 return;
[email protected]558847a2010-03-24 07:02:544227 }
[email protected]c3e4c4e2012-03-02 19:23:244228 info->SetAttribLocationBinding(name, static_cast<GLint>(index));
[email protected]258a3313f2011-10-18 20:13:574229 glBindAttribLocation(info->service_id(), index, name);
4230}
4231
4232error::Error GLES2DecoderImpl::HandleBindAttribLocation(
4233 uint32 immediate_data_size, const gles2::BindAttribLocation& c) {
4234 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544235 GLuint index = static_cast<GLuint>(c.index);
4236 uint32 name_size = c.data_size;
4237 const char* name = GetSharedMemoryAs<const char*>(
4238 c.name_shm_id, c.name_shm_offset, name_size);
4239 if (name == NULL) {
4240 return error::kOutOfBounds;
4241 }
4242 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574243 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544244 return error::kNoError;
4245}
4246
4247error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate(
4248 uint32 immediate_data_size, const gles2::BindAttribLocationImmediate& c) {
[email protected]6b8cf1a2010-05-06 16:13:584249 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544250 GLuint index = static_cast<GLuint>(c.index);
4251 uint32 name_size = c.data_size;
4252 const char* name = GetImmediateDataAs<const char*>(
4253 c, name_size, immediate_data_size);
4254 if (name == NULL) {
4255 return error::kOutOfBounds;
4256 }
4257 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574258 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544259 return error::kNoError;
4260}
4261
4262error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
4263 uint32 immediate_data_size, const gles2::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584264 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544265 GLuint index = static_cast<GLuint>(c.index);
4266 Bucket* bucket = GetBucket(c.name_bucket_id);
4267 if (!bucket || bucket->size() == 0) {
4268 return error::kInvalidArguments;
4269 }
4270 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184271 if (!bucket->GetAsString(&name_str)) {
4272 return error::kInvalidArguments;
4273 }
[email protected]258a3313f2011-10-18 20:13:574274 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544275 return error::kNoError;
4276}
4277
[email protected]2be6abf32012-06-26 00:28:334278void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
4279 GLuint program, GLint location, const char* name) {
4280 if (!StringIsValidForGLES(name)) {
4281 SetGLError(GL_INVALID_VALUE,
4282 "glBindUniformLocationCHROMIUM", "Invalid character");
4283 return;
4284 }
4285 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
4286 SetGLError(GL_INVALID_OPERATION,
4287 "glBindUniformLocationCHROMIUM", "reserved prefix");
4288 return;
4289 }
4290 if (location < 0 || static_cast<uint32>(location) >=
4291 (group_->max_fragment_uniform_vectors() +
4292 group_->max_vertex_uniform_vectors()) * 4) {
4293 SetGLError(GL_INVALID_VALUE,
4294 "glBindUniformLocationCHROMIUM", "location out of range");
4295 return;
4296 }
4297 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4298 program, "glBindUniformLocationCHROMIUM");
4299 if (!info) {
4300 return;
4301 }
4302 if (!info->SetUniformLocationBinding(name, location)) {
4303 SetGLError(GL_INVALID_VALUE,
4304 "glBindUniformLocationCHROMIUM", "location out of range");
4305 }
4306}
4307
4308error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
4309 uint32 immediate_data_size, const gles2::BindUniformLocationCHROMIUM& c) {
4310 GLuint program = static_cast<GLuint>(c.program);
4311 GLint location = static_cast<GLint>(c.location);
4312 uint32 name_size = c.data_size;
4313 const char* name = GetSharedMemoryAs<const char*>(
4314 c.name_shm_id, c.name_shm_offset, name_size);
4315 if (name == NULL) {
4316 return error::kOutOfBounds;
4317 }
4318 String name_str(name, name_size);
4319 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4320 return error::kNoError;
4321}
4322
4323error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4324 uint32 immediate_data_size,
4325 const gles2::BindUniformLocationCHROMIUMImmediate& c) {
4326 GLuint program = static_cast<GLuint>(c.program);
4327 GLint location = static_cast<GLint>(c.location);
4328 uint32 name_size = c.data_size;
4329 const char* name = GetImmediateDataAs<const char*>(
4330 c, name_size, immediate_data_size);
4331 if (name == NULL) {
4332 return error::kOutOfBounds;
4333 }
4334 String name_str(name, name_size);
4335 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4336 return error::kNoError;
4337}
4338
4339error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4340 uint32 immediate_data_size,
4341 const gles2::BindUniformLocationCHROMIUMBucket& c) {
4342 GLuint program = static_cast<GLuint>(c.program);
4343 GLint location = static_cast<GLint>(c.location);
4344 Bucket* bucket = GetBucket(c.name_bucket_id);
4345 if (!bucket || bucket->size() == 0) {
4346 return error::kInvalidArguments;
4347 }
4348 std::string name_str;
4349 if (!bucket->GetAsString(&name_str)) {
4350 return error::kInvalidArguments;
4351 }
4352 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4353 return error::kNoError;
4354}
4355
[email protected]f7a64ee2010-02-01 22:24:144356error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ba3176a2009-12-16 18:19:464357 uint32 immediate_data_size, const gles2::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034358 GLuint client_id = c.shader;
4359 if (client_id) {
4360 ShaderManager::ShaderInfo* info = GetShaderInfo(client_id);
4361 if (info) {
[email protected]ca488e12010-12-13 20:06:144362 if (!info->IsDeleted()) {
4363 glDeleteShader(info->service_id());
4364 shader_manager()->MarkAsDeleted(info);
4365 }
[email protected]ae51d192010-04-27 00:48:034366 } else {
[email protected]ad84a3a2012-06-08 21:42:434367 SetGLError(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034368 }
[email protected]96449d2c2009-11-25 00:01:324369 }
[email protected]f7a64ee2010-02-01 22:24:144370 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324371}
4372
[email protected]f7a64ee2010-02-01 22:24:144373error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ba3176a2009-12-16 18:19:464374 uint32 immediate_data_size, const gles2::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034375 GLuint client_id = c.program;
4376 if (client_id) {
4377 ProgramManager::ProgramInfo* info = GetProgramInfo(client_id);
4378 if (info) {
[email protected]ca488e12010-12-13 20:06:144379 if (!info->IsDeleted()) {
[email protected]ca488e12010-12-13 20:06:144380 program_manager()->MarkAsDeleted(shader_manager(), info);
4381 }
[email protected]ae51d192010-04-27 00:48:034382 } else {
[email protected]ad84a3a2012-06-08 21:42:434383 SetGLError(GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034384 }
[email protected]96449d2c2009-11-25 00:01:324385 }
[email protected]f7a64ee2010-02-01 22:24:144386 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324387}
4388
[email protected]269200b12010-11-18 22:53:064389void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104390 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574391 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104392 for (GLsizei ii = 0; ii < n; ++ii) {
4393 id_allocator->FreeID(ids[ii]);
4394 }
4395}
4396
[email protected]269200b12010-11-18 22:53:064397error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
4398 uint32 immediate_data_size, const gles2::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104399 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4400 GLsizei n = static_cast<GLsizei>(c.n);
4401 uint32 data_size;
4402 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4403 return error::kOutOfBounds;
4404 }
4405 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4406 c.ids_shm_id, c.ids_shm_offset, data_size);
4407 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434408 SetGLError(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104409 return error::kNoError;
4410 }
4411 if (ids == NULL) {
4412 return error::kOutOfBounds;
4413 }
[email protected]269200b12010-11-18 22:53:064414 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104415 return error::kNoError;
4416}
4417
[email protected]269200b12010-11-18 22:53:064418void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104419 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574420 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104421 if (id_offset == 0) {
4422 for (GLsizei ii = 0; ii < n; ++ii) {
4423 ids[ii] = id_allocator->AllocateID();
4424 }
4425 } else {
4426 for (GLsizei ii = 0; ii < n; ++ii) {
4427 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4428 id_offset = ids[ii] + 1;
4429 }
4430 }
4431}
4432
[email protected]269200b12010-11-18 22:53:064433error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
4434 uint32 immediate_data_size, const gles2::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104435 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4436 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4437 GLsizei n = static_cast<GLsizei>(c.n);
4438 uint32 data_size;
4439 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4440 return error::kOutOfBounds;
4441 }
4442 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4443 c.ids_shm_id, c.ids_shm_offset, data_size);
4444 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434445 SetGLError(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104446 return error::kNoError;
4447 }
4448 if (ids == NULL) {
4449 return error::kOutOfBounds;
4450 }
[email protected]269200b12010-11-18 22:53:064451 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104452 return error::kNoError;
4453}
4454
[email protected]269200b12010-11-18 22:53:064455void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104456 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574457 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104458 for (GLsizei ii = 0; ii < n; ++ii) {
4459 if (!id_allocator->MarkAsUsed(ids[ii])) {
4460 for (GLsizei jj = 0; jj < ii; ++jj) {
4461 id_allocator->FreeID(ids[jj]);
4462 }
4463 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:434464 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4465 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104466 return;
4467 }
4468 }
4469}
4470
[email protected]269200b12010-11-18 22:53:064471error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
4472 uint32 immediate_data_size, const gles2::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104473 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4474 GLsizei n = static_cast<GLsizei>(c.n);
4475 uint32 data_size;
4476 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4477 return error::kOutOfBounds;
4478 }
4479 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4480 c.ids_shm_id, c.ids_shm_offset, data_size);
4481 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:434482 SetGLError(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104483 return error::kNoError;
4484 }
4485 if (ids == NULL) {
4486 return error::kOutOfBounds;
4487 }
[email protected]269200b12010-11-18 22:53:064488 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104489 return error::kNoError;
4490}
4491
[email protected]a7266a92012-06-28 02:11:084492error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444493 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204494 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]e259eb412012-10-13 05:47:244495 UNSHIPPED_TRACE_EVENT_INSTANT2(
4496 "test_gpu", "DoClear",
4497 "red", state_.color_clear_red,
4498 "green", state_.color_clear_green);
[email protected]297ca1c2011-06-20 23:08:464499 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274500 glClear(mask);
4501 }
[email protected]a7266a92012-06-28 02:11:084502 return error::kNoError;
4503}
4504
[email protected]36cef8ce2010-03-16 07:34:454505void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4506 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034507 GLuint client_renderbuffer_id) {
[email protected]8e3e0662010-08-23 18:46:304508 FramebufferManager::FramebufferInfo* framebuffer_info =
4509 GetFramebufferInfoForTarget(target);
4510 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294511 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434512 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454513 return;
4514 }
[email protected]ae51d192010-04-27 00:48:034515 GLuint service_id = 0;
[email protected]3a2e7c7b2010-08-06 01:12:284516 RenderbufferManager::RenderbufferInfo* info = NULL;
[email protected]ae51d192010-04-27 00:48:034517 if (client_renderbuffer_id) {
[email protected]3a2e7c7b2010-08-06 01:12:284518 info = GetRenderbufferInfo(client_renderbuffer_id);
[email protected]ae51d192010-04-27 00:48:034519 if (!info) {
[email protected]8eee29c2010-04-29 03:38:294520 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434521 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034522 return;
4523 }
4524 service_id = info->service_id();
4525 }
[email protected]9edc6b22010-12-23 02:00:264526 CopyRealGLErrorsToWrapper();
[email protected]ae51d192010-04-27 00:48:034527 glFramebufferRenderbufferEXT(
4528 target, attachment, renderbuffertarget, service_id);
[email protected]1002c2d2011-06-28 22:39:044529 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264530 if (error == GL_NO_ERROR) {
[email protected]8e3e0662010-08-23 18:46:304531 framebuffer_info->AttachRenderbuffer(attachment, info);
[email protected]3a2e7c7b2010-08-06 01:12:284532 }
[email protected]e259eb412012-10-13 05:47:244533 if (framebuffer_info == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424534 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464535 }
[email protected]3a2e7c7b2010-08-06 01:12:284536}
4537
[email protected]3a2e7c7b2010-08-06 01:12:284538void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464539 if (SetCapabilityState(cap, false)) {
4540 glDisable(cap);
4541 }
[email protected]3a2e7c7b2010-08-06 01:12:284542}
4543
4544void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464545 if (SetCapabilityState(cap, true)) {
4546 glEnable(cap);
4547 }
[email protected]3a2e7c7b2010-08-06 01:12:284548}
4549
[email protected]88a61bf2012-10-27 13:00:424550void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4551 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4552 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4553 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284554}
4555
[email protected]88a61bf2012-10-27 13:00:424556void GLES2DecoderImpl::DoHint(GLenum target, GLenum mode) {
4557 switch (target) {
4558 case GL_GENERATE_MIPMAP_HINT:
4559 state_.hint_generate_mipmap = mode;
4560 break;
4561 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4562 state_.hint_fragment_shader_derivative = mode;
4563 break;
4564 default:
4565 NOTREACHED();
4566 }
4567 glHint(target, mode);
4568}
4569
4570void GLES2DecoderImpl::DoSampleCoverage (GLclampf value, GLboolean invert) {
4571 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4572 state_.sample_coverage_invert = (invert != 0);
4573 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284574}
4575
[email protected]0d6bfdc2011-11-02 01:32:204576// Assumes framebuffer is complete.
4577void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]8e3e0662010-08-23 18:46:304578 GLenum target, FramebufferManager::FramebufferInfo* info) {
4579 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204580 // bind this to the DRAW point, clear then bind back to READ
4581 // TODO(gman): I don't think there is any guarantee that an FBO that
4582 // is complete on the READ attachment will be complete as a DRAW
4583 // attachment.
4584 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
4585 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, info->service_id());
[email protected]8e3e0662010-08-23 18:46:304586 }
[email protected]3a2e7c7b2010-08-06 01:12:284587 GLbitfield clear_bits = 0;
4588 if (info->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464589 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204590 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464591 (GLES2Util::GetChannelsForFormat(
[email protected]0d6bfdc2011-11-02 01:32:204592 info->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f : 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284593 glColorMask(true, true, true, true);
4594 clear_bits |= GL_COLOR_BUFFER_BIT;
4595 }
4596
4597 if (info->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4598 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
4599 glClearStencil(0);
4600 glStencilMask(-1);
4601 clear_bits |= GL_STENCIL_BUFFER_BIT;
4602 }
4603
4604 if (info->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4605 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
4606 glClearDepth(1.0f);
4607 glDepthMask(true);
4608 clear_bits |= GL_DEPTH_BUFFER_BIT;
4609 }
4610
4611 glDisable(GL_SCISSOR_TEST);
4612 glClear(clear_bits);
4613
[email protected]968351b2011-12-20 08:26:514614 framebuffer_manager()->MarkAttachmentsAsCleared(
4615 info, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284616
[email protected]c007aa02010-09-02 22:22:404617 RestoreClearState();
4618
4619 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204620 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, info->service_id());
[email protected]87d1a3fe2011-12-01 04:25:484621 FramebufferManager::FramebufferInfo* framebuffer =
4622 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4623 GLuint service_id =
4624 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
4625 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404626 }
4627}
4628
4629void GLES2DecoderImpl::RestoreClearState() {
[email protected]88a61bf2012-10-27 13:00:424630 clear_state_dirty_ = true;
[email protected]e259eb412012-10-13 05:47:244631 glClearColor(
4632 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4633 state_.color_clear_alpha);
4634 glClearStencil(state_.stencil_clear);
4635 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224636 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284637 glEnable(GL_SCISSOR_TEST);
4638 }
[email protected]36cef8ce2010-03-16 07:34:454639}
4640
4641GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]0d6bfdc2011-11-02 01:32:204642 FramebufferManager::FramebufferInfo* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304643 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204644 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454645 return GL_FRAMEBUFFER_COMPLETE;
4646 }
[email protected]0d6bfdc2011-11-02 01:32:204647 GLenum completeness = framebuffer->IsPossiblyComplete();
4648 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4649 return completeness;
4650 }
[email protected]73276522012-11-09 05:50:204651 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454652}
4653
4654void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034655 GLenum target, GLenum attachment, GLenum textarget,
4656 GLuint client_texture_id, GLint level) {
[email protected]8e3e0662010-08-23 18:46:304657 FramebufferManager::FramebufferInfo* framebuffer_info =
4658 GetFramebufferInfoForTarget(target);
4659 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294660 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434661 "glFramebufferTexture2D", "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454662 return;
4663 }
[email protected]ae51d192010-04-27 00:48:034664 GLuint service_id = 0;
[email protected]3a2e7c7b2010-08-06 01:12:284665 TextureManager::TextureInfo* info = NULL;
[email protected]ae51d192010-04-27 00:48:034666 if (client_texture_id) {
[email protected]3a2e7c7b2010-08-06 01:12:284667 info = GetTextureInfo(client_texture_id);
[email protected]ae51d192010-04-27 00:48:034668 if (!info) {
[email protected]8eee29c2010-04-29 03:38:294669 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434670 "glFramebufferTexture2D", "unknown texture");
[email protected]ae51d192010-04-27 00:48:034671 return;
4672 }
4673 service_id = info->service_id();
4674 }
[email protected]0d6bfdc2011-11-02 01:32:204675
[email protected]80eb6b52012-01-19 00:14:414676 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]0d6bfdc2011-11-02 01:32:204677 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434678 "glFramebufferTexture2D", "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204679 return;
4680 }
4681
[email protected]9edc6b22010-12-23 02:00:264682 CopyRealGLErrorsToWrapper();
[email protected]ae51d192010-04-27 00:48:034683 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
[email protected]1002c2d2011-06-28 22:39:044684 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264685 if (error == GL_NO_ERROR) {
4686 framebuffer_info->AttachTexture(attachment, info, textarget, level);
[email protected]3a2e7c7b2010-08-06 01:12:284687 }
[email protected]e259eb412012-10-13 05:47:244688 if (framebuffer_info == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424689 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464690 }
[email protected]36cef8ce2010-03-16 07:34:454691}
4692
4693void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4694 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]8e3e0662010-08-23 18:46:304695 FramebufferManager::FramebufferInfo* framebuffer_info =
4696 GetFramebufferInfoForTarget(target);
4697 if (!framebuffer_info) {
[email protected]8eee29c2010-04-29 03:38:294698 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434699 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454700 return;
4701 }
4702 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:574703 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
4704 GLint type = 0;
4705 GLuint client_id = 0;
4706 glGetFramebufferAttachmentParameterivEXT(
4707 target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
4708 switch (type) {
4709 case GL_RENDERBUFFER: {
4710 renderbuffer_manager()->GetClientId(*params, &client_id);
4711 break;
4712 }
4713 case GL_TEXTURE: {
4714 texture_manager()->GetClientId(*params, &client_id);
4715 break;
4716 }
4717 default:
4718 break;
4719 }
4720 *params = client_id;
4721 }
[email protected]36cef8ce2010-03-16 07:34:454722}
4723
4724void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
4725 GLenum target, GLenum pname, GLint* params) {
[email protected]0d6bfdc2011-11-02 01:32:204726 RenderbufferManager::RenderbufferInfo* renderbuffer =
4727 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4728 if (!renderbuffer) {
[email protected]8eee29c2010-04-29 03:38:294729 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434730 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454731 return;
4732 }
[email protected]3a03a8f2011-03-19 00:51:274733 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434734 case GL_RENDERBUFFER_INTERNAL_FORMAT:
4735 *params = renderbuffer->internal_format();
4736 break;
4737 case GL_RENDERBUFFER_WIDTH:
4738 *params = renderbuffer->width();
4739 break;
4740 case GL_RENDERBUFFER_HEIGHT:
4741 *params = renderbuffer->height();
4742 break;
4743 default:
4744 glGetRenderbufferParameterivEXT(target, pname, params);
4745 break;
[email protected]b71f52c2010-06-18 22:20:204746 }
[email protected]36cef8ce2010-03-16 07:34:454747}
4748
[email protected]8e3e0662010-08-23 18:46:304749void GLES2DecoderImpl::DoBlitFramebufferEXT(
4750 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4751 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4752 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:444753 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:154754 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:304755 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434756 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304757 }
[email protected]d058bca2012-11-26 10:27:264758 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:244759 if (IsAngle()) {
4760 glBlitFramebufferANGLE(
4761 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4762 } else {
4763 glBlitFramebufferEXT(
4764 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4765 }
[email protected]d058bca2012-11-26 10:27:264766 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]529c6672012-01-04 02:18:264767 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", "width", srcX1 - srcX0);
[email protected]8e3e0662010-08-23 18:46:304768}
4769
4770void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
4771 GLenum target, GLsizei samples, GLenum internalformat,
4772 GLsizei width, GLsizei height) {
[email protected]62e155e2012-10-23 22:43:154773 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:304774 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434775 "glRenderbufferStorageMultisampleEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304776 return;
4777 }
[email protected]8e3e0662010-08-23 18:46:304778
[email protected]0d6bfdc2011-11-02 01:32:204779 RenderbufferManager::RenderbufferInfo* renderbuffer =
4780 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4781 if (!renderbuffer) {
4782 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434783 "glGetRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:204784 return;
4785 }
4786
[email protected]84afefa2011-10-19 21:45:534787 if (samples > renderbuffer_manager()->max_samples()) {
4788 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434789 "glGetRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:534790 return;
4791 }
4792
4793 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
4794 height > renderbuffer_manager()->max_renderbuffer_size()) {
4795 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434796 "glGetRenderbufferStorageMultisample", "size too large");
[email protected]84afefa2011-10-19 21:45:534797 return;
4798 }
4799
[email protected]9edc6b22010-12-23 02:00:264800 GLenum impl_format = internalformat;
[email protected]8e3e0662010-08-23 18:46:304801 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
[email protected]9edc6b22010-12-23 02:00:264802 switch (impl_format) {
[email protected]8e3e0662010-08-23 18:46:304803 case GL_DEPTH_COMPONENT16:
[email protected]9edc6b22010-12-23 02:00:264804 impl_format = GL_DEPTH_COMPONENT;
[email protected]8e3e0662010-08-23 18:46:304805 break;
4806 case GL_RGBA4:
4807 case GL_RGB5_A1:
[email protected]9edc6b22010-12-23 02:00:264808 impl_format = GL_RGBA;
[email protected]8e3e0662010-08-23 18:46:304809 break;
4810 case GL_RGB565:
[email protected]9edc6b22010-12-23 02:00:264811 impl_format = GL_RGB;
[email protected]8e3e0662010-08-23 18:46:304812 break;
4813 }
4814 }
4815
[email protected]9edc6b22010-12-23 02:00:264816 CopyRealGLErrorsToWrapper();
[email protected]866b91c52011-03-23 14:38:084817 if (IsAngle()) {
4818 glRenderbufferStorageMultisampleANGLE(
4819 target, samples, impl_format, width, height);
4820 } else {
4821 glRenderbufferStorageMultisampleEXT(
4822 target, samples, impl_format, width, height);
4823 }
[email protected]1002c2d2011-06-28 22:39:044824 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264825 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:514826 // TODO(gman): If renderbuffers tracked which framebuffers they were
4827 // attached to we could just mark those framebuffers as not complete.
4828 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:204829 renderbuffer_manager()->SetInfo(
4830 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:264831 }
[email protected]8e3e0662010-08-23 18:46:304832}
4833
[email protected]36cef8ce2010-03-16 07:34:454834void GLES2DecoderImpl::DoRenderbufferStorage(
4835 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]0d6bfdc2011-11-02 01:32:204836 RenderbufferManager::RenderbufferInfo* renderbuffer =
4837 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4838 if (!renderbuffer) {
[email protected]8eee29c2010-04-29 03:38:294839 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:434840 "glGetRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454841 return;
4842 }
[email protected]876f6fee2010-08-02 23:10:324843
[email protected]84afefa2011-10-19 21:45:534844 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
4845 height > renderbuffer_manager()->max_renderbuffer_size()) {
4846 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:434847 "glGetRenderbufferStorage", "size too large");
[email protected]84afefa2011-10-19 21:45:534848 return;
4849 }
4850
[email protected]9edc6b22010-12-23 02:00:264851 GLenum impl_format = internalformat;
[email protected]876f6fee2010-08-02 23:10:324852 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
[email protected]9edc6b22010-12-23 02:00:264853 switch (impl_format) {
[email protected]876f6fee2010-08-02 23:10:324854 case GL_DEPTH_COMPONENT16:
[email protected]9edc6b22010-12-23 02:00:264855 impl_format = GL_DEPTH_COMPONENT;
[email protected]876f6fee2010-08-02 23:10:324856 break;
4857 case GL_RGBA4:
4858 case GL_RGB5_A1:
[email protected]9edc6b22010-12-23 02:00:264859 impl_format = GL_RGBA;
[email protected]876f6fee2010-08-02 23:10:324860 break;
4861 case GL_RGB565:
[email protected]9edc6b22010-12-23 02:00:264862 impl_format = GL_RGB;
[email protected]876f6fee2010-08-02 23:10:324863 break;
4864 }
[email protected]b71f52c2010-06-18 22:20:204865 }
[email protected]876f6fee2010-08-02 23:10:324866
[email protected]9edc6b22010-12-23 02:00:264867 CopyRealGLErrorsToWrapper();
4868 glRenderbufferStorageEXT(target, impl_format, width, height);
[email protected]1002c2d2011-06-28 22:39:044869 GLenum error = PeekGLError();
[email protected]9edc6b22010-12-23 02:00:264870 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:514871 // TODO(gman): If tetxures tracked which framebuffers they were attached to
4872 // we could just mark those framebuffers as not complete.
4873 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:204874 renderbuffer_manager()->SetInfo(
4875 renderbuffer, 0, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:264876 }
[email protected]36cef8ce2010-03-16 07:34:454877}
4878
[email protected]07f54fcc2009-12-22 02:46:304879void GLES2DecoderImpl::DoLinkProgram(GLuint program) {
[email protected]43ed3a72012-05-30 22:55:384880 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]6b8cf1a2010-05-06 16:13:584881 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
4882 program, "glLinkProgram");
[email protected]a93bb842010-02-16 23:03:474883 if (!info) {
[email protected]a93bb842010-02-16 23:03:474884 return;
4885 }
[email protected]05afda12011-01-20 00:17:344886
[email protected]cae20172012-12-07 00:06:194887 LogClientServiceForInfo(info, program, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:394888 ShaderTranslator* vertex_translator = NULL;
4889 ShaderTranslator* fragment_translator = NULL;
4890 if (use_shader_translator_) {
4891 vertex_translator = vertex_translator_;
4892 fragment_translator = fragment_translator_;
4893 }
4894 if (info->Link(shader_manager(),
4895 vertex_translator,
4896 fragment_translator,
4897 feature_info_)) {
[email protected]e259eb412012-10-13 05:47:244898 if (info == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:154899 if (workarounds().use_current_program_after_successful_link) {
4900 glUseProgram(info->service_id());
[email protected]c2a3caf12012-10-23 19:32:004901 }
[email protected]62e155e2012-10-23 22:43:154902 program_manager()->ClearUniforms(info);
[email protected]2df73892012-04-28 01:09:544903 }
4904 }
[email protected]07f54fcc2009-12-22 02:46:304905};
4906
[email protected]3916c97e2010-02-25 03:20:504907void GLES2DecoderImpl::DoTexParameterf(
4908 GLenum target, GLenum pname, GLfloat param) {
4909 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]07f54fcc2009-12-22 02:46:304910 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434911 SetGLError(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244912 return;
[email protected]07f54fcc2009-12-22 02:46:304913 }
[email protected]cbb22e42011-05-12 23:36:244914
[email protected]445a8762012-12-06 15:43:214915 GLenum error = texture_manager()->SetParameter(
4916 info, pname, static_cast<GLint>(param));
4917 if (error != GL_NO_ERROR) {
4918 SetGLErrorInvalidParam(
4919 error, "glTexParameterf", pname, static_cast<GLint>(param));
[email protected]cbb22e42011-05-12 23:36:244920 return;
4921 }
4922 glTexParameterf(target, pname, param);
[email protected]07f54fcc2009-12-22 02:46:304923}
4924
[email protected]3916c97e2010-02-25 03:20:504925void GLES2DecoderImpl::DoTexParameteri(
4926 GLenum target, GLenum pname, GLint param) {
4927 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4928 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434929 SetGLError(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244930 return;
[email protected]3916c97e2010-02-25 03:20:504931 }
[email protected]cbb22e42011-05-12 23:36:244932
[email protected]445a8762012-12-06 15:43:214933 GLenum error = texture_manager()->SetParameter(info, pname, param);
4934 if(error != GL_NO_ERROR) {
4935 SetGLErrorInvalidParam(error, "glTexParameteri", pname, param);
[email protected]cbb22e42011-05-12 23:36:244936 return;
4937 }
[email protected]36f65962012-12-14 21:38:564938 // Texture tracking pools exist only for the command decoder, so
4939 // do not pass them on to the native GL implementation.
4940 if (pname == GL_TEXTURE_POOL_CHROMIUM) {
4941 return;
4942 }
[email protected]cbb22e42011-05-12 23:36:244943 glTexParameteri(target, pname, param);
[email protected]3916c97e2010-02-25 03:20:504944}
4945
4946void GLES2DecoderImpl::DoTexParameterfv(
4947 GLenum target, GLenum pname, const GLfloat* params) {
4948 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4949 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434950 SetGLError(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244951 return;
[email protected]3916c97e2010-02-25 03:20:504952 }
[email protected]cbb22e42011-05-12 23:36:244953
[email protected]445a8762012-12-06 15:43:214954 GLenum error =texture_manager()->SetParameter(
4955 info, pname, static_cast<GLint>(params[0]));
4956 if (error != GL_NO_ERROR) {
4957 SetGLErrorInvalidParam(
4958 error, "glTexParameterfv", pname, static_cast<GLint>(params[0]));
[email protected]cbb22e42011-05-12 23:36:244959 return;
4960 }
4961 glTexParameterfv(target, pname, params);
[email protected]3916c97e2010-02-25 03:20:504962}
4963
4964void GLES2DecoderImpl::DoTexParameteriv(
4965 GLenum target, GLenum pname, const GLint* params) {
4966 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
4967 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:434968 SetGLError(GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:244969 return;
[email protected]3916c97e2010-02-25 03:20:504970 }
[email protected]cbb22e42011-05-12 23:36:244971
[email protected]445a8762012-12-06 15:43:214972 GLenum error = texture_manager()->SetParameter(info, pname, *params);
4973 if (error != GL_NO_ERROR) {
4974 SetGLErrorInvalidParam(error, "glTexParameteriv", pname, *params);
[email protected]cbb22e42011-05-12 23:36:244975 return;
4976 }
4977 glTexParameteriv(target, pname, params);
[email protected]3916c97e2010-02-25 03:20:504978}
4979
[email protected]939e7362010-05-13 20:49:104980bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]e259eb412012-10-13 05:47:244981 if (!state_.current_program) {
[email protected]ad84a3a2012-06-08 21:42:434982 // The program does not exist.
4983 SetGLError(GL_INVALID_OPERATION, function_name, "no program in use");
4984 return false;
[email protected]939e7362010-05-13 20:49:104985 }
[email protected]e259eb412012-10-13 05:47:244986 if (!state_.current_program->InUse()) {
[email protected]ad84a3a2012-06-08 21:42:434987 SetGLError(GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:104988 return false;
4989 }
4990 return true;
4991}
4992
4993bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
4994 GLint location, const char* function_name) {
4995 if (!CheckCurrentProgram(function_name)) {
4996 return false;
4997 }
4998 return location != -1;
4999}
5000
[email protected]476ccb72012-12-06 15:52:525001namespace {
5002
5003static const GLenum valid_int_vec1_types_list[] = {
5004 GL_INT,
5005 GL_BOOL,
5006 GL_SAMPLER_2D,
5007 GL_SAMPLER_2D_RECT_ARB,
5008 GL_SAMPLER_CUBE,
5009 GL_SAMPLER_EXTERNAL_OES,
5010};
5011
5012static const GLenum valid_int_vec2_types_list[] = {
5013 GL_INT_VEC2,
5014 GL_BOOL_VEC2,
5015};
5016
5017static const GLenum valid_int_vec3_types_list[] = {
5018 GL_INT_VEC3,
5019 GL_BOOL_VEC3,
5020};
5021
5022static const GLenum valid_int_vec4_types_list[] = {
5023 GL_INT_VEC4,
5024 GL_BOOL_VEC4,
5025};
5026
5027static const GLenum valid_float_vec1_types_list[] = {
5028 GL_FLOAT,
5029 GL_BOOL,
5030};
5031
5032static const GLenum valid_float_vec2_types_list[] = {
5033 GL_FLOAT_VEC2,
5034 GL_BOOL_VEC2,
5035};
5036
5037static const GLenum valid_float_vec3_types_list[] = {
5038 GL_FLOAT_VEC3,
5039 GL_BOOL_VEC3,
5040};
5041
5042static const GLenum valid_float_vec4_types_list[] = {
5043 GL_FLOAT_VEC4,
5044 GL_BOOL_VEC4,
5045};
5046
5047static const GLenum valid_float_mat2_types_list[] = {
5048 GL_FLOAT_MAT2,
5049};
5050
5051static const GLenum valid_float_mat3_types_list[] = {
5052 GL_FLOAT_MAT3,
5053};
5054
5055static const GLenum valid_float_mat4_types_list[] = {
5056 GL_FLOAT_MAT4,
5057};
5058
5059static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5060 valid_int_vec1_types_list,
5061 arraysize(valid_int_vec1_types_list),
5062};
5063
5064static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5065 valid_int_vec2_types_list,
5066 arraysize(valid_int_vec2_types_list),
5067};
5068
5069static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5070 valid_int_vec3_types_list,
5071 arraysize(valid_int_vec3_types_list),
5072};
5073
5074static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5075 valid_int_vec4_types_list,
5076 arraysize(valid_int_vec4_types_list),
5077};
5078
5079static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5080 valid_float_vec1_types_list,
5081 arraysize(valid_float_vec1_types_list),
5082};
5083
5084static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5085 valid_float_vec2_types_list,
5086 arraysize(valid_float_vec2_types_list),
5087};
5088
5089static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5090 valid_float_vec3_types_list,
5091 arraysize(valid_float_vec3_types_list),
5092};
5093
5094static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5095 valid_float_vec4_types_list,
5096 arraysize(valid_float_vec4_types_list),
5097};
5098
5099static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5100 valid_float_mat2_types_list,
5101 arraysize(valid_float_mat2_types_list),
5102};
5103
5104static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5105 valid_float_mat3_types_list,
5106 arraysize(valid_float_mat3_types_list),
5107};
5108
5109static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5110 valid_float_mat4_types_list,
5111 arraysize(valid_float_mat4_types_list),
5112};
5113
5114} // anonymous namespace.
5115
[email protected]43c2f1f2011-03-25 18:35:365116bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125117 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525118 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125119 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365120 DCHECK(type);
5121 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125122 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525123
[email protected]1b0a6752012-02-22 03:44:125124 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105125 return false;
5126 }
[email protected]43c2f1f2011-03-25 18:35:365127 GLint array_index = -1;
5128 const ProgramManager::ProgramInfo::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245129 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125130 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365131 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:435132 SetGLError(GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105133 return false;
5134 }
[email protected]476ccb72012-12-06 15:52:525135 bool okay = false;
5136 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5137 if (base_info.valid_types[ii] == info->type) {
5138 okay = true;
5139 break;
5140 }
5141 }
5142 if (!okay) {
5143 SetGLError(
5144 GL_INVALID_OPERATION, function_name, "wrong uniform function for type");
5145 return false;
5146 }
[email protected]43c2f1f2011-03-25 18:35:365147 if (*count > 1 && !info->is_array) {
5148 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435149 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365150 return false;
5151 }
5152 *count = std::min(info->size - array_index, *count);
5153 if (*count <= 0) {
5154 return false;
5155 }
5156 *type = info->type;
[email protected]939e7362010-05-13 20:49:105157 return true;
5158}
5159
[email protected]1b0a6752012-02-22 03:44:125160void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5161 GLenum type = 0;
5162 GLsizei count = 1;
5163 GLint real_location = -1;
5164 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525165 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5166 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505167 return;
5168 }
[email protected]e259eb412012-10-13 05:47:245169 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025170 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ad84a3a2012-06-08 21:42:435171 SetGLError(GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465172 return;
5173 }
[email protected]1b0a6752012-02-22 03:44:125174 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505175}
5176
5177void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125178 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365179 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125180 GLint real_location = -1;
5181 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525182 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5183 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365184 return;
5185 }
[email protected]74727112012-06-13 21:18:085186 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5187 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245188 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025189 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ad84a3a2012-06-08 21:42:435190 SetGLError(GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465191 return;
5192 }
[email protected]43c2f1f2011-03-25 18:35:365193 }
[email protected]1b0a6752012-02-22 03:44:125194 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505195}
5196
[email protected]939e7362010-05-13 20:49:105197void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125198 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365199 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125200 GLint real_location = -1;
5201 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525202 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5203 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105204 return;
5205 }
5206 if (type == GL_BOOL) {
5207 scoped_array<GLint> temp(new GLint[count]);
5208 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535209 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105210 }
[email protected]1b0a6752012-02-22 03:44:125211 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105212 } else {
[email protected]1b0a6752012-02-22 03:44:125213 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105214 }
5215}
5216
5217void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125218 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365219 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125220 GLint real_location = -1;
5221 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525222 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5223 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105224 return;
5225 }
5226 if (type == GL_BOOL_VEC2) {
5227 GLsizei num_values = count * 2;
5228 scoped_array<GLint> temp(new GLint[num_values]);
5229 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535230 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105231 }
[email protected]1b0a6752012-02-22 03:44:125232 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105233 } else {
[email protected]1b0a6752012-02-22 03:44:125234 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105235 }
5236}
5237
5238void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125239 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365240 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125241 GLint real_location = -1;
5242 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525243 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5244 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105245 return;
5246 }
5247 if (type == GL_BOOL_VEC3) {
5248 GLsizei num_values = count * 3;
5249 scoped_array<GLint> temp(new GLint[num_values]);
5250 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535251 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105252 }
[email protected]1b0a6752012-02-22 03:44:125253 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105254 } else {
[email protected]1b0a6752012-02-22 03:44:125255 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105256 }
5257}
5258
5259void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125260 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365261 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125262 GLint real_location = -1;
5263 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525264 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5265 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105266 return;
5267 }
5268 if (type == GL_BOOL_VEC4) {
5269 GLsizei num_values = count * 4;
5270 scoped_array<GLint> temp(new GLint[num_values]);
5271 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535272 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105273 }
[email protected]1b0a6752012-02-22 03:44:125274 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105275 } else {
[email protected]1b0a6752012-02-22 03:44:125276 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105277 }
5278}
5279
[email protected]43c2f1f2011-03-25 18:35:365280void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125281 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365282 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125283 GLint real_location = -1;
5284 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525285 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5286 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365287 return;
5288 }
[email protected]1b0a6752012-02-22 03:44:125289 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365290}
5291
5292void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125293 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365294 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125295 GLint real_location = -1;
5296 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525297 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5298 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365299 return;
5300 }
[email protected]1b0a6752012-02-22 03:44:125301 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365302}
5303
5304void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125305 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365306 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125307 GLint real_location = -1;
5308 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525309 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5310 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365311 return;
5312 }
[email protected]1b0a6752012-02-22 03:44:125313 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365314}
5315
5316void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125317 GLint fake_location, GLsizei count, GLboolean transpose,
5318 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365319 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125320 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365321 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525322 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5323 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365324 return;
5325 }
[email protected]1b0a6752012-02-22 03:44:125326 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365327}
5328
5329void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125330 GLint fake_location, GLsizei count, GLboolean transpose,
5331 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365332 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125333 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365334 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525335 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5336 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365337 return;
5338 }
[email protected]1b0a6752012-02-22 03:44:125339 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365340}
5341
5342void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125343 GLint fake_location, GLsizei count, GLboolean transpose,
5344 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365345 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125346 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365347 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525348 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5349 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365350 return;
5351 }
[email protected]1b0a6752012-02-22 03:44:125352 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365353}
5354
[email protected]3916c97e2010-02-25 03:20:505355void GLES2DecoderImpl::DoUseProgram(GLuint program) {
[email protected]ae51d192010-04-27 00:48:035356 GLuint service_id = 0;
[email protected]3916c97e2010-02-25 03:20:505357 ProgramManager::ProgramInfo* info = NULL;
5358 if (program) {
[email protected]6b8cf1a2010-05-06 16:13:585359 info = GetProgramInfoNotShader(program, "glUseProgram");
[email protected]3916c97e2010-02-25 03:20:505360 if (!info) {
[email protected]ae51d192010-04-27 00:48:035361 return;
5362 }
5363 if (!info->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505364 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ad84a3a2012-06-08 21:42:435365 SetGLError(GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505366 return;
5367 }
[email protected]ae51d192010-04-27 00:48:035368 service_id = info->service_id();
[email protected]3916c97e2010-02-25 03:20:505369 }
[email protected]e259eb412012-10-13 05:47:245370 if (state_.current_program) {
5371 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
[email protected]ca488e12010-12-13 20:06:145372 }
[email protected]e259eb412012-10-13 05:47:245373 state_.current_program = info;
[email protected]cae20172012-12-07 00:06:195374 LogClientServiceMapping("glUseProgram", program, service_id);
[email protected]2df73892012-04-28 01:09:545375 glUseProgram(service_id);
[email protected]e259eb412012-10-13 05:47:245376 if (state_.current_program) {
5377 program_manager()->UseProgram(state_.current_program);
[email protected]ca488e12010-12-13 20:06:145378 }
[email protected]3916c97e2010-02-25 03:20:505379}
5380
[email protected]efcdd2362012-07-09 21:07:005381uint32 GLES2DecoderImpl::GetGLError() {
[email protected]96449d2c2009-11-25 00:01:325382 // Check the GL error first, then our wrapped error.
5383 GLenum error = glGetError();
5384 if (error == GL_NO_ERROR && error_bits_ != 0) {
[email protected]03f882a2010-01-08 20:46:375385 for (uint32 mask = 1; mask != 0; mask = mask << 1) {
[email protected]96449d2c2009-11-25 00:01:325386 if ((error_bits_ & mask) != 0) {
[email protected]ddd968b82010-03-02 00:44:295387 error = GLES2Util::GLErrorBitToGLError(mask);
[email protected]96449d2c2009-11-25 00:01:325388 break;
5389 }
5390 }
5391 }
5392
5393 if (error != GL_NO_ERROR) {
5394 // There was an error, clear the corresponding wrapped error.
[email protected]ddd968b82010-03-02 00:44:295395 error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
[email protected]96449d2c2009-11-25 00:01:325396 }
5397 return error;
5398}
5399
[email protected]1002c2d2011-06-28 22:39:045400GLenum GLES2DecoderImpl::PeekGLError() {
5401 GLenum error = glGetError();
5402 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435403 SetGLError(error, "", "");
[email protected]1002c2d2011-06-28 22:39:045404 }
5405 return error;
5406}
5407
[email protected]ad84a3a2012-06-08 21:42:435408void GLES2DecoderImpl::SetGLError(
5409 GLenum error, const char* function_name, const char* msg) {
[email protected]8eee29c2010-04-29 03:38:295410 if (msg) {
5411 last_error_ = msg;
[email protected]d2a0e1a2012-08-12 02:25:015412 LogMessage(GetLogPrefix() + ": " + std::string("GL ERROR :") +
[email protected]ad84a3a2012-06-08 21:42:435413 GLES2Util::GetStringEnum(error) + " : " +
5414 function_name + ": " + msg);
[email protected]8eee29c2010-04-29 03:38:295415 }
[email protected]ddd968b82010-03-02 00:44:295416 error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
[email protected]96449d2c2009-11-25 00:01:325417}
5418
[email protected]f80e6e12012-08-31 00:43:535419void GLES2DecoderImpl::SetGLErrorInvalidEnum(
5420 const char* function_name, GLenum value, const char* label) {
5421 SetGLError(GL_INVALID_ENUM, function_name,
5422 (std::string(label) + " was " +
5423 GLES2Util::GetStringEnum(value)).c_str());
5424}
5425
[email protected]445a8762012-12-06 15:43:215426void GLES2DecoderImpl::SetGLErrorInvalidParam(
5427 GLenum error,
5428 const char* function_name,
5429 GLenum pname,
5430 GLint param) {
5431 if (error == GL_INVALID_ENUM) {
5432 SetGLError(
5433 GL_INVALID_ENUM, function_name,
5434 (std::string("trying to set ") +
5435 GLES2Util::GetStringEnum(pname) + " to " +
5436 GLES2Util::GetStringEnum(param)).c_str());
5437 } else {
5438 SetGLError(
5439 error, function_name,
5440 (std::string("trying to set ") +
5441 GLES2Util::GetStringEnum(pname) + " to " +
5442 base::StringPrintf("%d", param)).c_str());
5443 }
5444}
5445
[email protected]d2a0e1a2012-08-12 02:25:015446const std::string& GLES2DecoderImpl::GetLogPrefix() const {
5447 const std::string& prefix(debug_marker_manager_.GetMarker());
5448 return prefix.empty() ? this_in_hex_ : prefix;
5449}
5450
[email protected]0f8afe82012-05-14 23:43:015451void GLES2DecoderImpl::LogMessage(const std::string& msg) {
5452 if (log_message_count_ < kMaxLogMessages ||
5453 CommandLine::ForCurrentProcess()->HasSwitch(
5454 switches::kDisableGLErrorLimit)) {
5455 ++log_message_count_;
5456 // LOG this unless logging is turned off as any chromium code that
5457 // generates these errors probably has a bug.
5458 if (log_synthesized_gl_errors()) {
[email protected]3f00df92012-06-19 00:44:585459 LOG(ERROR) << msg;
[email protected]0f8afe82012-05-14 23:43:015460 }
5461 if (!msg_callback_.is_null()) {
5462 msg_callback_.Run(0, msg);
5463 }
5464 } else {
5465 if (log_message_count_ == kMaxLogMessages) {
5466 ++log_message_count_;
5467 LOG(ERROR)
5468 << "Too many GL errors, not reporting any more for this context."
5469 << " use --disable-gl-error-limit to see all errors.";
5470 }
5471 }
5472}
5473
5474void GLES2DecoderImpl::RenderWarning(const std::string& msg) {
5475 LogMessage(std::string("RENDER WARNING: ") + msg);
5476}
5477
5478void GLES2DecoderImpl::PerformanceWarning(const std::string& msg) {
5479 LogMessage(std::string("PERFORMANCE WARNING: ") + msg);
5480}
5481
[email protected]c447acd2012-07-23 23:48:415482void GLES2DecoderImpl::ForceCompileShaderIfPending(
5483 ShaderManager::ShaderInfo* info) {
5484 if (info->compilation_status() ==
5485 ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE) {
[email protected]c447acd2012-07-23 23:48:415486 ShaderTranslator* translator = NULL;
5487 if (use_shader_translator_) {
5488 translator = info->shader_type() == GL_VERTEX_SHADER ?
5489 vertex_translator_.get() : fragment_translator_.get();
5490 }
5491 // We know there will be no errors, because we only defer compilation on
5492 // shaders that were previously compiled successfully.
5493 program_manager()->ForceCompileShader(info->deferred_compilation_source(),
5494 info,
5495 translator,
5496 feature_info_);
5497 }
5498}
5499
[email protected]07f54fcc2009-12-22 02:46:305500void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() {
5501 GLenum error;
5502 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435503 SetGLError(error, "", NULL);
[email protected]07f54fcc2009-12-22 02:46:305504 }
5505}
5506
[email protected]6217d392010-03-25 22:08:355507void GLES2DecoderImpl::ClearRealGLErrors() {
5508 GLenum error;
5509 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]3ed14d112011-12-13 22:05:515510 if (error != GL_OUT_OF_MEMORY) {
5511 // GL_OUT_OF_MEMORY can legally happen on lost device.
5512 NOTREACHED() << "GL error " << error << " was unhandled.";
5513 }
[email protected]6217d392010-03-25 22:08:355514 }
5515}
5516
[email protected]ef526492010-06-02 23:12:255517bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245518 DCHECK(state_.current_program);
[email protected]ef526492010-06-02 23:12:255519 // Only check if there are some unrenderable textures.
5520 if (!texture_manager()->HaveUnrenderableTextures()) {
5521 return false;
5522 }
5523 bool textures_set = false;
[email protected]3916c97e2010-02-25 03:20:505524 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245525 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505526 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5527 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245528 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505529 DCHECK(uniform_info);
5530 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5531 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025532 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245533 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]3916c97e2010-02-25 03:20:505534 TextureManager::TextureInfo* texture_info =
[email protected]61eeb33f2011-07-26 15:30:315535 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]80eb6b52012-01-19 00:14:415536 if (!texture_info || !texture_manager()->CanRender(texture_info)) {
[email protected]ef526492010-06-02 23:12:255537 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505538 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5539 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315540 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495541 texture_manager()->black_texture_id(uniform_info->type));
[email protected]0f8afe82012-05-14 23:43:015542 RenderWarning(
5543 std::string("texture bound to texture unit ") +
5544 base::IntToString(texture_unit_index) +
5545 " is not renderable. It maybe non-power-of-2 and have "
5546 " incompatible texture filtering or is not "
5547 "'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505548 }
5549 }
5550 // else: should this be an error?
5551 }
5552 }
[email protected]ef526492010-06-02 23:12:255553 return textures_set;
[email protected]3916c97e2010-02-25 03:20:505554}
5555
5556void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245557 DCHECK(state_.current_program);
[email protected]3916c97e2010-02-25 03:20:505558 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245559 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505560 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5561 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245562 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505563 DCHECK(uniform_info);
5564 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5565 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025566 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245567 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]3916c97e2010-02-25 03:20:505568 TextureManager::TextureInfo* texture_info =
5569 uniform_info->type == GL_SAMPLER_2D ?
5570 texture_unit.bound_texture_2d :
5571 texture_unit.bound_texture_cube_map;
[email protected]80eb6b52012-01-19 00:14:415572 if (!texture_info || !texture_manager()->CanRender(texture_info)) {
[email protected]3916c97e2010-02-25 03:20:505573 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5574 // Get the texture info that was previously bound here.
5575 texture_info = texture_unit.bind_target == GL_TEXTURE_2D ?
5576 texture_unit.bound_texture_2d :
5577 texture_unit.bound_texture_cube_map;
5578 glBindTexture(texture_unit.bind_target,
[email protected]ae51d192010-04-27 00:48:035579 texture_info ? texture_info->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505580 }
5581 }
5582 }
5583 }
5584 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245585 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305586}
5587
[email protected]0d6bfdc2011-11-02 01:32:205588bool GLES2DecoderImpl::ClearUnclearedTextures() {
5589 // Only check if there are some uncleared textures.
5590 if (!texture_manager()->HaveUnsafeTextures()) {
5591 return true;
5592 }
5593
5594 // 1: Check all textures we are about to render with.
[email protected]e259eb412012-10-13 05:47:245595 if (state_.current_program) {
[email protected]0d6bfdc2011-11-02 01:32:205596 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245597 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205598 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5599 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245600 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205601 DCHECK(uniform_info);
5602 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5603 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025604 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245605 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]0d6bfdc2011-11-02 01:32:205606 TextureManager::TextureInfo* texture_info =
5607 texture_unit.GetInfoForSamplerType(uniform_info->type);
5608 if (texture_info && !texture_info->SafeToRenderFrom()) {
5609 if (!texture_manager()->ClearRenderableLevels(this, texture_info)) {
5610 return false;
5611 }
5612 }
5613 }
5614 }
5615 }
5616 }
5617 return true;
5618}
5619
[email protected]c6aef902012-02-14 03:31:425620bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435621 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035622 // NOTE: We specifically do not check current_program->IsValid() because
5623 // it could never be invalid since glUseProgram would have failed. While
5624 // glLinkProgram could later mark the program as invalid the previous
5625 // valid program will still function if it is still the current program.
[email protected]e259eb412012-10-13 05:47:245626 if (!state_.current_program) {
[email protected]3916c97e2010-02-25 03:20:505627 // The program does not exist.
5628 // But GL says no ERROR.
[email protected]0f8afe82012-05-14 23:43:015629 RenderWarning("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505630 return false;
5631 }
[email protected]c6aef902012-02-14 03:31:425632
5633 // true if any enabled, used divisor is zero
5634 bool divisor0 = false;
[email protected]f39f4b3f2010-05-12 17:04:085635 // Validate all attribs currently enabled. If they are used by the current
5636 // program then check that they have enough elements to handle the draw call.
5637 // If they are not used by the current program check that they have a buffer
5638 // assigned.
5639 const VertexAttribManager::VertexAttribInfoList& infos =
[email protected]e259eb412012-10-13 05:47:245640 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos();
[email protected]f39f4b3f2010-05-12 17:04:085641 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
[email protected]8fbedc02010-11-18 18:43:405642 infos.begin(); it != infos.end(); ++it) {
[email protected]f39f4b3f2010-05-12 17:04:085643 const VertexAttribManager::VertexAttribInfo* info = *it;
5644 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245645 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]f39f4b3f2010-05-12 17:04:085646 if (attrib_info) {
[email protected]c6aef902012-02-14 03:31:425647 divisor0 |= (info->divisor() == 0);
5648 GLuint count = info->MaxVertexAccessed(primcount, max_vertex_accessed);
[email protected]f39f4b3f2010-05-12 17:04:085649 // This attrib is used in the current program.
[email protected]c6aef902012-02-14 03:31:425650 if (!info->CanAccess(count)) {
[email protected]0f8afe82012-05-14 23:43:015651 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435652 GL_INVALID_OPERATION, function_name,
[email protected]0f8afe82012-05-14 23:43:015653 (std::string(
[email protected]ad84a3a2012-06-08 21:42:435654 "attempt to access out of range vertices in attribute ") +
5655 base::IntToString(info->index())).c_str());
[email protected]f39f4b3f2010-05-12 17:04:085656 return false;
5657 }
5658 } else {
5659 // This attrib is not used in the current program.
[email protected]a0b78dc2011-11-11 10:43:105660 if (!info->buffer()) {
[email protected]f39f4b3f2010-05-12 17:04:085661 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435662 GL_INVALID_OPERATION, function_name,
[email protected]0f8afe82012-05-14 23:43:015663 (std::string(
[email protected]ad84a3a2012-06-08 21:42:435664 "attempt to render with no buffer attached to "
[email protected]0f8afe82012-05-14 23:43:015665 "enabled attribute ") +
5666 base::IntToString(info->index())).c_str());
[email protected]f39f4b3f2010-05-12 17:04:085667 return false;
5668 }
[email protected]1d32bc82010-01-13 22:06:465669 }
[email protected]07f54fcc2009-12-22 02:46:305670 }
[email protected]c6aef902012-02-14 03:31:425671
5672 if (primcount && !divisor0) {
5673 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:435674 GL_INVALID_OPERATION, function_name,
5675 "attempt instanced render with all attributes having "
[email protected]c6aef902012-02-14 03:31:425676 "non-zero divisors");
5677 return false;
5678 }
5679
[email protected]3916c97e2010-02-25 03:20:505680 return true;
[email protected]b1122982010-05-17 23:04:245681}
5682
[email protected]c13e1da62011-09-09 21:48:305683bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435684 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305685 DCHECK(simulated);
5686 *simulated = false;
5687
[email protected]876f6fee2010-08-02 23:10:325688 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305689 return true;
[email protected]876f6fee2010-08-02 23:10:325690
[email protected]b1122982010-05-17 23:04:245691 const VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:245692 state_.vertex_attrib_manager->GetVertexAttribInfo(0);
[email protected]b1122982010-05-17 23:04:245693 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245694 bool attrib_0_used =
5695 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]fc753442011-02-04 19:49:495696 if (info->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305697 return true;
[email protected]b1122982010-05-17 23:04:245698 }
5699
[email protected]b1122982010-05-17 23:04:245700 // Make a buffer with a single repeated vec4 value enough to
5701 // simulate the constant value that is supposed to be here.
5702 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305703 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475704 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305705
5706 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475707 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305708 size_needed > 0x7FFFFFFFU) {
[email protected]ad84a3a2012-06-08 21:42:435709 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305710 return false;
5711 }
5712
[email protected]0f8afe82012-05-14 23:43:015713 PerformanceWarning(
5714 "Attribute 0 is disabled. This has signficant performance penalty");
5715
[email protected]c13e1da62011-09-09 21:48:305716 CopyRealGLErrorsToWrapper();
5717 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5718
[email protected]8f0b86c2f2012-04-10 05:48:285719 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5720 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495721 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305722 GLenum error = glGetError();
5723 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435724 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305725 return false;
5726 }
[email protected]fc753442011-02-04 19:49:495727 }
[email protected]af6380962012-11-29 23:24:135728
5729 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:285730 if (new_buffer ||
5731 (attrib_0_used &&
5732 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:135733 (value.v[0] != attrib_0_value_.v[0] ||
5734 value.v[1] != attrib_0_value_.v[1] ||
5735 value.v[2] != attrib_0_value_.v[2] ||
5736 value.v[3] != attrib_0_value_.v[3])))) {
5737 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:495738 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
5739 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:135740 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:245741 attrib_0_size_ = size_needed;
5742 }
5743
5744 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
5745
[email protected]c6aef902012-02-14 03:31:425746 if (info->divisor())
5747 glVertexAttribDivisorANGLE(0, 0);
5748
[email protected]c13e1da62011-09-09 21:48:305749 *simulated = true;
[email protected]b1122982010-05-17 23:04:245750 return true;
[email protected]b1122982010-05-17 23:04:245751}
5752
[email protected]43410e92012-04-20 17:06:285753void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib) {
[email protected]b1122982010-05-17 23:04:245754 const VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:245755 state_.vertex_attrib_manager->GetVertexAttribInfo(attrib);
[email protected]b1122982010-05-17 23:04:245756 const void* ptr = reinterpret_cast<const void*>(info->offset());
5757 BufferManager::BufferInfo* buffer_info = info->buffer();
5758 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0);
5759 glVertexAttribPointer(
[email protected]43410e92012-04-20 17:06:285760 attrib, info->size(), info->type(), info->normalized(), info->gl_stride(),
[email protected]b1122982010-05-17 23:04:245761 ptr);
[email protected]c6aef902012-02-14 03:31:425762 if (info->divisor())
[email protected]43410e92012-04-20 17:06:285763 glVertexAttribDivisorANGLE(attrib, info->divisor());
[email protected]e259eb412012-10-13 05:47:245764 glBindBuffer(
5765 GL_ARRAY_BUFFER,
5766 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:285767
[email protected]265f8992012-07-20 01:03:145768 // Never touch vertex attribute 0's state (in particular, never
5769 // disable it) when running on desktop GL because it will never be
5770 // re-enabled.
5771 if (attrib != 0 ||
5772 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
5773 if (info->enabled()) {
5774 glEnableVertexAttribArray(attrib);
5775 } else {
5776 glDisableVertexAttribArray(attrib);
5777 }
[email protected]43410e92012-04-20 17:06:285778 }
[email protected]b1122982010-05-17 23:04:245779}
[email protected]07f54fcc2009-12-22 02:46:305780
[email protected]8fbedc02010-11-18 18:43:405781bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:435782 const char* function_name,
[email protected]c6aef902012-02-14 03:31:425783 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:405784 DCHECK(simulated);
5785 *simulated = false;
5786 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
5787 return true;
5788
[email protected]e259eb412012-10-13 05:47:245789 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:405790 return true;
5791 }
5792
[email protected]0f8afe82012-05-14 23:43:015793 PerformanceWarning(
5794 "GL_FIXED attributes have a signficant performance penalty");
5795
[email protected]8fbedc02010-11-18 18:43:405796 // NOTE: we could be smart and try to check if a buffer is used
5797 // twice in 2 different attribs, find the overlapping parts and therefore
5798 // duplicate the minimum amount of data but this whole code path is not meant
5799 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
5800 // tests so we just add to the buffer attrib used.
5801
[email protected]c13e1da62011-09-09 21:48:305802 GLuint elements_needed = 0;
[email protected]8fbedc02010-11-18 18:43:405803 const VertexAttribManager::VertexAttribInfoList& infos =
[email protected]e259eb412012-10-13 05:47:245804 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos();
[email protected]8fbedc02010-11-18 18:43:405805 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
5806 infos.begin(); it != infos.end(); ++it) {
5807 const VertexAttribManager::VertexAttribInfo* info = *it;
5808 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245809 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]c6aef902012-02-14 03:31:425810 GLuint max_accessed = info->MaxVertexAccessed(primcount,
5811 max_vertex_accessed);
5812 GLuint num_vertices = max_accessed + 1;
5813 if (num_vertices == 0) {
[email protected]ad84a3a2012-06-08 21:42:435814 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425815 return false;
5816 }
[email protected]8fbedc02010-11-18 18:43:405817 if (attrib_info &&
[email protected]c6aef902012-02-14 03:31:425818 info->CanAccess(max_accessed) &&
[email protected]8fbedc02010-11-18 18:43:405819 info->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:475820 uint32 elements_used = 0;
5821 if (!SafeMultiplyUint32(num_vertices, info->size(), &elements_used) ||
5822 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ad84a3a2012-06-08 21:42:435823 SetGLError(
5824 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405825 return false;
5826 }
5827 }
5828 }
5829
[email protected]3aad1a32012-09-07 20:54:475830 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
5831 uint32 size_needed = 0;
5832 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305833 size_needed > 0x7FFFFFFFU) {
[email protected]ad84a3a2012-06-08 21:42:435834 SetGLError(GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405835 return false;
5836 }
5837
[email protected]c13e1da62011-09-09 21:48:305838 CopyRealGLErrorsToWrapper();
[email protected]8fbedc02010-11-18 18:43:405839
5840 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:305841 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:405842 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305843 GLenum error = glGetError();
5844 if (error != GL_NO_ERROR) {
[email protected]ad84a3a2012-06-08 21:42:435845 SetGLError(
5846 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:305847 return false;
5848 }
[email protected]8fbedc02010-11-18 18:43:405849 }
5850
5851 // Copy the elements and convert to float
5852 GLintptr offset = 0;
5853 for (VertexAttribManager::VertexAttribInfoList::const_iterator it =
5854 infos.begin(); it != infos.end(); ++it) {
5855 const VertexAttribManager::VertexAttribInfo* info = *it;
5856 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
[email protected]e259eb412012-10-13 05:47:245857 state_.current_program->GetAttribInfoByLocation(info->index());
[email protected]c6aef902012-02-14 03:31:425858 GLuint max_accessed = info->MaxVertexAccessed(primcount,
5859 max_vertex_accessed);
5860 GLuint num_vertices = max_accessed + 1;
5861 if (num_vertices == 0) {
[email protected]ad84a3a2012-06-08 21:42:435862 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425863 return false;
5864 }
[email protected]8fbedc02010-11-18 18:43:405865 if (attrib_info &&
[email protected]c6aef902012-02-14 03:31:425866 info->CanAccess(max_accessed) &&
[email protected]8fbedc02010-11-18 18:43:405867 info->type() == GL_FIXED) {
5868 int num_elements = info->size() * kSizeOfFloat;
5869 int size = num_elements * num_vertices;
5870 scoped_array<float> data(new float[size]);
5871 const int32* src = reinterpret_cast<const int32 *>(
5872 info->buffer()->GetRange(info->offset(), size));
5873 const int32* end = src + num_elements;
5874 float* dst = data.get();
5875 while (src != end) {
5876 *dst++ = static_cast<float>(*src++) / 65536.0f;
5877 }
5878 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
5879 glVertexAttribPointer(
5880 info->index(), info->size(), GL_FLOAT, false, 0,
5881 reinterpret_cast<GLvoid*>(offset));
5882 offset += size;
5883 }
5884 }
5885 *simulated = true;
5886 return true;
5887}
5888
5889void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
5890 // There's no need to call glVertexAttribPointer because we shadow all the
5891 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:245892 glBindBuffer(
5893 GL_ARRAY_BUFFER,
5894 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]8fbedc02010-11-18 18:43:405895}
5896
[email protected]ad84a3a2012-06-08 21:42:435897error::Error GLES2DecoderImpl::DoDrawArrays(
5898 const char* function_name,
5899 bool instanced,
5900 GLenum mode,
5901 GLint first,
5902 GLsizei count,
5903 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:085904 if (ShouldDeferDraws())
5905 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:435906 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]f80e6e12012-08-31 00:43:535907 SetGLErrorInvalidEnum(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:435908 return error::kNoError;
5909 }
5910 if (count < 0) {
[email protected]ad84a3a2012-06-08 21:42:435911 SetGLError(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:435912 return error::kNoError;
5913 }
[email protected]c6aef902012-02-14 03:31:425914 if (primcount < 0) {
[email protected]ad84a3a2012-06-08 21:42:435915 SetGLError(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:425916 return error::kNoError;
5917 }
[email protected]ad84a3a2012-06-08 21:42:435918 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:435919 return error::kNoError;
5920 }
5921 // We have to check this here because the prototype for glDrawArrays
5922 // is GLint not GLsizei.
5923 if (first < 0) {
[email protected]ad84a3a2012-06-08 21:42:435924 SetGLError(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:435925 return error::kNoError;
5926 }
5927
[email protected]c6aef902012-02-14 03:31:425928 if (count == 0 || (instanced && primcount == 0)) {
[email protected]0f8afe82012-05-14 23:43:015929 RenderWarning("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:435930 return error::kNoError;
5931 }
5932
5933 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:435934 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:205935 if (!ClearUnclearedTextures()) {
[email protected]ad84a3a2012-06-08 21:42:435936 SetGLError(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:205937 return error::kNoError;
5938 }
[email protected]c13e1da62011-09-09 21:48:305939 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:435940 if (!SimulateAttrib0(
5941 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:305942 return error::kNoError;
5943 }
[email protected]38d139d2011-07-14 00:38:435944 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:435945 if (SimulateFixedAttribs(
5946 function_name, max_vertex_accessed, &simulated_fixed_attribs,
5947 primcount)) {
[email protected]38d139d2011-07-14 00:38:435948 bool textures_set = SetBlackTextureForNonRenderableTextures();
5949 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:425950 if (!instanced) {
5951 glDrawArrays(mode, first, count);
5952 } else {
5953 glDrawArraysInstancedANGLE(mode, first, count, primcount);
5954 }
[email protected]22e3f552012-03-13 01:54:195955 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:435956 if (textures_set) {
5957 RestoreStateForNonRenderableTextures();
5958 }
5959 if (simulated_fixed_attribs) {
5960 RestoreStateForSimulatedFixedAttribs();
5961 }
5962 }
5963 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:285964 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:435965 }
[email protected]38d139d2011-07-14 00:38:435966 }
5967 return error::kNoError;
5968}
5969
[email protected]c6aef902012-02-14 03:31:425970error::Error GLES2DecoderImpl::HandleDrawArrays(
5971 uint32 immediate_data_size, const gles2::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:435972 return DoDrawArrays("glDrawArrays",
5973 false,
[email protected]c6aef902012-02-14 03:31:425974 static_cast<GLenum>(c.mode),
5975 static_cast<GLint>(c.first),
5976 static_cast<GLsizei>(c.count),
5977 0);
5978}
5979
5980error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
5981 uint32 immediate_data_size, const gles2::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:155982 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:425983 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:435984 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:425985 return error::kNoError;
5986 }
[email protected]ad84a3a2012-06-08 21:42:435987 return DoDrawArrays("glDrawArraysIntancedANGLE",
5988 true,
[email protected]c6aef902012-02-14 03:31:425989 static_cast<GLenum>(c.mode),
5990 static_cast<GLint>(c.first),
5991 static_cast<GLsizei>(c.count),
5992 static_cast<GLsizei>(c.primcount));
5993}
5994
[email protected]ad84a3a2012-06-08 21:42:435995error::Error GLES2DecoderImpl::DoDrawElements(
5996 const char* function_name,
5997 bool instanced,
5998 GLenum mode,
5999 GLsizei count,
6000 GLenum type,
6001 int32 offset,
6002 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086003 if (ShouldDeferDraws())
6004 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:246005 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]8eee29c2010-04-29 03:38:296006 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436007 function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296008 return error::kNoError;
6009 }
6010
[email protected]8eee29c2010-04-29 03:38:296011 if (count < 0) {
[email protected]ad84a3a2012-06-08 21:42:436012 SetGLError(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296013 return error::kNoError;
6014 }
6015 if (offset < 0) {
[email protected]ad84a3a2012-06-08 21:42:436016 SetGLError(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296017 return error::kNoError;
6018 }
[email protected]9438b012010-06-15 22:55:056019 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]f80e6e12012-08-31 00:43:536020 SetGLErrorInvalidEnum(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296021 return error::kNoError;
6022 }
[email protected]9438b012010-06-15 22:55:056023 if (!validators_->index_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536024 SetGLErrorInvalidEnum(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296025 return error::kNoError;
6026 }
[email protected]c6aef902012-02-14 03:31:426027 if (primcount < 0) {
[email protected]ad84a3a2012-06-08 21:42:436028 SetGLError(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426029 return error::kNoError;
6030 }
[email protected]8eee29c2010-04-29 03:38:296031
[email protected]ad84a3a2012-06-08 21:42:436032 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276033 return error::kNoError;
6034 }
6035
[email protected]c6aef902012-02-14 03:31:426036 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316037 return error::kNoError;
6038 }
6039
[email protected]8eee29c2010-04-29 03:38:296040 GLuint max_vertex_accessed;
[email protected]e259eb412012-10-13 05:47:246041 if (!state_.vertex_attrib_manager->element_array_buffer(
6042 )->GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) {
[email protected]8eee29c2010-04-29 03:38:296043 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436044 function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296045 return error::kNoError;
6046 }
6047
[email protected]ad84a3a2012-06-08 21:42:436048 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206049 if (!ClearUnclearedTextures()) {
[email protected]ad84a3a2012-06-08 21:42:436050 SetGLError(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206051 return error::kNoError;
6052 }
[email protected]c13e1da62011-09-09 21:48:306053 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436054 if (!SimulateAttrib0(
6055 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306056 return error::kNoError;
6057 }
[email protected]8fbedc02010-11-18 18:43:406058 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436059 if (SimulateFixedAttribs(
6060 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6061 primcount)) {
[email protected]8fbedc02010-11-18 18:43:406062 bool textures_set = SetBlackTextureForNonRenderableTextures();
[email protected]297ca1c2011-06-20 23:08:466063 ApplyDirtyState();
[email protected]8fbedc02010-11-18 18:43:406064 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]c6aef902012-02-14 03:31:426065 if (!instanced) {
6066 glDrawElements(mode, count, type, indices);
6067 } else {
6068 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6069 }
[email protected]22e3f552012-03-13 01:54:196070 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406071 if (textures_set) {
6072 RestoreStateForNonRenderableTextures();
6073 }
6074 if (simulated_fixed_attribs) {
6075 RestoreStateForSimulatedFixedAttribs();
6076 }
[email protected]ba3176a2009-12-16 18:19:466077 }
[email protected]b1122982010-05-17 23:04:246078 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286079 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246080 }
[email protected]96449d2c2009-11-25 00:01:326081 }
[email protected]f7a64ee2010-02-01 22:24:146082 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326083}
6084
[email protected]c6aef902012-02-14 03:31:426085error::Error GLES2DecoderImpl::HandleDrawElements(
6086 uint32 immediate_data_size, const gles2::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436087 return DoDrawElements("glDrawElements",
6088 false,
[email protected]c6aef902012-02-14 03:31:426089 static_cast<GLenum>(c.mode),
6090 static_cast<GLsizei>(c.count),
6091 static_cast<GLenum>(c.type),
6092 static_cast<int32>(c.index_offset),
6093 0);
6094}
6095
6096error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
6097 uint32 immediate_data_size, const gles2::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156098 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:426099 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436100 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426101 return error::kNoError;
6102 }
[email protected]ad84a3a2012-06-08 21:42:436103 return DoDrawElements("glDrawElementsInstancedANGLE",
6104 true,
[email protected]c6aef902012-02-14 03:31:426105 static_cast<GLenum>(c.mode),
6106 static_cast<GLsizei>(c.count),
6107 static_cast<GLenum>(c.type),
6108 static_cast<int32>(c.index_offset),
6109 static_cast<GLsizei>(c.primcount));
6110}
6111
[email protected]269200b12010-11-18 22:53:066112GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236113 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6114 GLuint max_vertex_accessed = 0;
6115 BufferManager::BufferInfo* info = GetBufferInfo(buffer_id);
[email protected]8eee29c2010-04-29 03:38:296116 if (!info) {
[email protected]ae51d192010-04-27 00:48:036117 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]8eee29c2010-04-29 03:38:296118 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436119 "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236120 } else {
6121 if (!info->GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036122 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]269200b12010-11-18 22:53:066123 SetGLError(
6124 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436125 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236126 }
6127 }
6128 return max_vertex_accessed;
6129}
6130
[email protected]96449d2c2009-11-25 00:01:326131// Calls glShaderSource for the various versions of the ShaderSource command.
6132// Assumes that data / data_size points to a piece of memory that is in range
6133// of whatever context it came from (shared memory, immediate memory, bucket
6134// memory.)
[email protected]45bf5152010-02-12 00:11:316135error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036136 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576137 std::string str(data, data + data_size);
[email protected]6b8cf1a2010-05-06 16:13:586138 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6139 client_id, "glShaderSource");
[email protected]45bf5152010-02-12 00:11:316140 if (!info) {
[email protected]45bf5152010-02-12 00:11:316141 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326142 }
[email protected]45bf5152010-02-12 00:11:316143 // Note: We don't actually call glShaderSource here. We wait until
6144 // the call to glCompileShader.
[email protected]258a3313f2011-10-18 20:13:576145 info->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146146 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326147}
6148
[email protected]f7a64ee2010-02-01 22:24:146149error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]b9849abf2009-11-25 19:13:196150 uint32 immediate_data_size, const gles2::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326151 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316152 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326153 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466154 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146155 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326156 }
[email protected]ae51d192010-04-27 00:48:036157 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326158}
6159
[email protected]f7a64ee2010-02-01 22:24:146160error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]b9849abf2009-11-25 19:13:196161 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:326162 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316163 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:306164 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:466165 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146166 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326167 }
[email protected]ae51d192010-04-27 00:48:036168 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:316169}
6170
[email protected]558847a2010-03-24 07:02:546171error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
6172 uint32 immediate_data_size, const gles2::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546173 Bucket* bucket = GetBucket(c.data_bucket_id);
6174 if (!bucket || bucket->size() == 0) {
6175 return error::kInvalidArguments;
6176 }
6177 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036178 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546179 bucket->size() - 1);
6180}
6181
[email protected]ae51d192010-04-27 00:48:036182void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386183 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]6b8cf1a2010-05-06 16:13:586184 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6185 client_id, "glCompileShader");
[email protected]45bf5152010-02-12 00:11:316186 if (!info) {
[email protected]45bf5152010-02-12 00:11:316187 return;
6188 }
[email protected]f57bb282010-11-12 00:51:346189 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186190 if (use_shader_translator_) {
[email protected]f57bb282010-11-12 00:51:346191 translator = info->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456192 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416193 }
[email protected]de17df392010-04-23 21:09:416194
[email protected]65dfc602012-07-23 20:39:396195 program_manager()->DoCompileShader(info, translator, feature_info_);
[email protected]45bf5152010-02-12 00:11:316196};
6197
[email protected]ddd968b82010-03-02 00:44:296198void GLES2DecoderImpl::DoGetShaderiv(
6199 GLuint shader, GLenum pname, GLint* params) {
[email protected]6b8cf1a2010-05-06 16:13:586200 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6201 shader, "glGetShaderiv");
[email protected]ddd968b82010-03-02 00:44:296202 if (!info) {
[email protected]ddd968b82010-03-02 00:44:296203 return;
6204 }
[email protected]8f1ccdac2010-05-19 21:01:486205 switch (pname) {
6206 case GL_SHADER_SOURCE_LENGTH:
[email protected]df6cf1ad2011-01-29 01:20:526207 *params = info->source() ? info->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486208 return;
6209 case GL_COMPILE_STATUS:
[email protected]062c38b2012-01-18 03:25:106210 *params = compile_shader_always_succeeds_ ? true : info->IsValid();
[email protected]e5186162010-06-14 18:54:416211 return;
[email protected]8f1ccdac2010-05-19 21:01:486212 case GL_INFO_LOG_LENGTH:
[email protected]df6cf1ad2011-01-29 01:20:526213 *params = info->log_info() ? info->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416214 return;
[email protected]d6a53e42011-10-05 00:09:366215 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]c447acd2012-07-23 23:48:416216 ForceCompileShaderIfPending(info);
[email protected]d6a53e42011-10-05 00:09:366217 *params = info->translated_source() ?
6218 info->translated_source()->size() + 1 : 0;
6219 return;
[email protected]8f1ccdac2010-05-19 21:01:486220 default:
6221 break;
[email protected]ddd968b82010-03-02 00:44:296222 }
[email protected]8f1ccdac2010-05-19 21:01:486223 glGetShaderiv(info->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296224}
6225
[email protected]ae51d192010-04-27 00:48:036226error::Error GLES2DecoderImpl::HandleGetShaderSource(
6227 uint32 immediate_data_size, const gles2::GetShaderSource& c) {
6228 GLuint shader = c.shader;
[email protected]ae51d192010-04-27 00:48:036229 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6230 Bucket* bucket = CreateBucket(bucket_id);
[email protected]6b8cf1a2010-05-06 16:13:586231 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6232 shader, "glGetShaderSource");
[email protected]df6cf1ad2011-01-29 01:20:526233 if (!info || !info->source()) {
[email protected]8eee29c2010-04-29 03:38:296234 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296235 return error::kNoError;
6236 }
[email protected]df6cf1ad2011-01-29 01:20:526237 bucket->SetFromString(info->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036238 return error::kNoError;
6239}
6240
[email protected]d6a53e42011-10-05 00:09:366241error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6242 uint32 immediate_data_size,
6243 const gles2::GetTranslatedShaderSourceANGLE& c) {
6244 GLuint shader = c.shader;
6245
6246 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6247 Bucket* bucket = CreateBucket(bucket_id);
6248 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6249 shader, "glTranslatedGetShaderSourceANGLE");
6250 if (!info) {
6251 bucket->SetSize(0);
6252 return error::kNoError;
6253 }
[email protected]c447acd2012-07-23 23:48:416254 ForceCompileShaderIfPending(info);
[email protected]d6a53e42011-10-05 00:09:366255
6256 bucket->SetFromString(info->translated_source() ?
6257 info->translated_source()->c_str() : NULL);
6258 return error::kNoError;
6259}
6260
[email protected]ae51d192010-04-27 00:48:036261error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
6262 uint32 immediate_data_size, const gles2::GetProgramInfoLog& c) {
6263 GLuint program = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586264 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6265 Bucket* bucket = CreateBucket(bucket_id);
6266 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6267 program, "glGetProgramInfoLog");
[email protected]df6cf1ad2011-01-29 01:20:526268 if (!info || !info->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466269 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036270 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316271 }
[email protected]df6cf1ad2011-01-29 01:20:526272 bucket->SetFromString(info->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036273 return error::kNoError;
6274}
6275
6276error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
6277 uint32 immediate_data_size, const gles2::GetShaderInfoLog& c) {
6278 GLuint shader = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586279 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6280 Bucket* bucket = CreateBucket(bucket_id);
6281 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram(
6282 shader, "glGetShaderInfoLog");
[email protected]df6cf1ad2011-01-29 01:20:526283 if (!info || !info->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466284 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036285 return error::kNoError;
6286 }
[email protected]df6cf1ad2011-01-29 01:20:526287 bucket->SetFromString(info->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036288 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326289}
6290
[email protected]d058bca2012-11-26 10:27:266291bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6292 return state_.GetEnabled(cap);
6293}
6294
[email protected]1958e0e2010-04-22 05:17:156295bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106296 const BufferManager::BufferInfo* buffer = GetBufferInfo(client_id);
6297 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156298}
6299
6300bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106301 const FramebufferManager::FramebufferInfo* framebuffer =
[email protected]06c8b082011-01-05 18:00:366302 GetFramebufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:106303 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156304}
6305
6306bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366307 // IsProgram is true for programs as soon as they are created, until they are
6308 // deleted and no longer in use.
[email protected]a0b78dc2011-11-11 10:43:106309 const ProgramManager::ProgramInfo* program = GetProgramInfo(client_id);
6310 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156311}
6312
6313bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106314 const RenderbufferManager::RenderbufferInfo* renderbuffer =
[email protected]06c8b082011-01-05 18:00:366315 GetRenderbufferInfo(client_id);
[email protected]a0b78dc2011-11-11 10:43:106316 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156317}
6318
6319bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366320 // IsShader is true for shaders as soon as they are created, until they
6321 // are deleted and not attached to any programs.
[email protected]a0b78dc2011-11-11 10:43:106322 const ShaderManager::ShaderInfo* shader = GetShaderInfo(client_id);
6323 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156324}
6325
6326bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]a0b78dc2011-11-11 10:43:106327 const TextureManager::TextureInfo* texture = GetTextureInfo(client_id);
6328 return texture && texture->IsValid() && !texture->IsDeleted();
[email protected]ae51d192010-04-27 00:48:036329}
6330
6331void GLES2DecoderImpl::DoAttachShader(
6332 GLuint program_client_id, GLint shader_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:586333 ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader(
6334 program_client_id, "glAttachShader");
[email protected]ae51d192010-04-27 00:48:036335 if (!program_info) {
[email protected]ae51d192010-04-27 00:48:036336 return;
[email protected]1958e0e2010-04-22 05:17:156337 }
[email protected]6b8cf1a2010-05-06 16:13:586338 ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram(
6339 shader_client_id, "glAttachShader");
[email protected]ae51d192010-04-27 00:48:036340 if (!shader_info) {
[email protected]ae51d192010-04-27 00:48:036341 return;
6342 }
[email protected]ca488e12010-12-13 20:06:146343 if (!program_info->AttachShader(shader_manager(), shader_info)) {
[email protected]fb96c8e2010-08-12 04:10:316344 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436345 "glAttachShader", "can not attach more than"
[email protected]fb96c8e2010-08-12 04:10:316346 " one shader of the same type.");
6347 return;
6348 }
[email protected]ae51d192010-04-27 00:48:036349 glAttachShader(program_info->service_id(), shader_info->service_id());
6350}
6351
6352void GLES2DecoderImpl::DoDetachShader(
6353 GLuint program_client_id, GLint shader_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:586354 ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader(
6355 program_client_id, "glDetachShader");
[email protected]ae51d192010-04-27 00:48:036356 if (!program_info) {
[email protected]ae51d192010-04-27 00:48:036357 return;
6358 }
[email protected]6b8cf1a2010-05-06 16:13:586359 ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram(
6360 shader_client_id, "glDetachShader");
[email protected]ae51d192010-04-27 00:48:036361 if (!shader_info) {
[email protected]ae51d192010-04-27 00:48:036362 return;
6363 }
[email protected]9a0ccd42011-03-16 23:58:226364 if (!program_info->DetachShader(shader_manager(), shader_info)) {
6365 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436366 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226367 return;
6368 }
[email protected]ae51d192010-04-27 00:48:036369 glDetachShader(program_info->service_id(), shader_info->service_id());
6370}
6371
6372void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]6b8cf1a2010-05-06 16:13:586373 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6374 program_client_id, "glValidateProgram");
[email protected]ae51d192010-04-27 00:48:036375 if (!info) {
[email protected]ae51d192010-04-27 00:48:036376 return;
6377 }
[email protected]d685a682011-04-29 16:19:576378 info->Validate();
[email protected]1958e0e2010-04-22 05:17:156379}
6380
[email protected]b1122982010-05-17 23:04:246381void GLES2DecoderImpl::DoGetVertexAttribfv(
6382 GLuint index, GLenum pname, GLfloat* params) {
6383 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246384 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246385 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436386 SetGLError(GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]b1122982010-05-17 23:04:246387 return;
6388 }
6389 switch (pname) {
6390 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
6391 BufferManager::BufferInfo* buffer = info->buffer();
6392 if (buffer && !buffer->IsDeleted()) {
6393 GLuint client_id;
6394 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6395 *params = static_cast<GLfloat>(client_id);
6396 }
6397 break;
6398 }
6399 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
6400 *params = static_cast<GLfloat>(info->enabled());
6401 break;
6402 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
6403 *params = static_cast<GLfloat>(info->size());
6404 break;
6405 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
6406 *params = static_cast<GLfloat>(info->gl_stride());
6407 break;
6408 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
6409 *params = static_cast<GLfloat>(info->type());
6410 break;
6411 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
6412 *params = static_cast<GLfloat>(info->normalized());
6413 break;
[email protected]af6380962012-11-29 23:24:136414 case GL_CURRENT_VERTEX_ATTRIB: {
6415 const Vec4& value = state_.attrib_values[index];
6416 params[0] = value.v[0];
6417 params[1] = value.v[1];
6418 params[2] = value.v[2];
6419 params[3] = value.v[3];
[email protected]b1122982010-05-17 23:04:246420 break;
[email protected]af6380962012-11-29 23:24:136421 }
[email protected]c6aef902012-02-14 03:31:426422 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
6423 *params = static_cast<GLfloat>(info->divisor());
6424 break;
[email protected]b1122982010-05-17 23:04:246425 default:
6426 NOTREACHED();
6427 break;
6428 }
6429}
6430
6431void GLES2DecoderImpl::DoGetVertexAttribiv(
6432 GLuint index, GLenum pname, GLint* params) {
6433 VertexAttribManager::VertexAttribInfo* info =
[email protected]e259eb412012-10-13 05:47:246434 state_.vertex_attrib_manager->GetVertexAttribInfo(index);
[email protected]b1122982010-05-17 23:04:246435 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:436436 SetGLError(GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]b1122982010-05-17 23:04:246437 return;
6438 }
6439 switch (pname) {
6440 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
6441 BufferManager::BufferInfo* buffer = info->buffer();
6442 if (buffer && !buffer->IsDeleted()) {
6443 GLuint client_id;
6444 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6445 *params = client_id;
6446 }
6447 break;
6448 }
6449 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
6450 *params = info->enabled();
6451 break;
6452 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
6453 *params = info->size();
6454 break;
6455 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
6456 *params = info->gl_stride();
6457 break;
6458 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
6459 *params = info->type();
6460 break;
6461 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
6462 *params = static_cast<GLint>(info->normalized());
6463 break;
[email protected]c6aef902012-02-14 03:31:426464 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
6465 *params = info->divisor();
6466 break;
[email protected]af6380962012-11-29 23:24:136467 case GL_CURRENT_VERTEX_ATTRIB: {
6468 const Vec4& value = state_.attrib_values[index];
6469 params[0] = static_cast<GLint>(value.v[0]);
6470 params[1] = static_cast<GLint>(value.v[1]);
6471 params[2] = static_cast<GLint>(value.v[2]);
6472 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246473 break;
[email protected]af6380962012-11-29 23:24:136474 }
[email protected]b1122982010-05-17 23:04:246475 default:
6476 NOTREACHED();
6477 break;
6478 }
6479}
6480
[email protected]af6380962012-11-29 23:24:136481bool GLES2DecoderImpl::SetVertexAttribValue(
6482 const char* function_name, GLuint index, const GLfloat* value) {
6483 if (index >= state_.attrib_values.size()) {
6484 SetGLError(GL_INVALID_VALUE, function_name, "index out of range");
6485 return false;
[email protected]b1122982010-05-17 23:04:246486 }
[email protected]af6380962012-11-29 23:24:136487 Vec4& v = state_.attrib_values[index];
6488 v.v[0] = value[0];
6489 v.v[1] = value[1];
6490 v.v[2] = value[2];
6491 v.v[3] = value[3];
6492 return true;
6493}
6494
6495void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6496 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6497 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6498 glVertexAttrib1f(index, v0);
6499 }
[email protected]b1122982010-05-17 23:04:246500}
6501
6502void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136503 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6504 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6505 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246506 }
[email protected]b1122982010-05-17 23:04:246507}
6508
6509void GLES2DecoderImpl::DoVertexAttrib3f(
6510 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136511 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6512 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6513 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246514 }
[email protected]b1122982010-05-17 23:04:246515}
6516
6517void GLES2DecoderImpl::DoVertexAttrib4f(
6518 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136519 GLfloat v[4] = { v0, v1, v2, v3, };
6520 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6521 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246522 }
[email protected]b1122982010-05-17 23:04:246523}
6524
6525void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136526 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6527 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6528 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246529 }
[email protected]b1122982010-05-17 23:04:246530}
6531
6532void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136533 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6534 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6535 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246536 }
[email protected]b1122982010-05-17 23:04:246537}
6538
6539void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136540 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6541 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6542 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246543 }
[email protected]b1122982010-05-17 23:04:246544}
6545
6546void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136547 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6548 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246549 }
[email protected]b1122982010-05-17 23:04:246550}
6551
[email protected]f7a64ee2010-02-01 22:24:146552error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]b9849abf2009-11-25 19:13:196553 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466554
[email protected]e259eb412012-10-13 05:47:246555 if (!state_.bound_array_buffer || state_.bound_array_buffer->IsDeleted()) {
6556 if (state_.vertex_attrib_manager == default_vertex_attrib_manager_) {
[email protected]944b62f32012-09-27 02:20:466557 SetGLError(GL_INVALID_VALUE,
6558 "glVertexAttribPointer", "no array buffer bound");
6559 return error::kNoError;
6560 } else if (c.offset != 0) {
6561 SetGLError(GL_INVALID_VALUE,
6562 "glVertexAttribPointer", "client side arrays are not allowed");
6563 return error::kNoError;
6564 }
[email protected]96449d2c2009-11-25 00:01:326565 }
[email protected]8eee29c2010-04-29 03:38:296566
6567 GLuint indx = c.indx;
6568 GLint size = c.size;
6569 GLenum type = c.type;
6570 GLboolean normalized = c.normalized;
6571 GLsizei stride = c.stride;
6572 GLsizei offset = c.offset;
6573 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056574 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536575 SetGLErrorInvalidEnum("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296576 return error::kNoError;
6577 }
[email protected]9438b012010-06-15 22:55:056578 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ff81c192011-01-07 23:04:316579 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436580 "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296581 return error::kNoError;
6582 }
6583 if (indx >= group_->max_vertex_attribs()) {
[email protected]ad84a3a2012-06-08 21:42:436584 SetGLError(GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296585 return error::kNoError;
6586 }
6587 if (stride < 0) {
6588 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436589 "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296590 return error::kNoError;
6591 }
6592 if (stride > 255) {
6593 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436594 "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296595 return error::kNoError;
6596 }
6597 if (offset < 0) {
6598 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436599 "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296600 return error::kNoError;
6601 }
6602 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316603 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296604 if (offset % component_size > 0) {
[email protected]ff81c192011-01-07 23:04:316605 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436606 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316607 return error::kNoError;
6608 }
6609 if (stride % component_size > 0) {
6610 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436611 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296612 return error::kNoError;
6613 }
[email protected]e259eb412012-10-13 05:47:246614 state_.vertex_attrib_manager->SetAttribInfo(
[email protected]8fbedc02010-11-18 18:43:406615 indx,
[email protected]e259eb412012-10-13 05:47:246616 state_.bound_array_buffer,
[email protected]8eee29c2010-04-29 03:38:296617 size,
6618 type,
[email protected]b1122982010-05-17 23:04:246619 normalized,
6620 stride,
6621 stride != 0 ? stride : component_size * size,
[email protected]8eee29c2010-04-29 03:38:296622 offset);
[email protected]8fbedc02010-11-18 18:43:406623 if (type != GL_FIXED) {
6624 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6625 }
[email protected]f7a64ee2010-02-01 22:24:146626 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326627}
6628
[email protected]43410e92012-04-20 17:06:286629void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6630 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246631 state_.viewport_x = x;
6632 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026633 state_.viewport_width = std::min(width, viewport_max_width_);
6634 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286635 glViewport(x, y, width, height);
6636}
6637
[email protected]c6aef902012-02-14 03:31:426638error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
6639 uint32 immediate_data_size, const gles2::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156640 if (!features().angle_instanced_arrays) {
[email protected]c6aef902012-02-14 03:31:426641 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436642 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426643 }
6644 GLuint index = c.index;
6645 GLuint divisor = c.divisor;
6646 if (index >= group_->max_vertex_attribs()) {
6647 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436648 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426649 return error::kNoError;
6650 }
6651
[email protected]e259eb412012-10-13 05:47:246652 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426653 index,
6654 divisor);
6655 glVertexAttribDivisorANGLE(index, divisor);
6656 return error::kNoError;
6657}
6658
[email protected]f7a64ee2010-02-01 22:24:146659error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]b9849abf2009-11-25 19:13:196660 uint32 immediate_data_size, const gles2::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:446661 if (ShouldDeferReads())
6662 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:316663 GLint x = c.x;
6664 GLint y = c.y;
6665 GLsizei width = c.width;
6666 GLsizei height = c.height;
6667 GLenum format = c.format;
6668 GLenum type = c.type;
[email protected]57f223832010-03-19 01:57:566669 if (width < 0 || height < 0) {
[email protected]ad84a3a2012-06-08 21:42:436670 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566671 return error::kNoError;
6672 }
[email protected]a51788e2010-02-24 21:54:256673 typedef gles2::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186674 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346675 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246676 width, height, format, type, state_.pack_alignment, &pixels_size,
6677 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186678 return error::kOutOfBounds;
6679 }
[email protected]612d2f82009-12-08 20:49:316680 void* pixels = GetSharedMemoryAs<void*>(
6681 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]a51788e2010-02-24 21:54:256682 Result* result = GetSharedMemoryAs<Result*>(
6683 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6684 if (!pixels || !result) {
[email protected]f7a64ee2010-02-01 22:24:146685 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466686 }
[email protected]a51788e2010-02-24 21:54:256687
[email protected]9438b012010-06-15 22:55:056688 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:536689 SetGLErrorInvalidEnum("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296690 return error::kNoError;
6691 }
[email protected]9438b012010-06-15 22:55:056692 if (!validators_->pixel_type.IsValid(type)) {
[email protected]f80e6e12012-08-31 00:43:536693 SetGLErrorInvalidEnum("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:126694 return error::kNoError;
6695 }
[email protected]57f223832010-03-19 01:57:566696 if (width == 0 || height == 0) {
6697 return error::kNoError;
6698 }
6699
[email protected]57f223832010-03-19 01:57:566700 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:306701 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:566702
[email protected]3aad1a32012-09-07 20:54:476703 int32 max_x;
6704 int32 max_y;
6705 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ad84a3a2012-06-08 21:42:436706 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:146707 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:316708 }
[email protected]57f223832010-03-19 01:57:566709
[email protected]0d6bfdc2011-11-02 01:32:206710 if (!CheckBoundFramebuffersValid("glReadPixels")) {
6711 return error::kNoError;
6712 }
6713
[email protected]a0b78dc2011-11-11 10:43:106714 CopyRealGLErrorsToWrapper();
6715
6716 ScopedResolvedFrameBufferBinder binder(this, false, true);
6717
[email protected]d37231fa2010-04-09 21:16:026718 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:566719 // The user requested an out of range area. Get the results 1 line
6720 // at a time.
6721 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346722 uint32 unpadded_row_size;
6723 uint32 padded_row_size;
6724 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246725 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346726 &unpadded_row_size, &padded_row_size)) {
[email protected]ad84a3a2012-06-08 21:42:436727 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566728 return error::kNoError;
6729 }
6730
6731 GLint dest_x_offset = std::max(-x, 0);
6732 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:346733 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246734 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
6735 NULL, NULL)) {
[email protected]ad84a3a2012-06-08 21:42:436736 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566737 return error::kNoError;
6738 }
6739
6740 // Copy each row into the larger dest rect.
6741 int8* dst = static_cast<int8*>(pixels);
6742 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:026743 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:566744 GLint read_width = read_end_x - read_x;
6745 for (GLint yy = 0; yy < height; ++yy) {
6746 GLint ry = y + yy;
6747
6748 // Clear the row.
6749 memset(dst, 0, unpadded_row_size);
6750
6751 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:026752 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:566753 glReadPixels(
6754 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6755 }
6756 dst += padded_row_size;
6757 }
6758 } else {
6759 glReadPixels(x, y, width, height, format, type, pixels);
6760 }
[email protected]1002c2d2011-06-28 22:39:046761 GLenum error = PeekGLError();
[email protected]a51788e2010-02-24 21:54:256762 if (error == GL_NO_ERROR) {
6763 *result = true;
[email protected]4848b9f82011-03-10 18:37:566764
6765 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6766 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
[email protected]84eb4252012-06-29 22:56:446767 if ((channels_exist & 0x0008) == 0 &&
[email protected]62e155e2012-10-23 22:43:156768 workarounds().clear_alpha_in_readpixels) {
[email protected]4848b9f82011-03-10 18:37:566769 // Set the alpha to 255 because some drivers are buggy in this regard.
6770 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346771
6772 uint32 unpadded_row_size;
6773 uint32 padded_row_size;
6774 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246775 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346776 &unpadded_row_size, &padded_row_size)) {
[email protected]ad84a3a2012-06-08 21:42:436777 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]4848b9f82011-03-10 18:37:566778 return error::kNoError;
6779 }
6780 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6781 // of this implementation.
6782 if (type != GL_UNSIGNED_BYTE) {
[email protected]ad84a3a2012-06-08 21:42:436783 SetGLError(
6784 GL_INVALID_OPERATION, "glReadPixels",
6785 "unsupported readPixel format");
[email protected]4848b9f82011-03-10 18:37:566786 return error::kNoError;
6787 }
6788 switch (format) {
6789 case GL_RGBA:
[email protected]297ca1c2011-06-20 23:08:466790 case GL_BGRA_EXT:
[email protected]4848b9f82011-03-10 18:37:566791 case GL_ALPHA: {
6792 int offset = (format == GL_ALPHA) ? 0 : 3;
6793 int step = (format == GL_ALPHA) ? 1 : 4;
6794 uint8* dst = static_cast<uint8*>(pixels) + offset;
6795 for (GLint yy = 0; yy < height; ++yy) {
6796 uint8* end = dst + unpadded_row_size;
6797 for (uint8* d = dst; d < end; d += step) {
6798 *d = 255;
6799 }
6800 dst += padded_row_size;
6801 }
6802 break;
6803 }
6804 default:
6805 break;
6806 }
6807 }
[email protected]a51788e2010-02-24 21:54:256808 }
[email protected]4848b9f82011-03-10 18:37:566809
[email protected]f7a64ee2010-02-01 22:24:146810 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326811}
6812
[email protected]f7a64ee2010-02-01 22:24:146813error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]b9849abf2009-11-25 19:13:196814 uint32 immediate_data_size, const gles2::PixelStorei& c) {
6815 GLenum pname = c.pname;
6816 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:056817 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]f80e6e12012-08-31 00:43:536818 SetGLErrorInvalidEnum("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:126819 return error::kNoError;
6820 }
[email protected]222471d2011-11-30 18:06:396821 switch (pname) {
6822 case GL_PACK_ALIGNMENT:
6823 case GL_UNPACK_ALIGNMENT:
6824 if (!validators_->pixel_store_alignment.IsValid(param)) {
6825 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:436826 "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:396827 return error::kNoError;
6828 }
[email protected]164d6d52012-05-05 00:55:036829 break;
[email protected]0a1e9ad2012-05-04 21:13:036830 case GL_UNPACK_FLIP_Y_CHROMIUM:
6831 unpack_flip_y_ = (param != 0);
6832 return error::kNoError;
6833 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
6834 unpack_premultiply_alpha_ = (param != 0);
6835 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:176836 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
6837 unpack_unpremultiply_alpha_ = (param != 0);
6838 return error::kNoError;
[email protected]222471d2011-11-30 18:06:396839 default:
6840 break;
[email protected]b9849abf2009-11-25 19:13:196841 }
6842 glPixelStorei(pname, param);
6843 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:436844 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246845 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436846 break;
6847 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:426848 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:436849 break;
6850 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246851 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436852 break;
6853 default:
6854 // Validation should have prevented us from getting here.
6855 NOTREACHED();
6856 break;
[email protected]b9849abf2009-11-25 19:13:196857 }
[email protected]f7a64ee2010-02-01 22:24:146858 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196859}
6860
[email protected]1c75a3702011-11-11 14:15:286861error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
6862 uint32 immediate_data_size, const gles2::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:386863 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:456864 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]1c75a3702011-11-11 14:15:286865 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436866 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:286867 return error::kNoError;
6868 }
[email protected]7794d512012-04-17 20:36:496869 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:286870 return error::kNoError;
[email protected]7794d512012-04-17 20:36:496871 } else {
6872 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:286873 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:496874 }
[email protected]1c75a3702011-11-11 14:15:286875}
6876
[email protected]558847a2010-03-24 07:02:546877error::Error GLES2DecoderImpl::GetAttribLocationHelper(
6878 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6879 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576880 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ad84a3a2012-06-08 21:42:436881 SetGLError(GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576882 return error::kNoError;
6883 }
[email protected]6b8cf1a2010-05-06 16:13:586884 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6885 client_id, "glGetAttribLocation");
[email protected]ae51d192010-04-27 00:48:036886 if (!info) {
[email protected]f7a64ee2010-02-01 22:24:146887 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196888 }
[email protected]ae51d192010-04-27 00:48:036889 if (!info->IsValid()) {
[email protected]ad84a3a2012-06-08 21:42:436890 SetGLError(
6891 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256892 return error::kNoError;
6893 }
[email protected]b9849abf2009-11-25 19:13:196894 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:546895 location_shm_id, location_shm_offset, sizeof(GLint));
6896 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:146897 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196898 }
[email protected]558847a2010-03-24 07:02:546899 // Require the client to init this incase the context is lost and we are no
6900 // longer executing commands.
6901 if (*location != -1) {
6902 return error::kGenericError;
6903 }
[email protected]0bfd9882010-02-05 23:02:256904 *location = info->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:146905 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196906}
6907
[email protected]558847a2010-03-24 07:02:546908error::Error GLES2DecoderImpl::HandleGetAttribLocation(
6909 uint32 immediate_data_size, const gles2::GetAttribLocation& c) {
6910 uint32 name_size = c.data_size;
6911 const char* name = GetSharedMemoryAs<const char*>(
6912 c.name_shm_id, c.name_shm_offset, name_size);
6913 if (!name) {
6914 return error::kOutOfBounds;
6915 }
6916 String name_str(name, name_size);
6917 return GetAttribLocationHelper(
6918 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6919}
6920
[email protected]f7a64ee2010-02-01 22:24:146921error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]b9849abf2009-11-25 19:13:196922 uint32 immediate_data_size, const gles2::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:546923 uint32 name_size = c.data_size;
6924 const char* name = GetImmediateDataAs<const char*>(
6925 c, name_size, immediate_data_size);
6926 if (!name) {
6927 return error::kOutOfBounds;
6928 }
6929 String name_str(name, name_size);
6930 return GetAttribLocationHelper(
6931 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6932}
6933
6934error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
6935 uint32 immediate_data_size, const gles2::GetAttribLocationBucket& c) {
6936 Bucket* bucket = GetBucket(c.name_bucket_id);
6937 if (!bucket) {
6938 return error::kInvalidArguments;
6939 }
6940 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:186941 if (!bucket->GetAsString(&name_str)) {
6942 return error::kInvalidArguments;
6943 }
[email protected]558847a2010-03-24 07:02:546944 return GetAttribLocationHelper(
6945 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6946}
6947
6948error::Error GLES2DecoderImpl::GetUniformLocationHelper(
6949 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6950 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576951 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ad84a3a2012-06-08 21:42:436952 SetGLError(GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576953 return error::kNoError;
6954 }
[email protected]6b8cf1a2010-05-06 16:13:586955 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
6956 client_id, "glUniformLocation");
[email protected]ae51d192010-04-27 00:48:036957 if (!info) {
[email protected]f7a64ee2010-02-01 22:24:146958 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196959 }
[email protected]ae51d192010-04-27 00:48:036960 if (!info->IsValid()) {
[email protected]ad84a3a2012-06-08 21:42:436961 SetGLError(
6962 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256963 return error::kNoError;
6964 }
[email protected]b9849abf2009-11-25 19:13:196965 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:546966 location_shm_id, location_shm_offset, sizeof(GLint));
6967 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:146968 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196969 }
[email protected]558847a2010-03-24 07:02:546970 // Require the client to init this incase the context is lost an we are no
6971 // longer executing commands.
6972 if (*location != -1) {
6973 return error::kGenericError;
6974 }
[email protected]2be6abf32012-06-26 00:28:336975 *location = info->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:146976 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196977}
6978
[email protected]f7a64ee2010-02-01 22:24:146979error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]b9849abf2009-11-25 19:13:196980 uint32 immediate_data_size, const gles2::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:196981 uint32 name_size = c.data_size;
6982 const char* name = GetSharedMemoryAs<const char*>(
6983 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:546984 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:146985 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196986 }
6987 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:546988 return GetUniformLocationHelper(
6989 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:196990}
6991
[email protected]f7a64ee2010-02-01 22:24:146992error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]b9849abf2009-11-25 19:13:196993 uint32 immediate_data_size, const gles2::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:196994 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:306995 const char* name = GetImmediateDataAs<const char*>(
6996 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:546997 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:146998 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196999 }
7000 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547001 return GetUniformLocationHelper(
7002 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7003}
7004
7005error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
7006 uint32 immediate_data_size, const gles2::GetUniformLocationBucket& c) {
7007 Bucket* bucket = GetBucket(c.name_bucket_id);
7008 if (!bucket) {
7009 return error::kInvalidArguments;
7010 }
7011 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187012 if (!bucket->GetAsString(&name_str)) {
7013 return error::kInvalidArguments;
7014 }
[email protected]558847a2010-03-24 07:02:547015 return GetUniformLocationHelper(
7016 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197017}
7018
[email protected]ddd968b82010-03-02 00:44:297019error::Error GLES2DecoderImpl::HandleGetString(
7020 uint32 immediate_data_size, const gles2::GetString& c) {
7021 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057022 if (!validators_->string_type.IsValid(name)) {
[email protected]f80e6e12012-08-31 00:43:537023 SetGLErrorInvalidEnum("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297024 return error::kNoError;
7025 }
[email protected]1958e0e2010-04-22 05:17:157026 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
7027 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:047028 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157029 switch (name) {
7030 case GL_VERSION:
7031 str = "OpenGL ES 2.0 Chromium";
7032 break;
7033 case GL_SHADING_LANGUAGE_VERSION:
7034 str = "OpenGL ES GLSL ES 1.0 Chromium";
7035 break;
[email protected]32939602012-05-09 06:25:167036 case GL_RENDERER:
7037 str = "Chromium";
7038 break;
7039 case GL_VENDOR:
7040 str = "Chromium";
7041 break;
[email protected]1958e0e2010-04-22 05:17:157042 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047043 {
7044 // For WebGL contexts, strip out the OES derivatives extension if it has
7045 // not been enabled.
7046 if (force_webgl_glsl_validation_ &&
7047 !derivatives_explicitly_enabled_) {
7048 extensions = feature_info_->extensions();
7049 size_t offset = extensions.find(kOESDerivativeExtension);
7050 if (std::string::npos != offset) {
7051 extensions.replace(offset,
7052 offset + arraysize(kOESDerivativeExtension),
7053 std::string());
7054 }
[email protected]f0d74742011-10-03 16:31:047055 } else {
[email protected]6f5fac9d12012-06-26 21:02:457056 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047057 }
[email protected]6f5fac9d12012-06-26 21:02:457058 std::string surface_extensions = surface_->GetExtensions();
7059 if (!surface_extensions.empty())
7060 extensions += " " + surface_extensions;
7061 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047062 }
[email protected]1958e0e2010-04-22 05:17:157063 break;
7064 default:
7065 str = gl_str;
7066 break;
7067 }
[email protected]ddd968b82010-03-02 00:44:297068 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157069 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297070 return error::kNoError;
7071}
7072
[email protected]0c86dbf2010-03-05 08:14:117073void GLES2DecoderImpl::DoBufferData(
[email protected]b9363b22010-06-09 22:06:157074 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
[email protected]9438b012010-06-15 22:55:057075 if (!validators_->buffer_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:537076 SetGLErrorInvalidEnum("glBufferData", target, "target");
[email protected]8eee29c2010-04-29 03:38:297077 return;
7078 }
[email protected]9438b012010-06-15 22:55:057079 if (!validators_->buffer_usage.IsValid(usage)) {
[email protected]f80e6e12012-08-31 00:43:537080 SetGLErrorInvalidEnum("glBufferData", usage, "usage");
[email protected]0c86dbf2010-03-05 08:14:117081 return;
[email protected]3b6ec202010-03-05 05:16:237082 }
7083 if (size < 0) {
[email protected]ad84a3a2012-06-08 21:42:437084 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0");
[email protected]037896bd2010-04-21 19:07:287085 return;
[email protected]3b6ec202010-03-05 05:16:237086 }
7087 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target);
7088 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:437089 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287090 return;
[email protected]3b6ec202010-03-05 05:16:237091 }
7092 // Clear the buffer to 0 if no initial data was passed in.
7093 scoped_array<int8> zero;
7094 if (!data) {
7095 zero.reset(new int8[size]);
7096 memset(zero.get(), 0, size);
7097 data = zero.get();
7098 }
[email protected]473c01ccb2011-06-07 01:33:307099
[email protected]3b6ec202010-03-05 05:16:237100 CopyRealGLErrorsToWrapper();
7101 glBufferData(target, size, data, usage);
[email protected]1002c2d2011-06-28 22:39:047102 GLenum error = PeekGLError();
7103 if (error == GL_NO_ERROR) {
[email protected]473c01ccb2011-06-07 01:33:307104 buffer_manager()->SetInfo(info, size, usage);
[email protected]0c86dbf2010-03-05 08:14:117105 info->SetRange(0, size, data);
[email protected]a39370652012-09-25 21:52:137106 } else {
7107 buffer_manager()->SetInfo(info, 0, usage);
[email protected]3b6ec202010-03-05 05:16:237108 }
[email protected]0c86dbf2010-03-05 08:14:117109}
7110
7111error::Error GLES2DecoderImpl::HandleBufferData(
7112 uint32 immediate_data_size, const gles2::BufferData& c) {
7113 GLenum target = static_cast<GLenum>(c.target);
7114 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7115 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7116 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7117 GLenum usage = static_cast<GLenum>(c.usage);
7118 const void* data = NULL;
7119 if (data_shm_id != 0 || data_shm_offset != 0) {
7120 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7121 if (!data) {
7122 return error::kOutOfBounds;
7123 }
7124 }
7125 DoBufferData(target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147126 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197127}
7128
[email protected]f7a64ee2010-02-01 22:24:147129error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]b9849abf2009-11-25 19:13:197130 uint32 immediate_data_size, const gles2::BufferDataImmediate& c) {
7131 GLenum target = static_cast<GLenum>(c.target);
7132 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:307133 const void* data = GetImmediateDataAs<const void*>(
7134 c, size, immediate_data_size);
7135 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147136 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:307137 }
[email protected]b9849abf2009-11-25 19:13:197138 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0c86dbf2010-03-05 08:14:117139 DoBufferData(target, size, data, usage);
7140 return error::kNoError;
7141}
7142
7143void GLES2DecoderImpl::DoBufferSubData(
7144 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]3916c97e2010-02-25 03:20:507145 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477146 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:437147 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287148 return;
[email protected]a93bb842010-02-16 23:03:477149 }
[email protected]0c86dbf2010-03-05 08:14:117150 if (!info->SetRange(offset, size, data)) {
[email protected]ad84a3a2012-06-08 21:42:437151 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range");
[email protected]473c01ccb2011-06-07 01:33:307152 return;
[email protected]07f54fcc2009-12-22 02:46:307153 }
[email protected]473c01ccb2011-06-07 01:33:307154 glBufferSubData(target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197155}
7156
[email protected]0d6bfdc2011-11-02 01:32:207157bool GLES2DecoderImpl::ClearLevel(
7158 unsigned service_id,
7159 unsigned bind_target,
7160 unsigned target,
7161 int level,
7162 unsigned format,
7163 unsigned type,
7164 int width,
[email protected]4502e6492011-12-14 19:39:157165 int height,
7166 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007167 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7168 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7169 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7170 // on depth formats.
7171 GLuint fb = 0;
7172 glGenFramebuffersEXT(1, &fb);
7173 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7174
7175 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7176 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7177 GL_DEPTH_ATTACHMENT;
7178
7179 glFramebufferTexture2DEXT(
7180 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7181 // ANGLE promises a depth only attachment ok.
7182 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7183 GL_FRAMEBUFFER_COMPLETE) {
7184 return false;
7185 }
7186 glClearStencil(0);
7187 glStencilMask(-1);
7188 glClearDepth(1.0f);
7189 glDepthMask(true);
7190 glDisable(GL_SCISSOR_TEST);
7191 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7192
7193 RestoreClearState();
7194
7195 glDeleteFramebuffersEXT(1, &fb);
7196 FramebufferManager::FramebufferInfo* framebuffer =
7197 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7198 GLuint fb_service_id =
7199 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7200 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7201 return true;
7202 }
7203
[email protected]45d15a62012-04-18 14:33:177204 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7205
7206 uint32 size;
7207 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347208 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247209 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177210 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207211 return false;
7212 }
[email protected]45d15a62012-04-18 14:33:177213
[email protected]a5d3dad2012-05-26 04:34:447214 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7215
[email protected]45d15a62012-04-18 14:33:177216 int tile_height;
7217
7218 if (size > kMaxZeroSize) {
7219 if (kMaxZeroSize < padded_row_size) {
7220 // That'd be an awfully large texture.
7221 return false;
7222 }
7223 // We should never have a large total size with a zero row size.
7224 DCHECK_GT(padded_row_size, 0U);
7225 tile_height = kMaxZeroSize / padded_row_size;
7226 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247227 width, tile_height, format, type, state_.unpack_alignment, &size,
7228 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177229 return false;
7230 }
[email protected]4502e6492011-12-14 19:39:157231 } else {
[email protected]45d15a62012-04-18 14:33:177232 tile_height = height;
7233 }
7234
7235 // Assumes the size has already been checked.
7236 scoped_array<char> zero(new char[size]);
7237 memset(zero.get(), 0, size);
7238 glBindTexture(bind_target, service_id);
7239
7240 GLint y = 0;
7241 while (y < height) {
7242 GLint h = y + tile_height > height ? height - y : tile_height;
7243 if (is_texture_immutable || h != height) {
7244 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7245 } else {
7246 WrappedTexImage2D(
7247 target, level, format, width, h, 0, format, type, zero.get());
7248 }
7249 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157250 }
[email protected]0d6bfdc2011-11-02 01:32:207251 TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target);
7252 glBindTexture(bind_target, info ? info->service_id() : 0);
7253 return true;
7254}
7255
[email protected]ad84a3a2012-06-08 21:42:437256namespace {
7257
7258const int kS3TCBlockWidth = 4;
7259const int kS3TCBlockHeight = 4;
7260const int kS3TCDXT1BlockSize = 8;
7261const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077262const int kETC1BlockWidth = 4;
7263const int kETC1BlockHeight = 4;
7264const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437265
7266bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517267 return (size == 1) ||
7268 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437269}
7270
7271} // anonymous namespace.
7272
7273bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7274 const char* function_name,
7275 GLsizei width, GLsizei height, GLenum format, size_t size) {
7276 unsigned int bytes_required = 0;
7277
7278 switch (format) {
7279 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7280 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7281 int num_blocks_across =
7282 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7283 int num_blocks_down =
7284 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7285 int num_blocks = num_blocks_across * num_blocks_down;
7286 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7287 break;
7288 }
7289 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7290 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7291 int num_blocks_across =
7292 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7293 int num_blocks_down =
7294 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7295 int num_blocks = num_blocks_across * num_blocks_down;
7296 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7297 break;
7298 }
[email protected]2d3765b2012-10-03 00:31:077299 case GL_ETC1_RGB8_OES: {
7300 int num_blocks_across =
7301 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7302 int num_blocks_down =
7303 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7304 int num_blocks = num_blocks_across * num_blocks_down;
7305 bytes_required = num_blocks * kETC1BlockSize;
7306 break;
7307 }
[email protected]ad84a3a2012-06-08 21:42:437308 default:
[email protected]f80e6e12012-08-31 00:43:537309 SetGLErrorInvalidEnum(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437310 return false;
7311 }
7312
7313 if (size != bytes_required) {
7314 SetGLError(
7315 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7316 return false;
7317 }
7318
7319 return true;
7320}
7321
7322bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7323 const char* function_name,
7324 GLint level, GLsizei width, GLsizei height, GLenum format) {
7325 switch (format) {
7326 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7327 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7328 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7329 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7330 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
7331 SetGLError(
7332 GL_INVALID_OPERATION, function_name,
7333 "width or height invalid for level");
7334 return false;
7335 }
7336 return true;
7337 }
[email protected]2d3765b2012-10-03 00:31:077338 case GL_ETC1_RGB8_OES:
7339 if (width <= 0 || height <= 0) {
7340 SetGLError(
7341 GL_INVALID_OPERATION, function_name,
7342 "width or height invalid for level");
7343 return false;
7344 }
7345 return true;
[email protected]ad84a3a2012-06-08 21:42:437346 default:
7347 return false;
7348 }
7349}
7350
7351bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7352 const char* function_name,
7353 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7354 GLsizei width, GLsizei height, GLenum format,
7355 TextureManager::TextureInfo* texture) {
7356 if (xoffset < 0 || yoffset < 0) {
7357 SetGLError(
7358 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7359 return false;
7360 }
7361
7362 switch (format) {
7363 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7364 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7365 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7366 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7367 const int kBlockWidth = 4;
7368 const int kBlockHeight = 4;
7369 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
7370 SetGLError(
7371 GL_INVALID_OPERATION, function_name,
7372 "xoffset or yoffset not multiple of 4");
7373 return false;
7374 }
7375 GLsizei tex_width = 0;
7376 GLsizei tex_height = 0;
7377 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7378 width - xoffset > tex_width ||
7379 height - yoffset > tex_height) {
7380 SetGLError(
7381 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7382 return false;
7383 }
7384 return ValidateCompressedTexDimensions(
7385 function_name, level, width, height, format);
7386 }
[email protected]2d3765b2012-10-03 00:31:077387 case GL_ETC1_RGB8_OES: {
7388 SetGLError(
7389 GL_INVALID_OPERATION, function_name,
7390 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7391 return false;
7392 }
[email protected]ad84a3a2012-06-08 21:42:437393 default:
7394 return false;
7395 }
7396}
7397
[email protected]a93bb842010-02-16 23:03:477398error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7399 GLenum target,
7400 GLint level,
7401 GLenum internal_format,
7402 GLsizei width,
7403 GLsizei height,
7404 GLint border,
7405 GLsizei image_size,
7406 const void* data) {
[email protected]a93bb842010-02-16 23:03:477407 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057408 if (!validators_->texture_target.IsValid(target)) {
[email protected]f80e6e12012-08-31 00:43:537409 SetGLErrorInvalidEnum("glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297410 return error::kNoError;
7411 }
[email protected]9438b012010-06-15 22:55:057412 if (!validators_->compressed_texture_format.IsValid(
7413 internal_format)) {
[email protected]f80e6e12012-08-31 00:43:537414 SetGLErrorInvalidEnum(
7415 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477416 return error::kNoError;
7417 }
[email protected]80eb6b52012-01-19 00:14:417418 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477419 border != 0) {
[email protected]8eee29c2010-04-29 03:38:297420 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437421 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477422 return error::kNoError;
7423 }
[email protected]3916c97e2010-02-25 03:20:507424 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477425 if (!info) {
[email protected]8eee29c2010-04-29 03:38:297426 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437427 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477428 return error::kNoError;
7429 }
[email protected]97dc7cbe2011-12-06 17:26:177430 if (info->IsImmutable()) {
7431 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437432 "glCompressedTexImage2D", "texture is immutable");
7433 return error::kNoError;
7434 }
7435
7436 if (!ValidateCompressedTexDimensions(
7437 "glCompressedTexImage2D", level, width, height, internal_format) ||
7438 !ValidateCompressedTexFuncData(
7439 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177440 return error::kNoError;
7441 }
[email protected]968351b2011-12-20 08:26:517442
7443 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427444 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517445 // TODO(gman): If textures tracked which framebuffers they were attached to
7446 // we could just mark those framebuffers as not complete.
7447 framebuffer_manager()->IncFramebufferStateChangeCount();
7448 }
7449
[email protected]a93bb842010-02-16 23:03:477450 scoped_array<int8> zero;
7451 if (!data) {
7452 zero.reset(new int8[image_size]);
7453 memset(zero.get(), 0, image_size);
7454 data = zero.get();
7455 }
[email protected]cadde4a2010-07-31 17:10:437456 CopyRealGLErrorsToWrapper();
[email protected]a93bb842010-02-16 23:03:477457 glCompressedTexImage2D(
7458 target, level, internal_format, width, height, border, image_size, data);
[email protected]1002c2d2011-06-28 22:39:047459 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437460 if (error == GL_NO_ERROR) {
7461 texture_manager()->SetLevelInfo(
[email protected]0d6bfdc2011-11-02 01:32:207462 info, target, level, internal_format, width, height, 1, border, 0, 0,
7463 true);
[email protected]cadde4a2010-07-31 17:10:437464 }
[email protected]a93bb842010-02-16 23:03:477465 return error::kNoError;
7466}
7467
[email protected]f7a64ee2010-02-01 22:24:147468error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197469 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) {
7470 GLenum target = static_cast<GLenum>(c.target);
7471 GLint level = static_cast<GLint>(c.level);
7472 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7473 GLsizei width = static_cast<GLsizei>(c.width);
7474 GLsizei height = static_cast<GLsizei>(c.height);
7475 GLint border = static_cast<GLint>(c.border);
7476 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7477 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7478 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7479 const void* data = NULL;
7480 if (data_shm_id != 0 || data_shm_offset != 0) {
7481 data = GetSharedMemoryAs<const void*>(
7482 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467483 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147484 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197485 }
7486 }
[email protected]a93bb842010-02-16 23:03:477487 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197488 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197489}
7490
[email protected]f7a64ee2010-02-01 22:24:147491error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]b9849abf2009-11-25 19:13:197492 uint32 immediate_data_size, const gles2::CompressedTexImage2DImmediate& c) {
7493 GLenum target = static_cast<GLenum>(c.target);
7494 GLint level = static_cast<GLint>(c.level);
7495 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7496 GLsizei width = static_cast<GLsizei>(c.width);
7497 GLsizei height = static_cast<GLsizei>(c.height);
7498 GLint border = static_cast<GLint>(c.border);
7499 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307500 const void* data = GetImmediateDataAs<const void*>(
7501 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467502 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147503 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467504 }
[email protected]a93bb842010-02-16 23:03:477505 return DoCompressedTexImage2D(
7506 target, level, internal_format, width, height, border, image_size, data);
7507}
7508
[email protected]b6140d02010-05-17 14:47:167509error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
7510 uint32 immediate_data_size, const gles2::CompressedTexImage2DBucket& c) {
7511 GLenum target = static_cast<GLenum>(c.target);
7512 GLint level = static_cast<GLint>(c.level);
7513 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7514 GLsizei width = static_cast<GLsizei>(c.width);
7515 GLsizei height = static_cast<GLsizei>(c.height);
7516 GLint border = static_cast<GLint>(c.border);
7517 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287518 if (!bucket) {
7519 return error::kInvalidArguments;
7520 }
7521 uint32 data_size = bucket->size();
7522 GLsizei imageSize = data_size;
7523 const void* data = bucket->GetData(0, data_size);
7524 if (!data) {
7525 return error::kInvalidArguments;
7526 }
[email protected]b6140d02010-05-17 14:47:167527 return DoCompressedTexImage2D(
7528 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287529 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167530}
7531
7532error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7533 uint32 immediate_data_size,
7534 const gles2::CompressedTexSubImage2DBucket& c) {
7535 GLenum target = static_cast<GLenum>(c.target);
7536 GLint level = static_cast<GLint>(c.level);
7537 GLint xoffset = static_cast<GLint>(c.xoffset);
7538 GLint yoffset = static_cast<GLint>(c.yoffset);
7539 GLsizei width = static_cast<GLsizei>(c.width);
7540 GLsizei height = static_cast<GLsizei>(c.height);
7541 GLenum format = static_cast<GLenum>(c.format);
7542 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287543 if (!bucket) {
7544 return error::kInvalidArguments;
7545 }
[email protected]b6140d02010-05-17 14:47:167546 uint32 data_size = bucket->size();
7547 GLsizei imageSize = data_size;
7548 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287549 if (!data) {
7550 return error::kInvalidArguments;
7551 }
[email protected]9438b012010-06-15 22:55:057552 if (!validators_->texture_target.IsValid(target)) {
[email protected]b6140d02010-05-17 14:47:167553 SetGLError(
[email protected]f80e6e12012-08-31 00:43:537554 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167555 return error::kNoError;
7556 }
[email protected]9438b012010-06-15 22:55:057557 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]f80e6e12012-08-31 00:43:537558 SetGLErrorInvalidEnum("glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057559 return error::kNoError;
7560 }
[email protected]b6140d02010-05-17 14:47:167561 if (width < 0) {
[email protected]ad84a3a2012-06-08 21:42:437562 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167563 return error::kNoError;
7564 }
7565 if (height < 0) {
[email protected]ad84a3a2012-06-08 21:42:437566 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167567 return error::kNoError;
7568 }
7569 if (imageSize < 0) {
[email protected]ad84a3a2012-06-08 21:42:437570 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167571 return error::kNoError;
7572 }
[email protected]cadde4a2010-07-31 17:10:437573 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167574 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7575 return error::kNoError;
7576}
7577
[email protected]81375742012-06-08 00:04:007578bool GLES2DecoderImpl::ValidateTextureParameters(
7579 const char* function_name,
7580 GLenum target, GLenum format, GLenum type, GLint level) {
7581 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
[email protected]ad84a3a2012-06-08 21:42:437582 SetGLError(GL_INVALID_OPERATION, function_name,
7583 (std::string("invalid type ") +
[email protected]81375742012-06-08 00:04:007584 GLES2Util::GetStringEnum(type) + " for format " +
7585 GLES2Util::GetStringEnum(format)).c_str());
7586 return false;
7587 }
7588
7589 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7590 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
[email protected]ad84a3a2012-06-08 21:42:437591 SetGLError(GL_INVALID_OPERATION, function_name,
7592 (std::string("invalid type ") +
[email protected]81375742012-06-08 00:04:007593 GLES2Util::GetStringEnum(type) + " for format " +
7594 GLES2Util::GetStringEnum(format)).c_str());
7595 return false;
7596 }
7597 return true;
7598}
7599
[email protected]f598f422012-12-07 08:30:037600bool GLES2DecoderImpl::ValidateTexImage2D(
7601 const char* function_name,
7602 GLenum target,
7603 GLint level,
7604 GLenum internal_format,
7605 GLsizei width,
7606 GLsizei height,
7607 GLint border,
7608 GLenum format,
7609 GLenum type,
7610 const void* pixels,
7611 uint32 pixels_size) {
[email protected]9438b012010-06-15 22:55:057612 if (!validators_->texture_target.IsValid(target)) {
[email protected]f598f422012-12-07 08:30:037613 SetGLErrorInvalidEnum(function_name, target, "target");
7614 return false;
[email protected]8eee29c2010-04-29 03:38:297615 }
[email protected]9438b012010-06-15 22:55:057616 if (!validators_->texture_format.IsValid(internal_format)) {
[email protected]f598f422012-12-07 08:30:037617 SetGLErrorInvalidEnum(function_name, internal_format, "internal_format");
7618 return false;
[email protected]8eee29c2010-04-29 03:38:297619 }
[email protected]9438b012010-06-15 22:55:057620 if (!validators_->texture_format.IsValid(format)) {
[email protected]f598f422012-12-07 08:30:037621 SetGLErrorInvalidEnum(function_name, format, "format");
7622 return false;
[email protected]8eee29c2010-04-29 03:38:297623 }
[email protected]9438b012010-06-15 22:55:057624 if (!validators_->pixel_type.IsValid(type)) {
[email protected]f598f422012-12-07 08:30:037625 SetGLErrorInvalidEnum(function_name, type, "type");
7626 return false;
[email protected]b9849abf2009-11-25 19:13:197627 }
[email protected]7b92c412010-07-20 17:48:257628 if (format != internal_format) {
[email protected]ad84a3a2012-06-08 21:42:437629 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037630 function_name, "format != internalFormat");
7631 return false;
[email protected]7b92c412010-07-20 17:48:257632 }
[email protected]f598f422012-12-07 08:30:037633 if (!ValidateTextureParameters(function_name, target, format, type, level)) {
7634 return false;
[email protected]81375742012-06-08 00:04:007635 }
[email protected]80eb6b52012-01-19 00:14:417636 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477637 border != 0) {
[email protected]f598f422012-12-07 08:30:037638 SetGLError(GL_INVALID_VALUE, function_name, "dimensions out of range");
7639 return false;
[email protected]a93bb842010-02-16 23:03:477640 }
[email protected]81375742012-06-08 00:04:007641 if ((GLES2Util::GetChannelsForFormat(format) &
7642 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
7643 SetGLError(
7644 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037645 function_name, "can not supply data for depth or stencil textures");
7646 return false;
[email protected]81375742012-06-08 00:04:007647 }
[email protected]3916c97e2010-02-25 03:20:507648 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]a93bb842010-02-16 23:03:477649 if (!info) {
[email protected]8eee29c2010-04-29 03:38:297650 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037651 function_name, "unknown texture for target");
7652 return false;
[email protected]a93bb842010-02-16 23:03:477653 }
[email protected]97dc7cbe2011-12-06 17:26:177654 if (info->IsImmutable()) {
7655 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037656 function_name, "texture is immutable");
7657 return false;
[email protected]97dc7cbe2011-12-06 17:26:177658 }
[email protected]f598f422012-12-07 08:30:037659 return true;
7660}
[email protected]97dc7cbe2011-12-06 17:26:177661
[email protected]f598f422012-12-07 08:30:037662void GLES2DecoderImpl::DoTexImage2D(
7663 GLenum target,
7664 GLint level,
7665 GLenum internal_format,
7666 GLsizei width,
7667 GLsizei height,
7668 GLint border,
7669 GLenum format,
7670 GLenum type,
7671 const void* pixels,
7672 uint32 pixels_size) {
7673 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format,
7674 width, height, border, format, type, pixels, pixels_size)) {
7675 return;
7676 }
7677 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]0226c112011-07-22 03:25:077678 GLsizei tex_width = 0;
7679 GLsizei tex_height = 0;
7680 GLenum tex_type = 0;
7681 GLenum tex_format = 0;
7682 bool level_is_same =
7683 info->GetLevelSize(target, level, &tex_width, &tex_height) &&
7684 info->GetLevelType(target, level, &tex_type, &tex_format) &&
7685 width == tex_width && height == tex_height &&
7686 type == tex_type && format == tex_format;
7687
7688 if (level_is_same && !pixels) {
[email protected]1bed6222011-12-21 11:21:397689 // Just set the level info but mark the texture as uncleared.
7690 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417691 info,
[email protected]1bed6222011-12-21 11:21:397692 target, level, internal_format, width, height, 1, border, format, type,
7693 false);
[email protected]ea72ed222011-08-17 18:58:437694 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037695 return;
[email protected]0226c112011-07-22 03:25:077696 }
7697
[email protected]297ca1c2011-06-20 23:08:467698 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427699 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517700 // TODO(gman): If textures tracked which framebuffers they were attached to
7701 // we could just mark those framebuffers as not complete.
7702 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:467703 }
7704
[email protected]1bed6222011-12-21 11:21:397705 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) {
[email protected]0226c112011-07-22 03:25:077706 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
[email protected]60f22d32012-12-12 00:31:587707 texture_manager()->SetLevelCleared(info, target, level, true);
[email protected]0226c112011-07-22 03:25:077708 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037709 return;
[email protected]7488d962010-07-16 02:41:587710 }
[email protected]876f6fee2010-08-02 23:10:327711
[email protected]cadde4a2010-07-31 17:10:437712 CopyRealGLErrorsToWrapper();
[email protected]473c01ccb2011-06-07 01:33:307713 WrappedTexImage2D(
7714 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477715 pixels);
[email protected]1002c2d2011-06-28 22:39:047716 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437717 if (error == GL_NO_ERROR) {
[email protected]0d6bfdc2011-11-02 01:32:207718 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417719 info,
[email protected]0d6bfdc2011-11-02 01:32:207720 target, level, internal_format, width, height, 1, border, format, type,
7721 pixels != NULL);
[email protected]b493ee622011-04-13 23:52:007722 tex_image_2d_failed_ = false;
[email protected]cadde4a2010-07-31 17:10:437723 }
[email protected]f598f422012-12-07 08:30:037724 return;
[email protected]b9849abf2009-11-25 19:13:197725}
7726
[email protected]f7a64ee2010-02-01 22:24:147727error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197728 uint32 immediate_data_size, const gles2::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387729 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]b493ee622011-04-13 23:52:007730 tex_image_2d_failed_ = true;
[email protected]b9849abf2009-11-25 19:13:197731 GLenum target = static_cast<GLenum>(c.target);
7732 GLint level = static_cast<GLint>(c.level);
7733 GLint internal_format = static_cast<GLint>(c.internalformat);
7734 GLsizei width = static_cast<GLsizei>(c.width);
7735 GLsizei height = static_cast<GLsizei>(c.height);
7736 GLint border = static_cast<GLint>(c.border);
7737 GLenum format = static_cast<GLenum>(c.format);
7738 GLenum type = static_cast<GLenum>(c.type);
7739 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7740 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187741 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347742 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247743 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347744 NULL)) {
[email protected]a76b0052010-03-05 00:33:187745 return error::kOutOfBounds;
7746 }
[email protected]b9849abf2009-11-25 19:13:197747 const void* pixels = NULL;
7748 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7749 pixels = GetSharedMemoryAs<const void*>(
7750 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467751 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147752 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197753 }
7754 }
[email protected]f598f422012-12-07 08:30:037755
7756 DoTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197757 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477758 pixels, pixels_size);
[email protected]f598f422012-12-07 08:30:037759 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197760}
7761
[email protected]f7a64ee2010-02-01 22:24:147762error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]b9849abf2009-11-25 19:13:197763 uint32 immediate_data_size, const gles2::TexImage2DImmediate& c) {
7764 GLenum target = static_cast<GLenum>(c.target);
7765 GLint level = static_cast<GLint>(c.level);
[email protected]ba3176a2009-12-16 18:19:467766 GLint internal_format = static_cast<GLint>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197767 GLsizei width = static_cast<GLsizei>(c.width);
7768 GLsizei height = static_cast<GLsizei>(c.height);
7769 GLint border = static_cast<GLint>(c.border);
7770 GLenum format = static_cast<GLenum>(c.format);
7771 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:187772 uint32 size;
[email protected]3458a64a2012-04-10 17:39:347773 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247774 width, height, format, type, state_.unpack_alignment, &size,
7775 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187776 return error::kOutOfBounds;
7777 }
[email protected]07f54fcc2009-12-22 02:46:307778 const void* pixels = GetImmediateDataAs<const void*>(
7779 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467780 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147781 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467782 }
[email protected]a93bb842010-02-16 23:03:477783 DoTexImage2D(
[email protected]ba3176a2009-12-16 18:19:467784 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477785 pixels, size);
[email protected]f7a64ee2010-02-01 22:24:147786 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327787}
7788
[email protected]cadde4a2010-07-31 17:10:437789void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7790 GLenum target,
7791 GLint level,
7792 GLint xoffset,
7793 GLint yoffset,
7794 GLsizei width,
7795 GLsizei height,
7796 GLenum format,
7797 GLsizei image_size,
7798 const void * data) {
7799 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7800 if (!info) {
7801 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437802 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437803 return;
7804 }
7805 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527806 GLenum internal_format = 0;
7807 if (!info->GetLevelType(target, level, &type, &internal_format)) {
7808 SetGLError(
7809 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437810 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527811 return;
7812 }
7813 if (internal_format != format) {
7814 SetGLError(
7815 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437816 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527817 return;
7818 }
7819 if (!info->ValidForTexture(
7820 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]cadde4a2010-07-31 17:10:437821 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437822 "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437823 return;
7824 }
[email protected]ad84a3a2012-06-08 21:42:437825
7826 if (!ValidateCompressedTexFuncData(
7827 "glCompressedTexSubImage2D", width, height, format, image_size) ||
7828 !ValidateCompressedTexSubDimensions(
7829 "glCompressedTexSubImage2D",
7830 target, level, xoffset, yoffset, width, height, format, info)) {
7831 return;
7832 }
7833
7834
[email protected]0d6bfdc2011-11-02 01:32:207835 // Note: There is no need to deal with texture cleared tracking here
7836 // because the validation above means you can only get here if the level
7837 // is already a matching compressed format and in that case
7838 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:437839 glCompressedTexSubImage2D(
7840 target, level, xoffset, yoffset, width, height, format, image_size, data);
7841}
7842
[email protected]6e288612010-12-21 20:45:037843static void Clip(
7844 GLint start, GLint range, GLint sourceRange,
7845 GLint* out_start, GLint* out_range) {
7846 DCHECK(out_start);
7847 DCHECK(out_range);
7848 if (start < 0) {
7849 range += start;
7850 start = 0;
7851 }
7852 GLint end = start + range;
7853 if (end > sourceRange) {
7854 range -= end - sourceRange;
7855 }
7856 *out_start = start;
7857 *out_range = range;
7858}
7859
[email protected]cadde4a2010-07-31 17:10:437860void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:447861 GLenum target,
7862 GLint level,
7863 GLenum internal_format,
7864 GLint x,
7865 GLint y,
7866 GLsizei width,
7867 GLsizei height,
7868 GLint border) {
[email protected]09e17272012-11-30 10:30:447869 DCHECK(!ShouldDeferReads());
[email protected]cadde4a2010-07-31 17:10:437870 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7871 if (!info) {
7872 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437873 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437874 return;
7875 }
[email protected]97dc7cbe2011-12-06 17:26:177876 if (info->IsImmutable()) {
7877 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437878 "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:177879 }
[email protected]80eb6b52012-01-19 00:14:417880 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:187881 border != 0) {
[email protected]ad84a3a2012-06-08 21:42:437882 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:187883 return;
7884 }
[email protected]81375742012-06-08 00:04:007885 if (!ValidateTextureParameters(
7886 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
7887 return;
7888 }
[email protected]f5719fb2010-08-04 18:27:187889
[email protected]9edc6b22010-12-23 02:00:267890 // Check we have compatible formats.
7891 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7892 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7893 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
7894
7895 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ad84a3a2012-06-08 21:42:437896 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:267897 return;
7898 }
7899
[email protected]81375742012-06-08 00:04:007900 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
7901 SetGLError(
7902 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437903 "glCopyImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:007904 return;
7905 }
7906
[email protected]a0b78dc2011-11-11 10:43:107907 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
7908 return;
7909 }
7910
[email protected]cadde4a2010-07-31 17:10:437911 CopyRealGLErrorsToWrapper();
[email protected]de26b3c2011-08-03 21:54:277912 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:037913 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:267914
[email protected]297ca1c2011-06-20 23:08:467915 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427916 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517917 // TODO(gman): If textures tracked which framebuffers they were attached to
7918 // we could just mark those framebuffers as not complete.
7919 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:467920 }
7921
[email protected]9edc6b22010-12-23 02:00:267922 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:037923 GLint copyX = 0;
7924 GLint copyY = 0;
7925 GLint copyWidth = 0;
7926 GLint copyHeight = 0;
7927 Clip(x, width, size.width(), &copyX, &copyWidth);
7928 Clip(y, height, size.height(), &copyY, &copyHeight);
7929
7930 if (copyX != x ||
7931 copyY != y ||
7932 copyWidth != width ||
7933 copyHeight != height) {
7934 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:207935 if (!ClearLevel(
7936 info->service_id(), info->target(),
[email protected]4502e6492011-12-14 19:39:157937 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
7938 info->IsImmutable())) {
[email protected]ad84a3a2012-06-08 21:42:437939 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:037940 return;
7941 }
[email protected]6e288612010-12-21 20:45:037942 if (copyHeight > 0 && copyWidth > 0) {
7943 GLint dx = copyX - x;
7944 GLint dy = copyY - y;
7945 GLint destX = dx;
7946 GLint destY = dy;
7947 glCopyTexSubImage2D(target, level,
7948 destX, destY, copyX, copyY,
7949 copyWidth, copyHeight);
7950 }
7951 } else {
7952 glCopyTexImage2D(target, level, internal_format,
7953 copyX, copyY, copyWidth, copyHeight, border);
7954 }
[email protected]1002c2d2011-06-28 22:39:047955 GLenum error = PeekGLError();
[email protected]cadde4a2010-07-31 17:10:437956 if (error == GL_NO_ERROR) {
7957 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:417958 info, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:207959 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:437960 }
7961}
7962
7963void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:447964 GLenum target,
7965 GLint level,
7966 GLint xoffset,
7967 GLint yoffset,
7968 GLint x,
7969 GLint y,
7970 GLsizei width,
7971 GLsizei height) {
[email protected]09e17272012-11-30 10:30:447972 DCHECK(!ShouldDeferReads());
[email protected]cadde4a2010-07-31 17:10:437973 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
7974 if (!info) {
7975 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437976 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437977 return;
7978 }
7979 GLenum type = 0;
7980 GLenum format = 0;
7981 if (!info->GetLevelType(target, level, &type, &format) ||
7982 !info->ValidForTexture(
7983 target, level, xoffset, yoffset, width, height, format, type)) {
7984 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:437985 "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437986 return;
7987 }
[email protected]32145a92012-12-17 09:01:597988 if (info->AsyncTransferIsInProgress()) {
7989 SetGLError(GL_INVALID_OPERATION,
7990 "glCopyTexSubImage2D", "async upload pending for texture");
7991 return;
7992 }
[email protected]9edc6b22010-12-23 02:00:267993
7994 // Check we have compatible formats.
7995 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7996 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7997 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
7998
[email protected]2d3765b2012-10-03 00:31:077999 if (!channels_needed ||
8000 (channels_needed & channels_exist) != channels_needed) {
[email protected]9edc6b22010-12-23 02:00:268001 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:438002 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268003 return;
8004 }
8005
[email protected]81375742012-06-08 00:04:008006 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
8007 SetGLError(
8008 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438009 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008010 return;
8011 }
8012
[email protected]a0b78dc2011-11-11 10:43:108013 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8014 return;
8015 }
8016
[email protected]de26b3c2011-08-03 21:54:278017 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038018 gfx::Size size = GetBoundReadFrameBufferSize();
8019 GLint copyX = 0;
8020 GLint copyY = 0;
8021 GLint copyWidth = 0;
8022 GLint copyHeight = 0;
8023 Clip(x, width, size.width(), &copyX, &copyWidth);
8024 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208025
8026 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
[email protected]ad84a3a2012-06-08 21:42:438027 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208028 return;
8029 }
8030
[email protected]6e288612010-12-21 20:45:038031 if (copyX != x ||
8032 copyY != y ||
8033 copyWidth != width ||
8034 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208035 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038036 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348037 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248038 width, height, format, type, state_.unpack_alignment, &pixels_size,
8039 NULL, NULL)) {
[email protected]ad84a3a2012-06-08 21:42:438040 SetGLError(
8041 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038042 return;
8043 }
8044 scoped_array<char> zero(new char[pixels_size]);
8045 memset(zero.get(), 0, pixels_size);
8046 glTexSubImage2D(
8047 target, level, xoffset, yoffset, width, height,
8048 format, type, zero.get());
8049 }
[email protected]0d6bfdc2011-11-02 01:32:208050
[email protected]6e288612010-12-21 20:45:038051 if (copyHeight > 0 && copyWidth > 0) {
8052 GLint dx = copyX - x;
8053 GLint dy = copyY - y;
8054 GLint destX = xoffset + dx;
8055 GLint destY = yoffset + dy;
8056 glCopyTexSubImage2D(target, level,
8057 destX, destY, copyX, copyY,
8058 copyWidth, copyHeight);
8059 }
[email protected]cadde4a2010-07-31 17:10:438060}
8061
[email protected]f598f422012-12-07 08:30:038062bool GLES2DecoderImpl::ValidateTexSubImage2D(
8063 error::Error* error,
8064 const char* function_name,
8065 GLenum target,
8066 GLint level,
8067 GLint xoffset,
8068 GLint yoffset,
8069 GLsizei width,
8070 GLsizei height,
8071 GLenum format,
8072 GLenum type,
8073 const void * data) {
8074 (*error) = error::kNoError;
8075 if (!validators_->texture_target.IsValid(target)) {
8076 SetGLErrorInvalidEnum(function_name, target, "target");
8077 return false;
8078 }
8079 if (width < 0) {
8080 SetGLError(GL_INVALID_VALUE, function_name, "width < 0");
8081 return false;
8082 }
8083 if (height < 0) {
8084 SetGLError(GL_INVALID_VALUE, function_name, "height < 0");
8085 return false;
8086 }
8087 if (!validators_->texture_format.IsValid(format)) {
8088 SetGLErrorInvalidEnum(function_name, format, "format");
8089 return false;
8090 }
8091 if (!validators_->pixel_type.IsValid(type)) {
8092 SetGLErrorInvalidEnum(function_name, type, "type");
8093 return false;
8094 }
[email protected]cadde4a2010-07-31 17:10:438095 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
8096 if (!info) {
8097 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038098 function_name, "unknown texture for target");
8099 return false;
[email protected]cadde4a2010-07-31 17:10:438100 }
[email protected]df6cf1ad2011-01-29 01:20:528101 GLenum current_type = 0;
8102 GLenum internal_format = 0;
8103 if (!info->GetLevelType(target, level, &current_type, &internal_format)) {
8104 SetGLError(
[email protected]f598f422012-12-07 08:30:038105 GL_INVALID_OPERATION, function_name, "level does not exist.");
8106 return false;
[email protected]df6cf1ad2011-01-29 01:20:528107 }
8108 if (format != internal_format) {
8109 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038110 function_name, "format does not match internal format.");
8111 return false;
[email protected]df6cf1ad2011-01-29 01:20:528112 }
8113 if (type != current_type) {
8114 SetGLError(GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038115 function_name, "type does not match type of texture.");
8116 return false;
[email protected]df6cf1ad2011-01-29 01:20:528117 }
[email protected]32145a92012-12-17 09:01:598118 if (info->AsyncTransferIsInProgress()) {
8119 SetGLError(GL_INVALID_OPERATION,
8120 function_name, "async upload pending for texture");
8121 return false;
8122 }
[email protected]cadde4a2010-07-31 17:10:438123 if (!info->ValidForTexture(
8124 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]f598f422012-12-07 08:30:038125 SetGLError(GL_INVALID_VALUE, function_name, "bad dimensions.");
8126 return false;
[email protected]cadde4a2010-07-31 17:10:438127 }
[email protected]81375742012-06-08 00:04:008128 if ((GLES2Util::GetChannelsForFormat(format) &
8129 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
8130 SetGLError(
8131 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038132 function_name, "can not supply data for depth or stencil textures");
8133 return false;
[email protected]81375742012-06-08 00:04:008134 }
[email protected]f598f422012-12-07 08:30:038135 if (data == NULL) {
8136 (*error) = error::kOutOfBounds;
8137 return false;
8138 }
8139 return true;
8140}
[email protected]81375742012-06-08 00:04:008141
[email protected]f598f422012-12-07 08:30:038142error::Error GLES2DecoderImpl::DoTexSubImage2D(
8143 GLenum target,
8144 GLint level,
8145 GLint xoffset,
8146 GLint yoffset,
8147 GLsizei width,
8148 GLsizei height,
8149 GLenum format,
8150 GLenum type,
8151 const void * data) {
8152 error::Error error = error::kNoError;
8153 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8154 xoffset, yoffset, width, height, format, type, data)) {
8155 return error;
8156 }
8157 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
[email protected]4502e6492011-12-14 19:39:158158 GLsizei tex_width = 0;
8159 GLsizei tex_height = 0;
8160 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height);
8161 DCHECK(ok);
8162 if (xoffset != 0 || yoffset != 0 ||
8163 width != tex_width || height != tex_height) {
8164 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
[email protected]ad84a3a2012-06-08 21:42:438165 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038166 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308167 }
[email protected]63b465922012-09-06 02:04:528168 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158169 glTexSubImage2D(
8170 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038171 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208172 }
[email protected]4502e6492011-12-14 19:39:158173
8174 if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) {
[email protected]63b465922012-09-06 02:04:528175 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158176 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8177 // same as internal_foramt. If that changes we'll need to look them up.
8178 WrappedTexImage2D(
8179 target, level, format, width, height, 0, format, type, data);
8180 } else {
[email protected]63b465922012-09-06 02:04:528181 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158182 glTexSubImage2D(
8183 target, level, xoffset, yoffset, width, height, format, type, data);
8184 }
[email protected]60f22d32012-12-12 00:31:588185 texture_manager()->SetLevelCleared(info, target, level, true);
[email protected]f598f422012-12-07 08:30:038186 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438187}
8188
[email protected]b493ee622011-04-13 23:52:008189error::Error GLES2DecoderImpl::HandleTexSubImage2D(
8190 uint32 immediate_data_size, const gles2::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388191 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008192 GLboolean internal = static_cast<GLboolean>(c.internal);
8193 if (internal == GL_TRUE && tex_image_2d_failed_)
8194 return error::kNoError;
8195
8196 GLenum target = static_cast<GLenum>(c.target);
8197 GLint level = static_cast<GLint>(c.level);
8198 GLint xoffset = static_cast<GLint>(c.xoffset);
8199 GLint yoffset = static_cast<GLint>(c.yoffset);
8200 GLsizei width = static_cast<GLsizei>(c.width);
8201 GLsizei height = static_cast<GLsizei>(c.height);
8202 GLenum format = static_cast<GLenum>(c.format);
8203 GLenum type = static_cast<GLenum>(c.type);
8204 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348205 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248206 width, height, format, type, state_.unpack_alignment, &data_size,
8207 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008208 return error::kOutOfBounds;
8209 }
8210 const void* pixels = GetSharedMemoryAs<const void*>(
8211 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038212 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008213 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008214}
8215
8216error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
8217 uint32 immediate_data_size, const gles2::TexSubImage2DImmediate& c) {
8218 GLboolean internal = static_cast<GLboolean>(c.internal);
8219 if (internal == GL_TRUE && tex_image_2d_failed_)
8220 return error::kNoError;
8221
8222 GLenum target = static_cast<GLenum>(c.target);
8223 GLint level = static_cast<GLint>(c.level);
8224 GLint xoffset = static_cast<GLint>(c.xoffset);
8225 GLint yoffset = static_cast<GLint>(c.yoffset);
8226 GLsizei width = static_cast<GLsizei>(c.width);
8227 GLsizei height = static_cast<GLsizei>(c.height);
8228 GLenum format = static_cast<GLenum>(c.format);
8229 GLenum type = static_cast<GLenum>(c.type);
8230 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348231 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248232 width, height, format, type, state_.unpack_alignment, &data_size,
8233 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008234 return error::kOutOfBounds;
8235 }
8236 const void* pixels = GetImmediateDataAs<const void*>(
8237 c, data_size, immediate_data_size);
[email protected]f598f422012-12-07 08:30:038238 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008239 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008240}
8241
[email protected]f7a64ee2010-02-01 22:24:148242error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]b9849abf2009-11-25 19:13:198243 uint32 immediate_data_size, const gles2::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368244 GLuint index = static_cast<GLuint>(c.index);
8245 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]0bfd9882010-02-05 23:02:258246 typedef gles2::GetVertexAttribPointerv::Result Result;
8247 Result* result = GetSharedMemoryAs<Result*>(
8248 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368249 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148250 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368251 }
[email protected]07d0cc82010-02-17 04:51:408252 // Check that the client initialized the result.
8253 if (result->size != 0) {
8254 return error::kInvalidArguments;
8255 }
[email protected]9438b012010-06-15 22:55:058256 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]f80e6e12012-08-31 00:43:538257 SetGLErrorInvalidEnum("glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148258 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368259 }
[email protected]3916c97e2010-02-25 03:20:508260 if (index >= group_->max_vertex_attribs()) {
[email protected]8eee29c2010-04-29 03:38:298261 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438262 "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148263 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368264 }
[email protected]0bfd9882010-02-05 23:02:258265 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088266 *result->GetData() =
[email protected]e259eb412012-10-13 05:47:248267 state_.vertex_attrib_manager->GetVertexAttribInfo(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148268 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328269}
8270
[email protected]f7b85372010-02-03 01:11:378271bool GLES2DecoderImpl::GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128272 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378273 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128274 error::Error* error, GLint* real_location,
8275 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108276 DCHECK(error);
8277 DCHECK(service_id);
8278 DCHECK(result_pointer);
8279 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128280 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378281 *error = error::kNoError;
8282 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258283 SizedResult<GLint>* result;
8284 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8285 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8286 if (!result) {
[email protected]f7b85372010-02-03 01:11:378287 *error = error::kOutOfBounds;
8288 return false;
8289 }
[email protected]0bfd9882010-02-05 23:02:258290 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378291 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258292 result->SetNumResults(0);
[email protected]6b8cf1a2010-05-06 16:13:588293 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8294 program, "glGetUniform");
[email protected]f7b85372010-02-03 01:11:378295 if (!info) {
[email protected]ae51d192010-04-27 00:48:038296 return false;
8297 }
8298 if (!info->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378299 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ad84a3a2012-06-08 21:42:438300 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378301 return false;
8302 }
[email protected]ae51d192010-04-27 00:48:038303 *service_id = info->service_id();
[email protected]43c2f1f2011-03-25 18:35:368304 GLint array_index = -1;
8305 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
[email protected]1b0a6752012-02-22 03:44:128306 info->GetUniformInfoByFakeLocation(
8307 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368308 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378309 // No such location.
[email protected]ad84a3a2012-06-08 21:42:438310 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378311 return false;
8312 }
[email protected]43c2f1f2011-03-25 18:35:368313 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508314 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378315 if (size == 0) {
[email protected]ad84a3a2012-06-08 21:42:438316 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378317 return false;
8318 }
[email protected]0bfd9882010-02-05 23:02:258319 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8320 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8321 if (!result) {
[email protected]f7b85372010-02-03 01:11:378322 *error = error::kOutOfBounds;
8323 return false;
8324 }
[email protected]0bfd9882010-02-05 23:02:258325 result->size = size;
[email protected]939e7362010-05-13 20:49:108326 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378327 return true;
8328}
8329
[email protected]f7a64ee2010-02-01 22:24:148330error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]b9849abf2009-11-25 19:13:198331 uint32 immediate_data_size, const gles2::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378332 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338333 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378334 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108335 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128336 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378337 Error error;
[email protected]0bfd9882010-02-05 23:02:258338 void* result;
[email protected]f7b85372010-02-03 01:11:378339 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128340 program, fake_location, c.params_shm_id, c.params_shm_offset,
8341 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258342 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128343 service_id, real_location,
[email protected]0bfd9882010-02-05 23:02:258344 static_cast<gles2::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378345 }
8346 return error;
[email protected]96449d2c2009-11-25 00:01:328347}
8348
[email protected]f7a64ee2010-02-01 22:24:148349error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]b9849abf2009-11-25 19:13:198350 uint32 immediate_data_size, const gles2::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378351 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338352 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378353 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128354 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378355 Error error;
[email protected]0bfd9882010-02-05 23:02:258356 typedef gles2::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108357 Result* result;
8358 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378359 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128360 program, fake_location, c.params_shm_id, c.params_shm_offset,
8361 &error, &real_location, &service_id,
8362 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108363 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8364 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8365 GLsizei num_values = result->GetNumResults();
8366 scoped_array<GLint> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128367 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108368 GLfloat* dst = result->GetData();
8369 for (GLsizei ii = 0; ii < num_values; ++ii) {
8370 dst[ii] = (temp[ii] != 0);
8371 }
8372 } else {
[email protected]1b0a6752012-02-22 03:44:128373 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108374 }
[email protected]f7b85372010-02-03 01:11:378375 }
8376 return error;
[email protected]96449d2c2009-11-25 00:01:328377}
8378
[email protected]f7a64ee2010-02-01 22:24:148379error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]b9849abf2009-11-25 19:13:198380 uint32 immediate_data_size, const gles2::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258381 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8382 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
8383 typedef gles2::GetShaderPrecisionFormat::Result Result;
8384 Result* result = GetSharedMemoryAs<Result*>(
8385 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8386 if (!result) {
8387 return error::kOutOfBounds;
8388 }
[email protected]07d0cc82010-02-17 04:51:408389 // Check that the client initialized the result.
8390 if (result->success != 0) {
8391 return error::kInvalidArguments;
8392 }
[email protected]9438b012010-06-15 22:55:058393 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]f80e6e12012-08-31 00:43:538394 SetGLErrorInvalidEnum(
8395 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298396 return error::kNoError;
8397 }
[email protected]9438b012010-06-15 22:55:058398 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]f80e6e12012-08-31 00:43:538399 SetGLErrorInvalidEnum(
8400 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298401 return error::kNoError;
8402 }
8403
8404 result->success = 1; // true
8405 switch (precision_type) {
8406 case GL_LOW_INT:
8407 case GL_MEDIUM_INT:
8408 case GL_HIGH_INT:
[email protected]0a34b582012-04-09 22:42:568409 // These values are for a 32-bit twos-complement integer format.
8410 result->min_range = 31;
8411 result->max_range = 30;
[email protected]8eee29c2010-04-29 03:38:298412 result->precision = 0;
[email protected]4e8a5b122010-05-08 22:00:108413 break;
[email protected]8eee29c2010-04-29 03:38:298414 case GL_LOW_FLOAT:
8415 case GL_MEDIUM_FLOAT:
8416 case GL_HIGH_FLOAT:
[email protected]0a34b582012-04-09 22:42:568417 // These values are for an IEEE single-precision floating-point format.
8418 result->min_range = 127;
8419 result->max_range = 127;
8420 result->precision = 23;
[email protected]8eee29c2010-04-29 03:38:298421 break;
8422 default:
8423 NOTREACHED();
8424 break;
[email protected]0bfd9882010-02-05 23:02:258425 }
[email protected]f7a64ee2010-02-01 22:24:148426 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328427}
8428
[email protected]f7a64ee2010-02-01 22:24:148429error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]b9849abf2009-11-25 19:13:198430 uint32 immediate_data_size, const gles2::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258431 uint32 result_size = c.result_size;
[email protected]6b8cf1a2010-05-06 16:13:588432 GLuint program = static_cast<GLuint>(c.program);
8433 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8434 program, "glGetAttachedShaders");
[email protected]ae51d192010-04-27 00:48:038435 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258436 return error::kNoError;
8437 }
8438 typedef gles2::GetAttachedShaders::Result Result;
8439 uint32 max_count = Result::ComputeMaxResults(result_size);
8440 Result* result = GetSharedMemoryAs<Result*>(
8441 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8442 if (!result) {
8443 return error::kOutOfBounds;
8444 }
[email protected]07d0cc82010-02-17 04:51:408445 // Check that the client initialized the result.
8446 if (result->size != 0) {
8447 return error::kInvalidArguments;
8448 }
[email protected]0bfd9882010-02-05 23:02:258449 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038450 glGetAttachedShaders(
8451 info->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258452 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038453 if (!shader_manager()->GetClientId(result->GetData()[ii],
8454 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258455 NOTREACHED();
8456 return error::kGenericError;
8457 }
8458 }
8459 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148460 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328461}
8462
[email protected]f7a64ee2010-02-01 22:24:148463error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]b9849abf2009-11-25 19:13:198464 uint32 immediate_data_size, const gles2::GetActiveUniform& c) {
[email protected]0bfd9882010-02-05 23:02:258465 GLuint program = c.program;
8466 GLuint index = c.index;
8467 uint32 name_bucket_id = c.name_bucket_id;
[email protected]0bfd9882010-02-05 23:02:258468 typedef gles2::GetActiveUniform::Result Result;
8469 Result* result = GetSharedMemoryAs<Result*>(
8470 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8471 if (!result) {
8472 return error::kOutOfBounds;
8473 }
[email protected]07d0cc82010-02-17 04:51:408474 // Check that the client initialized the result.
8475 if (result->success != 0) {
8476 return error::kInvalidArguments;
8477 }
[email protected]6b8cf1a2010-05-06 16:13:588478 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8479 program, "glGetActiveUniform");
[email protected]ae51d192010-04-27 00:48:038480 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258481 return error::kNoError;
8482 }
8483 const ProgramManager::ProgramInfo::UniformInfo* uniform_info =
8484 info->GetUniformInfo(index);
8485 if (!uniform_info) {
[email protected]ad84a3a2012-06-08 21:42:438486 SetGLError(GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258487 return error::kNoError;
8488 }
8489 result->success = 1; // true.
8490 result->size = uniform_info->size;
8491 result->type = uniform_info->type;
8492 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298493 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148494 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328495}
8496
[email protected]f7a64ee2010-02-01 22:24:148497error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]b9849abf2009-11-25 19:13:198498 uint32 immediate_data_size, const gles2::GetActiveAttrib& c) {
[email protected]0bfd9882010-02-05 23:02:258499 GLuint program = c.program;
8500 GLuint index = c.index;
8501 uint32 name_bucket_id = c.name_bucket_id;
[email protected]0bfd9882010-02-05 23:02:258502 typedef gles2::GetActiveAttrib::Result Result;
8503 Result* result = GetSharedMemoryAs<Result*>(
8504 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8505 if (!result) {
8506 return error::kOutOfBounds;
8507 }
[email protected]07d0cc82010-02-17 04:51:408508 // Check that the client initialized the result.
8509 if (result->success != 0) {
8510 return error::kInvalidArguments;
8511 }
[email protected]6b8cf1a2010-05-06 16:13:588512 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader(
8513 program, "glGetActiveAttrib");
[email protected]ae51d192010-04-27 00:48:038514 if (!info) {
[email protected]0bfd9882010-02-05 23:02:258515 return error::kNoError;
8516 }
8517 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info =
8518 info->GetAttribInfo(index);
8519 if (!attrib_info) {
[email protected]ad84a3a2012-06-08 21:42:438520 SetGLError(GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258521 return error::kNoError;
8522 }
8523 result->success = 1; // true.
8524 result->size = attrib_info->size;
8525 result->type = attrib_info->type;
8526 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298527 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148528 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328529}
8530
[email protected]b273e432010-04-12 17:23:588531error::Error GLES2DecoderImpl::HandleShaderBinary(
8532 uint32 immediate_data_size, const gles2::ShaderBinary& c) {
8533#if 1 // No binary shader support.
[email protected]ad84a3a2012-06-08 21:42:438534 SetGLError(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588535 return error::kNoError;
8536#else
8537 GLsizei n = static_cast<GLsizei>(c.n);
8538 if (n < 0) {
[email protected]ad84a3a2012-06-08 21:42:438539 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588540 return error::kNoError;
8541 }
8542 GLsizei length = static_cast<GLsizei>(c.length);
8543 if (length < 0) {
[email protected]ad84a3a2012-06-08 21:42:438544 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588545 return error::kNoError;
8546 }
8547 uint32 data_size;
8548 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8549 return error::kOutOfBounds;
8550 }
8551 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8552 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8553 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8554 const void* binary = GetSharedMemoryAs<const void*>(
8555 c.binary_shm_id, c.binary_shm_offset, length);
8556 if (shaders == NULL || binary == NULL) {
8557 return error::kOutOfBounds;
8558 }
8559 scoped_array<GLuint> service_ids(new GLuint[n]);
8560 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ae51d192010-04-27 00:48:038561 ShaderManager::ShaderInfo* info = GetShaderInfo(shaders[ii]);
8562 if (!info) {
[email protected]ad84a3a2012-06-08 21:42:438563 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588564 return error::kNoError;
8565 }
[email protected]ae51d192010-04-27 00:48:038566 service_ids[ii] = info->service_id();
[email protected]b273e432010-04-12 17:23:588567 }
8568 // TODO(gman): call glShaderBinary
8569 return error::kNoError;
8570#endif
8571}
8572
[email protected]6217d392010-03-25 22:08:358573error::Error GLES2DecoderImpl::HandleSwapBuffers(
8574 uint32 immediate_data_size, const gles2::SwapBuffers& c) {
[email protected]64ace852011-05-19 21:49:498575 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088576 if (!is_offscreen && surface_->DeferSwapBuffers()) {
8577 return error::kDeferCommandUntilLater;
8578 }
8579
[email protected]64ace852011-05-19 21:49:498580 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428581 // TRACE_EVENT for gpu tests:
8582 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
8583 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8584 "width", (is_offscreen ? offscreen_size_.width() :
8585 surface_->GetSize().width()));
[email protected]64ace852011-05-19 21:49:498586 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleSwapBuffers",
8587 "offscreen", is_offscreen,
8588 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358589 // If offscreen then don't actually SwapBuffers to the display. Just copy
8590 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498591 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318592 TRACE_EVENT2("gpu", "Offscreen",
8593 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538594 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8595 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8596 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8597 // fix this.
[email protected]62e155e2012-10-23 22:43:158598 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538599 offscreen_saved_frame_buffer_->Create();
8600 glFinish();
8601 }
8602
8603 // Allocate the offscreen saved color texture.
8604 DCHECK(offscreen_saved_color_format_);
8605 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098606 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538607
8608 offscreen_saved_frame_buffer_->AttachRenderTexture(
8609 offscreen_saved_color_texture_.get());
8610 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8611 GL_FRAMEBUFFER_COMPLETE) {
8612 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8613 << "because offscreen saved FBO was incomplete.";
8614 return error::kLostContext;
8615 }
8616
[email protected]1fb8c482011-08-31 01:01:538617 // Clear the offscreen color texture.
8618 // TODO(piman): Is this still necessary?
8619 {
8620 ScopedFrameBufferBinder binder(this,
8621 offscreen_saved_frame_buffer_->id());
8622 glClearColor(0, 0, 0, 0);
8623 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8624 glDisable(GL_SCISSOR_TEST);
8625 glClear(GL_COLOR_BUFFER_BIT);
8626 RestoreClearState();
8627 }
8628
8629 UpdateParentTextureInfo();
8630 }
8631
[email protected]6217d392010-03-25 22:08:358632 ScopedGLErrorSuppressor suppressor(this);
8633
[email protected]34ff8b0c2010-10-01 20:06:028634 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138635 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278636 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]89d6ed02011-04-20 00:23:238637 return error::kNoError;
[email protected]b86b14982010-10-11 18:45:488638 } else {
[email protected]069944672012-04-25 20:52:238639 ScopedFrameBufferBinder binder(this,
8640 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138641
[email protected]069944672012-04-25 20:52:238642 if (offscreen_target_buffer_preserved_) {
8643 // Copy the target frame buffer to the saved offscreen texture.
8644 offscreen_saved_color_texture_->Copy(
8645 offscreen_saved_color_texture_->size(),
8646 offscreen_saved_color_format_);
8647 } else {
8648 // Flip the textures in the parent context via the texture manager.
8649 if (!!offscreen_saved_color_texture_info_.get())
8650 offscreen_saved_color_texture_info_->
8651 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568652
[email protected]069944672012-04-25 20:52:238653 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8654 offscreen_target_frame_buffer_->AttachRenderTexture(
8655 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488656 }
[email protected]069944672012-04-25 20:52:238657
8658 // Ensure the side effects of the copy are visible to the parent
8659 // context. There is no need to do this for ANGLE because it uses a
8660 // single D3D device for all contexts.
8661 if (!IsAngle())
8662 glFlush();
[email protected]89d6ed02011-04-20 00:23:238663 return error::kNoError;
[email protected]0c8c9d22010-06-25 17:36:398664 }
[email protected]6217d392010-03-25 22:08:358665 } else {
[email protected]111975c62012-09-06 01:37:318666 TRACE_EVENT2("gpu", "Onscreen",
8667 "width", surface_->GetSize().width(),
8668 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158669 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018670 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]5259ead82010-09-10 18:02:028671 return error::kLostContext;
[email protected]d0498742010-09-20 20:27:018672 }
[email protected]6217d392010-03-25 22:08:358673 }
8674
[email protected]89d6ed02011-04-20 00:23:238675 return error::kNoError;
[email protected]6217d392010-03-25 22:08:358676}
8677
[email protected]d4239852011-08-12 04:51:228678error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
8679 uint32 immediate_data_size, const gles2::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188680 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288681 if (!bucket || bucket->size() == 0) {
8682 return error::kInvalidArguments;
8683 }
[email protected]d4239852011-08-12 04:51:228684 typedef gles2::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188685 Result* result = GetSharedMemoryAs<Result*>(
8686 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8687 if (!result) {
8688 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108689 }
[email protected]b1d2dcb2010-05-17 19:24:188690 // Check that the client initialized the result.
8691 if (*result != 0) {
8692 return error::kInvalidArguments;
8693 }
8694 std::string feature_str;
8695 if (!bucket->GetAsString(&feature_str)) {
8696 return error::kInvalidArguments;
8697 }
8698
8699 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228700 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188701 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228702 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408703 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8704 // TODO(gman): decide how to remove the need for this const_cast.
8705 // I could make validators_ non const but that seems bad as this is the only
8706 // place it is needed. I could make some special friend class of validators
8707 // just to allow this to set them. That seems silly. I could refactor this
8708 // code to use the extension mechanism or the initialization attributes to
8709 // turn this feature on. Given that the only real point of this is to make
8710 // the conformance tests pass and given that there is lots of real work that
8711 // needs to be done it seems like refactoring for one to one of those
8712 // methods is a very low priority.
8713 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048714 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8715 force_webgl_glsl_validation_ = true;
8716 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188717 } else {
8718 return error::kNoError;
8719 }
8720
8721 *result = 1; // true.
8722 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108723}
8724
[email protected]c2f8c8402010-12-06 18:07:248725error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8726 uint32 immediate_data_size,
8727 const gles2::GetRequestableExtensionsCHROMIUM& c) {
8728 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]80eb6b52012-01-19 00:14:418729 FeatureInfo::Ref info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:298730 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:248731 bucket->SetFromString(info->extensions().c_str());
8732 return error::kNoError;
8733}
8734
8735error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
8736 uint32 immediate_data_size, const gles2::RequestExtensionCHROMIUM& c) {
8737 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288738 if (!bucket || bucket->size() == 0) {
8739 return error::kInvalidArguments;
8740 }
[email protected]c2f8c8402010-12-06 18:07:248741 std::string feature_str;
8742 if (!bucket->GetAsString(&feature_str)) {
8743 return error::kInvalidArguments;
8744 }
8745
[email protected]4b7eba92013-01-08 02:23:568746 bool desire_webgl_glsl_validation =
8747 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
8748 bool desire_standard_derivatives = false;
8749 if (force_webgl_glsl_validation_) {
8750 desire_standard_derivatives =
8751 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:048752 }
8753
[email protected]4b7eba92013-01-08 02:23:568754 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
8755 desire_standard_derivatives != derivatives_explicitly_enabled_) {
8756 force_webgl_glsl_validation_ = desire_webgl_glsl_validation;
8757 derivatives_explicitly_enabled_ = desire_standard_derivatives;
[email protected]c2f8c8402010-12-06 18:07:248758 InitializeShaderTranslator();
8759 }
8760
[email protected]302ce6d2011-07-07 23:28:118761 UpdateCapabilities();
8762
[email protected]c2f8c8402010-12-06 18:07:248763 return error::kNoError;
8764}
8765
[email protected]372e0412011-06-28 16:08:568766error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
8767 uint32 immediate_data_size, const gles2::GetMultipleIntegervCHROMIUM& c) {
8768 GLuint count = c.count;
8769 uint32 pnames_size;
8770 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8771 return error::kOutOfBounds;
8772 }
8773 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8774 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8775 if (pnames == NULL) {
8776 return error::kOutOfBounds;
8777 }
8778
8779 // We have to copy them since we use them twice so the client
8780 // can't change them between the time we validate them and the time we use
8781 // them.
8782 scoped_array<GLenum> enums(new GLenum[count]);
8783 memcpy(enums.get(), pnames, pnames_size);
8784
8785 // Count up the space needed for the result.
8786 uint32 num_results = 0;
8787 for (GLuint ii = 0; ii < count; ++ii) {
8788 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8789 if (num == 0) {
[email protected]f80e6e12012-08-31 00:43:538790 SetGLErrorInvalidEnum("glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568791 return error::kNoError;
8792 }
8793 // Num will never be more than 4.
8794 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478795 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568796 return error::kOutOfBounds;
8797 }
8798 }
8799
8800 uint32 result_size = 0;
8801 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8802 return error::kOutOfBounds;
8803 }
8804
8805 if (result_size != static_cast<uint32>(c.size)) {
8806 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:438807 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:568808 return error::kNoError;
8809 }
8810
8811 GLint* results = GetSharedMemoryAs<GLint*>(
8812 c.results_shm_id, c.results_shm_offset, result_size);
8813 if (results == NULL) {
8814 return error::kOutOfBounds;
8815 }
8816
8817 // Check the results have been cleared in case the context was lost.
8818 for (uint32 ii = 0; ii < num_results; ++ii) {
8819 if (results[ii]) {
8820 return error::kInvalidArguments;
8821 }
8822 }
8823
8824 // Get each result.
8825 GLint* start = results;
8826 for (GLuint ii = 0; ii < count; ++ii) {
8827 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:268828 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:538829 !GetHelper(enums[ii], results, &num_written)) {
[email protected]372e0412011-06-28 16:08:568830 glGetIntegerv(enums[ii], results);
8831 }
8832 results += num_written;
8833 }
8834
8835 // Just to verify. Should this be a DCHECK?
8836 if (static_cast<uint32>(results - start) != num_results) {
8837 return error::kOutOfBounds;
8838 }
8839
8840 return error::kNoError;
8841}
8842
[email protected]2318d342011-07-11 22:27:428843error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
8844 uint32 immediate_data_size, const gles2::GetProgramInfoCHROMIUM& c) {
8845 GLuint program = static_cast<GLuint>(c.program);
8846 uint32 bucket_id = c.bucket_id;
8847 Bucket* bucket = CreateBucket(bucket_id);
8848 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
8849 ProgramManager::ProgramInfo* info = NULL;
[email protected]9a14ae612011-08-08 17:51:468850 info = GetProgramInfo(program);
8851 if (!info || !info->IsValid()) {
8852 return error::kNoError;
[email protected]2318d342011-07-11 22:27:428853 }
[email protected]5d4c6b22012-02-07 08:22:288854 info->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:428855 return error::kNoError;
8856}
8857
[email protected]38d139d2011-07-14 00:38:438858error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
8859 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:438860 case GL_NO_ERROR:
8861 // TODO(kbr): improve the precision of the error code in this case.
8862 // Consider delegating to context for error code if MakeCurrent fails.
8863 return error::kUnknown;
8864 case GL_GUILTY_CONTEXT_RESET_ARB:
8865 return error::kGuilty;
8866 case GL_INNOCENT_CONTEXT_RESET_ARB:
8867 return error::kInnocent;
8868 case GL_UNKNOWN_CONTEXT_RESET_ARB:
8869 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:438870 }
8871
8872 NOTREACHED();
8873 return error::kUnknown;
8874}
8875
8876bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:098877 if (reset_status_ != GL_NO_ERROR) {
8878 return true;
8879 }
[email protected]706b69f2012-07-27 04:59:308880 if (context_->WasAllocatedUsingRobustnessExtension()) {
8881 GLenum status = GL_NO_ERROR;
8882 if (has_robustness_extension_)
8883 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:438884 if (status != GL_NO_ERROR) {
8885 // The graphics card was reset. Signal a lost context to the application.
8886 reset_status_ = status;
8887 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:098888 << " context lost via ARB/EXT_robustness. Reset status = "
8889 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:438890 return true;
8891 }
8892 }
8893 return false;
8894}
8895
[email protected]c4485aad62012-12-17 10:19:098896void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
8897 // Only loses the context once.
8898 if (reset_status_ != GL_NO_ERROR) {
8899 return;
8900 }
8901
8902 // Marks this context as lost.
8903 reset_status_ = reset_status;
8904 current_decoder_error_ = error::kLostContext;
8905
8906 // Loses the parent's context.
8907 if (parent_) {
8908 parent_->LoseContext(reset_status);
8909 }
8910
8911 // Loses any child contexts.
8912 for (ChildList::iterator it = children_.begin();
8913 it != children_.end();
8914 ++it) {
8915 (*it)->LoseContext(reset_status);
8916 }
8917}
8918
8919error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
8920 uint32 immediate_data_size, const gles2::LoseContextCHROMIUM& c) {
8921 GLenum current = static_cast<GLenum>(c.current);
8922 GLenum other = static_cast<GLenum>(c.other);
8923 if (!validators_->reset_status.IsValid(current)) {
8924 SetGLErrorInvalidEnum("glLoseContextCHROMIUM", current, "current");
8925 }
8926 if (!validators_->reset_status.IsValid(other)) {
8927 SetGLErrorInvalidEnum("glLoseContextCHROMIUM", other, "other");
8928 }
8929 group_->LoseContexts(other);
8930 reset_status_ = current;
8931 current_decoder_error_ = error::kLostContext;
8932 return error::kLostContext;
8933}
8934
[email protected]882ba1e22012-03-08 19:02:538935bool GLES2DecoderImpl::GenQueriesEXTHelper(
8936 GLsizei n, const GLuint* client_ids) {
8937 for (GLsizei ii = 0; ii < n; ++ii) {
8938 if (query_manager_->GetQuery(client_ids[ii])) {
8939 return false;
8940 }
8941 }
[email protected]c45f1972012-03-14 07:27:368942 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:538943 return true;
8944}
8945
8946void GLES2DecoderImpl::DeleteQueriesEXTHelper(
8947 GLsizei n, const GLuint* client_ids) {
8948 for (GLsizei ii = 0; ii < n; ++ii) {
8949 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
8950 if (query && !query->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:248951 if (query == state_.current_query) {
8952 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:538953 }
[email protected]c45f1972012-03-14 07:27:368954 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:538955 query_manager_->RemoveQuery(client_ids[ii]);
8956 }
8957 }
8958}
8959
[email protected]22e3f552012-03-13 01:54:198960bool GLES2DecoderImpl::ProcessPendingQueries() {
8961 if (query_manager_.get() == NULL) {
8962 return false;
8963 }
[email protected]c45f1972012-03-14 07:27:368964 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:198965 current_decoder_error_ = error::kOutOfBounds;
8966 }
8967 return query_manager_->HavePendingQueries();
8968}
8969
[email protected]882ba1e22012-03-08 19:02:538970error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
8971 uint32 immediate_data_size, const gles2::BeginQueryEXT& c) {
8972 GLenum target = static_cast<GLenum>(c.target);
8973 GLuint client_id = static_cast<GLuint>(c.id);
8974 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
8975 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
8976
[email protected]c45f1972012-03-14 07:27:368977 switch (target) {
8978 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:558979 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]0713f43d2012-12-14 22:41:308980 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:368981 break;
8982 default:
[email protected]62e155e2012-10-23 22:43:158983 if (!features().occlusion_query_boolean) {
[email protected]ad84a3a2012-06-08 21:42:438984 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "not enabled");
[email protected]c45f1972012-03-14 07:27:368985 return error::kNoError;
8986 }
8987 break;
[email protected]882ba1e22012-03-08 19:02:538988 }
8989
[email protected]e259eb412012-10-13 05:47:248990 if (state_.current_query) {
[email protected]882ba1e22012-03-08 19:02:538991 SetGLError(
[email protected]ad84a3a2012-06-08 21:42:438992 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:538993 return error::kNoError;
8994 }
8995
8996 if (client_id == 0) {
[email protected]ad84a3a2012-06-08 21:42:438997 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:538998 return error::kNoError;
8999 }
9000
9001 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9002 if (!query) {
[email protected]c45f1972012-03-14 07:27:369003 // TODO(gman): Decide if we need this check.
9004 //
[email protected]882ba1e22012-03-08 19:02:539005 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369006 //
9007 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9008 // for all Query ids but from the POV of the command buffer service maybe
9009 // you don't.
9010 //
9011 // The client can enforce this. I don't think the service cares.
9012 //
9013 // IdAllocatorInterface* id_allocator =
9014 // group_->GetIdAllocator(id_namespaces::kQueries);
9015 // if (!id_allocator->InUse(client_id)) {
9016 // SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439017 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369018 // return error::kNoError;
9019 // }
9020 query = query_manager_->CreateQuery(
9021 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539022 }
9023
[email protected]c45f1972012-03-14 07:27:369024 if (query->target() != target) {
[email protected]ad84a3a2012-06-08 21:42:439025 SetGLError(
9026 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539027 return error::kNoError;
9028 } else if (query->shm_id() != sync_shm_id ||
9029 query->shm_offset() != sync_shm_offset) {
9030 DLOG(ERROR) << "Shared memory used by query not the same as before";
9031 return error::kInvalidArguments;
9032 }
9033
[email protected]c45f1972012-03-14 07:27:369034 if (!query_manager_->BeginQuery(query)) {
9035 return error::kOutOfBounds;
9036 }
[email protected]882ba1e22012-03-08 19:02:539037
[email protected]e259eb412012-10-13 05:47:249038 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539039 return error::kNoError;
9040}
9041
9042error::Error GLES2DecoderImpl::HandleEndQueryEXT(
9043 uint32 immediate_data_size, const gles2::EndQueryEXT& c) {
9044 GLenum target = static_cast<GLenum>(c.target);
9045 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9046
[email protected]e259eb412012-10-13 05:47:249047 if (!state_.current_query) {
[email protected]ad84a3a2012-06-08 21:42:439048 SetGLError(GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539049 return error::kNoError;
9050 }
[email protected]e259eb412012-10-13 05:47:249051 if (state_.current_query->target() != target) {
[email protected]882ba1e22012-03-08 19:02:539052 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439053 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539054 return error::kNoError;
9055 }
[email protected]882ba1e22012-03-08 19:02:539056
[email protected]e259eb412012-10-13 05:47:249057 if (!query_manager_->EndQuery(state_.current_query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369058 return error::kOutOfBounds;
9059 }
9060
[email protected]e259eb412012-10-13 05:47:249061 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539062 return error::kNoError;
9063}
9064
[email protected]944b62f32012-09-27 02:20:469065bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9066 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469067 for (GLsizei ii = 0; ii < n; ++ii) {
9068 if (GetVertexAttribManager(client_ids[ii])) {
9069 return false;
9070 }
9071 }
[email protected]ab4fd7282012-10-12 16:25:579072
[email protected]62e155e2012-10-23 22:43:159073 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579074 // Emulated VAO
9075 for (GLsizei ii = 0; ii < n; ++ii) {
9076 CreateVertexAttribManager(client_ids[ii], 0);
9077 }
9078 } else {
9079 scoped_array<GLuint> service_ids(new GLuint[n]);
9080
9081 glGenVertexArraysOES(n, service_ids.get());
9082 for (GLsizei ii = 0; ii < n; ++ii) {
9083 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9084 }
[email protected]944b62f32012-09-27 02:20:469085 }
[email protected]ab4fd7282012-10-12 16:25:579086
[email protected]944b62f32012-09-27 02:20:469087 return true;
9088}
9089
9090void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9091 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469092 for (GLsizei ii = 0; ii < n; ++ii) {
9093 VertexAttribManager* vao =
9094 GetVertexAttribManager(client_ids[ii]);
9095 if (vao && !vao->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249096 if (state_.vertex_attrib_manager == vao) {
9097 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469098 }
9099 RemoveVertexAttribManager(client_ids[ii]);
9100 }
9101 }
9102}
9103
9104void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469105 VertexAttribManager* vao = NULL;
9106 GLuint service_id = 0;
9107 if (client_id != 0) {
9108 vao = GetVertexAttribManager(client_id);
9109 if (!vao) {
9110 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9111 // only allows names that have been previously generated. As such, we do
9112 // not generate new names here.
9113 SetGLError(GL_INVALID_OPERATION,
9114 "glBindVertexArrayOES", ""
9115 "bad vertex array id.");
9116 current_decoder_error_ = error::kNoError;
9117 return;
9118 } else {
9119 service_id = vao->service_id();
9120 }
[email protected]944b62f32012-09-27 02:20:469121 } else {
[email protected]ab4fd7282012-10-12 16:25:579122 vao = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469123 }
9124
[email protected]ab4fd7282012-10-12 16:25:579125 // Only set the VAO state if it's changed
[email protected]e259eb412012-10-13 05:47:249126 if (state_.vertex_attrib_manager != vao) {
9127 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159128 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579129 EmulateVertexArrayState();
9130 } else {
9131 glBindVertexArrayOES(service_id);
9132 }
9133 }
9134}
9135
9136// Used when OES_vertex_array_object isn't natively supported
9137void GLES2DecoderImpl::EmulateVertexArrayState() {
9138 // Setup the Vertex attribute state
9139 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9140 RestoreStateForAttrib(vv);
9141 }
9142
9143 // Setup the element buffer
9144 BufferManager::BufferInfo* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249145 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579146 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9147 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469148}
9149
9150bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469151 const VertexAttribManager* vao =
9152 GetVertexAttribManager(client_id);
9153 return vao && vao->IsValid() && !vao->IsDeleted();
9154}
9155
[email protected]b0af4f52011-09-28 22:04:429156error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9157 uint32 immediate_data_size,
9158 const gles2::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159159 if (!features().chromium_stream_texture) {
[email protected]b0af4f52011-09-28 22:04:429160 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439161 "glOpenStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429162 "not supported.");
9163 return error::kNoError;
9164 }
9165
9166 uint32 client_id = c.client_id;
9167 typedef gles2::CreateStreamTextureCHROMIUM::Result Result;
9168 Result* result = GetSharedMemoryAs<Result*>(
9169 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9170
[email protected]e5081262012-01-05 23:09:039171 if (!result)
9172 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429173 *result = GL_ZERO;
9174 TextureManager::TextureInfo* info =
9175 texture_manager()->GetTextureInfo(client_id);
9176 if (!info) {
9177 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439178 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429179 "bad texture id.");
9180 return error::kNoError;
9181 }
9182
9183 if (info->IsStreamTexture()) {
9184 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439185 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429186 "is already a stream texture.");
9187 return error::kNoError;
9188 }
9189
9190 if (info->target() && info->target() != GL_TEXTURE_EXTERNAL_OES) {
9191 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439192 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429193 "is already bound to incompatible target.");
9194 return error::kNoError;
9195 }
9196
9197 if (!stream_texture_manager_)
9198 return error::kInvalidArguments;
9199
9200 GLuint object_id = stream_texture_manager_->CreateStreamTexture(
9201 info->service_id(), client_id);
9202
9203 if (object_id) {
9204 info->SetStreamTexture(true);
9205 } else {
9206 SetGLError(GL_OUT_OF_MEMORY,
[email protected]ad84a3a2012-06-08 21:42:439207 "glCreateStreamTextureCHROMIUM", ""
[email protected]b0af4f52011-09-28 22:04:429208 "failed to create platform texture.");
9209 }
9210
9211 *result = object_id;
9212 return error::kNoError;
9213}
9214
9215error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9216 uint32 immediate_data_size,
9217 const gles2::DestroyStreamTextureCHROMIUM& c) {
9218 GLuint client_id = c.texture;
9219 TextureManager::TextureInfo* info =
9220 texture_manager()->GetTextureInfo(client_id);
9221 if (info && info->IsStreamTexture()) {
9222 if (!stream_texture_manager_)
9223 return error::kInvalidArguments;
9224
9225 stream_texture_manager_->DestroyStreamTexture(info->service_id());
9226 info->SetStreamTexture(false);
[email protected]b0af4f52011-09-28 22:04:429227 } else {
9228 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439229 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429230 }
9231
9232 return error::kNoError;
9233}
9234
[email protected]e51bdf32011-11-23 22:21:469235#if defined(OS_MACOSX)
9236void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9237 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9238 texture_id);
9239 if (it != texture_to_io_surface_map_.end()) {
9240 // Found a previous IOSurface bound to this texture; release it.
9241 CFTypeRef surface = it->second;
9242 CFRelease(surface);
9243 texture_to_io_surface_map_.erase(it);
9244 }
9245}
9246#endif
9247
9248void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9249 GLenum target, GLsizei width, GLsizei height,
9250 GLuint io_surface_id, GLuint plane) {
9251#if defined(OS_MACOSX)
9252 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ad84a3a2012-06-08 21:42:439253 SetGLError(
9254 GL_INVALID_OPERATION,
9255 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469256 return;
9257 }
9258
9259 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9260 if (!surface_support) {
9261 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439262 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469263 return;
9264 }
9265
9266 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9267 // This might be supported in the future, and if we could require
9268 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9269 // could delete a lot of code. For now, perform strict validation so we
9270 // know what's going on.
9271 SetGLError(
9272 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439273 "glTexImageIOSurface2DCHROMIUM",
9274 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469275 return;
9276 }
9277
[email protected]09d50362012-10-18 20:54:379278 // Default target might be conceptually valid, but disallow it to avoid
9279 // accidents.
9280 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9281 target);
[email protected]e51bdf32011-11-23 22:21:469282 if (!info) {
9283 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439284 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469285 return;
9286 }
[email protected]e51bdf32011-11-23 22:21:469287
9288 // Look up the new IOSurface. Note that because of asynchrony
9289 // between processes this might fail; during live resizing the
9290 // plugin process might allocate and release an IOSurface before
9291 // this process gets a chance to look it up. Hold on to any old
9292 // IOSurface in this case.
9293 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9294 if (!surface) {
[email protected]ad84a3a2012-06-08 21:42:439295 SetGLError(
9296 GL_INVALID_OPERATION,
9297 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469298 return;
9299 }
9300
9301 // Release any IOSurface previously bound to this texture.
9302 ReleaseIOSurfaceForTexture(info->service_id());
9303
9304 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9305 texture_to_io_surface_map_.insert(
9306 std::make_pair(info->service_id(), surface));
9307
9308 CGLContextObj context =
9309 static_cast<CGLContextObj>(context_->GetHandle());
9310
9311 CGLError err = surface_support->CGLTexImageIOSurface2D(
9312 context,
9313 target,
9314 GL_RGBA,
9315 width,
9316 height,
9317 GL_BGRA,
9318 GL_UNSIGNED_INT_8_8_8_8_REV,
9319 surface,
9320 plane);
9321
9322 if (err != kCGLNoError) {
9323 SetGLError(
9324 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439325 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469326 return;
9327 }
9328
9329 texture_manager()->SetLevelInfo(
[email protected]80eb6b52012-01-19 00:14:419330 info, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469331 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9332
9333#else
9334 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439335 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469336#endif
9337}
9338
[email protected]97dc7cbe2011-12-06 17:26:179339static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9340 switch (internalformat) {
9341 case GL_RGB565:
9342 return GL_RGB;
9343 case GL_RGBA4:
9344 return GL_RGBA;
9345 case GL_RGB5_A1:
9346 return GL_RGBA;
9347 case GL_RGB8_OES:
9348 return GL_RGB;
9349 case GL_RGBA8_OES:
9350 return GL_RGBA;
9351 case GL_LUMINANCE8_ALPHA8_EXT:
9352 return GL_LUMINANCE_ALPHA;
9353 case GL_LUMINANCE8_EXT:
9354 return GL_LUMINANCE;
9355 case GL_ALPHA8_EXT:
9356 return GL_ALPHA;
9357 case GL_RGBA32F_EXT:
9358 return GL_RGBA;
9359 case GL_RGB32F_EXT:
9360 return GL_RGB;
9361 case GL_ALPHA32F_EXT:
9362 return GL_ALPHA;
9363 case GL_LUMINANCE32F_EXT:
9364 return GL_LUMINANCE;
9365 case GL_LUMINANCE_ALPHA32F_EXT:
9366 return GL_LUMINANCE_ALPHA;
9367 case GL_RGBA16F_EXT:
9368 return GL_RGBA;
9369 case GL_RGB16F_EXT:
9370 return GL_RGB;
9371 case GL_ALPHA16F_EXT:
9372 return GL_ALPHA;
9373 case GL_LUMINANCE16F_EXT:
9374 return GL_LUMINANCE;
9375 case GL_LUMINANCE_ALPHA16F_EXT:
9376 return GL_LUMINANCE_ALPHA;
9377 case GL_BGRA8_EXT:
9378 return GL_BGRA_EXT;
9379 default:
9380 return GL_NONE;
9381 }
9382}
9383
[email protected]43410e92012-04-20 17:06:289384void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039385 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
9386 GLenum internal_format) {
[email protected]43410e92012-04-20 17:06:289387 TextureManager::TextureInfo* dest_info = GetTextureInfo(dest_id);
9388 TextureManager::TextureInfo* source_info = GetTextureInfo(source_id);
9389
9390 if (!source_info || !dest_info) {
[email protected]ad84a3a2012-06-08 21:42:439391 SetGLError(GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289392 return;
9393 }
9394
9395 if (GL_TEXTURE_2D != target) {
9396 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439397 "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289398 return;
9399 }
9400
[email protected]0a1e9ad2012-05-04 21:13:039401 if (dest_info->target() != GL_TEXTURE_2D ||
9402 source_info->target() != GL_TEXTURE_2D) {
9403 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439404 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039405 return;
9406 }
9407
[email protected]43410e92012-04-20 17:06:289408 int source_width, source_height, dest_width, dest_height;
9409 if (!source_info->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
9410 &source_height)) {
9411 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439412 "glCopyTextureChromium", "source texture has no level 0");
[email protected]43410e92012-04-20 17:06:289413 return;
9414 }
9415
[email protected]43410e92012-04-20 17:06:289416 // Check that this type of texture is allowed.
9417 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
9418 source_height, 1)) {
9419 SetGLError(GL_INVALID_VALUE,
[email protected]ad84a3a2012-06-08 21:42:439420 "glCopyTextureCHROMIUM", "Bad dimensions");
[email protected]43410e92012-04-20 17:06:289421 return;
9422 }
9423
[email protected]cf6b8f62012-05-25 21:43:379424 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9425 // needed because it takes 10s of milliseconds to initialize.
9426 if (!copy_texture_CHROMIUM_.get()) {
9427 CopyRealGLErrorsToWrapper();
9428 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
9429 copy_texture_CHROMIUM_->Initialize();
9430 RestoreCurrentFramebufferBindings();
9431 if (PeekGLError() != GL_NO_ERROR)
9432 return;
9433 }
9434
[email protected]0a1e9ad2012-05-04 21:13:039435 GLenum dest_type;
9436 GLenum dest_internal_format;
9437 bool dest_level_defined = dest_info->GetLevelSize(GL_TEXTURE_2D, level,
9438 &dest_width,
9439 &dest_height);
[email protected]43410e92012-04-20 17:06:289440
[email protected]0a1e9ad2012-05-04 21:13:039441 if (dest_level_defined) {
9442 dest_info->GetLevelType(GL_TEXTURE_2D, level, &dest_type,
9443 &dest_internal_format);
9444 } else {
9445 GLenum source_internal_format;
9446 source_info->GetLevelType(GL_TEXTURE_2D, 0, &dest_type,
9447 &source_internal_format);
9448 }
9449
9450 // Resize the destination texture to the dimensions of the source texture.
9451 if (!dest_level_defined || dest_width != source_width ||
9452 dest_height != source_height ||
9453 dest_internal_format != internal_format) {
[email protected]43410e92012-04-20 17:06:289454 // Ensure that the glTexImage2D succeeds.
9455 CopyRealGLErrorsToWrapper();
[email protected]0a1e9ad2012-05-04 21:13:039456 glBindTexture(GL_TEXTURE_2D, dest_info->service_id());
[email protected]43410e92012-04-20 17:06:289457 WrappedTexImage2D(
9458 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039459 0, internal_format, dest_type, NULL);
[email protected]43410e92012-04-20 17:06:289460 GLenum error = PeekGLError();
[email protected]0a1e9ad2012-05-04 21:13:039461 if (error != GL_NO_ERROR) {
9462 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289463 return;
[email protected]0a1e9ad2012-05-04 21:13:039464 }
[email protected]43410e92012-04-20 17:06:289465
9466 texture_manager()->SetLevelInfo(
9467 dest_info, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039468 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259469 } else {
[email protected]60f22d32012-12-12 00:31:589470 texture_manager()->SetLevelCleared(dest_info, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289471 }
9472
[email protected]88a61bf2012-10-27 13:00:429473 clear_state_dirty_ = true;
[email protected]0a1e9ad2012-05-04 21:13:039474 glViewport(0, 0, source_width, source_height);
[email protected]43410e92012-04-20 17:06:289475 copy_texture_CHROMIUM_->DoCopyTexture(target, source_info->service_id(),
9476 dest_info->service_id(), level,
9477 unpack_flip_y_,
[email protected]6c75c712012-06-19 15:43:179478 unpack_premultiply_alpha_,
9479 unpack_unpremultiply_alpha_);
[email protected]e259eb412012-10-13 05:47:249480 glViewport(
9481 state_.viewport_x, state_.viewport_y,
9482 state_.viewport_width, state_.viewport_height);
[email protected]43410e92012-04-20 17:06:289483
9484 // Restore all of the state touched by the extension.
[email protected]e259eb412012-10-13 05:47:249485 if (state_.current_program)
9486 glUseProgram(state_.current_program->service_id());
[email protected]43410e92012-04-20 17:06:289487 else
9488 glUseProgram(0);
9489
9490 RestoreCurrentFramebufferBindings();
9491 RestoreCurrentTexture2DBindings();
9492 RestoreStateForAttrib(
9493 CopyTextureCHROMIUMResourceManager::kVertexPositionAttrib);
9494 RestoreStateForAttrib(
9495 CopyTextureCHROMIUMResourceManager::kVertexTextureAttrib);
9496
9497 ApplyDirtyState();
9498}
9499
[email protected]97dc7cbe2011-12-06 17:26:179500static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9501 switch (internalformat) {
9502 case GL_RGB565:
9503 return GL_UNSIGNED_SHORT_5_6_5;
9504 case GL_RGBA4:
9505 return GL_UNSIGNED_SHORT_4_4_4_4;
9506 case GL_RGB5_A1:
9507 return GL_UNSIGNED_SHORT_5_5_5_1;
9508 case GL_RGB8_OES:
9509 return GL_UNSIGNED_BYTE;
9510 case GL_RGBA8_OES:
9511 return GL_UNSIGNED_BYTE;
9512 case GL_LUMINANCE8_ALPHA8_EXT:
9513 return GL_UNSIGNED_BYTE;
9514 case GL_LUMINANCE8_EXT:
9515 return GL_UNSIGNED_BYTE;
9516 case GL_ALPHA8_EXT:
9517 return GL_UNSIGNED_BYTE;
9518 case GL_RGBA32F_EXT:
9519 return GL_FLOAT;
9520 case GL_RGB32F_EXT:
9521 return GL_FLOAT;
9522 case GL_ALPHA32F_EXT:
9523 return GL_FLOAT;
9524 case GL_LUMINANCE32F_EXT:
9525 return GL_FLOAT;
9526 case GL_LUMINANCE_ALPHA32F_EXT:
9527 return GL_FLOAT;
9528 case GL_RGBA16F_EXT:
9529 return GL_HALF_FLOAT_OES;
9530 case GL_RGB16F_EXT:
9531 return GL_HALF_FLOAT_OES;
9532 case GL_ALPHA16F_EXT:
9533 return GL_HALF_FLOAT_OES;
9534 case GL_LUMINANCE16F_EXT:
9535 return GL_HALF_FLOAT_OES;
9536 case GL_LUMINANCE_ALPHA16F_EXT:
9537 return GL_HALF_FLOAT_OES;
9538 case GL_BGRA8_EXT:
9539 return GL_UNSIGNED_BYTE;
9540 default:
9541 return GL_NONE;
9542 }
9543}
9544
9545void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449546 GLenum target,
9547 GLint levels,
9548 GLenum internal_format,
9549 GLsizei width,
9550 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389551 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419552 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179553 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ad84a3a2012-06-08 21:42:439554 SetGLError(
9555 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179556 return;
9557 }
9558 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9559 if (!info) {
9560 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439561 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179562 return;
9563 }
9564 if (info->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:429565 clear_state_dirty_ = true;
[email protected]97dc7cbe2011-12-06 17:26:179566 }
9567 if (info->IsImmutable()) {
9568 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439569 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179570 return;
9571 }
9572 CopyRealGLErrorsToWrapper();
[email protected]f0e6a34f2012-01-04 20:53:409573 glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format),
9574 width, height);
[email protected]97dc7cbe2011-12-06 17:26:179575 GLenum error = PeekGLError();
9576 if (error == GL_NO_ERROR) {
9577 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9578 GLenum type = ExtractTypeFromStorageFormat(internal_format);
[email protected]4502e6492011-12-14 19:39:159579 GLsizei level_width = width;
9580 GLsizei level_height = height;
9581 for (int ii = 0; ii < levels; ++ii) {
9582 texture_manager()->SetLevelInfo(
[email protected]e071ea72012-11-26 22:29:599583 info, target, ii, format, level_width, level_height, 1, 0, format,
[email protected]80eb6b52012-01-19 00:14:419584 type, false);
[email protected]4502e6492011-12-14 19:39:159585 level_width = std::max(1, level_width >> 1);
9586 level_height = std::max(1, level_height >> 1);
9587 }
[email protected]97dc7cbe2011-12-06 17:26:179588 info->SetImmutable(true);
9589 }
[email protected]97dc7cbe2011-12-06 17:26:179590}
[email protected]e51bdf32011-11-23 22:21:469591
[email protected]78b514b2012-05-01 21:50:599592error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
9593 uint32 immediate_data_size, const gles2::GenMailboxCHROMIUM& c) {
9594 MailboxName name;
9595 mailbox_manager()->GenerateMailboxName(&name);
9596 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
9597 Bucket* bucket = CreateBucket(bucket_id);
9598
9599 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
9600 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
9601
9602 return error::kNoError;
9603}
9604
9605void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9606 const GLbyte* mailbox) {
9607 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9608 if (!info) {
9609 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439610 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599611 return;
9612 }
9613
9614 TextureDefinition* definition = texture_manager()->Save(info);
9615 if (!definition) {
9616 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439617 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599618 return;
9619 }
9620
9621 if (!group_->mailbox_manager()->ProduceTexture(
9622 target,
9623 *reinterpret_cast<const MailboxName*>(mailbox),
9624 definition,
9625 texture_manager())) {
9626 bool success = texture_manager()->Restore(info, definition);
9627 DCHECK(success);
9628 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439629 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599630 return;
9631 }
9632
9633 BindAndApplyTextureParameters(info);
9634}
9635
9636void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9637 const GLbyte* mailbox) {
9638 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9639 if (!info) {
9640 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439641 "glConsumeTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599642 return;
9643 }
9644
9645 scoped_ptr<TextureDefinition> definition(
9646 group_->mailbox_manager()->ConsumeTexture(
9647 target,
9648 *reinterpret_cast<const MailboxName*>(mailbox)));
9649 if (!definition.get()) {
9650 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439651 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599652 return;
9653 }
9654
9655 if (!texture_manager()->Restore(info, definition.release())) {
9656 SetGLError(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439657 "glConsumeTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599658 return;
9659 }
9660
9661 BindAndApplyTextureParameters(info);
9662}
9663
[email protected]d2a0e1a2012-08-12 02:25:019664void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9665 GLsizei length, const GLchar* marker) {
9666 if (!marker) {
9667 marker = "";
9668 }
9669 debug_marker_manager_.SetMarker(
9670 length ? std::string(marker, length) : std::string(marker));
9671}
9672
9673void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9674 GLsizei length, const GLchar* marker) {
9675 if (!marker) {
9676 marker = "";
9677 }
9678 debug_marker_manager_.PushGroup(
9679 length ? std::string(marker, length) : std::string(marker));
9680}
9681
9682void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9683 debug_marker_manager_.PopGroup();
9684}
9685
[email protected]09d50362012-10-18 20:54:379686void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9687 GLenum target, GLint image_id) {
9688 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9689 if (target != GL_TEXTURE_2D) {
9690 // This might be supported in the future.
9691 SetGLError(
9692 GL_INVALID_OPERATION,
9693 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9694 return;
9695 }
9696
9697 // Default target might be conceptually valid, but disallow it to avoid
9698 // accidents.
9699 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9700 target);
9701 if (!info) {
9702 SetGLError(GL_INVALID_OPERATION,
9703 "glBindTexImage2DCHROMIUM", "no texture bound");
9704 return;
9705 }
9706
9707 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9708 if (!gl_image) {
9709 SetGLError(GL_INVALID_OPERATION,
9710 "glBindTexImage2DCHROMIUM",
9711 "no image found with the given ID");
9712 return;
9713 }
9714
9715 if (!gl_image->BindTexImage()) {
9716 SetGLError(GL_INVALID_OPERATION,
9717 "glBindTexImage2DCHROMIUM",
9718 "fail to bind image with the given ID");
9719 return;
9720 }
9721
9722 gfx::Size size = gl_image->GetSize();
9723 texture_manager()->SetLevelInfo(
9724 info, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
9725 GL_RGBA, GL_UNSIGNED_BYTE, true);
9726 texture_manager()->SetLevelImage(info, target, 0, gl_image);
9727}
9728
9729void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
9730 GLenum target, GLint image_id) {
9731 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
9732 if (target != GL_TEXTURE_2D) {
9733 // This might be supported in the future.
9734 SetGLError(
9735 GL_INVALID_OPERATION,
9736 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9737 return;
9738 }
9739
9740 // Default target might be conceptually valid, but disallow it to avoid
9741 // accidents.
9742 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
9743 target);
9744 if (!info) {
9745 SetGLError(GL_INVALID_OPERATION,
9746 "glReleaseTexImage2DCHROMIUM", "no texture bound");
9747 return;
9748 }
9749
9750 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9751 if (!gl_image) {
9752 SetGLError(GL_INVALID_OPERATION,
9753 "glReleaseTexImage2DCHROMIUM",
9754 "no image found with the given ID");
9755 return;
9756 }
9757
9758 // Do nothing when image is not currently bound.
9759 if (info->GetLevelImage(target, 0) != gl_image)
9760 return;
9761
9762 gl_image->ReleaseTexImage();
9763
9764 texture_manager()->SetLevelInfo(
9765 info, target, 0, GL_RGBA, 0, 0, 1, 0,
9766 GL_RGBA, GL_UNSIGNED_BYTE, false);
9767}
[email protected]d2a0e1a2012-08-12 02:25:019768
[email protected]94307712012-11-16 23:26:119769error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
9770 uint32 immediate_data_size, const gles2::TraceBeginCHROMIUM& c) {
9771 Bucket* bucket = GetBucket(c.bucket_id);
9772 if (!bucket || bucket->size() == 0) {
9773 return error::kInvalidArguments;
9774 }
9775 std::string command_name;
9776 if (!bucket->GetAsString(&command_name)) {
9777 return error::kInvalidArguments;
9778 }
9779
9780 linked_ptr<GPUTrace> trace(new GPUTrace(command_name));
9781 trace->EnableStartTrace();
9782 gpu_trace_stack_.push(trace);
9783
9784 return error::kNoError;
9785}
9786
9787void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
9788 if (gpu_trace_stack_.empty()) {
9789 SetGLError(GL_INVALID_OPERATION,
9790 "glTraceEndCHROMIUM", "no trace begin found");
9791 return;
9792 }
9793
9794 linked_ptr<GPUTrace> trace = gpu_trace_stack_.top();
9795 trace->EnableEndTrace();
9796 gpu_trace_stack_.pop();
9797}
9798
[email protected]32145a92012-12-17 09:01:599799bool GLES2DecoderImpl::ValidateAsyncTransfer(
9800 const char* function_name,
9801 TextureManager::TextureInfo* info,
9802 GLenum target,
9803 GLint level,
9804 const void * data) {
9805 // We only support async uploads to 2D textures for now.
9806 if (GL_TEXTURE_2D != target) {
9807 SetGLErrorInvalidEnum(function_name, target, "target");
9808 return false;
9809 }
9810 // We only support uploads to level zero for now.
9811 if (level != 0) {
9812 SetGLError(GL_INVALID_VALUE, function_name, "level != 0");
9813 return false;
9814 }
9815 // A transfer buffer must be bound, even for asyncTexImage2D.
9816 if (data == NULL) {
9817 SetGLError(GL_INVALID_OPERATION, function_name, "buffer == 0");
9818 return false;
9819 }
9820 // We only support one async transfer in progress.
9821 if (!info || info->AsyncTransferIsInProgress()) {
9822 SetGLError(GL_INVALID_OPERATION,
9823 function_name, "transfer already in progress");
9824 return false;
9825 }
9826 return true;
9827}
9828
[email protected]69023942012-11-30 19:57:169829error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
9830 uint32 immediate_data_size, const gles2::AsyncTexImage2DCHROMIUM& c) {
9831 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:169832 GLenum target = static_cast<GLenum>(c.target);
9833 GLint level = static_cast<GLint>(c.level);
9834 GLint internal_format = static_cast<GLint>(c.internalformat);
9835 GLsizei width = static_cast<GLsizei>(c.width);
9836 GLsizei height = static_cast<GLsizei>(c.height);
9837 GLint border = static_cast<GLint>(c.border);
9838 GLenum format = static_cast<GLenum>(c.format);
9839 GLenum type = static_cast<GLenum>(c.type);
9840 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9841 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
9842 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:599843
9844 // TODO(epenner): Move this and copies of this memory validation
9845 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:169846 if (!GLES2Util::ComputeImageDataSizes(
9847 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
9848 NULL)) {
9849 return error::kOutOfBounds;
9850 }
9851 const void* pixels = NULL;
9852 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9853 pixels = GetSharedMemoryAs<const void*>(
9854 pixels_shm_id, pixels_shm_offset, pixels_size);
9855 if (!pixels) {
9856 return error::kOutOfBounds;
9857 }
9858 }
9859
[email protected]32145a92012-12-17 09:01:599860 // All the normal glTexSubImage2D validation.
9861 if (!ValidateTexImage2D(
9862 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
9863 width, height, border, format, type, pixels, pixels_size)) {
9864 return error::kNoError;
9865 }
9866
9867 // Extra async validation.
9868 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9869 if (!ValidateAsyncTransfer(
9870 "glAsyncTexImage2DCHROMIUM", info, target, level, pixels))
9871 return error::kNoError;
9872
9873 // Don't allow async redefinition of a textures.
9874 if (info->IsDefined()) {
9875 SetGLError(GL_INVALID_OPERATION,
9876 "glAsyncTexImage2DCHROMIUM", "already defined");
9877 return error::kNoError;
9878 }
9879
9880 // We know the memory/size is safe, so get the real shared memory since
9881 // it might need to be duped to prevent use-after-free of the memory.
9882 Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
9883 base::SharedMemory* shared_memory = buffer.shared_memory;
9884 uint32 shm_size = buffer.size;
9885 uint32 shm_data_offset = c.pixels_shm_offset;
9886 uint32 shm_data_size = pixels_size;
9887
9888 // Set up the async state if needed, and make the texture
9889 // immutable so the async state stays valid. The level info
9890 // is set up lazily when the transfer completes.
9891 DCHECK(!info->GetAsyncTransferState());
9892 info->SetAsyncTransferState(
9893 async_pixel_transfer_delegate_->
9894 CreatePixelTransferState(info->service_id()));
9895 info->SetImmutable(true);
9896
9897 // Issue the async call and set up the texture.
9898 GLenum gl_internal_format =
9899 GetTexInternalFormat(internal_format, format, type);
9900 gfx::AsyncTexImage2DParams tex_params = {target, level, gl_internal_format,
9901 width, height, border, format, type};
9902 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
9903 shm_data_offset, shm_data_size};
9904
9905 // Add a pending transfer to the texture manager, which will bind the
9906 // transfer data to the texture and set the level info at the same time,
9907 // after the the transfer is complete.
9908 texture_manager()->AddPendingAsyncPixelTransfer(
9909 info->GetAsyncTransferState()->AsWeakPtr(), info);
9910
9911 async_pixel_transfer_delegate_->AsyncTexImage2D(
9912 info->GetAsyncTransferState(), tex_params, mem_params);
[email protected]f598f422012-12-07 08:30:039913 return error::kNoError;
[email protected]69023942012-11-30 19:57:169914}
9915
9916error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
9917 uint32 immediate_data_size, const gles2::AsyncTexSubImage2DCHROMIUM& c) {
9918 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:169919 GLenum target = static_cast<GLenum>(c.target);
9920 GLint level = static_cast<GLint>(c.level);
9921 GLint xoffset = static_cast<GLint>(c.xoffset);
9922 GLint yoffset = static_cast<GLint>(c.yoffset);
9923 GLsizei width = static_cast<GLsizei>(c.width);
9924 GLsizei height = static_cast<GLsizei>(c.height);
9925 GLenum format = static_cast<GLenum>(c.format);
9926 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:599927
9928 // TODO(epenner): Move this and copies of this memory validation
9929 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:169930 uint32 data_size;
9931 if (!GLES2Util::ComputeImageDataSizes(
9932 width, height, format, type, state_.unpack_alignment, &data_size,
9933 NULL, NULL)) {
9934 return error::kOutOfBounds;
9935 }
9936 const void* pixels = GetSharedMemoryAs<const void*>(
9937 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:599938
9939 // All the normal glTexSubImage2D validation.
9940 error::Error error = error::kNoError;
9941 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
9942 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
9943 return error;
[email protected]69023942012-11-30 19:57:169944 }
9945
[email protected]32145a92012-12-17 09:01:599946 // Extra async validation.
9947 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
9948 if (!ValidateAsyncTransfer(
9949 "glAsyncTexSubImage2DCHROMIUM", info, target, level, pixels))
9950 return error::kNoError;
9951
9952 // Guarantee async textures are always 'cleared' as follows:
9953 // - AsyncTexImage2D can not redefine an existing texture
9954 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
9955 // - AsyncTexSubImage2D clears synchronously if not already cleared.
9956 // - Textures become immutable after an async call.
9957 // This way we know in all cases that an async texture is always clear.
9958 if (!info->SafeToRenderFrom()) {
9959 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
9960 SetGLError(GL_OUT_OF_MEMORY,
9961 "glAsyncTexSubImage2DCHROMIUM","dimensions too big");
9962 return error::kNoError;
9963 }
9964 }
9965
9966 // We know the memory/size is safe, so get the real shared memory since
9967 // it might need to be duped to prevent use-after-free of the memory.
9968 Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
9969 base::SharedMemory* shared_memory = buffer.shared_memory;
9970 uint32 shm_size = buffer.size;
9971 uint32 shm_data_offset = c.data_shm_offset;
9972 uint32 shm_data_size = data_size;
9973
9974 if (!info->GetAsyncTransferState()) {
9975 // Set up the async state if needed, and make the texture
9976 // immutable so the async state stays valid.
9977 info->SetAsyncTransferState(
9978 async_pixel_transfer_delegate_->
9979 CreatePixelTransferState(info->service_id()));
9980 info->SetImmutable(true);
9981 }
9982
9983 gfx::AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
9984 width, height, format, type};
9985 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
9986 shm_data_offset, shm_data_size};
9987 async_pixel_transfer_delegate_->AsyncTexSubImage2D(
9988 info->GetAsyncTransferState(), tex_params, mem_params);
9989 return error::kNoError;
[email protected]69023942012-11-30 19:57:169990}
9991
[email protected]96449d2c2009-11-25 00:01:329992// Include the auto-generated part of this file. We split this because it means
9993// we can easily edit the non-auto generated parts right here in this file
9994// instead of having to edit some template or the code generator.
9995#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
9996
9997} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:259998} // namespace gpu