blob: 863b9ec0ddd889c3b80d18d9039817b6feae7db1 [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]fb97b662013-02-20 23:02:1443#include "gpu/command_buffer/service/gpu_tracer.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]d8bc3ec2013-03-07 06:28:4060#include "ui/gl/gl_bindings.h"
[email protected]09d50362012-10-18 20:54:3761#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2762#include "ui/gl/gl_implementation.h"
63#include "ui/gl/gl_surface.h"
[email protected]e51bdf32011-11-23 22:21:4664#if defined(OS_MACOSX)
[email protected]d353541f2012-05-03 22:45:4165#include "ui/surface/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4666#endif
[email protected]de17df392010-04-23 21:09:4167
[email protected]693ca512012-11-13 18:09:1368// TODO(zmo): we can't include "City.h" due to type def conflicts.
69extern uint64 CityHash64(const char*, size_t);
70
[email protected]a7a27ace2009-12-12 00:11:2571namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3272namespace gles2 {
73
[email protected]f0d74742011-10-03 16:31:0474namespace {
[email protected]693ca512012-11-13 18:09:1375
[email protected]f0d74742011-10-03 16:31:0476static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]693ca512012-11-13 18:09:1377
[email protected]3d944a82013-02-12 19:09:0278#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]693ca512012-11-13 18:09:1379khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
80 return static_cast<khronos_uint64_t>(
81 CityHash64(name, static_cast<size_t>(len)));
82}
[email protected]3d944a82013-02-12 19:09:0283#endif
[email protected]693ca512012-11-13 18:09:1384
[email protected]8dc1bf92013-03-12 03:58:2185static void GetShaderPrecisionFormatImpl(GLenum shader_type,
86 GLenum precision_type,
87 GLint *range, GLint *precision) {
88 switch (precision_type) {
89 case GL_LOW_INT:
90 case GL_MEDIUM_INT:
91 case GL_HIGH_INT:
92 // These values are for a 32-bit twos-complement integer format.
93 range[0] = 31;
94 range[1] = 30;
95 *precision = 0;
96 break;
97 case GL_LOW_FLOAT:
98 case GL_MEDIUM_FLOAT:
99 case GL_HIGH_FLOAT:
100 // These values are for an IEEE single-precision floating-point format.
101 range[0] = 127;
102 range[1] = 127;
103 *precision = 23;
104 break;
105 default:
106 NOTREACHED();
107 break;
108 }
109
[email protected]8af4d5e2013-03-15 23:55:33110 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
111 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21112 // This function is sometimes defined even though it's really just
113 // a stub, so we need to set range and precision as if it weren't
114 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44115 // On Mac OS with some GPUs, calling this generates a
116 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
117 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21118 glGetShaderPrecisionFormat(shader_type, precision_type,
119 range, precision);
120 }
121}
122
[email protected]b04e24c2013-01-08 18:35:25123} // namespace
[email protected]f0d74742011-10-03 16:31:04124
[email protected]6217d392010-03-25 22:08:35125class GLES2DecoderImpl;
126
[email protected]ab09b612013-03-11 22:11:51127// Local versions of the SET_GL_ERROR macros
128#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
129 GLESDECODER_SET_GL_ERROR(this, error, function_name, msg)
130#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
131 GLESDECODER_SET_GL_ERROR_INVALID_ENUM(this, function_name, value, label)
132#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
133 GLESDECODER_SET_GL_ERROR_INVALID_PARAM(this, error, function_name, pname)
134#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
135 GLESDECODER_COPY_REAL_GL_ERRORS_TO_WRAPPER(this, function_name)
136#define LOCAL_PEEK_GL_ERROR(function_name) \
137 GLESDECODER_PEEK_GL_ERROR(this, function_name)
138#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
139 GLESDECODER_CLEARREAL_GL_ERRORS(this, function_name)
140#define LOCAL_PERFORMANCE_WARNING(msg) \
141 PerformanceWarning(__FILE__, __LINE__, msg)
142#define LOCAL_RENDER_WARNING(msg) \
143 RenderWarning(__FILE__, __LINE__, msg)
144
[email protected]07f54fcc2009-12-22 02:46:30145// Check that certain assumptions the code makes are true. There are places in
146// the code where shared memory is passed direclty to GL. Example, glUniformiv,
147// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
148// a few others) are 32bits. If they are not 32bits the code will have to change
149// to call those GL functions with service side memory and then copy the results
150// to shared memory, converting the sizes.
151COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
152 GLint_not_same_size_as_uint32);
153COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
154 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37155COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
156 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30157
[email protected]43f28f832010-02-03 02:28:48158// TODO(kbr): the use of this anonymous namespace core dumps the
159// linker on Mac OS X 10.6 when the symbol ordering file is used
160// namespace {
[email protected]96449d2c2009-11-25 00:01:32161
162// Returns the address of the first byte after a struct.
163template <typename T>
164const void* AddressAfterStruct(const T& pod) {
165 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
166}
167
[email protected]07f54fcc2009-12-22 02:46:30168// Returns the address of the frst byte after the struct or NULL if size >
169// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32170template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30171RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
172 uint32 size,
173 uint32 immediate_data_size) {
174 return (size <= immediate_data_size) ?
175 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
176 NULL;
[email protected]96449d2c2009-11-25 00:01:32177}
178
[email protected]07f54fcc2009-12-22 02:46:30179// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18180bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32181 GLuint count,
182 size_t size,
[email protected]a76b0052010-03-05 00:33:18183 unsigned int elements_per_unit,
184 uint32* dst) {
185 uint32 value;
186 if (!SafeMultiplyUint32(count, size, &value)) {
187 return false;
188 }
189 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
190 return false;
191 }
192 *dst = value;
193 return true;
[email protected]96449d2c2009-11-25 00:01:32194}
195
196// A struct to hold info about each command.
197struct CommandInfo {
198 int arg_flags; // How to handle the arguments for this command
199 int arg_count; // How many arguments are expected for this command.
200};
201
202// A table of CommandInfo for all the commands.
203const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35204 #define GLES2_CMD_OP(name) { \
205 cmds::name::kArgFlags, \
206 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
[email protected]96449d2c2009-11-25 00:01:32207
208 GLES2_COMMAND_LIST(GLES2_CMD_OP)
209
210 #undef GLES2_CMD_OP
211};
212
[email protected]258a3313f2011-10-18 20:13:57213// Return true if a character belongs to the ASCII subset as defined in
214// GLSL ES 1.0 spec section 3.1.
215static bool CharacterIsValidForGLES(unsigned char c) {
216 // Printing characters are valid except " $ ` @ \ ' DEL.
217 if (c >= 32 && c <= 126 &&
218 c != '"' &&
219 c != '$' &&
220 c != '`' &&
221 c != '@' &&
222 c != '\\' &&
223 c != '\'') {
224 return true;
225 }
226 // Horizontal tab, line feed, vertical tab, form feed, carriage return
227 // are also valid.
228 if (c >= 9 && c <= 13) {
229 return true;
230 }
231
232 return false;
233}
234
235static bool StringIsValidForGLES(const char* str) {
236 for (; *str; ++str) {
237 if (!CharacterIsValidForGLES(*str)) {
238 return false;
239 }
240 }
241 return true;
242}
243
[email protected]f0e6a34f2012-01-04 20:53:40244static inline GLenum GetTexInternalFormat(GLenum internal_format) {
245 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
246 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT)
247 return GL_RGBA8;
248 }
249 return internal_format;
250}
251
[email protected]32145a92012-12-17 09:01:59252// TODO(epenner): Could the above function be merged into this and removed?
253static inline GLenum GetTexInternalFormat(GLenum internal_format,
254 GLenum format,
255 GLenum type) {
256 GLenum gl_internal_format = GetTexInternalFormat(internal_format);
257
258 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
259 return gl_internal_format;
260
261 if (type == GL_FLOAT) {
262 switch (format) {
263 case GL_RGBA:
264 gl_internal_format = GL_RGBA32F_ARB;
265 break;
266 case GL_RGB:
267 gl_internal_format = GL_RGB32F_ARB;
268 break;
269 case GL_LUMINANCE_ALPHA:
270 gl_internal_format = GL_LUMINANCE_ALPHA32F_ARB;
271 break;
272 case GL_LUMINANCE:
273 gl_internal_format = GL_LUMINANCE32F_ARB;
274 break;
275 case GL_ALPHA:
276 gl_internal_format = GL_ALPHA32F_ARB;
277 break;
278 default:
279 NOTREACHED();
280 break;
281 }
282 } else if (type == GL_HALF_FLOAT_OES) {
283 switch (format) {
284 case GL_RGBA:
285 gl_internal_format = GL_RGBA16F_ARB;
286 break;
287 case GL_RGB:
288 gl_internal_format = GL_RGB16F_ARB;
289 break;
290 case GL_LUMINANCE_ALPHA:
291 gl_internal_format = GL_LUMINANCE_ALPHA16F_ARB;
292 break;
293 case GL_LUMINANCE:
294 gl_internal_format = GL_LUMINANCE16F_ARB;
295 break;
296 case GL_ALPHA:
297 gl_internal_format = GL_ALPHA16F_ARB;
298 break;
299 default:
300 NOTREACHED();
301 break;
302 }
303 }
304 return gl_internal_format;
305}
306
[email protected]297ca1c2011-06-20 23:08:46307static void WrappedTexImage2D(
[email protected]473c01ccb2011-06-07 01:33:30308 GLenum target,
309 GLint level,
310 GLenum internal_format,
311 GLsizei width,
312 GLsizei height,
313 GLint border,
314 GLenum format,
315 GLenum type,
316 const void* pixels) {
[email protected]473c01ccb2011-06-07 01:33:30317 glTexImage2D(
[email protected]32145a92012-12-17 09:01:59318 target, level, GetTexInternalFormat(internal_format, format, type),
319 width, height, border, format, type, pixels);
[email protected]473c01ccb2011-06-07 01:33:30320}
321
[email protected]297ca1c2011-06-20 23:08:46322// Wrapper for glEnable/glDisable that doesn't suck.
323static void EnableDisable(GLenum pname, bool enable) {
324 if (enable) {
325 glEnable(pname);
326 } else {
327 glDisable(pname);
328 }
329}
330
[email protected]6217d392010-03-25 22:08:35331// This class prevents any GL errors that occur when it is in scope from
332// being reported to the client.
333class ScopedGLErrorSuppressor {
334 public:
[email protected]ab09b612013-03-11 22:11:51335 explicit ScopedGLErrorSuppressor(
336 const char* function_name, GLES2DecoderImpl* decoder);
[email protected]6217d392010-03-25 22:08:35337 ~ScopedGLErrorSuppressor();
338 private:
[email protected]ab09b612013-03-11 22:11:51339 const char* function_name_;
[email protected]6217d392010-03-25 22:08:35340 GLES2DecoderImpl* decoder_;
341 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
342};
343
344// Temporarily changes a decoder's bound 2D texture and restore it when this
345// object goes out of scope. Also temporarily switches to using active texture
346// unit zero in case the client has changed that to something invalid.
347class ScopedTexture2DBinder {
348 public:
349 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
350 ~ScopedTexture2DBinder();
351
352 private:
353 GLES2DecoderImpl* decoder_;
354 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
355};
356
357// Temporarily changes a decoder's bound render buffer and restore it when this
358// object goes out of scope.
359class ScopedRenderBufferBinder {
360 public:
361 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
362 ~ScopedRenderBufferBinder();
363
364 private:
365 GLES2DecoderImpl* decoder_;
366 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
367};
368
369// Temporarily changes a decoder's bound frame buffer and restore it when this
370// object goes out of scope.
371class ScopedFrameBufferBinder {
372 public:
373 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
374 ~ScopedFrameBufferBinder();
375
376 private:
377 GLES2DecoderImpl* decoder_;
378 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
379};
380
[email protected]34ff8b0c2010-10-01 20:06:02381// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52382// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27383// if it is bound or enforce_internal_framebuffer is true. If internal is
384// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02385class ScopedResolvedFrameBufferBinder {
386 public:
[email protected]e7e38032011-07-26 17:25:25387 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27388 bool enforce_internal_framebuffer,
389 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02390 ~ScopedResolvedFrameBufferBinder();
391
392 private:
393 GLES2DecoderImpl* decoder_;
394 bool resolve_and_bind_;
395 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
396};
397
[email protected]63b465922012-09-06 02:04:52398// This class records texture upload time when in scope.
399class ScopedTextureUploadTimer {
400 public:
401 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder);
402 ~ScopedTextureUploadTimer();
403
404 private:
405 GLES2DecoderImpl* decoder_;
406 base::TimeTicks begin_time_;
407 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer);
408};
409
[email protected]6217d392010-03-25 22:08:35410// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35411class BackTexture {
[email protected]6217d392010-03-25 22:08:35412 public:
[email protected]ed9f9cd2013-02-27 21:12:35413 explicit BackTexture(GLES2DecoderImpl* decoder);
414 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35415
416 // Create a new render texture.
417 void Create();
418
419 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09420 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35421
422 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58423 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35424
425 // Destroy the render texture. This must be explicitly called before
426 // destroying this object.
427 void Destroy();
428
[email protected]97872062010-11-03 19:07:05429 // Invalidate the texture. This can be used when a context is lost and it is
430 // not possible to make it current in order to free the resource.
431 void Invalidate();
432
[email protected]6217d392010-03-25 22:08:35433 GLuint id() const {
434 return id_;
435 }
436
[email protected]d37231fa2010-04-09 21:16:02437 gfx::Size size() const {
438 return size_;
439 }
440
[email protected]1078f912011-12-23 13:12:14441 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25442 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14443 }
444
[email protected]6217d392010-03-25 22:08:35445 private:
446 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25447 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48448 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35449 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02450 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35451 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35452};
453
454// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35455class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35456 public:
[email protected]ed9f9cd2013-02-27 21:12:35457 explicit BackRenderbuffer(GLES2DecoderImpl* decoder);
458 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35459
460 // Create a new render buffer.
461 void Create();
462
463 // Set the initial size and format of a render buffer or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02464 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
[email protected]6217d392010-03-25 22:08:35465
466 // Destroy the render buffer. This must be explicitly called before destroying
467 // this object.
468 void Destroy();
469
[email protected]97872062010-11-03 19:07:05470 // Invalidate the render buffer. This can be used when a context is lost and
471 // it is not possible to make it current in order to free the resource.
472 void Invalidate();
473
[email protected]6217d392010-03-25 22:08:35474 GLuint id() const {
475 return id_;
476 }
477
[email protected]1078f912011-12-23 13:12:14478 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25479 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14480 }
481
[email protected]6217d392010-03-25 22:08:35482 private:
483 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25484 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48485 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35486 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35487 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35488};
489
490// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35491class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35492 public:
[email protected]ed9f9cd2013-02-27 21:12:35493 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
494 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35495
496 // Create a new frame buffer.
497 void Create();
498
499 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35500 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35501
[email protected]b9363b22010-06-09 22:06:15502 // Attach a render buffer to a frame buffer. Note that this unbinds any
503 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35504 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35505
[email protected]6217d392010-03-25 22:08:35506 // Destroy the frame buffer. This must be explicitly called before destroying
507 // this object.
508 void Destroy();
509
[email protected]97872062010-11-03 19:07:05510 // Invalidate the frame buffer. This can be used when a context is lost and it
511 // is not possible to make it current in order to free the resource.
512 void Invalidate();
513
[email protected]6217d392010-03-25 22:08:35514 // See glCheckFramebufferStatusEXT.
515 GLenum CheckStatus();
516
517 GLuint id() const {
518 return id_;
519 }
520
521 private:
522 GLES2DecoderImpl* decoder_;
523 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35524 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35525};
[email protected]34ff8b0c2010-10-01 20:06:02526
[email protected]43f28f832010-02-03 02:28:48527// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32528
[email protected]ddb1e5a2010-12-13 20:10:45529bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
530 uint32* service_texture_id) {
531 return false;
532}
533
[email protected]a3ded6d2010-10-19 06:44:39534GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06535 : initialized_(false),
536 debug_(false),
[email protected]b5d647c2012-02-10 01:41:32537 log_commands_(false),
538 log_synthesized_gl_errors_(true) {
[email protected]96449d2c2009-11-25 00:01:32539}
540
[email protected]3916c97e2010-02-25 03:20:50541GLES2Decoder::~GLES2Decoder() {
542}
543
[email protected]57edfdad2012-02-07 04:57:15544bool GLES2Decoder::testing_force_is_angle_;
545
546void GLES2Decoder::set_testing_force_is_angle(bool force) {
547 testing_force_is_angle_ = force;
548}
549
550bool GLES2Decoder::IsAngle() {
551#if defined(OS_WIN)
552 return testing_force_is_angle_ ||
553 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
554#else
555 return testing_force_is_angle_;
556#endif
557}
558
[email protected]f39f4b3f2010-05-12 17:04:08559// This class implements GLES2Decoder so we don't have to expose all the GLES2
560// cmd stuff to outside this class.
[email protected]ee1e6aa2012-11-29 09:24:10561class GLES2DecoderImpl : public GLES2Decoder {
[email protected]f39f4b3f2010-05-12 17:04:08562 public:
[email protected]0f8afe82012-05-14 23:43:01563 static const int kMaxLogMessages = 256;
[email protected]fa20ec82012-05-04 04:02:48564
[email protected]476ccb72012-12-06 15:52:52565 // Used by PrepForSetUniformByLocation to validate types.
566 struct BaseUniformInfo {
567 const GLenum* const valid_types;
568 size_t num_valid_types;
569 };
570
[email protected]aa7666122011-09-02 19:45:52571 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00572 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08573
[email protected]96449d2c2009-11-25 00:01:32574 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14575 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50576 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00577 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32578
579 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00580 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32581
582 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38583 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
584 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23585 bool offscreen,
[email protected]6217d392010-03-25 22:08:35586 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29587 const DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39588 const char* allowed_extensions,
[email protected]b8e97b62012-09-30 15:09:00589 const std::vector<int32>& attribs) OVERRIDE;
590 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38591 virtual void SetSurface(
592 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]3c644d82011-06-20 19:58:24593 virtual bool SetParent(GLES2Decoder* parent_decoder,
[email protected]b8e97b62012-09-30 15:09:00594 uint32 parent_texture_id) OVERRIDE;
595 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39596 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00597 virtual bool MakeCurrent() OVERRIDE;
598 virtual void ReleaseCurrent() OVERRIDE;
599 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
600 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
601 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]1868a342012-11-07 15:56:02602 virtual void RestoreState() const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06603
604 virtual void RestoreActiveTexture() const OVERRIDE {
605 state_.RestoreActiveTexture();
606 }
607 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
608 state_.RestoreAttribute(index);
609 }
610 virtual void RestoreBufferBindings() const OVERRIDE {
611 state_.RestoreBufferBindings();
612 }
613 virtual void RestoreGlobalState() const OVERRIDE {
614 state_.RestoreGlobalState();
615 }
616 virtual void RestoreProgramBindings() const OVERRIDE {
617 state_.RestoreProgramBindings();
618 }
619 virtual void RestoreRenderbufferBindings() const OVERRIDE {
620 state_.RestoreRenderbufferBindings();
621 }
622 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
623 state_.RestoreTextureUnitBindings(unit);
624 }
625 virtual void RestoreFramebufferBindings() const OVERRIDE;
626 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
627
[email protected]b8e97b62012-09-30 15:09:00628 virtual QueryManager* GetQueryManager() OVERRIDE {
629 return query_manager_.get();
630 }
631 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46632 return vertex_array_manager_.get();
633 }
[email protected]b8e97b62012-09-30 15:09:00634 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05635 virtual bool HasMoreIdleWork() OVERRIDE;
636 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48637
[email protected]9d37f062011-11-22 01:24:52638 virtual void SetResizeCallback(
[email protected]b8e97b62012-09-30 15:09:00639 const base::Callback<void(gfx::Size)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00640
[email protected]b8e97b62012-09-30 15:09:00641 virtual void SetMsgCallback(const MsgCallback& callback) OVERRIDE;
[email protected]e3932abb2013-03-13 00:01:37642 virtual void SetShaderCacheCallback(
643 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51644 virtual void SetWaitSyncPointCallback(
645 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00646
[email protected]b8e97b62012-09-30 15:09:00647 virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE;
[email protected]32145a92012-12-17 09:01:59648
649 virtual gfx::AsyncPixelTransferDelegate*
650 GetAsyncPixelTransferDelegate() OVERRIDE;
651 virtual void SetAsyncPixelTransferDelegate(
652 gfx::AsyncPixelTransferDelegate* delegate) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09653 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59654
[email protected]1318e922010-09-17 22:03:16655 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00656 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48657
[email protected]efcdd2362012-07-09 21:07:00658 virtual uint32 GetGLError() OVERRIDE;
659
[email protected]63b465922012-09-06 02:04:52660 virtual uint32 GetTextureUploadCount() OVERRIDE;
661 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
662 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30663 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52664
[email protected]8e3e0662010-08-23 18:46:30665 // Restores the current state to the user's settings.
666 void RestoreCurrentFramebufferBindings();
667 void RestoreCurrentRenderbufferBindings();
668 void RestoreCurrentTexture2DBindings();
669
[email protected]297ca1c2011-06-20 23:08:46670 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
671 void ApplyDirtyState();
672
673 // These check the state of the currently bound framebuffer or the
674 // backbuffer if no framebuffer is bound.
675 bool BoundFramebufferHasColorAttachmentWithAlpha();
676 bool BoundFramebufferHasDepthAttachment();
677 bool BoundFramebufferHasStencilAttachment();
678
[email protected]b8e97b62012-09-30 15:09:00679 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43680
[email protected]96449d2c2009-11-25 00:01:32681 private:
[email protected]70d34263c2013-01-09 00:27:45682 friend class ScopedFrameBufferBinder;
[email protected]6217d392010-03-25 22:08:35683 friend class ScopedGLErrorSuppressor;
[email protected]34ff8b0c2010-10-01 20:06:02684 friend class ScopedResolvedFrameBufferBinder;
[email protected]63b465922012-09-06 02:04:52685 friend class ScopedTextureUploadTimer;
[email protected]ed9f9cd2013-02-27 21:12:35686 friend class BackTexture;
687 friend class BackRenderbuffer;
688 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35689
[email protected]c2f8c8402010-12-06 18:07:24690 // Initialize or re-initialize the shader translator.
691 bool InitializeShaderTranslator();
692
[email protected]302ce6d2011-07-07 23:28:11693 void UpdateCapabilities();
694
[email protected]ae51d192010-04-27 00:48:03695 // Helpers for the glGen and glDelete functions.
696 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
697 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
698 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
699 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
700 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
701 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
702 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
703 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53704 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
705 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46706 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
707 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47708
[email protected]70d34263c2013-01-09 00:27:45709 // Workarounds
710 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51711 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45712
[email protected]3916c97e2010-02-25 03:20:50713 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50714 BufferManager* buffer_manager() {
715 return group_->buffer_manager();
716 }
717
[email protected]a25fa872010-03-25 02:57:58718 RenderbufferManager* renderbuffer_manager() {
719 return group_->renderbuffer_manager();
720 }
721
722 FramebufferManager* framebuffer_manager() {
723 return group_->framebuffer_manager();
724 }
725
[email protected]3916c97e2010-02-25 03:20:50726 ProgramManager* program_manager() {
727 return group_->program_manager();
728 }
729
730 ShaderManager* shader_manager() {
731 return group_->shader_manager();
732 }
733
[email protected]29a4d902013-02-26 20:18:06734 const TextureManager* texture_manager() const {
735 return group_->texture_manager();
736 }
737
[email protected]3916c97e2010-02-25 03:20:50738 TextureManager* texture_manager() {
739 return group_->texture_manager();
740 }
741
[email protected]78b514b2012-05-01 21:50:59742 MailboxManager* mailbox_manager() {
743 return group_->mailbox_manager();
744 }
745
[email protected]09d50362012-10-18 20:54:37746 ImageManager* image_manager() {
747 return group_->image_manager();
748 }
749
[email protected]944b62f32012-09-27 02:20:46750 VertexArrayManager* vertex_array_manager() {
751 return vertex_array_manager_.get();
752 }
753
[email protected]7989c9e2013-01-23 06:39:26754 MemoryTracker* memory_tracker() {
755 return group_->memory_tracker();
756 }
757
758 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
759 MemoryTracker* tracker = memory_tracker();
760 if (tracker) {
761 return tracker->EnsureGPUMemoryAvailable(estimated_size);
762 }
763 return true;
764 }
765
[email protected]34ff8b0c2010-10-01 20:06:02766 bool IsOffscreenBufferMultisampled() const {
767 return offscreen_target_samples_ > 1;
768 }
769
[email protected]ed9f9cd2013-02-27 21:12:35770 // Creates a Texture for the given texture.
771 Texture* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03772 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35773 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47774 }
775
776 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35777 Texture* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07778 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47779 }
780
781 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35782 void RemoveTexture(GLuint client_id) {
783 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50784 }
[email protected]a93bb842010-02-16 23:03:47785
[email protected]d37231fa2010-04-09 21:16:02786 // Get the size (in pixels) of the currently bound frame buffer (either FBO
787 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30788 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02789
[email protected]9edc6b22010-12-23 02:00:26790 // Get the format of the currently bound frame buffer (either FBO or regular
791 // back buffer)
792 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46793 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26794
[email protected]a93bb842010-02-16 23:03:47795 // Wrapper for CompressedTexImage2D commands.
796 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37797 GLenum target,
798 GLint level,
799 GLenum internal_format,
800 GLsizei width,
801 GLsizei height,
802 GLint border,
803 GLsizei image_size,
804 const void* data);
[email protected]a93bb842010-02-16 23:03:47805
[email protected]cadde4a2010-07-31 17:10:43806 // Wrapper for CompressedTexSubImage2D.
807 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37808 GLenum target,
809 GLint level,
810 GLint xoffset,
811 GLint yoffset,
812 GLsizei width,
813 GLsizei height,
814 GLenum format,
815 GLsizei imageSize,
816 const void * data);
[email protected]cadde4a2010-07-31 17:10:43817
818 // Wrapper for CopyTexImage2D.
819 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37820 GLenum target,
821 GLint level,
822 GLenum internal_format,
823 GLint x,
824 GLint y,
825 GLsizei width,
826 GLsizei height,
827 GLint border);
[email protected]cadde4a2010-07-31 17:10:43828
829 // Wrapper for CopyTexSubImage2D.
830 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37831 GLenum target,
832 GLint level,
833 GLint xoffset,
834 GLint yoffset,
835 GLint x,
836 GLint y,
837 GLsizei width,
838 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43839
[email protected]f598f422012-12-07 08:30:03840 // Validation for TexImage2D commands.
841 bool ValidateTexImage2D(
842 const char* function_name,
[email protected]09d50362012-10-18 20:54:37843 GLenum target,
844 GLint level,
845 GLenum internal_format,
846 GLsizei width,
847 GLsizei height,
848 GLint border,
849 GLenum format,
850 GLenum type,
851 const void* pixels,
852 uint32 pixels_size);
[email protected]a93bb842010-02-16 23:03:47853
[email protected]f598f422012-12-07 08:30:03854 // Wrapper for TexImage2D commands.
855 void DoTexImage2D(
856 GLenum target,
857 GLint level,
858 GLenum internal_format,
859 GLsizei width,
860 GLsizei height,
861 GLint border,
862 GLenum format,
863 GLenum type,
864 const void* pixels,
865 uint32 pixels_size);
866
867 // Validation for TexSubImage2D.
868 bool ValidateTexSubImage2D(
869 error::Error* error,
870 const char* function_name,
871 GLenum target,
872 GLint level,
873 GLint xoffset,
874 GLint yoffset,
875 GLsizei width,
876 GLsizei height,
877 GLenum format,
878 GLenum type,
879 const void * data);
880
[email protected]cadde4a2010-07-31 17:10:43881 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03882 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37883 GLenum target,
884 GLint level,
885 GLint xoffset,
886 GLint yoffset,
887 GLsizei width,
888 GLsizei height,
889 GLenum format,
890 GLenum type,
891 const void * data);
[email protected]cadde4a2010-07-31 17:10:43892
[email protected]32145a92012-12-17 09:01:59893 // Extra validation for async tex(Sub)Image2D.
894 bool ValidateAsyncTransfer(
895 const char* function_name,
[email protected]02965c22013-03-09 02:40:07896 Texture* texture,
[email protected]32145a92012-12-17 09:01:59897 GLenum target,
898 GLint level,
899 const void * data);
900
[email protected]e51bdf32011-11-23 22:21:46901 // Wrapper for TexImageIOSurface2DCHROMIUM.
902 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37903 GLenum target,
904 GLsizei width,
905 GLsizei height,
906 GLuint io_surface_id,
907 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46908
[email protected]43410e92012-04-20 17:06:28909 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37910 GLenum target,
911 GLuint source_id,
912 GLuint target_id,
913 GLint level,
914 GLenum internal_format);
[email protected]43410e92012-04-20 17:06:28915
[email protected]97dc7cbe2011-12-06 17:26:17916 // Wrapper for TexStorage2DEXT.
917 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37918 GLenum target,
919 GLint levels,
920 GLenum internal_format,
921 GLsizei width,
922 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17923
[email protected]78b514b2012-05-01 21:50:59924 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
925 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
926
[email protected]09d50362012-10-18 20:54:37927 void DoBindTexImage2DCHROMIUM(
928 GLenum target,
929 GLint image_id);
930 void DoReleaseTexImage2DCHROMIUM(
931 GLenum target,
932 GLint image_id);
933
[email protected]94307712012-11-16 23:26:11934 void DoTraceEndCHROMIUM(void);
935
[email protected]2f143d482013-03-14 18:04:49936 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
937
[email protected]ed9f9cd2013-02-27 21:12:35938 // Creates a Program for the given program.
939 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57940 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35941 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47942 }
943
[email protected]07f54fcc2009-12-22 02:46:30944 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35945 Program* GetProgram(GLuint client_id) {
946 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46947 }
[email protected]07f54fcc2009-12-22 02:46:30948
[email protected]cae20172012-12-07 00:06:19949#if defined(NDEBUG)
950 void LogClientServiceMapping(
951 const char* /* function_name */,
952 GLuint /* client_id */,
953 GLuint /* service_id */) {
954 }
955 template<typename T>
956 void LogClientServiceForInfo(
957 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
958 }
959#else
960 void LogClientServiceMapping(
961 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26962 if (service_logging_) {
963 DLOG(INFO) << "[" << GetLogPrefix() << "] " << function_name
964 << ": client_id = " << client_id
965 << ", service_id = " << service_id;
966 }
[email protected]cae20172012-12-07 00:06:19967 }
968 template<typename T>
969 void LogClientServiceForInfo(
970 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26971 if (info) {
[email protected]cae20172012-12-07 00:06:19972 LogClientServiceMapping(function_name, client_id, info->service_id());
973 }
974 }
975#endif
976
[email protected]6b8cf1a2010-05-06 16:13:58977 // Gets the program info for the given program. If it's not a program
978 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35979 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58980 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42981 Program* program = GetProgram(client_id);
982 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35983 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51984 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43985 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58986 } else {
[email protected]ab09b612013-03-11 22:11:51987 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58988 }
989 }
[email protected]df37b9932013-03-08 05:21:42990 LogClientServiceForInfo(program, client_id, function_name);
991 return program;
[email protected]6b8cf1a2010-05-06 16:13:58992 }
993
994
[email protected]ed9f9cd2013-02-27 21:12:35995 // Creates a Shader for the given shader.
996 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57997 GLuint client_id,
998 GLuint service_id,
999 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351000 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571001 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311002 }
1003
1004 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351005 Shader* GetShader(GLuint client_id) {
1006 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311007 }
1008
[email protected]6b8cf1a2010-05-06 16:13:581009 // Gets the shader info for the given shader. If it's not a shader generates a
1010 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351011 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581012 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421013 Shader* shader = GetShader(client_id);
1014 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351015 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511016 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431017 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581018 } else {
[email protected]ab09b612013-03-11 22:11:511019 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431020 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581021 }
1022 }
[email protected]df37b9932013-03-08 05:21:421023 LogClientServiceForInfo(shader, client_id, function_name);
1024 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581025 }
1026
[email protected]a93bb842010-02-16 23:03:471027 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351028 void CreateBuffer(GLuint client_id, GLuint service_id) {
1029 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471030 }
1031
[email protected]07f54fcc2009-12-22 02:46:301032 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211033 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071034 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1035 return buffer;
[email protected]1d32bc82010-01-13 22:06:461036 }
[email protected]07f54fcc2009-12-22 02:46:301037
[email protected]a93bb842010-02-16 23:03:471038 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1039 // on glDeleteBuffers so we can make sure the user does not try to render
1040 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351041 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471042
[email protected]a25fa872010-03-25 02:57:581043 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351044 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1045 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581046 }
1047
1048 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061049 Framebuffer* GetFramebuffer(GLuint client_id) {
1050 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581051 }
1052
1053 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351054 void RemoveFramebuffer(GLuint client_id) {
1055 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581056 }
1057
1058 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351059 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1060 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031061 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581062 }
1063
1064 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271065 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1066 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581067 }
1068
1069 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351070 void RemoveRenderbuffer(GLuint client_id) {
1071 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581072 }
1073
[email protected]944b62f32012-09-27 02:20:461074 // Gets the vertex attrib manager for the given vertex array.
1075 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1076 VertexAttribManager* info =
1077 vertex_array_manager()->GetVertexAttribManager(client_id);
1078 return info;
1079 }
1080
1081 // Removes the vertex attrib manager for the given vertex array.
1082 void RemoveVertexAttribManager(GLuint client_id) {
1083 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1084 }
1085
1086 // Creates a vertex attrib manager for the given vertex array.
1087 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1088 return vertex_array_manager()->CreateVertexAttribManager(
1089 client_id, service_id, group_->max_vertex_attribs());
1090 }
1091
[email protected]258a3313f2011-10-18 20:13:571092 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331093 void DoBindUniformLocationCHROMIUM(
1094 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571095
[email protected]558847a2010-03-24 07:02:541096 error::Error GetAttribLocationHelper(
1097 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1098 const std::string& name_str);
1099
1100 error::Error GetUniformLocationHelper(
1101 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1102 const std::string& name_str);
1103
[email protected]3916c97e2010-02-25 03:20:501104 // Helper for glShaderSource.
1105 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031106 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301107
[email protected]0d6bfdc2011-11-02 01:32:201108 // Clear any textures used by the current program.
1109 bool ClearUnclearedTextures();
1110
1111 // Clear any uncleared level in texture.
1112 // Returns false if there was a generated GL error.
[email protected]02965c22013-03-09 02:40:071113 bool ClearTexture(Texture* texture);
[email protected]0d6bfdc2011-11-02 01:32:201114
1115 // Clears any uncleared attachments attached to the given frame buffer.
1116 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061117 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281118
[email protected]0d6bfdc2011-11-02 01:32:201119 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001120 virtual bool ClearLevel(unsigned service_id,
1121 unsigned bind_target,
1122 unsigned target,
1123 int level,
1124 unsigned format,
1125 unsigned type,
1126 int width,
1127 int height,
1128 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201129
[email protected]c007aa02010-09-02 22:22:401130 // Restore all GL state that affects clearing.
1131 void RestoreClearState();
1132
[email protected]3a2e7c7b2010-08-06 01:12:281133 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461134 // Returns: true if glEnable/glDisable should actually be called.
1135 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281136
[email protected]0d6bfdc2011-11-02 01:32:201137 // Check that the currently bound framebuffers are valid.
1138 // Generates GL error if not.
1139 bool CheckBoundFramebuffersValid(const char* func_name);
1140
1141 // Check if a framebuffer meets our requirements.
1142 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351143 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201144 GLenum target,
1145 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271146
[email protected]939e7362010-05-13 20:49:101147 // Checks if the current program exists and is valid. If not generates the
1148 // appropriate GL error. Returns true if the current program is in a usable
1149 // state.
1150 bool CheckCurrentProgram(const char* function_name);
1151
1152 // Checks if the current program exists and is valid and that location is not
1153 // -1. If the current program is not valid generates the appropriate GL
1154 // error. Returns true if the current program is in a usable state and
1155 // location is not -1.
1156 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1157
1158 // Gets the type of a uniform for a location in the current program. Sets GL
1159 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361160 // program is valid and the location exists. Adjusts count so it
1161 // does not overflow the uniform.
1162 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121163 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521164 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121165 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101166
[email protected]b177ae22011-11-01 03:29:111167 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021168 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111169
[email protected]b273e432010-04-12 17:23:581170 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1171 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1172
[email protected]ac77603c72013-03-08 13:52:061173 // Helper for glGetVertexAttrib
1174 void GetVertexAttribHelper(
1175 const VertexAttrib* attrib, GLenum pname, GLint* param);
1176
[email protected]96449d2c2009-11-25 00:01:321177 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031178 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321179
1180 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031181 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321182
[email protected]3916c97e2010-02-25 03:20:501183 // Wrapper for glActiveTexture
1184 void DoActiveTexture(GLenum texture_unit);
1185
[email protected]ae51d192010-04-27 00:48:031186 // Wrapper for glAttachShader
1187 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1188
[email protected]96449d2c2009-11-25 00:01:321189 // Wrapper for glBindBuffer since we need to track the current targets.
1190 void DoBindBuffer(GLenum target, GLuint buffer);
1191
[email protected]86093972010-03-11 00:13:561192 // Wrapper for glBindFramebuffer since we need to track the current targets.
1193 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1194
1195 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1196 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1197
[email protected]a93bb842010-02-16 23:03:471198 // Wrapper for glBindTexture since we need to track the current targets.
1199 void DoBindTexture(GLenum target, GLuint texture);
1200
[email protected]944b62f32012-09-27 02:20:461201 // Wrapper for glBindVertexArrayOES
1202 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571203 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461204
[email protected]8e3e0662010-08-23 18:46:301205 // Wrapper for glBlitFramebufferEXT.
1206 void DoBlitFramebufferEXT(
1207 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1208 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1209 GLbitfield mask, GLenum filter);
1210
[email protected]36cef8ce2010-03-16 07:34:451211 // Wrapper for glBufferData.
[email protected]0c86dbf2010-03-05 08:14:111212 void DoBufferData(
1213 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
1214
[email protected]36cef8ce2010-03-16 07:34:451215 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111216 void DoBufferSubData(
1217 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1218
[email protected]36cef8ce2010-03-16 07:34:451219 // Wrapper for glCheckFramebufferStatus
1220 GLenum DoCheckFramebufferStatus(GLenum target);
1221
[email protected]3a03a8f2011-03-19 00:51:271222 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081223 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271224
[email protected]88a61bf2012-10-27 13:00:421225 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421226 void DoDepthRangef(GLclampf znear, GLclampf zfar);
1227 void DoHint(GLenum target, GLenum mode);
[email protected]b04e24c2013-01-08 18:35:251228 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281229
[email protected]45bf5152010-02-12 00:11:311230 // Wrapper for glCompileShader.
1231 void DoCompileShader(GLuint shader);
1232
[email protected]269200b12010-11-18 22:53:061233 // Helper for DeleteSharedIdsCHROMIUM commands.
1234 void DoDeleteSharedIdsCHROMIUM(
1235 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101236
[email protected]ae51d192010-04-27 00:48:031237 // Wrapper for glDetachShader
1238 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1239
[email protected]3a2e7c7b2010-08-06 01:12:281240 // Wrapper for glDisable
1241 void DoDisable(GLenum cap);
1242
[email protected]07f54fcc2009-12-22 02:46:301243 // Wrapper for glDisableVertexAttribArray.
1244 void DoDisableVertexAttribArray(GLuint index);
1245
[email protected]60f22d32012-12-12 00:31:581246 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1247 // attachments.
1248 void DoDiscardFramebufferEXT(GLenum target,
1249 GLsizei numAttachments,
1250 const GLenum* attachments);
1251
[email protected]3a2e7c7b2010-08-06 01:12:281252 // Wrapper for glEnable
1253 void DoEnable(GLenum cap);
1254
[email protected]07f54fcc2009-12-22 02:46:301255 // Wrapper for glEnableVertexAttribArray.
1256 void DoEnableVertexAttribArray(GLuint index);
1257
[email protected]882ba1e22012-03-08 19:02:531258 // Wrapper for glFinish.
1259 void DoFinish();
1260
1261 // Wrapper for glFlush.
1262 void DoFlush();
1263
[email protected]36cef8ce2010-03-16 07:34:451264 // Wrapper for glFramebufferRenderbufffer.
1265 void DoFramebufferRenderbuffer(
1266 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1267 GLuint renderbuffer);
1268
1269 // Wrapper for glFramebufferTexture2D.
1270 void DoFramebufferTexture2D(
1271 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1272 GLint level);
1273
[email protected]a93bb842010-02-16 23:03:471274 // Wrapper for glGenerateMipmap
1275 void DoGenerateMipmap(GLenum target);
1276
[email protected]269200b12010-11-18 22:53:061277 // Helper for GenSharedIdsCHROMIUM commands.
1278 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101279 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1280
[email protected]b273e432010-04-12 17:23:581281 // Wrapper for DoGetBooleanv.
1282 void DoGetBooleanv(GLenum pname, GLboolean* params);
1283
1284 // Wrapper for DoGetFloatv.
1285 void DoGetFloatv(GLenum pname, GLfloat* params);
1286
[email protected]36cef8ce2010-03-16 07:34:451287 // Wrapper for glGetFramebufferAttachmentParameteriv.
1288 void DoGetFramebufferAttachmentParameteriv(
1289 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1290
[email protected]a0c3e972010-04-21 00:49:131291 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581292 void DoGetIntegerv(GLenum pname, GLint* params);
1293
[email protected]29a9eb52010-04-13 09:04:231294 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061295 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231296 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1297
[email protected]17cfbe0e2013-03-07 01:26:081298 // Wrapper for glGetBufferParameteriv.
1299 void DoGetBufferParameteriv(
1300 GLenum target, GLenum pname, GLint* params);
1301
[email protected]a0c3e972010-04-21 00:49:131302 // Wrapper for glGetProgramiv.
1303 void DoGetProgramiv(
1304 GLuint program_id, GLenum pname, GLint* params);
1305
[email protected]36cef8ce2010-03-16 07:34:451306 // Wrapper for glRenderbufferParameteriv.
1307 void DoGetRenderbufferParameteriv(
1308 GLenum target, GLenum pname, GLint* params);
1309
[email protected]ddd968b82010-03-02 00:44:291310 // Wrapper for glGetShaderiv
1311 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1312
[email protected]b1122982010-05-17 23:04:241313 // Wrappers for glGetVertexAttrib.
1314 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1315 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1316
[email protected]1958e0e2010-04-22 05:17:151317 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241318 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151319 bool DoIsBuffer(GLuint client_id);
1320 bool DoIsFramebuffer(GLuint client_id);
1321 bool DoIsProgram(GLuint client_id);
1322 bool DoIsRenderbuffer(GLuint client_id);
1323 bool DoIsShader(GLuint client_id);
1324 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461325 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151326
[email protected]07f54fcc2009-12-22 02:46:301327 // Wrapper for glLinkProgram
1328 void DoLinkProgram(GLuint program);
1329
[email protected]269200b12010-11-18 22:53:061330 // Helper for RegisterSharedIdsCHROMIUM.
1331 void DoRegisterSharedIdsCHROMIUM(
1332 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101333
[email protected]36cef8ce2010-03-16 07:34:451334 // Wrapper for glRenderbufferStorage.
1335 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031336 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451337
[email protected]8e3e0662010-08-23 18:46:301338 // Wrapper for glRenderbufferStorageMultisampleEXT.
1339 void DoRenderbufferStorageMultisample(
1340 GLenum target, GLsizei samples, GLenum internalformat,
1341 GLsizei width, GLsizei height);
1342
[email protected]b273e432010-04-12 17:23:581343 // Wrapper for glReleaseShaderCompiler.
1344 void DoReleaseShaderCompiler() { }
1345
[email protected]3916c97e2010-02-25 03:20:501346 // Wrappers for glTexParameter functions.
1347 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1348 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1349 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1350 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1351
1352 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1353 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121354 void DoUniform1i(GLint fake_location, GLint v0);
1355 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1356 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1357 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1358 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101359
1360 // Wrappers for glUniformfv because some drivers don't correctly accept
1361 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121362 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1363 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1364 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1365 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501366
[email protected]43c2f1f2011-03-25 18:35:361367 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121368 GLint fake_location, GLsizei count, GLboolean transpose,
1369 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361370 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121371 GLint fake_location, GLsizei count, GLboolean transpose,
1372 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361373 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121374 GLint fake_location, GLsizei count, GLboolean transpose,
1375 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361376
[email protected]af6380962012-11-29 23:24:131377 bool SetVertexAttribValue(
1378 const char* function_name, GLuint index, const GLfloat* value);
1379
[email protected]b1122982010-05-17 23:04:241380 // Wrappers for glVertexAttrib??
1381 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1382 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1383 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1384 void DoVertexAttrib4f(
1385 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1386 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1387 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1388 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1389 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1390
[email protected]43410e92012-04-20 17:06:281391 // Wrapper for glViewport
1392 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1393
[email protected]07f54fcc2009-12-22 02:46:301394 // Wrapper for glUseProgram
1395 void DoUseProgram(GLuint program);
1396
[email protected]ae51d192010-04-27 00:48:031397 // Wrapper for glValidateProgram.
1398 void DoValidateProgram(GLuint program_client_id);
1399
[email protected]d2a0e1a2012-08-12 02:25:011400 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1401 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1402 void DoPopGroupMarkerEXT(void);
1403
[email protected]4e8a5b122010-05-08 22:00:101404 // Gets the number of values that will be returned by glGetXXX. Returns
1405 // false if pname is unknown.
1406 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1407
[email protected]ab09b612013-03-11 22:11:511408 virtual void SetGLError(
1409 const char* filename,
1410 int line,
1411 unsigned error,
1412 const char* function_name,
1413 const char* msg) OVERRIDE;
1414 virtual void SetGLErrorInvalidEnum(
1415 const char* filename,
1416 int line,
1417 const char* function_name,
1418 unsigned value,
1419 const char* label) OVERRIDE;
[email protected]445a8762012-12-06 15:43:211420 // Generates a GL error for a bad parameter.
[email protected]e5dfab42013-03-05 09:27:421421 virtual void SetGLErrorInvalidParam(
[email protected]ab09b612013-03-11 22:11:511422 const char* filename,
1423 int line,
[email protected]e5dfab42013-03-05 09:27:421424 unsigned error,
[email protected]445a8762012-12-06 15:43:211425 const char* function_name,
[email protected]e5dfab42013-03-05 09:27:421426 unsigned pname,
1427 int param) OVERRIDE;
1428
[email protected]ab09b612013-03-11 22:11:511429 virtual unsigned PeekGLError(
1430 const char* filename, int line, const char* function_name) OVERRIDE;
1431 virtual void CopyRealGLErrorsToWrapper(
1432 const char* filename, int line, const char* function_name) OVERRIDE;
1433 virtual void ClearRealGLErrors(
1434 const char* filename, int line, const char* function_name) OVERRIDE;
[email protected]445a8762012-12-06 15:43:211435
[email protected]07f54fcc2009-12-22 02:46:301436 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431437 bool IsDrawValid(
1438 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301439
[email protected]c13e1da62011-09-09 21:48:301440 // Returns true if successful, simulated will be true if attrib0 was
1441 // simulated.
[email protected]c6aef902012-02-14 03:31:421442 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431443 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281444 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241445
[email protected]ef526492010-06-02 23:12:251446 // Returns true if textures were set.
1447 bool SetBlackTextureForNonRenderableTextures();
[email protected]3916c97e2010-02-25 03:20:501448 void RestoreStateForNonRenderableTextures();
1449
[email protected]8fbedc02010-11-18 18:43:401450 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421451 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431452 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421453 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401454 void RestoreStateForSimulatedFixedAttribs();
1455
[email protected]c6aef902012-02-14 03:31:421456 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1457 // cases (primcount is 0 for non-instanced).
1458 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431459 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421460 bool instanced, GLenum mode, GLint first, GLsizei count,
1461 GLsizei primcount);
1462 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431463 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421464 bool instanced, GLenum mode, GLsizei count, GLenum type,
1465 int32 offset, GLsizei primcount);
1466
[email protected]07f54fcc2009-12-22 02:46:301467 // Gets the buffer id for a given target.
[email protected]16ccec12013-02-28 03:40:211468 Buffer* GetBufferInfoForTarget(GLenum target) {
[email protected]07f54fcc2009-12-22 02:46:301469 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
[email protected]944b62f32012-09-27 02:20:461470 if (target == GL_ARRAY_BUFFER) {
[email protected]e259eb412012-10-13 05:47:241471 return state_.bound_array_buffer;
[email protected]944b62f32012-09-27 02:20:461472 } else {
[email protected]e259eb412012-10-13 05:47:241473 return state_.vertex_attrib_manager->element_array_buffer();
[email protected]944b62f32012-09-27 02:20:461474 }
[email protected]07f54fcc2009-12-22 02:46:301475 }
1476
[email protected]a93bb842010-02-16 23:03:471477 // Gets the texture id for a given target.
[email protected]ed9f9cd2013-02-27 21:12:351478 Texture* GetTextureInfoForTarget(GLenum target) {
[email protected]e259eb412012-10-13 05:47:241479 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]02965c22013-03-09 02:40:071480 Texture* texture = NULL;
[email protected]a93bb842010-02-16 23:03:471481 switch (target) {
1482 case GL_TEXTURE_2D:
[email protected]02965c22013-03-09 02:40:071483 texture = unit.bound_texture_2d;
[email protected]3916c97e2010-02-25 03:20:501484 break;
[email protected]a93bb842010-02-16 23:03:471485 case GL_TEXTURE_CUBE_MAP:
1486 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1487 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1488 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1489 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1490 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1491 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
[email protected]02965c22013-03-09 02:40:071492 texture = unit.bound_texture_cube_map;
[email protected]3916c97e2010-02-25 03:20:501493 break;
[email protected]61eeb33f2011-07-26 15:30:311494 case GL_TEXTURE_EXTERNAL_OES:
[email protected]02965c22013-03-09 02:40:071495 texture = unit.bound_texture_external_oes;
[email protected]61eeb33f2011-07-26 15:30:311496 break;
[email protected]e51bdf32011-11-23 22:21:461497 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]02965c22013-03-09 02:40:071498 texture = unit.bound_texture_rectangle_arb;
[email protected]e51bdf32011-11-23 22:21:461499 break;
[email protected]a93bb842010-02-16 23:03:471500 default:
1501 NOTREACHED();
[email protected]3916c97e2010-02-25 03:20:501502 return NULL;
[email protected]a93bb842010-02-16 23:03:471503 }
[email protected]02965c22013-03-09 02:40:071504 return texture;
[email protected]a93bb842010-02-16 23:03:471505 }
1506
[email protected]ed9f9cd2013-02-27 21:12:351507 Texture* GetTextureInfoForTargetUnlessDefault(
[email protected]09d50362012-10-18 20:54:371508 GLenum target) {
[email protected]02965c22013-03-09 02:40:071509 Texture* texture = GetTextureInfoForTarget(target);
1510 if (!texture)
[email protected]09d50362012-10-18 20:54:371511 return NULL;
[email protected]02965c22013-03-09 02:40:071512 if (texture == texture_manager()->GetDefaultTextureInfo(target))
[email protected]09d50362012-10-18 20:54:371513 return NULL;
[email protected]02965c22013-03-09 02:40:071514 return texture;
[email protected]09d50362012-10-18 20:54:371515 }
1516
[email protected]61eeb33f2011-07-26 15:30:311517 GLenum GetBindTargetForSamplerType(GLenum type) {
1518 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461519 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1520 switch (type) {
1521 case GL_SAMPLER_2D:
1522 return GL_TEXTURE_2D;
1523 case GL_SAMPLER_CUBE:
1524 return GL_TEXTURE_CUBE_MAP;
1525 case GL_SAMPLER_EXTERNAL_OES:
1526 return GL_TEXTURE_EXTERNAL_OES;
1527 case GL_SAMPLER_2D_RECT_ARB:
1528 return GL_TEXTURE_RECTANGLE_ARB;
1529 }
1530
1531 NOTREACHED();
1532 return 0;
[email protected]61eeb33f2011-07-26 15:30:311533 }
1534
[email protected]8e3e0662010-08-23 18:46:301535 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061536 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1537 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301538 switch (target) {
1539 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451540 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]4d8f0dd2013-03-09 14:37:061541 framebuffer = state_.bound_draw_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301542 break;
[email protected]ebfb73c2012-08-15 02:37:451543 case GL_READ_FRAMEBUFFER_EXT:
[email protected]4d8f0dd2013-03-09 14:37:061544 framebuffer = state_.bound_read_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301545 break;
1546 default:
1547 NOTREACHED();
1548 break;
1549 }
[email protected]4d8f0dd2013-03-09 14:37:061550 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301551 }
1552
[email protected]ed9f9cd2013-02-27 21:12:351553 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201554 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271555 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201556 switch (target) {
1557 case GL_RENDERBUFFER:
[email protected]ee2a79c32013-03-10 03:50:271558 renderbuffer = state_.bound_renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201559 break;
1560 default:
1561 NOTREACHED();
1562 break;
1563 }
[email protected]ee2a79c32013-03-10 03:50:271564 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201565 }
1566
[email protected]f7b85372010-02-03 01:11:371567 // Validates the program and location for a glGetUniform call and returns
1568 // a SizeResult setup to receive the result. Returns true if glGetUniform
1569 // should be called.
1570 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121571 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371572 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121573 error::Error* error, GLint* real_location, GLuint* service_id,
1574 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371575
[email protected]1078f912011-12-23 13:12:141576 // Computes the estimated memory used for the backbuffer and passes it to
1577 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531578 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141579
[email protected]a10b4a02012-11-26 23:09:501580 virtual bool WasContextLost() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091581 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431582
[email protected]e51bdf32011-11-23 22:21:461583#if defined(OS_MACOSX)
1584 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1585#endif
1586
[email protected]81375742012-06-08 00:04:001587 // Validates the combination of texture parameters. For example validates that
1588 // for a given format the specific type, level and targets are valid.
1589 // Synthesizes the correct GL error if invalid. Returns true if valid.
1590 bool ValidateTextureParameters(
1591 const char* function_name,
1592 GLenum target, GLenum format, GLenum type, GLint level);
1593
[email protected]ad84a3a2012-06-08 21:42:431594 bool ValidateCompressedTexDimensions(
1595 const char* function_name,
1596 GLint level, GLsizei width, GLsizei height, GLenum format);
1597 bool ValidateCompressedTexFuncData(
1598 const char* function_name,
1599 GLsizei width, GLsizei height, GLenum format, size_t size);
1600 bool ValidateCompressedTexSubDimensions(
1601 const char* function_name,
1602 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1603 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351604 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431605
[email protected]ab09b612013-03-11 22:11:511606 void LogMessage(const char* filename, int line, const std::string& msg);
1607 void RenderWarning(const char* filename, int line, const std::string& msg);
1608 void PerformanceWarning(
1609 const char* filename, int line, const std::string& msg);
[email protected]d2a0e1a2012-08-12 02:25:011610 const std::string& GetLogPrefix() const;
[email protected]0f8afe82012-05-14 23:43:011611
[email protected]62e155e2012-10-23 22:43:151612 const FeatureInfo::FeatureFlags& features() const {
1613 return feature_info_->feature_flags();
1614 }
1615
1616 const FeatureInfo::Workarounds& workarounds() const {
1617 return feature_info_->workarounds();
1618 }
1619
[email protected]a7266a92012-06-28 02:11:081620 bool ShouldDeferDraws() {
1621 return !offscreen_target_frame_buffer_.get() &&
[email protected]e259eb412012-10-13 05:47:241622 state_.bound_draw_framebuffer == NULL &&
[email protected]a7266a92012-06-28 02:11:081623 surface_->DeferDraws();
1624 }
1625
[email protected]09e17272012-11-30 10:30:441626 bool ShouldDeferReads() {
1627 return !offscreen_target_frame_buffer_.get() &&
1628 state_.bound_read_framebuffer == NULL &&
1629 surface_->DeferDraws();
1630 }
1631
[email protected]df37b9932013-03-08 05:21:421632 void ForceCompileShaderIfPending(Shader* shader);
[email protected]c447acd2012-07-23 23:48:411633
[email protected]96449d2c2009-11-25 00:01:321634 // Generate a member function prototype for each command in an automated and
1635 // typesafe way.
1636 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141637 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351638 uint32 immediate_data_size, \
1639 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321640
1641 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1642
1643 #undef GLES2_CMD_OP
1644
[email protected]2f2d7042010-04-14 21:45:581645 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381646 scoped_refptr<gfx::GLSurface> surface_;
1647 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021648
[email protected]a3ded6d2010-10-19 06:44:391649 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351650 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391651
[email protected]e259eb412012-10-13 05:47:241652 // All the state for this context.
1653 ContextState state_;
1654
[email protected]6217d392010-03-25 22:08:351655 // A parent decoder can access this decoders saved offscreen frame buffer.
1656 // The parent pointer is reset if the parent is destroyed.
1657 base::WeakPtr<GLES2DecoderImpl> parent_;
1658
[email protected]34ff8b0c2010-10-01 20:06:021659 // Current width and height of the offscreen frame buffer.
1660 gfx::Size offscreen_size_;
1661
[email protected]96449d2c2009-11-25 00:01:321662 // Current GL error bits.
1663 uint32 error_bits_;
1664
[email protected]96449d2c2009-11-25 00:01:321665 // Util to help with GL.
1666 GLES2Util util_;
1667
[email protected]43410e92012-04-20 17:06:281668 // unpack flip y as last set by glPixelStorei
1669 bool unpack_flip_y_;
1670
[email protected]6c75c712012-06-19 15:43:171671 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281672 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171673 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281674
[email protected]944b62f32012-09-27 02:20:461675 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351676 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301677
[email protected]b1122982010-05-17 23:04:241678 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1679 GLuint attrib_0_buffer_id_;
1680
1681 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131682 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241683
[email protected]fc753442011-02-04 19:49:491684 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1685 bool attrib_0_buffer_matches_value_;
1686
[email protected]b1122982010-05-17 23:04:241687 // The size of attrib 0.
1688 GLsizei attrib_0_size_;
1689
[email protected]8fbedc02010-11-18 18:43:401690 // The buffer used to simulate GL_FIXED attribs.
1691 GLuint fixed_attrib_buffer_id_;
1692
1693 // The size of fiixed attrib buffer.
1694 GLsizei fixed_attrib_buffer_size_;
1695
[email protected]3a2e7c7b2010-08-06 01:12:281696 // state saved for clearing so we can clear render buffers and then
1697 // restore to these values.
[email protected]88a61bf2012-10-27 13:00:421698 bool clear_state_dirty_;
[email protected]3a2e7c7b2010-08-06 01:12:281699
[email protected]b9363b22010-06-09 22:06:151700 // The offscreen frame buffer that the client renders to. With EGL, the
1701 // depth and stencil buffers are separate. With regular GL there is a single
1702 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1703 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351704 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1705 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1706 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1707 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1708 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021709 GLenum offscreen_target_color_format_;
1710 GLenum offscreen_target_depth_format_;
1711 GLenum offscreen_target_stencil_format_;
1712 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561713 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351714
[email protected]de26b3c2011-08-03 21:54:271715 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351716 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1717 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
1718 scoped_refptr<Texture>
1719 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271720
1721 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351722 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1723 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051724 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351725
[email protected]882ba1e22012-03-08 19:02:531726 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531727
[email protected]944b62f32012-09-27 02:20:461728 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1729
[email protected]9d37f062011-11-22 01:24:521730 base::Callback<void(gfx::Size)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001731
[email protected]6b6e7ee2011-12-13 08:04:521732 MsgCallback msg_callback_;
[email protected]840a7e462013-02-27 01:29:511733 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481734
[email protected]e3932abb2013-03-13 00:01:371735 ShaderCacheCallback shader_cache_callback_;
1736
[email protected]b0af4f52011-09-28 22:04:421737 StreamTextureManager* stream_texture_manager_;
[email protected]32145a92012-12-17 09:01:591738 scoped_ptr<gfx::AsyncPixelTransferDelegate> async_pixel_transfer_delegate_;
[email protected]b0af4f52011-09-28 22:04:421739
[email protected]32fe9aa2011-01-21 23:47:131740 // The format of the back buffer_
1741 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461742 bool back_buffer_has_depth_;
1743 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131744
[email protected]60f22d32012-12-12 00:31:581745 // Backbuffer attachments that are currently undefined.
1746 uint32 backbuffer_needs_clear_bits_;
1747
[email protected]473c01ccb2011-06-07 01:33:301748 bool teximage2d_faster_than_texsubimage2d_;
[email protected]473c01ccb2011-06-07 01:33:301749
[email protected]8eee29c2010-04-29 03:38:291750 // The last error message set.
1751 std::string last_error_;
1752
[email protected]0f8afe82012-05-14 23:43:011753 int log_message_count_;
[email protected]fa20ec82012-05-04 04:02:481754
[email protected]a3a93e7b2010-08-28 00:48:561755 // The current decoder error.
1756 error::Error current_decoder_error_;
1757
[email protected]d2a0e1a2012-08-12 02:25:011758 DebugMarkerManager debug_marker_manager_;
1759 std::string this_in_hex_;
1760
[email protected]b1d2dcb2010-05-17 19:24:181761 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041762 scoped_refptr<ShaderTranslator> vertex_translator_;
1763 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181764
[email protected]e82fb792011-09-22 00:33:291765 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411766
[email protected]915a59a12010-09-30 21:29:111767 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051768 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351769 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051770
[email protected]b493ee622011-04-13 23:52:001771 // This indicates all the following texSubImage2D calls that are part of the
1772 // failed texImage2D call should be ignored.
1773 bool tex_image_2d_failed_;
1774
[email protected]65225772011-05-12 21:10:241775 int frame_number_;
1776
[email protected]706b69f2012-07-27 04:59:301777 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431778 GLenum reset_status_;
1779
[email protected]f0d74742011-10-03 16:31:041780 // These flags are used to override the state of the shared feature_info_
1781 // member. Because the same FeatureInfo instance may be shared among many
1782 // contexts, the assumptions on the availablity of extensions in WebGL
1783 // contexts may be broken. These flags override the shared state to preserve
1784 // WebGL semantics.
1785 bool force_webgl_glsl_validation_;
1786 bool derivatives_explicitly_enabled_;
1787
[email protected]062c38b2012-01-18 03:25:101788 bool compile_shader_always_succeeds_;
1789
[email protected]cae20172012-12-07 00:06:191790 // Log extra info.
1791 bool service_logging_;
1792
[email protected]e51bdf32011-11-23 22:21:461793#if defined(OS_MACOSX)
1794 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1795 TextureToIOSurfaceMap texture_to_io_surface_map_;
1796#endif
1797
[email protected]c826d732012-02-09 04:40:261798 typedef std::vector<GLES2DecoderImpl*> ChildList;
1799 ChildList children_;
1800
[email protected]43410e92012-04-20 17:06:281801 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1802
[email protected]1868a342012-11-07 15:56:021803 // Cached values of the currently assigned viewport dimensions.
1804 GLsizei viewport_max_width_;
1805 GLsizei viewport_max_height_;
1806
[email protected]63b465922012-09-06 02:04:521807 // Command buffer stats.
1808 int texture_upload_count_;
1809 base::TimeDelta total_texture_upload_time_;
1810 base::TimeDelta total_processing_commands_time_;
1811
[email protected]fb97b662013-02-20 23:02:141812 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]94307712012-11-16 23:26:111813
[email protected]96449d2c2009-11-25 00:01:321814 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1815};
1816
[email protected]ab09b612013-03-11 22:11:511817ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
1818 const char* function_name, GLES2DecoderImpl* decoder)
1819 : function_name_(function_name),
1820 decoder_(decoder) {
1821 GLESDECODER_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_, function_name_);
[email protected]6217d392010-03-25 22:08:351822}
1823
1824ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]ab09b612013-03-11 22:11:511825 GLESDECODER_CLEAR_REAL_GL_ERRORS(decoder_, function_name_);
[email protected]6217d392010-03-25 22:08:351826}
1827
1828ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1829 GLuint id)
1830 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511831 ScopedGLErrorSuppressor suppressor(
1832 "ScopedTexture2DBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351833
1834 // TODO(apatrick): Check if there are any other states that need to be reset
1835 // before binding a new texture.
1836 glActiveTexture(GL_TEXTURE0);
1837 glBindTexture(GL_TEXTURE_2D, id);
1838}
1839
1840ScopedTexture2DBinder::~ScopedTexture2DBinder() {
[email protected]ab09b612013-03-11 22:11:511841 ScopedGLErrorSuppressor suppressor(
1842 "ScopedTexture2DBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301843 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351844}
1845
1846ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1847 GLuint id)
1848 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511849 ScopedGLErrorSuppressor suppressor(
1850 "ScopedRenderBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351851 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1852}
1853
1854ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511855 ScopedGLErrorSuppressor suppressor(
1856 "ScopedRenderBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301857 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351858}
1859
1860ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1861 GLuint id)
1862 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511863 ScopedGLErrorSuppressor suppressor(
1864 "ScopedFrameBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351865 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451866 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351867}
1868
1869ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511870 ScopedGLErrorSuppressor suppressor(
1871 "ScopedFrameBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301872 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351873}
1874
[email protected]34ff8b0c2010-10-01 20:06:021875ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271876 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521877 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021878 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1879 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241880 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521881 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021882 if (!resolve_and_bind_)
1883 return;
1884
[email protected]ab09b612013-03-11 22:11:511885 ScopedGLErrorSuppressor suppressor(
1886 "ScopedResolvedFrameBufferBinder::ctor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021887 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1888 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271889 GLuint targetid;
1890 if (internal) {
1891 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1892 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351893 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271894 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351895 decoder_->offscreen_resolved_color_texture_.reset(
1896 new BackTexture(decoder_));
[email protected]de26b3c2011-08-03 21:54:271897 decoder_->offscreen_resolved_color_texture_->Create();
1898
1899 DCHECK(decoder_->offscreen_saved_color_format_);
1900 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091901 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1902 false);
[email protected]de26b3c2011-08-03 21:54:271903 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1904 decoder_->offscreen_resolved_color_texture_.get());
1905 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1906 GL_FRAMEBUFFER_COMPLETE) {
1907 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1908 << "because offscreen resolved FBO was incomplete.";
1909 return;
1910 }
1911 }
1912 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1913 } else {
1914 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1915 }
1916 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021917 const int width = decoder_->offscreen_size_.width();
1918 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181919 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151920 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021921 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1922 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1923 } else {
1924 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1925 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1926 }
[email protected]de26b3c2011-08-03 21:54:271927 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021928}
1929
1930ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1931 if (!resolve_and_bind_)
1932 return;
1933
[email protected]ab09b612013-03-11 22:11:511934 ScopedGLErrorSuppressor suppressor(
1935 "ScopedResolvedFrameBufferBinder::dtor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021936 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221937 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181938 glEnable(GL_SCISSOR_TEST);
1939 }
[email protected]34ff8b0c2010-10-01 20:06:021940}
1941
[email protected]63b465922012-09-06 02:04:521942ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder)
1943 : decoder_(decoder),
1944 begin_time_(base::TimeTicks::HighResNow()) {
1945}
1946
1947ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1948 decoder_->texture_upload_count_++;
1949 decoder_->total_texture_upload_time_ +=
1950 base::TimeTicks::HighResNow() - begin_time_;
1951}
1952
[email protected]ed9f9cd2013-02-27 21:12:351953BackTexture::BackTexture(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351954 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261955 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481956 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251957 id_(0) {
[email protected]6217d392010-03-25 22:08:351958}
1959
[email protected]ed9f9cd2013-02-27 21:12:351960BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351961 // This does not destroy the render texture because that would require that
1962 // the associated GL context was current. Just check that it was explicitly
1963 // destroyed.
1964 DCHECK_EQ(id_, 0u);
1965}
1966
[email protected]ed9f9cd2013-02-27 21:12:351967void BackTexture::Create() {
[email protected]ab09b612013-03-11 22:11:511968 ScopedGLErrorSuppressor suppressor("BackTexture::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351969 Destroy();
1970 glGenTextures(1, &id_);
[email protected]3a4d0c52011-06-29 23:11:581971 ScopedTexture2DBinder binder(decoder_, id_);
1972 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1973 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1974 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1975 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161976
1977 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1978 // never called on an offscreen context, no data will ever be uploaded to the
1979 // saved offscreen color texture (it is deferred until to when SwapBuffers
1980 // is called). My idea is that some nvidia drivers might have a bug where
1981 // deleting a texture that has never been populated might cause a
1982 // crash.
1983 glTexImage2D(
1984 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481985
1986 bytes_allocated_ = 16u * 16u * 4u;
1987 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351988}
1989
[email protected]ed9f9cd2013-02-27 21:12:351990bool BackTexture::AllocateStorage(
1991 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351992 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511993 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351994 ScopedTexture2DBinder binder(decoder_, id_);
[email protected]678a73f2012-12-19 19:22:091995 uint32 image_size = 0;
1996 GLES2Util::ComputeImageDataSizes(
1997 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1998 NULL, NULL);
1999
[email protected]7989c9e2013-01-23 06:39:262000 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2001 return false;
2002 }
2003
[email protected]678a73f2012-12-19 19:22:092004 scoped_array<char> zero_data;
2005 if (zero) {
2006 zero_data.reset(new char[image_size]);
2007 memset(zero_data.get(), 0, image_size);
2008 }
[email protected]6217d392010-03-25 22:08:352009
[email protected]f0e6a34f2012-01-04 20:53:402010 WrappedTexImage2D(GL_TEXTURE_2D,
2011 0, // mip level
2012 format,
2013 size.width(),
2014 size.height(),
2015 0, // border
2016 format,
2017 GL_UNSIGNED_BYTE,
[email protected]678a73f2012-12-19 19:22:092018 zero_data.get());
[email protected]6217d392010-03-25 22:08:352019
[email protected]d37231fa2010-04-09 21:16:022020 size_ = size;
2021
[email protected]1078f912011-12-23 13:12:142022 bool success = glGetError() == GL_NO_ERROR;
2023 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482024 memory_tracker_.TrackMemFree(bytes_allocated_);
2025 bytes_allocated_ = image_size;
2026 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142027 }
2028 return success;
[email protected]6217d392010-03-25 22:08:352029}
2030
[email protected]ed9f9cd2013-02-27 21:12:352031void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352032 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512033 ScopedGLErrorSuppressor suppressor("BackTexture::Copy", decoder_);
[email protected]6217d392010-03-25 22:08:352034 ScopedTexture2DBinder binder(decoder_, id_);
2035 glCopyTexImage2D(GL_TEXTURE_2D,
2036 0, // level
[email protected]3a4d0c52011-06-29 23:11:582037 format,
[email protected]6217d392010-03-25 22:08:352038 0, 0,
2039 size.width(),
2040 size.height(),
2041 0); // border
2042}
2043
[email protected]ed9f9cd2013-02-27 21:12:352044void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352045 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512046 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352047 glDeleteTextures(1, &id_);
2048 id_ = 0;
2049 }
[email protected]68e81a4a62012-12-13 01:16:482050 memory_tracker_.TrackMemFree(bytes_allocated_);
2051 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352052}
2053
[email protected]ed9f9cd2013-02-27 21:12:352054void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052055 id_ = 0;
2056}
2057
[email protected]ed9f9cd2013-02-27 21:12:352058BackRenderbuffer::BackRenderbuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352059 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:262060 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:482061 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252062 id_(0) {
[email protected]6217d392010-03-25 22:08:352063}
2064
[email protected]ed9f9cd2013-02-27 21:12:352065BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352066 // This does not destroy the render buffer because that would require that
2067 // the associated GL context was current. Just check that it was explicitly
2068 // destroyed.
2069 DCHECK_EQ(id_, 0u);
2070}
2071
[email protected]ed9f9cd2013-02-27 21:12:352072void BackRenderbuffer::Create() {
[email protected]ab09b612013-03-11 22:11:512073 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:352074 Destroy();
2075 glGenRenderbuffersEXT(1, &id_);
2076}
2077
[email protected]ed9f9cd2013-02-27 21:12:352078bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format,
2079 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512080 ScopedGLErrorSuppressor suppressor(
2081 "BackRenderbuffer::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:352082 ScopedRenderBufferBinder binder(decoder_, id_);
[email protected]7989c9e2013-01-23 06:39:262083
2084 uint32 estimated_size = 0;
2085 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
2086 size.width(), size.height(), samples, format, &estimated_size)) {
2087 return false;
2088 }
2089
2090 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2091 return false;
2092 }
2093
[email protected]34ff8b0c2010-10-01 20:06:022094 if (samples <= 1) {
2095 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2096 format,
2097 size.width(),
2098 size.height());
2099 } else {
[email protected]57edfdad2012-02-07 04:57:152100 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:022101 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
2102 samples,
2103 format,
2104 size.width(),
2105 size.height());
2106 } else {
2107 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
2108 samples,
2109 format,
2110 size.width(),
2111 size.height());
2112 }
2113 }
[email protected]1078f912011-12-23 13:12:142114 bool success = glGetError() == GL_NO_ERROR;
2115 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482116 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262117 bytes_allocated_ = estimated_size;
[email protected]68e81a4a62012-12-13 01:16:482118 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142119 }
2120 return success;
[email protected]6217d392010-03-25 22:08:352121}
2122
[email protected]ed9f9cd2013-02-27 21:12:352123void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352124 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512125 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352126 glDeleteRenderbuffersEXT(1, &id_);
2127 id_ = 0;
2128 }
[email protected]68e81a4a62012-12-13 01:16:482129 memory_tracker_.TrackMemFree(bytes_allocated_);
2130 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352131}
2132
[email protected]ed9f9cd2013-02-27 21:12:352133void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052134 id_ = 0;
2135}
2136
[email protected]ed9f9cd2013-02-27 21:12:352137BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352138 : decoder_(decoder),
2139 id_(0) {
2140}
2141
[email protected]ed9f9cd2013-02-27 21:12:352142BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352143 // This does not destroy the frame buffer because that would require that
2144 // the associated GL context was current. Just check that it was explicitly
2145 // destroyed.
2146 DCHECK_EQ(id_, 0u);
2147}
2148
[email protected]ed9f9cd2013-02-27 21:12:352149void BackFramebuffer::Create() {
[email protected]ab09b612013-03-11 22:11:512150 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:352151 Destroy();
2152 glGenFramebuffersEXT(1, &id_);
2153}
2154
[email protected]ed9f9cd2013-02-27 21:12:352155void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352156 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512157 ScopedGLErrorSuppressor suppressor(
2158 "BackFramebuffer::AttachRenderTexture", decoder_);
[email protected]6217d392010-03-25 22:08:352159 ScopedFrameBufferBinder binder(decoder_, id_);
2160 GLuint attach_id = texture ? texture->id() : 0;
2161 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2162 GL_COLOR_ATTACHMENT0,
2163 GL_TEXTURE_2D,
2164 attach_id,
2165 0);
2166}
2167
[email protected]ed9f9cd2013-02-27 21:12:352168void BackFramebuffer::AttachRenderBuffer(GLenum target,
2169 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352170 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512171 ScopedGLErrorSuppressor suppressor(
2172 "BackFramebuffer::AttachRenderBuffer", decoder_);
[email protected]6217d392010-03-25 22:08:352173 ScopedFrameBufferBinder binder(decoder_, id_);
2174 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2175 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152176 target,
[email protected]6217d392010-03-25 22:08:352177 GL_RENDERBUFFER,
2178 attach_id);
2179}
2180
[email protected]ed9f9cd2013-02-27 21:12:352181void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352182 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512183 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352184 glDeleteFramebuffersEXT(1, &id_);
2185 id_ = 0;
2186 }
2187}
2188
[email protected]ed9f9cd2013-02-27 21:12:352189void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052190 id_ = 0;
2191}
2192
[email protected]ed9f9cd2013-02-27 21:12:352193GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352194 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512195 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", decoder_);
[email protected]6217d392010-03-25 22:08:352196 ScopedFrameBufferBinder binder(decoder_, id_);
2197 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2198}
2199
[email protected]aa7666122011-09-02 19:45:522200GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2201 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322202}
2203
[email protected]aa7666122011-09-02 19:45:522204GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392205 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572206 group_(group),
[email protected]b3cbad12012-12-05 19:56:362207 state_(group_->feature_info()),
[email protected]96449d2c2009-11-25 00:01:322208 error_bits_(0),
[email protected]43410e92012-04-20 17:06:282209 unpack_flip_y_(false),
2210 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172211 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242212 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492213 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242214 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402215 fixed_attrib_buffer_id_(0),
2216 fixed_attrib_buffer_size_(0),
[email protected]88a61bf2012-10-27 13:00:422217 clear_state_dirty_(true),
[email protected]34ff8b0c2010-10-01 20:06:022218 offscreen_target_color_format_(0),
2219 offscreen_target_depth_format_(0),
2220 offscreen_target_stencil_format_(0),
2221 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562222 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052223 offscreen_saved_color_format_(0),
[email protected]b0af4f52011-09-28 22:04:422224 stream_texture_manager_(NULL),
[email protected]32fe9aa2011-01-21 23:47:132225 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462226 back_buffer_has_depth_(false),
2227 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582228 backbuffer_needs_clear_bits_(0),
[email protected]473c01ccb2011-06-07 01:33:302229 teximage2d_faster_than_texsubimage2d_(true),
[email protected]0f8afe82012-05-14 23:43:012230 log_message_count_(0),
[email protected]a3a93e7b2010-08-28 00:48:562231 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052232 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112233 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002234 feature_info_(group_->feature_info()),
[email protected]65225772011-05-12 21:10:242235 tex_image_2d_failed_(false),
[email protected]38d139d2011-07-14 00:38:432236 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302237 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512238 reset_status_(GL_NO_ERROR),
[email protected]f0d74742011-10-03 16:31:042239 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102240 derivatives_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282241 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192242 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2243 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022244 viewport_max_width_(0),
2245 viewport_max_height_(0),
[email protected]63b465922012-09-06 02:04:522246 texture_upload_count_(0) {
[email protected]3b1ecc262011-08-03 22:49:572247 DCHECK(group);
2248
[email protected]d2a0e1a2012-08-12 02:25:012249 GLES2DecoderImpl* this_temp = this;
2250 this_in_hex_ = HexEncode(&this_temp, sizeof(this_temp));
2251
[email protected]b1122982010-05-17 23:04:242252 attrib_0_value_.v[0] = 0.0f;
2253 attrib_0_value_.v[1] = 0.0f;
2254 attrib_0_value_.v[2] = 0.0f;
2255 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152256
[email protected]c2f8c8402010-12-06 18:07:242257 // The shader translator is used for WebGL even when running on EGL
2258 // because additional restrictions are needed (like only enabling
2259 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562260 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2261 // the empty string to CompileShader and this is not a valid shader.
2262 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002263 CommandLine::ForCurrentProcess()->HasSwitch(
2264 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152265 use_shader_translator_ = false;
2266 }
[email protected]473c01ccb2011-06-07 01:33:302267
[email protected]a39370652012-09-25 21:52:132268 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:302269 if (IsAngle()) {
2270 teximage2d_faster_than_texsubimage2d_ = false;
[email protected]473c01ccb2011-06-07 01:33:302271 }
[email protected]96449d2c2009-11-25 00:01:322272}
2273
[email protected]80eb6b52012-01-19 00:14:412274GLES2DecoderImpl::~GLES2DecoderImpl() {
2275}
2276
[email protected]c410da802011-03-14 19:17:412277bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382278 const scoped_refptr<gfx::GLSurface>& surface,
2279 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232280 bool offscreen,
[email protected]c410da802011-03-14 19:17:412281 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292282 const DisallowedFeatures& disallowed_features,
[email protected]c410da802011-03-14 19:17:412283 const char* allowed_extensions,
[email protected]3c644d82011-06-20 19:58:242284 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322285 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382286 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302287 DCHECK(!context_.get());
2288
[email protected]55e136f2013-04-03 18:50:062289 set_initialized();
[email protected]fb97b662013-02-20 23:02:142290 gpu_tracer_ = GPUTracer::Create();
2291
[email protected]e844ae22012-01-14 03:36:262292 if (CommandLine::ForCurrentProcess()->HasSwitch(
2293 switches::kEnableGPUDebugging)) {
2294 set_debug(true);
2295 }
2296
[email protected]39ba4f02012-03-26 01:16:002297 if (CommandLine::ForCurrentProcess()->HasSwitch(
2298 switches::kEnableGPUCommandLogging)) {
2299 set_log_commands(true);
2300 }
2301
[email protected]062c38b2012-01-18 03:25:102302 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2303 switches::kCompileShaderAlwaysSucceeds);
2304
[email protected]f62a5ab2011-05-23 20:34:152305
[email protected]63c9b052012-05-17 18:27:382306 // Take ownership of the context and surface. The surface can be replaced with
2307 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382308 context_ = context;
[email protected]63c9b052012-05-17 18:27:382309 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182310
[email protected]c4485aad62012-12-17 10:19:092311 if (!group_->Initialize(this, disallowed_features, allowed_extensions)) {
[email protected]09ddb91f2011-04-14 23:16:222312 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392313 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422314 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382315 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032316 return false;
[email protected]a3ded6d2010-10-19 06:44:392317 }
[email protected]b64c24952012-04-19 03:20:272318 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282319
[email protected]e82fb792011-09-22 00:33:292320 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502321
[email protected]af6380962012-11-29 23:24:132322 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462323 default_vertex_attrib_manager_ = new VertexAttribManager();
2324 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2325
[email protected]ab4fd7282012-10-12 16:25:572326 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2327 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322328
[email protected]d6ca4792012-05-14 19:24:132329 query_manager_.reset(new QueryManager(this, feature_info_));
[email protected]944b62f32012-09-27 02:20:462330 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532331
[email protected]302ce6d2011-07-07 23:28:112332 util_.set_num_compressed_texture_formats(
2333 validators_->compressed_texture_format.GetValues().size());
2334
[email protected]1071e572011-02-09 20:00:122335 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2336 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2337 // OpenGL ES 2.0 does not have this issue.
2338 glEnableVertexAttribArray(0);
2339 }
[email protected]b1122982010-05-17 23:04:242340 glGenBuffersARB(1, &attrib_0_buffer_id_);
2341 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2342 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2343 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402344 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082345
[email protected]1868a342012-11-07 15:56:022346 state_.texture_units.resize(group_->max_texture_units());
2347 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492348 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312349 // We want the last bind to be 2D.
[email protected]02965c22013-03-09 02:40:072350 Texture* texture;
[email protected]62e155e2012-10-23 22:43:152351 if (features().oes_egl_image_external) {
[email protected]02965c22013-03-09 02:40:072352 texture = texture_manager()->GetDefaultTextureInfo(
2353 GL_TEXTURE_EXTERNAL_OES);
2354 state_.texture_units[tt].bound_texture_external_oes = texture;
2355 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture->service_id());
[email protected]61eeb33f2011-07-26 15:30:312356 }
[email protected]62e155e2012-10-23 22:43:152357 if (features().arb_texture_rectangle) {
[email protected]02965c22013-03-09 02:40:072358 texture = texture_manager()->GetDefaultTextureInfo(
2359 GL_TEXTURE_RECTANGLE_ARB);
2360 state_.texture_units[tt].bound_texture_rectangle_arb = texture;
2361 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture->service_id());
[email protected]e51bdf32011-11-23 22:21:462362 }
[email protected]02965c22013-03-09 02:40:072363 texture = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2364 state_.texture_units[tt].bound_texture_cube_map = texture;
2365 glBindTexture(GL_TEXTURE_CUBE_MAP, texture->service_id());
2366 texture = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2367 state_.texture_units[tt].bound_texture_2d = texture;
2368 glBindTexture(GL_TEXTURE_2D, texture->service_id());
[email protected]1958e0e2010-04-22 05:17:152369 }
[email protected]00f893d2010-08-24 18:55:492370 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502371 CHECK_GL_ERROR();
2372
[email protected]297ca1c2011-06-20 23:08:462373 ContextCreationAttribParser attrib_parser;
2374 if (!attrib_parser.Parse(attribs))
2375 return false;
[email protected]41c56362011-06-14 16:47:432376
[email protected]297ca1c2011-06-20 23:08:462377 // These are NOT if the back buffer has these proprorties. They are
2378 // if we want the command buffer to enforce them regardless of what
2379 // the real backbuffer is assuming the real back buffer gives us more than
2380 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2381 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2382 // can't do anything about that.
2383
2384 GLint v = 0;
2385 glGetIntegerv(GL_ALPHA_BITS, &v);
2386 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2387 // user requested RGB then RGB. If the user did not specify a preference than
2388 // use whatever we were given. Same for DEPTH and STENCIL.
2389 back_buffer_color_format_ =
2390 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2391 glGetIntegerv(GL_DEPTH_BITS, &v);
2392 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2393 glGetIntegerv(GL_STENCIL_BITS, &v);
2394 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
2395
[email protected]069944672012-04-25 20:52:232396 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022397 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542398 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022399 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432400 // max_sample_count must be initialized to a sane value. If
2401 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2402 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022403 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2404 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2405 max_sample_count);
2406 } else {
2407 offscreen_target_samples_ = 1;
2408 }
[email protected]8a61d872012-01-20 12:43:562409 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022410
2411 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2412 const bool rgb8_supported =
2413 context_->HasExtension("GL_OES_rgb8_rgba8");
2414 // The only available default render buffer formats in GLES2 have very
2415 // little precision. Don't enable multisampling unless 8-bit render
2416 // buffer formats are available--instead fall back to 8-bit textures.
2417 if (rgb8_supported && offscreen_target_samples_ > 1) {
2418 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2419 GL_RGBA8 : GL_RGB8;
2420 } else {
2421 offscreen_target_samples_ = 1;
2422 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2423 GL_RGBA : GL_RGB;
2424 }
2425
2426 // ANGLE only supports packed depth/stencil formats, so use it if it is
2427 // available.
2428 const bool depth24_stencil8_supported =
2429 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272430 VLOG(1) << "GL_OES_packed_depth_stencil "
2431 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002432 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2433 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022434 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2435 offscreen_target_stencil_format_ = 0;
2436 } else {
2437 // It may be the case that this depth/stencil combination is not
2438 // supported, but this will be checked later by CheckFramebufferStatus.
2439 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2440 GL_DEPTH_COMPONENT16 : 0;
2441 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2442 GL_STENCIL_INDEX8 : 0;
2443 }
2444 } else {
2445 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2446 GL_RGBA : GL_RGB;
2447
2448 // If depth is requested at all, use the packed depth stencil format if
2449 // it's available, as some desktop GL drivers don't support any non-packed
2450 // formats for depth attachments.
2451 const bool depth24_stencil8_supported =
2452 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272453 VLOG(1) << "GL_EXT_packed_depth_stencil "
2454 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022455
[email protected]71ee3642010-10-14 18:08:002456 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2457 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022458 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2459 offscreen_target_stencil_format_ = 0;
2460 } else {
2461 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2462 GL_DEPTH_COMPONENT : 0;
2463 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2464 GL_STENCIL_INDEX : 0;
2465 }
2466 }
2467
[email protected]97872062010-11-03 19:07:052468 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2469 GL_RGBA : GL_RGB;
2470
[email protected]6217d392010-03-25 22:08:352471 // Create the target frame buffer. This is the one that the client renders
2472 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352473 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352474 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022475 // Due to GLES2 format limitations, either the color texture (for
2476 // non-multisampling) or the color render buffer (for multisampling) will be
2477 // attached to the offscreen frame buffer. The render buffer has more
2478 // limited formats available to it, but the texture can't do multisampling.
2479 if (IsOffscreenBufferMultisampled()) {
[email protected]ed9f9cd2013-02-27 21:12:352480 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022481 offscreen_target_color_render_buffer_->Create();
2482 } else {
[email protected]ed9f9cd2013-02-27 21:12:352483 offscreen_target_color_texture_.reset(new BackTexture(this));
[email protected]34ff8b0c2010-10-01 20:06:022484 offscreen_target_color_texture_->Create();
2485 }
[email protected]ed9f9cd2013-02-27 21:12:352486 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152487 offscreen_target_depth_render_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352488 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152489 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352490
2491 // Create the saved offscreen texture. The target frame buffer is copied
2492 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352493 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022494 offscreen_saved_frame_buffer_->Create();
2495 //
[email protected]ed9f9cd2013-02-27 21:12:352496 offscreen_saved_color_texture_.reset(new BackTexture(this));
[email protected]6217d392010-03-25 22:08:352497 offscreen_saved_color_texture_->Create();
2498
[email protected]6217d392010-03-25 22:08:352499 // Allocate the render buffers at their initial size and check the status
2500 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592501 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012502 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382503 Destroy(true);
[email protected]6217d392010-03-25 22:08:352504 return false;
2505 }
2506
[email protected]678a73f2012-12-19 19:22:092507 // Allocate the offscreen saved color texture.
2508 DCHECK(offscreen_saved_color_format_);
2509 offscreen_saved_color_texture_->AllocateStorage(
2510 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2511
2512 offscreen_saved_frame_buffer_->AttachRenderTexture(
2513 offscreen_saved_color_texture_.get());
2514 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2515 GL_FRAMEBUFFER_COMPLETE) {
2516 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2517 Destroy(true);
2518 return false;
2519 }
2520
[email protected]6217d392010-03-25 22:08:352521 // Bind to the new default frame buffer (the offscreen target frame buffer).
2522 // This should now be associated with ID zero.
2523 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2524 }
2525
[email protected]295faf4b2012-01-25 23:31:412526 // Clear the backbuffer.
2527 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2528
[email protected]76a0ee102010-04-07 21:03:042529 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2530 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2531 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372532 // mailing list archives. It also implicitly enables the desktop GL
2533 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2534 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152535 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2536 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372537 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152538 }
[email protected]de17df392010-04-23 21:09:412539
[email protected]706b69f2012-07-27 04:59:302540 has_robustness_extension_ =
2541 context->HasExtension("GL_ARB_robustness") ||
2542 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432543
[email protected]c2f8c8402010-12-06 18:07:242544 if (!InitializeShaderTranslator()) {
2545 return false;
[email protected]de17df392010-04-23 21:09:412546 }
[email protected]76a0ee102010-04-07 21:03:042547
[email protected]e259eb412012-10-13 05:47:242548 state_.viewport_width = size.width();
2549 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282550
[email protected]5904806b2012-05-08 18:10:222551 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282552 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022553 viewport_max_width_ = viewport_params[0];
2554 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282555
[email protected]88a61bf2012-10-27 13:00:422556 state_.scissor_width = state_.viewport_width;
2557 state_.scissor_height = state_.viewport_height;
2558
[email protected]11f3e702012-06-19 19:00:012559 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222560 state_.InitCapabilities();
2561 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242562 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]88a61bf2012-10-27 13:00:422563 glHint(GL_GENERATE_MIPMAP_HINT, state_.hint_generate_mipmap);
[email protected]e259eb412012-10-13 05:47:242564 glPixelStorei(GL_PACK_ALIGNMENT, state_.pack_alignment);
[email protected]e259eb412012-10-13 05:47:242565 glPixelStorei(GL_UNPACK_ALIGNMENT, state_.unpack_alignment);
[email protected]11f3e702012-06-19 19:00:012566
2567 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2568 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2569 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2570 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2571
[email protected]6d9374e2012-07-17 03:31:242572 // AMD and Intel drivers on Mac OS apparently get gl_PointCoord
2573 // backward from the spec and this setting makes them work
2574 // correctly. rdar://problem/11883495
[email protected]62e155e2012-10-23 22:43:152575 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462576 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2577 }
[email protected]dd289a5d62012-06-30 22:05:462578
[email protected]32145a92012-12-17 09:01:592579 // Create a delegate to perform async pixel transfers.
2580 async_pixel_transfer_delegate_ =
2581 gfx::AsyncPixelTransferDelegate::Create(context.get());
2582
[email protected]246a70452010-03-05 21:53:502583 return true;
[email protected]96449d2c2009-11-25 00:01:322584}
2585
[email protected]302ce6d2011-07-07 23:28:112586void GLES2DecoderImpl::UpdateCapabilities() {
2587 util_.set_num_compressed_texture_formats(
2588 validators_->compressed_texture_format.GetValues().size());
2589 util_.set_num_shader_binary_formats(
2590 validators_->shader_binary_format.GetValues().size());
2591}
2592
[email protected]c2f8c8402010-12-06 18:07:242593bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442594 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2595
[email protected]c2f8c8402010-12-06 18:07:242596 if (!use_shader_translator_) {
2597 return true;
2598 }
2599 ShBuiltInResources resources;
2600 ShInitBuiltInResources(&resources);
2601 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2602 resources.MaxVertexUniformVectors =
2603 group_->max_vertex_uniform_vectors();
2604 resources.MaxVaryingVectors = group_->max_varying_vectors();
2605 resources.MaxVertexTextureImageUnits =
2606 group_->max_vertex_texture_image_units();
2607 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2608 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2609 resources.MaxFragmentUniformVectors =
2610 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492611 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]f0d74742011-10-03 16:31:042612
[email protected]9e98f61b2013-03-05 02:21:142613#if (ANGLE_SH_VERSION >= 110)
[email protected]8dc1bf92013-03-12 03:58:212614 GLint range[2];
2615 GLint precision = 0;
2616 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2617 range, &precision);
2618 resources.FragmentPrecisionHigh = ((range[0] >= 62) &&
2619 (range[1] >= 62) &&
2620 (precision >= 16));
[email protected]9e98f61b2013-03-05 02:21:142621#endif
2622
[email protected]f0d74742011-10-03 16:31:042623 if (force_webgl_glsl_validation_) {
2624 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
2625 } else {
2626 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152627 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462628 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152629 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062630 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152631 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492632 resources.EXT_draw_buffers =
2633 features().ext_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042634 }
2635
[email protected]26b61442013-03-17 16:12:012636 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2637 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052638 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022639#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052640 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022641#else
2642 resources.HashFunction = &CityHash64;
2643#endif
[email protected]6aedcdc2013-01-24 01:25:052644 else
2645 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122646 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2647 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2648 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2649 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
[email protected]62e155e2012-10-23 22:43:152650 workarounds().needs_glsl_built_in_function_emulation ?
[email protected]a2a0fe762011-09-20 00:59:122651 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
2652 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
[email protected]87fb6ab2012-06-13 22:28:042653
2654 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2655 vertex_translator_ = cache->GetTranslator(
2656 SH_VERTEX_SHADER, shader_spec, &resources,
2657 implementation_type, function_behavior);
2658 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242659 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382660 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242661 return false;
2662 }
[email protected]87fb6ab2012-06-13 22:28:042663
2664 fragment_translator_ = cache->GetTranslator(
2665 SH_FRAGMENT_SHADER, shader_spec, &resources,
2666 implementation_type, function_behavior);
2667 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242668 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382669 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242670 return false;
2671 }
2672 return true;
2673}
2674
[email protected]ae51d192010-04-27 00:48:032675bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472676 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352677 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032678 return false;
2679 }
2680 }
2681 scoped_array<GLuint> service_ids(new GLuint[n]);
2682 glGenBuffersARB(n, service_ids.get());
2683 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352684 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032685 }
2686 return true;
2687}
2688
2689bool GLES2DecoderImpl::GenFramebuffersHelper(
2690 GLsizei n, const GLuint* client_ids) {
2691 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352692 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032693 return false;
2694 }
2695 }
2696 scoped_array<GLuint> service_ids(new GLuint[n]);
2697 glGenFramebuffersEXT(n, service_ids.get());
2698 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352699 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032700 }
2701 return true;
2702}
2703
2704bool GLES2DecoderImpl::GenRenderbuffersHelper(
2705 GLsizei n, const GLuint* client_ids) {
2706 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352707 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032708 return false;
2709 }
2710 }
2711 scoped_array<GLuint> service_ids(new GLuint[n]);
2712 glGenRenderbuffersEXT(n, service_ids.get());
2713 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352714 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032715 }
2716 return true;
2717}
2718
2719bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2720 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352721 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032722 return false;
2723 }
2724 }
2725 scoped_array<GLuint> service_ids(new GLuint[n]);
2726 glGenTextures(n, service_ids.get());
2727 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352728 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032729 }
2730 return true;
2731}
2732
2733void GLES2DecoderImpl::DeleteBuffersHelper(
2734 GLsizei n, const GLuint* client_ids) {
2735 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212736 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102737 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242738 state_.vertex_attrib_manager->Unbind(buffer);
2739 if (state_.bound_array_buffer == buffer) {
2740 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102741 }
[email protected]ed9f9cd2013-02-27 21:12:352742 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032743 }
[email protected]a93bb842010-02-16 23:03:472744 }
[email protected]07f54fcc2009-12-22 02:46:302745}
2746
[email protected]ae51d192010-04-27 00:48:032747void GLES2DecoderImpl::DeleteFramebuffersHelper(
2748 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452749 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152750 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112751
[email protected]a25fa872010-03-25 02:57:582752 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352753 Framebuffer* framebuffer =
2754 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102755 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242756 if (framebuffer == state_.bound_draw_framebuffer) {
2757 state_.bound_draw_framebuffer = NULL;
[email protected]88a61bf2012-10-27 13:00:422758 clear_state_dirty_ = true;
[email protected]ebfb73c2012-08-15 02:37:452759 GLenum target = supports_separate_framebuffer_binds ?
2760 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112761 glBindFramebufferEXT(target, GetBackbufferServiceId());
2762 }
[email protected]e259eb412012-10-13 05:47:242763 if (framebuffer == state_.bound_read_framebuffer) {
2764 state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452765 GLenum target = supports_separate_framebuffer_binds ?
2766 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112767 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462768 }
[email protected]70d34263c2013-01-09 00:27:452769 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352770 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032771 }
[email protected]a25fa872010-03-25 02:57:582772 }
[email protected]07f54fcc2009-12-22 02:46:302773}
2774
[email protected]ae51d192010-04-27 00:48:032775void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2776 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452777 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152778 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582779 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352780 Renderbuffer* renderbuffer =
2781 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102782 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242783 if (state_.bound_renderbuffer == renderbuffer) {
2784 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102785 }
2786 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452787 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242788 if (state_.bound_read_framebuffer) {
2789 state_.bound_read_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452790 GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102791 }
[email protected]e259eb412012-10-13 05:47:242792 if (state_.bound_draw_framebuffer) {
2793 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452794 GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102795 }
2796 } else {
[email protected]e259eb412012-10-13 05:47:242797 if (state_.bound_draw_framebuffer) {
2798 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]a0b78dc2011-11-11 10:43:102799 GL_FRAMEBUFFER, renderbuffer);
2800 }
2801 }
[email protected]88a61bf2012-10-27 13:00:422802 clear_state_dirty_ = true;
[email protected]ed9f9cd2013-02-27 21:12:352803 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032804 }
[email protected]a25fa872010-03-25 02:57:582805 }
[email protected]07f54fcc2009-12-22 02:46:302806}
2807
[email protected]ae51d192010-04-27 00:48:032808void GLES2DecoderImpl::DeleteTexturesHelper(
2809 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452810 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152811 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472812 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352813 Texture* texture = GetTexture(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102814 if (texture && !texture->IsDeleted()) {
2815 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:422816 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462817 }
[email protected]a0b78dc2011-11-11 10:43:102818 // Unbind texture from texture units.
[email protected]1868a342012-11-07 15:56:022819 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]e259eb412012-10-13 05:47:242820 state_.texture_units[jj].Unbind(texture);
[email protected]a0b78dc2011-11-11 10:43:102821 }
2822 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452823 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242824 if (state_.bound_read_framebuffer) {
2825 state_.bound_read_framebuffer->UnbindTexture(
[email protected]ebfb73c2012-08-15 02:37:452826 GL_READ_FRAMEBUFFER_EXT, texture);
[email protected]a0b78dc2011-11-11 10:43:102827 }
[email protected]e259eb412012-10-13 05:47:242828 if (state_.bound_draw_framebuffer) {
2829 state_.bound_draw_framebuffer->UnbindTexture(
[email protected]ebfb73c2012-08-15 02:37:452830 GL_DRAW_FRAMEBUFFER_EXT, texture);
[email protected]a0b78dc2011-11-11 10:43:102831 }
2832 } else {
[email protected]e259eb412012-10-13 05:47:242833 if (state_.bound_draw_framebuffer) {
2834 state_.bound_draw_framebuffer->UnbindTexture(GL_FRAMEBUFFER, texture);
[email protected]a0b78dc2011-11-11 10:43:102835 }
2836 }
2837 GLuint service_id = texture->service_id();
2838 if (texture->IsStreamTexture() && stream_texture_manager_) {
[email protected]b0af4f52011-09-28 22:04:422839 stream_texture_manager_->DestroyStreamTexture(service_id);
2840 }
[email protected]e51bdf32011-11-23 22:21:462841#if defined(OS_MACOSX)
2842 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2843 ReleaseIOSurfaceForTexture(service_id);
2844 }
2845#endif
[email protected]ed9f9cd2013-02-27 21:12:352846 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032847 }
[email protected]a93bb842010-02-16 23:03:472848 }
[email protected]07f54fcc2009-12-22 02:46:302849}
2850
[email protected]43f28f832010-02-03 02:28:482851// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322852
[email protected]eb54a562010-01-20 21:55:182853bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382854 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2855 return false;
2856
2857 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432858 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292859
2860 // Some D3D drivers cannot recover from device lost in the GPU process
2861 // sandbox. Allow a new GPU process to launch.
2862 if (workarounds().exit_on_context_lost) {
2863 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2864 << " a D3D device in the Chrome GPU process sandbox.";
2865 exit(0);
2866 }
2867
[email protected]63c9b052012-05-17 18:27:382868 return false;
[email protected]38d139d2011-07-14 00:38:432869 }
2870
[email protected]69a8701e2013-03-07 21:31:092871 ProcessFinishedAsyncTransfers();
2872 if (workarounds().flush_on_context_switch)
2873 glFlush();
2874
2875 return true;
2876}
2877
2878void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]fe8d73c2013-02-16 22:37:322879 if (engine() && query_manager_.get())
2880 query_manager_->ProcessPendingTransferQueries();
2881
[email protected]5b3a8e02013-03-13 05:36:442882 // TODO(epenner): Is there a better place to do this?
2883 // This needs to occur before we execute any batch of commands
2884 // from the client, as the client may have recieved an async
2885 // completion while issuing those commands.
2886 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]2b1767cf2013-03-16 09:25:052887 // TODO(reveman): We should avoid using a bool return value to determine
2888 // if we need to restore some state. crbug.com/196303
[email protected]5b3a8e02013-03-13 05:36:442889 if (async_pixel_transfer_delegate_->BindCompletedAsyncTransfers())
[email protected]32145a92012-12-17 09:01:592890 RestoreCurrentTexture2DBindings();
[email protected]eb54a562010-01-20 21:55:182891}
2892
[email protected]a96a6022011-11-04 00:58:122893void GLES2DecoderImpl::ReleaseCurrent() {
2894 if (context_.get())
2895 context_->ReleaseCurrent(surface_.get());
2896}
2897
[email protected]8e3e0662010-08-23 18:46:302898void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
[email protected]ed9f9cd2013-02-27 21:12:352899 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:202900 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
[email protected]8e3e0662010-08-23 18:46:302901 glBindRenderbufferEXT(
[email protected]0d6bfdc2011-11-02 01:32:202902 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
[email protected]8e3e0662010-08-23 18:46:302903}
2904
2905static void RebindCurrentFramebuffer(
2906 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062907 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242908 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062909 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462910
[email protected]a3783712012-01-20 22:18:242911 if (framebuffer_id == 0) {
2912 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302913 }
[email protected]297ca1c2011-06-20 23:08:462914
[email protected]8e3e0662010-08-23 18:46:302915 glBindFramebufferEXT(target, framebuffer_id);
2916}
2917
2918void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]88a61bf2012-10-27 13:00:422919 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462920
[email protected]62e155e2012-10-23 22:43:152921 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302922 RebindCurrentFramebuffer(
2923 GL_FRAMEBUFFER,
[email protected]e259eb412012-10-13 05:47:242924 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242925 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302926 } else {
2927 RebindCurrentFramebuffer(
2928 GL_READ_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242929 state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242930 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302931 RebindCurrentFramebuffer(
2932 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242933 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242934 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302935 }
[email protected]70d34263c2013-01-09 00:27:452936 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302937}
2938
2939void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
[email protected]e259eb412012-10-13 05:47:242940 TextureUnit& info = state_.texture_units[0];
[email protected]8e3e0662010-08-23 18:46:302941 GLuint last_id;
2942 if (info.bound_texture_2d) {
2943 last_id = info.bound_texture_2d->service_id();
2944 } else {
2945 last_id = 0;
2946 }
2947
2948 glBindTexture(GL_TEXTURE_2D, last_id);
[email protected]e259eb412012-10-13 05:47:242949 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]8e3e0662010-08-23 18:46:302950}
2951
[email protected]0d6bfdc2011-11-02 01:32:202952bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352953 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202954 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102955 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582956 if (backbuffer_needs_clear_bits_) {
2957 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2958 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2959 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2960 glClearStencil(0);
2961 glStencilMask(-1);
2962 glClearDepth(1.0f);
2963 glDepthMask(true);
2964 glDisable(GL_SCISSOR_TEST);
2965 glClear(backbuffer_needs_clear_bits_);
2966 backbuffer_needs_clear_bits_ = 0;
2967 RestoreClearState();
2968 }
[email protected]0d6bfdc2011-11-02 01:32:202969 return true;
2970 }
2971
[email protected]968351b2011-12-20 08:26:512972 if (framebuffer_manager()->IsComplete(framebuffer)) {
2973 return true;
2974 }
2975
[email protected]0d6bfdc2011-11-02 01:32:202976 GLenum completeness = framebuffer->IsPossiblyComplete();
2977 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512978 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432979 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272980 return false;
2981 }
[email protected]0d6bfdc2011-11-02 01:32:202982
2983 // Are all the attachments cleared?
2984 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2985 texture_manager()->HaveUnclearedMips()) {
2986 if (!framebuffer->IsCleared()) {
2987 // Can we clear them?
[email protected]73276522012-11-09 05:50:202988 if (framebuffer->GetStatus(texture_manager(), target) !=
2989 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512990 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432991 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2992 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202993 return false;
2994 }
2995 ClearUnclearedAttachments(target, framebuffer);
2996 }
2997 }
2998
[email protected]968351b2011-12-20 08:26:512999 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203000 if (framebuffer->GetStatus(texture_manager(), target) !=
3001 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513002 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433003 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3004 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513005 return false;
3006 }
3007 framebuffer_manager()->MarkAsComplete(framebuffer);
3008 }
3009
[email protected]0d6bfdc2011-11-02 01:32:203010 // NOTE: At this point we don't know if the framebuffer is complete but
3011 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273012 return true;
3013}
3014
[email protected]0d6bfdc2011-11-02 01:32:203015bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153016 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513017 bool valid = CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:243018 state_.bound_draw_framebuffer, GL_FRAMEBUFFER_EXT, func_name);
[email protected]28718a92013-04-04 12:12:513019
3020 if (valid)
3021 OnUseFramebuffer();
3022
3023 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203024 }
3025 return CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:243026 state_.bound_draw_framebuffer,
3027 GL_DRAW_FRAMEBUFFER_EXT, func_name) &&
[email protected]0d6bfdc2011-11-02 01:32:203028 CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:243029 state_.bound_read_framebuffer,
3030 GL_READ_FRAMEBUFFER_EXT, func_name);
[email protected]0d6bfdc2011-11-02 01:32:203031}
3032
[email protected]8e3e0662010-08-23 18:46:303033gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353034 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453035 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203036 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353037 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203038 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263039 if (attachment) {
3040 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503041 }
[email protected]9edc6b22010-12-23 02:00:263042 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023043 } else if (offscreen_target_frame_buffer_.get()) {
3044 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353045 } else {
[email protected]f62a5ab2011-05-23 20:34:153046 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023047 }
[email protected]246a70452010-03-05 21:53:503048}
3049
[email protected]9edc6b22010-12-23 02:00:263050GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353051 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453052 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203053 if (framebuffer != NULL) {
3054 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463055 } else if (offscreen_target_frame_buffer_.get()) {
3056 return offscreen_target_color_format_;
3057 } else {
3058 return back_buffer_color_format_;
3059 }
3060}
3061
3062GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353063 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453064 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203065 if (framebuffer != NULL) {
3066 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263067 } else if (offscreen_target_frame_buffer_.get()) {
3068 return offscreen_target_color_format_;
3069 } else {
[email protected]32fe9aa2011-01-21 23:47:133070 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263071 }
3072}
3073
[email protected]9a5afa432011-07-22 18:16:393074void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]34ff8b0c2010-10-01 20:06:023075 if (parent_) {
[email protected]2f2d7042010-04-14 21:45:583076 // Update the info about the offscreen saved color texture in the parent.
3077 // The reference to the parent is a weak pointer and will become null if the
3078 // parent is later destroyed.
[email protected]262d7aa2010-12-03 22:07:293079 TextureManager* parent_texture_manager = parent_->texture_manager();
[email protected]262d7aa2010-12-03 22:07:293080 parent_texture_manager->SetLevelInfo(
[email protected]8a61d872012-01-20 12:43:563081 offscreen_saved_color_texture_info_,
[email protected]ef526492010-06-02 23:12:253082 GL_TEXTURE_2D,
3083 0, // level
3084 GL_RGBA,
[email protected]799b4b22011-08-22 17:09:593085 offscreen_size_.width(),
3086 offscreen_size_.height(),
[email protected]ef526492010-06-02 23:12:253087 1, // depth
3088 0, // border
3089 GL_RGBA,
[email protected]0d6bfdc2011-11-02 01:32:203090 GL_UNSIGNED_BYTE,
3091 true);
[email protected]262d7aa2010-12-03 22:07:293092 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073093 "UpdateParentTextureInfo",
3094 this,
[email protected]8a61d872012-01-20 12:43:563095 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043096 GL_TEXTURE_MAG_FILTER,
3097 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:293098 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073099 "UpdateParentTextureInfo",
3100 this,
[email protected]8a61d872012-01-20 12:43:563101 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043102 GL_TEXTURE_MIN_FILTER,
3103 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:293104 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073105 "UpdateParentTextureInfo",
3106 this,
[email protected]8a61d872012-01-20 12:43:563107 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043108 GL_TEXTURE_WRAP_S,
3109 GL_CLAMP_TO_EDGE);
[email protected]262d7aa2010-12-03 22:07:293110 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073111 "UpdateParentTextureInfo",
3112 this,
[email protected]8a61d872012-01-20 12:43:563113 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043114 GL_TEXTURE_WRAP_T,
3115 GL_CLAMP_TO_EDGE);
[email protected]8a61d872012-01-20 12:43:563116 } else {
3117 offscreen_saved_color_texture_info_ = NULL;
[email protected]0c8c9d22010-06-25 17:36:393118 }
[email protected]6217d392010-03-25 22:08:353119}
3120
[email protected]799b4b22011-08-22 17:09:593121void GLES2DecoderImpl::SetResizeCallback(
[email protected]9d37f062011-11-22 01:24:523122 const base::Callback<void(gfx::Size)>& callback) {
3123 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003124}
3125
[email protected]6b6e7ee2011-12-13 08:04:523126void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) {
3127 msg_callback_ = callback;
3128}
3129
[email protected]e3932abb2013-03-13 00:01:373130void GLES2DecoderImpl::SetShaderCacheCallback(
3131 const ShaderCacheCallback& callback) {
3132 shader_cache_callback_ = callback;
3133}
3134
[email protected]840a7e462013-02-27 01:29:513135void GLES2DecoderImpl::SetWaitSyncPointCallback(
3136 const WaitSyncPointCallback& callback) {
3137 wait_sync_point_callback_ = callback;
3138}
3139
[email protected]b0af4f52011-09-28 22:04:423140void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) {
3141 stream_texture_manager_ = manager;
3142}
3143
[email protected]32145a92012-12-17 09:01:593144gfx::AsyncPixelTransferDelegate*
3145 GLES2DecoderImpl::GetAsyncPixelTransferDelegate() {
3146 return async_pixel_transfer_delegate_.get();
3147}
3148
3149void GLES2DecoderImpl::SetAsyncPixelTransferDelegate(
3150 gfx::AsyncPixelTransferDelegate* delegate) {
3151 async_pixel_transfer_delegate_ = make_scoped_ptr(delegate);
3152}
3153
[email protected]1318e922010-09-17 22:03:163154bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3155 uint32* service_texture_id) {
[email protected]02965c22013-03-09 02:40:073156 Texture* texture = texture_manager()->GetTexture(client_texture_id);
[email protected]1318e922010-09-17 22:03:163157 if (texture) {
3158 *service_texture_id = texture->service_id();
3159 return true;
3160 }
3161 return false;
3162}
3163
[email protected]63b465922012-09-06 02:04:523164uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]b9804322013-01-08 17:54:123165 return texture_upload_count_ +
3166 async_pixel_transfer_delegate_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523167}
3168
3169base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]b9804322013-01-08 17:54:123170 return total_texture_upload_time_ +
3171 async_pixel_transfer_delegate_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523172}
3173
3174base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3175 return total_processing_commands_time_;
3176}
3177
[email protected]dc25dda2012-09-27 21:36:303178void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3179 total_processing_commands_time_ += time;
3180}
3181
[email protected]63c9b052012-05-17 18:27:383182void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063183 if (!initialized())
3184 return;
3185
[email protected]63c9b052012-05-17 18:27:383186 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053187
[email protected]c826d732012-02-09 04:40:263188 ChildList children = children_;
3189 for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
3190 (*it)->SetParent(NULL, 0);
3191 DCHECK(children_.empty());
[email protected]3c644d82011-06-20 19:58:243192 SetParent(NULL, 0);
3193
[email protected]80eb6b52012-01-19 00:14:413194 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243195 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463196 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023197 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243198 state_.bound_array_buffer = NULL;
3199 state_.current_query = NULL;
3200 state_.current_program = NULL;
3201 state_.bound_read_framebuffer = NULL;
3202 state_.bound_draw_framebuffer = NULL;
3203 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413204
[email protected]eadc96792010-10-27 19:39:393205 if (have_context) {
[email protected]c322e882012-05-23 18:06:183206 if (copy_texture_CHROMIUM_.get()) {
3207 copy_texture_CHROMIUM_->Destroy();
3208 copy_texture_CHROMIUM_.reset();
3209 }
[email protected]43410e92012-04-20 17:06:283210
[email protected]e259eb412012-10-13 05:47:243211 if (state_.current_program) {
3212 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
3213 state_.current_program = NULL;
[email protected]ca488e12010-12-13 20:06:143214 }
3215
[email protected]b1122982010-05-17 23:04:243216 if (attrib_0_buffer_id_) {
3217 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3218 }
[email protected]8fbedc02010-11-18 18:43:403219 if (fixed_attrib_buffer_id_) {
3220 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3221 }
[email protected]b1122982010-05-17 23:04:243222
[email protected]97872062010-11-03 19:07:053223 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543224 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053225 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543226 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053227 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023228 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053229 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153230 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053231 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153232 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053233 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023234 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053235 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543236 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273237 if (offscreen_resolved_frame_buffer_.get())
3238 offscreen_resolved_frame_buffer_->Destroy();
3239 if (offscreen_resolved_color_texture_.get())
3240 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053241 } else {
3242 if (offscreen_target_frame_buffer_.get())
3243 offscreen_target_frame_buffer_->Invalidate();
3244 if (offscreen_target_color_texture_.get())
3245 offscreen_target_color_texture_->Invalidate();
3246 if (offscreen_target_color_render_buffer_.get())
3247 offscreen_target_color_render_buffer_->Invalidate();
3248 if (offscreen_target_depth_render_buffer_.get())
3249 offscreen_target_depth_render_buffer_->Invalidate();
3250 if (offscreen_target_stencil_render_buffer_.get())
3251 offscreen_target_stencil_render_buffer_->Invalidate();
3252 if (offscreen_saved_frame_buffer_.get())
3253 offscreen_saved_frame_buffer_->Invalidate();
3254 if (offscreen_saved_color_texture_.get())
3255 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273256 if (offscreen_resolved_frame_buffer_.get())
3257 offscreen_resolved_frame_buffer_->Invalidate();
3258 if (offscreen_resolved_color_texture_.get())
3259 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023260 }
[email protected]43410e92012-04-20 17:06:283261 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053262
[email protected]882ba1e22012-03-08 19:02:533263 if (query_manager_.get()) {
3264 query_manager_->Destroy(have_context);
3265 query_manager_.reset();
3266 }
3267
[email protected]944b62f32012-09-27 02:20:463268 if (vertex_array_manager_ .get()) {
3269 vertex_array_manager_->Destroy(have_context);
3270 vertex_array_manager_.reset();
3271 }
3272
[email protected]97872062010-11-03 19:07:053273 offscreen_target_frame_buffer_.reset();
3274 offscreen_target_color_texture_.reset();
3275 offscreen_target_color_render_buffer_.reset();
3276 offscreen_target_depth_render_buffer_.reset();
3277 offscreen_target_stencil_render_buffer_.reset();
3278 offscreen_saved_frame_buffer_.reset();
3279 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273280 offscreen_resolved_frame_buffer_.reset();
3281 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463282
[email protected]2d9d3b92013-01-18 01:07:233283 if (group_) {
3284 group_->Destroy(this, have_context);
3285 group_ = NULL;
3286 }
3287
3288 if (context_.get()) {
3289 context_->ReleaseCurrent(NULL);
3290 context_ = NULL;
3291 }
3292
[email protected]e51bdf32011-11-23 22:21:463293#if defined(OS_MACOSX)
3294 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3295 it != texture_to_io_surface_map_.end(); ++it) {
3296 CFRelease(it->second);
3297 }
3298 texture_to_io_surface_map_.clear();
3299#endif
[email protected]96449d2c2009-11-25 00:01:323300}
3301
[email protected]63c9b052012-05-17 18:27:383302void GLES2DecoderImpl::SetSurface(
3303 const scoped_refptr<gfx::GLSurface>& surface) {
3304 DCHECK(context_->IsCurrent(NULL));
3305 DCHECK(surface_.get());
3306 surface_ = surface;
3307 RestoreCurrentFramebufferBindings();
3308}
3309
[email protected]3c644d82011-06-20 19:58:243310bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent,
3311 uint32 new_parent_texture_id) {
[email protected]9a5afa432011-07-22 18:16:393312 if (!offscreen_saved_color_texture_.get())
3313 return false;
3314
[email protected]3c644d82011-06-20 19:58:243315 // Remove the saved frame buffer mapping from the parent decoder. The
3316 // parent pointer is a weak pointer so it will be null if the parent has
3317 // already been destroyed.
3318 if (parent_) {
[email protected]c826d732012-02-09 04:40:263319 ChildList::iterator it = std::find(
3320 parent_->children_.begin(),
3321 parent_->children_.end(),
3322 this);
3323 DCHECK(it != parent_->children_.end());
3324 parent_->children_.erase(it);
[email protected]3c644d82011-06-20 19:58:243325 // First check the texture has been mapped into the parent. This might not
3326 // be the case if initialization failed midway through.
3327 GLuint service_id = offscreen_saved_color_texture_->id();
3328 GLuint client_id = 0;
3329 if (parent_->texture_manager()->GetClientId(service_id, &client_id)) {
[email protected]ed9f9cd2013-02-27 21:12:353330 parent_->texture_manager()->RemoveTexture(client_id);
[email protected]3c644d82011-06-20 19:58:243331 }
3332 }
3333
3334 GLES2DecoderImpl* new_parent_impl = static_cast<GLES2DecoderImpl*>(
3335 new_parent);
3336 if (new_parent_impl) {
[email protected]c826d732012-02-09 04:40:263337#ifndef NDEBUG
3338 ChildList::iterator it = std::find(
3339 new_parent_impl->children_.begin(),
3340 new_parent_impl->children_.end(),
3341 this);
3342 DCHECK(it == new_parent_impl->children_.end());
3343#endif
3344 new_parent_impl->children_.push_back(this);
[email protected]3c644d82011-06-20 19:58:243345 // Map the ID of the saved offscreen texture into the parent so that
3346 // it can reference it.
3347 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]98687862011-07-11 23:31:303348
3349 // Replace texture info when ID is already in use by parent.
[email protected]ed9f9cd2013-02-27 21:12:353350 if (new_parent_impl->texture_manager()->GetTexture(
[email protected]80eb6b52012-01-19 00:14:413351 new_parent_texture_id))
[email protected]ed9f9cd2013-02-27 21:12:353352 new_parent_impl->texture_manager()->RemoveTexture(
[email protected]80eb6b52012-01-19 00:14:413353 new_parent_texture_id);
[email protected]98687862011-07-11 23:31:303354
[email protected]8a61d872012-01-20 12:43:563355 offscreen_saved_color_texture_info_ =
[email protected]ed9f9cd2013-02-27 21:12:353356 new_parent_impl->CreateTexture(new_parent_texture_id, service_id);
[email protected]8a61d872012-01-20 12:43:563357 offscreen_saved_color_texture_info_->SetNotOwned();
3358 new_parent_impl->texture_manager()->
[email protected]02965c22013-03-09 02:40:073359 SetTarget(offscreen_saved_color_texture_info_, GL_TEXTURE_2D);
[email protected]3c644d82011-06-20 19:58:243360
[email protected]ee1e6aa2012-11-29 09:24:103361 parent_ = base::AsWeakPtr<GLES2DecoderImpl>(new_parent_impl);
[email protected]9a5afa432011-07-22 18:16:393362
3363 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243364 } else {
3365 parent_.reset();
[email protected]8a61d872012-01-20 12:43:563366 offscreen_saved_color_texture_info_ = NULL;
[email protected]3c644d82011-06-20 19:58:243367 }
3368
3369 return true;
3370}
3371
[email protected]260ddc4e2012-06-28 00:01:533372size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143373 size_t total = 0;
3374 if (offscreen_target_frame_buffer_.get()) {
3375 if (offscreen_target_color_texture_.get()) {
3376 total += offscreen_target_color_texture_->estimated_size();
3377 }
3378 if (offscreen_target_color_render_buffer_.get()) {
3379 total += offscreen_target_color_render_buffer_->estimated_size();
3380 }
3381 if (offscreen_target_depth_render_buffer_.get()) {
3382 total += offscreen_target_depth_render_buffer_->estimated_size();
3383 }
3384 if (offscreen_target_stencil_render_buffer_.get()) {
3385 total += offscreen_target_stencil_render_buffer_->estimated_size();
3386 }
3387 if (offscreen_saved_color_texture_.get()) {
3388 total += offscreen_saved_color_texture_->estimated_size();
3389 }
3390 if (offscreen_resolved_color_texture_.get()) {
3391 total += offscreen_resolved_color_texture_->estimated_size();
3392 }
3393 } else {
3394 gfx::Size size = surface_->GetSize();
3395 total += size.width() * size.height() *
3396 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3397 }
[email protected]260ddc4e2012-06-28 00:01:533398 return total;
[email protected]1078f912011-12-23 13:12:143399}
3400
[email protected]799b4b22011-08-22 17:09:593401bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3402 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3403 if (!is_offscreen) {
3404 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3405 << " with an onscreen framebuffer.";
3406 return false;
3407 }
3408
3409 if (offscreen_size_ == size)
3410 return true;
3411
3412 offscreen_size_ = size;
3413 int w = offscreen_size_.width();
3414 int h = offscreen_size_.height();
3415 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3416 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3417 << "to allocate storage due to excessive dimensions.";
3418 return false;
3419 }
3420
3421 // Reallocate the offscreen target buffers.
3422 DCHECK(offscreen_target_color_format_);
3423 if (IsOffscreenBufferMultisampled()) {
3424 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3425 offscreen_size_, offscreen_target_color_format_,
3426 offscreen_target_samples_)) {
3427 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3428 << "to allocate storage for offscreen target color buffer.";
3429 return false;
3430 }
3431 } else {
3432 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093433 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593434 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3435 << "to allocate storage for offscreen target color texture.";
3436 return false;
3437 }
3438 }
3439 if (offscreen_target_depth_format_ &&
3440 !offscreen_target_depth_render_buffer_->AllocateStorage(
3441 offscreen_size_, offscreen_target_depth_format_,
3442 offscreen_target_samples_)) {
3443 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3444 << "to allocate storage for offscreen target depth buffer.";
3445 return false;
3446 }
3447 if (offscreen_target_stencil_format_ &&
3448 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3449 offscreen_size_, offscreen_target_stencil_format_,
3450 offscreen_target_samples_)) {
3451 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3452 << "to allocate storage for offscreen target stencil buffer.";
3453 return false;
3454 }
3455
3456 // Attach the offscreen target buffers to the target frame buffer.
3457 if (IsOffscreenBufferMultisampled()) {
3458 offscreen_target_frame_buffer_->AttachRenderBuffer(
3459 GL_COLOR_ATTACHMENT0,
3460 offscreen_target_color_render_buffer_.get());
3461 } else {
3462 offscreen_target_frame_buffer_->AttachRenderTexture(
3463 offscreen_target_color_texture_.get());
3464 }
3465 if (offscreen_target_depth_format_) {
3466 offscreen_target_frame_buffer_->AttachRenderBuffer(
3467 GL_DEPTH_ATTACHMENT,
3468 offscreen_target_depth_render_buffer_.get());
3469 }
3470 const bool packed_depth_stencil =
3471 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3472 if (packed_depth_stencil) {
3473 offscreen_target_frame_buffer_->AttachRenderBuffer(
3474 GL_STENCIL_ATTACHMENT,
3475 offscreen_target_depth_render_buffer_.get());
3476 } else if (offscreen_target_stencil_format_) {
3477 offscreen_target_frame_buffer_->AttachRenderBuffer(
3478 GL_STENCIL_ATTACHMENT,
3479 offscreen_target_stencil_render_buffer_.get());
3480 }
3481
3482 if (offscreen_target_frame_buffer_->CheckStatus() !=
3483 GL_FRAMEBUFFER_COMPLETE) {
3484 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3485 << "because offscreen FBO was incomplete.";
3486 return false;
3487 }
3488
3489 // Clear the target frame buffer.
3490 {
3491 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3492 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3493 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3494 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3495 glClearStencil(0);
3496 glStencilMaskSeparate(GL_FRONT, -1);
3497 glStencilMaskSeparate(GL_BACK, -1);
3498 glClearDepth(0);
3499 glDepthMask(GL_TRUE);
3500 glDisable(GL_SCISSOR_TEST);
3501 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3502 RestoreClearState();
3503 }
[email protected]d85ef76d2011-09-08 22:21:433504
3505 // Destroy the offscreen resolved framebuffers.
3506 if (offscreen_resolved_frame_buffer_.get())
3507 offscreen_resolved_frame_buffer_->Destroy();
3508 if (offscreen_resolved_color_texture_.get())
3509 offscreen_resolved_color_texture_->Destroy();
3510 offscreen_resolved_color_texture_.reset();
3511 offscreen_resolved_frame_buffer_.reset();
3512
[email protected]799b4b22011-08-22 17:09:593513 return true;
[email protected]6217d392010-03-25 22:08:353514}
3515
[email protected]799b4b22011-08-22 17:09:593516error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353517 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443518 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023519 return error::kDeferCommandUntilLater;
3520
[email protected]799b4b22011-08-22 17:09:593521 GLuint width = static_cast<GLuint>(c.width);
3522 GLuint height = static_cast<GLuint>(c.height);
3523 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413524
3525 width = std::max(1U, width);
3526 height = std::max(1U, height);
3527
[email protected]a0d989162011-11-22 13:15:073528#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3529 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003530 // Make sure that we are done drawing to the back buffer before resizing.
3531 glFinish();
3532#endif
[email protected]799b4b22011-08-22 17:09:593533 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3534 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493535 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3536 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3537 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593538 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493539 }
[email protected]7ff86b92010-11-25 17:50:003540 }
[email protected]799b4b22011-08-22 17:09:593541
[email protected]9d37f062011-11-22 01:24:523542 if (!resize_callback_.is_null()) {
3543 resize_callback_.Run(gfx::Size(width, height));
[email protected]0e9346b2013-03-16 16:35:443544 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493545 if (!context_->IsCurrent(surface_.get())) {
3546 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3547 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053548 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493549 }
[email protected]658f7562011-09-09 05:24:053550 }
[email protected]799b4b22011-08-22 17:09:593551
3552 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393553}
3554
[email protected]96449d2c2009-11-25 00:01:323555const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3556 if (command_id > kStartPoint && command_id < kNumCommands) {
3557 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3558 }
3559 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3560}
3561
3562// Decode command with its arguments, and call the corresponding GL function.
3563// Note: args is a pointer to the command buffer. As such, it could be changed
3564// by a (malicious) client at any time, so if validation has to happen, it
3565// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143566error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323567 unsigned int command,
3568 unsigned int arg_count,
3569 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143570 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263571 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003572 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3573 // LOG(INFO), tried VLOG(1), no luck.
[email protected]d2a0e1a2012-08-12 02:25:013574 LOG(ERROR) << "[" << GetLogPrefix() << "]" << "cmd: "
3575 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193576 }
[email protected]96449d2c2009-11-25 00:01:323577 unsigned int command_index = command - kStartPoint - 1;
3578 if (command_index < arraysize(g_command_info)) {
3579 const CommandInfo& info = g_command_info[command_index];
3580 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3581 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3582 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193583 uint32 immediate_data_size =
3584 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323585 switch (command) {
3586 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353587 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193588 result = Handle ## name( \
3589 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353590 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193591 break; \
[email protected]96449d2c2009-11-25 00:01:323592
3593 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323594 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383595 }
3596 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303597 GLenum error;
3598 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]d2a0e1a2012-08-12 02:25:013599 LOG(ERROR) << "[" << GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003600 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3601 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513602 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193603 }
[email protected]96449d2c2009-11-25 00:01:323604 }
3605 } else {
[email protected]f7a64ee2010-02-01 22:24:143606 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323607 }
[email protected]b9849abf2009-11-25 19:13:193608 } else {
3609 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323610 }
[email protected]a3a93e7b2010-08-28 00:48:563611 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3612 result = current_decoder_error_;
3613 current_decoder_error_ = error::kNoError;
3614 }
[email protected]b9849abf2009-11-25 19:13:193615 return result;
[email protected]96449d2c2009-11-25 00:01:323616}
3617
[email protected]ed9f9cd2013-02-27 21:12:353618void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3619 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503620}
3621
[email protected]ae51d192010-04-27 00:48:033622bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353623 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033624 return false;
3625 }
[email protected]96449d2c2009-11-25 00:01:323626 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033627 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353628 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323629 }
[email protected]ae51d192010-04-27 00:48:033630 return true;
[email protected]96449d2c2009-11-25 00:01:323631}
3632
[email protected]ae51d192010-04-27 00:48:033633bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353634 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033635 return false;
[email protected]96449d2c2009-11-25 00:01:323636 }
[email protected]ae51d192010-04-27 00:48:033637 GLuint service_id = glCreateShader(type);
3638 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353639 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033640 }
3641 return true;
[email protected]96449d2c2009-11-25 00:01:323642}
3643
[email protected]882ba1e22012-03-08 19:02:533644void GLES2DecoderImpl::DoFinish() {
3645 glFinish();
[email protected]22e3f552012-03-13 01:54:193646 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533647}
3648
3649void GLES2DecoderImpl::DoFlush() {
3650 glFlush();
[email protected]22e3f552012-03-13 01:54:193651 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533652}
3653
[email protected]3916c97e2010-02-25 03:20:503654void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453655 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023656 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513657 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533658 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503659 return;
3660 }
[email protected]e259eb412012-10-13 05:47:243661 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453662 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503663}
3664
[email protected]051b1372010-04-12 02:42:083665void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073666 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083667 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033668 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073669 buffer = GetBuffer(client_id);
3670 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353671 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153672 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3673 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353674 return;
3675 }
3676
[email protected]b10492f2013-03-08 05:24:073677 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033678 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353679 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073680 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573681 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103682 group_->GetIdAllocator(id_namespaces::kBuffers);
3683 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033684 }
[email protected]051b1372010-04-12 02:42:083685 }
[email protected]b10492f2013-03-08 05:24:073686 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3687 if (buffer) {
3688 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513689 LOCAL_SET_GL_ERROR(
3690 GL_INVALID_OPERATION,
3691 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473692 return;
3693 }
[email protected]b10492f2013-03-08 05:24:073694 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473695 }
[email protected]96449d2c2009-11-25 00:01:323696 switch (target) {
3697 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073698 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323699 break;
3700 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073701 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323702 break;
3703 default:
[email protected]a93bb842010-02-16 23:03:473704 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323705 break;
3706 }
[email protected]051b1372010-04-12 02:42:083707 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323708}
3709
[email protected]297ca1c2011-06-20 23:08:463710bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
3711 return (GLES2Util::GetChannelsForFormat(
3712 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3713}
3714
3715bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353716 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453717 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203718 if (framebuffer) {
3719 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463720 }
3721 if (offscreen_target_frame_buffer_.get()) {
3722 return offscreen_target_depth_format_ != 0;
3723 }
3724 return back_buffer_has_depth_;
3725}
3726
3727bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353728 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453729 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203730 if (framebuffer) {
3731 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463732 }
3733 if (offscreen_target_frame_buffer_.get()) {
3734 return offscreen_target_stencil_format_ != 0 ||
3735 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3736 }
3737 return back_buffer_has_stencil_;
3738}
3739
3740void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]88a61bf2012-10-27 13:00:423741 if (clear_state_dirty_) {
[email protected]297ca1c2011-06-20 23:08:463742 glColorMask(
[email protected]e259eb412012-10-13 05:47:243743 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3744 state_.color_mask_alpha &&
3745 BoundFramebufferHasColorAttachmentWithAlpha());
[email protected]297ca1c2011-06-20 23:08:463746 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243747 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223748 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463749 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243750 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423751 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243752 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423753 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223754 EnableDisable(
3755 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3756 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3757 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3758 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]88a61bf2012-10-27 13:00:423759 clear_state_dirty_ = false;
[email protected]297ca1c2011-06-20 23:08:463760 }
3761}
3762
[email protected]1868a342012-11-07 15:56:023763GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]b177ae22011-11-01 03:29:113764 return (offscreen_target_frame_buffer_.get()) ?
3765 offscreen_target_frame_buffer_->id() :
[email protected]1868a342012-11-07 15:56:023766 (surface_ ? surface_->GetBackingFrameBufferObject() : 0);
3767}
3768
3769void GLES2DecoderImpl::RestoreState() const {
[email protected]29a4d902013-02-26 20:18:063770 // Restore the Framebuffer first because of bugs in Intel drivers.
3771 // Intel drivers incorrectly clip the viewport settings to
3772 // the size of the current framebuffer object.
3773 RestoreFramebufferBindings();
3774 state_.RestoreState();
3775}
3776
3777void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]1868a342012-11-07 15:56:023778 GLuint service_id = state_.bound_draw_framebuffer ?
3779 state_.bound_draw_framebuffer->service_id() :
3780 GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063781 if (!features().chromium_framebuffer_multisample) {
3782 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3783 } else {
3784 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
3785 service_id = state_.bound_read_framebuffer ?
3786 state_.bound_read_framebuffer->service_id() :
3787 GetBackbufferServiceId();
3788 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3789 }
[email protected]70d34263c2013-01-09 00:27:453790 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063791}
3792
3793void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
3794 GLuint client_id = 0;
3795 if (texture_manager()->GetClientId(service_id, &client_id)) {
[email protected]ed9f9cd2013-02-27 21:12:353796 Texture* texture = GetTexture(client_id);
[email protected]9bc9a2e82013-04-03 03:56:253797 GLenum target = texture->target();
3798 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063799 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253800 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063801 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253802 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063803 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253804 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063805 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253806 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063807 RestoreTextureUnitBindings(state_.active_texture_unit);
3808 }
[email protected]70d34263c2013-01-09 00:27:453809}
3810
3811void GLES2DecoderImpl::OnFboChanged() const {
3812 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513813 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3814}
3815
3816// Called after the FBO is checked for completeness.
3817void GLES2DecoderImpl::OnUseFramebuffer() const {
3818 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3819 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323820 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513821 glScissor(state_.scissor_x,
3822 state_.scissor_y,
3823 state_.scissor_width,
3824 state_.scissor_height);
3825
3826 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3827 // it's unclear how this bug works.
3828 glFlush();
3829 }
[email protected]b177ae22011-11-01 03:29:113830}
3831
[email protected]051b1372010-04-12 02:42:083832void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063833 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083834 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033835 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063836 framebuffer = GetFramebuffer(client_id);
3837 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353838 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153839 LOG(ERROR)
3840 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3841 current_decoder_error_ = error::kGenericError;
3842 return;
[email protected]bf5a8d132011-08-16 08:39:353843 }
3844
[email protected]4d8f0dd2013-03-09 14:37:063845 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033846 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353847 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063848 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573849 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103850 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3851 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033852 } else {
[email protected]4d8f0dd2013-03-09 14:37:063853 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083854 }
[email protected]4d8f0dd2013-03-09 14:37:063855 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083856 }
[email protected]4d8f0dd2013-03-09 14:37:063857 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303858
3859 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063860 state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303861 }
3862 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063863 state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303864 }
[email protected]6217d392010-03-25 22:08:353865
[email protected]88a61bf2012-10-27 13:00:423866 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:463867
[email protected]b177ae22011-11-01 03:29:113868 // If we are rendering to the backbuffer get the FBO id for any simulated
3869 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063870 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113871 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463872 }
[email protected]6217d392010-03-25 22:08:353873
[email protected]051b1372010-04-12 02:42:083874 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453875 OnFboChanged();
[email protected]86093972010-03-11 00:13:563876}
3877
[email protected]051b1372010-04-12 02:42:083878void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273879 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083880 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033881 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273882 renderbuffer = GetRenderbuffer(client_id);
3883 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353884 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153885 LOG(ERROR)
3886 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3887 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353888 return;
3889 }
3890
[email protected]ee2a79c32013-03-10 03:50:273891 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033892 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353893 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273894 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573895 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103896 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3897 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033898 } else {
[email protected]ee2a79c32013-03-10 03:50:273899 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083900 }
[email protected]ee2a79c32013-03-10 03:50:273901 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083902 }
[email protected]ee2a79c32013-03-10 03:50:273903 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer");
3904 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083905 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563906}
3907
[email protected]051b1372010-04-12 02:42:083908void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]02965c22013-03-09 02:40:073909 Texture* texture = NULL;
[email protected]051b1372010-04-12 02:42:083910 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033911 if (client_id != 0) {
[email protected]02965c22013-03-09 02:40:073912 texture = GetTexture(client_id);
3913 if (!texture) {
[email protected]bf5a8d132011-08-16 08:39:353914 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153915 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3916 current_decoder_error_ = error::kGenericError;
3917 return;
[email protected]bf5a8d132011-08-16 08:39:353918 }
3919
[email protected]02965c22013-03-09 02:40:073920 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033921 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413922 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353923 CreateTexture(client_id, service_id);
[email protected]02965c22013-03-09 02:40:073924 texture = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:573925 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103926 group_->GetIdAllocator(id_namespaces::kTextures);
3927 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033928 }
3929 } else {
[email protected]02965c22013-03-09 02:40:073930 texture = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083931 }
[email protected]ae51d192010-04-27 00:48:033932
[email protected]1958e0e2010-04-22 05:17:153933 // Check the texture exists
3934 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073935 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513936 LOCAL_SET_GL_ERROR(
3937 GL_INVALID_OPERATION,
3938 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153939 return;
3940 }
[email protected]02965c22013-03-09 02:40:073941 if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:513942 LOCAL_SET_GL_ERROR(
3943 GL_INVALID_OPERATION,
3944 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423945 return;
3946 }
[email protected]02965c22013-03-09 02:40:073947 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3948 if (texture->target() == 0) {
3949 texture_manager()->SetTarget(texture, target);
[email protected]a93bb842010-02-16 23:03:473950 }
[email protected]02965c22013-03-09 02:40:073951 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593952
[email protected]e259eb412012-10-13 05:47:243953 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503954 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473955 switch (target) {
3956 case GL_TEXTURE_2D:
[email protected]02965c22013-03-09 02:40:073957 unit.bound_texture_2d = texture;
[email protected]a93bb842010-02-16 23:03:473958 break;
3959 case GL_TEXTURE_CUBE_MAP:
[email protected]02965c22013-03-09 02:40:073960 unit.bound_texture_cube_map = texture;
[email protected]a93bb842010-02-16 23:03:473961 break;
[email protected]61eeb33f2011-07-26 15:30:313962 case GL_TEXTURE_EXTERNAL_OES:
[email protected]02965c22013-03-09 02:40:073963 unit.bound_texture_external_oes = texture;
3964 if (texture->IsStreamTexture()) {
[email protected]b0af4f52011-09-28 22:04:423965 DCHECK(stream_texture_manager_);
3966 StreamTexture* stream_tex =
[email protected]02965c22013-03-09 02:40:073967 stream_texture_manager_->LookupStreamTexture(texture->service_id());
[email protected]b0af4f52011-09-28 22:04:423968 if (stream_tex)
3969 stream_tex->Update();
3970 }
[email protected]61eeb33f2011-07-26 15:30:313971 break;
[email protected]e51bdf32011-11-23 22:21:463972 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]02965c22013-03-09 02:40:073973 unit.bound_texture_rectangle_arb = texture;
[email protected]e51bdf32011-11-23 22:21:463974 break;
[email protected]a93bb842010-02-16 23:03:473975 default:
3976 NOTREACHED(); // Validation should prevent us getting here.
3977 break;
3978 }
3979}
3980
[email protected]07f54fcc2009-12-22 02:46:303981void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243982 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123983 if (index != 0 ||
3984 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243985 glDisableVertexAttribArray(index);
3986 }
[email protected]07f54fcc2009-12-22 02:46:303987 } else {
[email protected]ab09b612013-03-11 22:11:513988 LOCAL_SET_GL_ERROR(
3989 GL_INVALID_VALUE,
3990 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303991 }
3992}
3993
[email protected]60f22d32012-12-12 00:31:583994void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3995 GLsizei numAttachments,
3996 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:353997 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:583998 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3999
4000 // Validates the attachments. If one of them fails
4001 // the whole command fails.
4002 for (GLsizei i = 0; i < numAttachments; ++i) {
4003 if ((framebuffer &&
4004 !validators_->attachment.IsValid(attachments[i])) ||
4005 (!framebuffer &&
4006 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514007 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4008 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584009 return;
4010 }
4011 }
4012
4013 // Marks each one of them as not cleared
4014 for (GLsizei i = 0; i < numAttachments; ++i) {
4015 if (framebuffer) {
4016 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4017 texture_manager(),
4018 attachments[i],
4019 false);
4020 } else {
4021 switch (attachments[i]) {
4022 case GL_COLOR_EXT:
4023 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4024 break;
4025 case GL_DEPTH_EXT:
4026 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4027 case GL_STENCIL_EXT:
4028 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4029 break;
4030 default:
4031 NOTREACHED();
4032 break;
4033 }
4034 }
4035 }
4036
4037 glDiscardFramebufferEXT(target, numAttachments, attachments);
4038}
4039
[email protected]07f54fcc2009-12-22 02:46:304040void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244041 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304042 glEnableVertexAttribArray(index);
4043 } else {
[email protected]ab09b612013-03-11 22:11:514044 LOCAL_SET_GL_ERROR(
4045 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304046 }
4047}
4048
[email protected]a93bb842010-02-16 23:03:474049void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]02965c22013-03-09 02:40:074050 Texture* texture = GetTextureInfoForTarget(target);
4051 if (!texture ||
4052 !texture_manager()->CanGenerateMipmaps(texture)) {
[email protected]ab09b612013-03-11 22:11:514053 LOCAL_SET_GL_ERROR(
4054 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474055 return;
4056 }
[email protected]38c0a972012-05-12 00:48:024057
[email protected]12d95352012-12-14 07:23:544058 if (target == GL_TEXTURE_CUBE_MAP) {
4059 for (int i = 0; i < 6; ++i) {
4060 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]02965c22013-03-09 02:40:074061 if (!texture_manager()->ClearTextureLevel(this, texture, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514062 LOCAL_SET_GL_ERROR(
4063 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544064 return;
4065 }
4066 }
4067 } else {
[email protected]02965c22013-03-09 02:40:074068 if (!texture_manager()->ClearTextureLevel(this, texture, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514069 LOCAL_SET_GL_ERROR(
4070 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544071 return;
4072 }
[email protected]7687479c2012-05-14 23:54:044073 }
4074
[email protected]ab09b612013-03-11 22:11:514075 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194076 // Workaround for Mac driver bug. In the large scheme of things setting
4077 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564078 // hit so there's probably no need to make this conditional. The bug appears
4079 // to be that if the filtering mode is set to something that doesn't require
4080 // mipmaps for rendering, or is never set to something other than the default,
4081 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154082 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194083 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4084 }
[email protected]a93bb842010-02-16 23:03:474085 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154086 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]02965c22013-03-09 02:40:074087 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]c892a4e12012-05-08 18:20:194088 }
[email protected]ab09b612013-03-11 22:11:514089 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024090 if (error == GL_NO_ERROR) {
[email protected]02965c22013-03-09 02:40:074091 texture_manager()->MarkMipmapsGenerated(texture);
[email protected]38c0a972012-05-12 00:48:024092 }
[email protected]a93bb842010-02-16 23:03:474093}
4094
[email protected]b273e432010-04-12 17:23:584095bool GLES2DecoderImpl::GetHelper(
4096 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584097 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154098 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4099 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434100 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4101 *num_written = 1;
4102 if (params) {
4103 *params = GL_RGBA; // We don't support other formats.
4104 }
4105 return true;
4106 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4107 *num_written = 1;
4108 if (params) {
4109 *params = GL_UNSIGNED_BYTE; // We don't support other types.
4110 }
4111 return true;
4112 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4113 *num_written = 1;
4114 if (params) {
4115 *params = group_->max_fragment_uniform_vectors();
4116 }
4117 return true;
4118 case GL_MAX_VARYING_VECTORS:
4119 *num_written = 1;
4120 if (params) {
4121 *params = group_->max_varying_vectors();
4122 }
4123 return true;
4124 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4125 *num_written = 1;
4126 if (params) {
4127 *params = group_->max_vertex_uniform_vectors();
4128 }
4129 return true;
[email protected]4e8a5b122010-05-08 22:00:104130 }
[email protected]5cb735d2011-10-13 01:37:234131 }
4132 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244133 case GL_MAX_VIEWPORT_DIMS:
4134 if (offscreen_target_frame_buffer_.get()) {
4135 *num_written = 2;
4136 if (params) {
4137 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4138 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4139 }
4140 return true;
4141 }
[email protected]5cb735d2011-10-13 01:37:234142 return false;
[email protected]84afefa2011-10-19 21:45:534143 case GL_MAX_SAMPLES:
4144 *num_written = 1;
4145 if (params) {
4146 params[0] = renderbuffer_manager()->max_samples();
4147 }
4148 return true;
4149 case GL_MAX_RENDERBUFFER_SIZE:
4150 *num_written = 1;
4151 if (params) {
4152 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4153 }
4154 return true;
[email protected]5cb735d2011-10-13 01:37:234155 case GL_MAX_TEXTURE_SIZE:
4156 *num_written = 1;
4157 if (params) {
4158 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4159 }
4160 return true;
4161 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4162 *num_written = 1;
4163 if (params) {
4164 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4165 }
4166 return true;
[email protected]2f143d482013-03-14 18:04:494167 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4168 *num_written = 1;
4169 if (params) {
4170 params[0] = group_->max_color_attachments();
4171 }
4172 return true;
4173 case GL_MAX_DRAW_BUFFERS_ARB:
4174 *num_written = 1;
4175 if (params) {
4176 params[0] = group_->max_draw_buffers();
4177 }
4178 return true;
[email protected]297ca1c2011-06-20 23:08:464179 case GL_ALPHA_BITS:
4180 *num_written = 1;
4181 if (params) {
4182 GLint v = 0;
4183 glGetIntegerv(GL_ALPHA_BITS, &v);
4184 params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0;
4185 }
4186 return true;
4187 case GL_DEPTH_BITS:
4188 *num_written = 1;
4189 if (params) {
4190 GLint v = 0;
4191 glGetIntegerv(GL_DEPTH_BITS, &v);
4192 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4193 }
4194 return true;
4195 case GL_STENCIL_BITS:
4196 *num_written = 1;
4197 if (params) {
4198 GLint v = 0;
4199 glGetIntegerv(GL_STENCIL_BITS, &v);
4200 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4201 }
4202 return true;
[email protected]656dcaad2010-05-07 17:18:374203 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114204 *num_written = validators_->compressed_texture_format.GetValues().size();
4205 if (params) {
4206 for (GLint ii = 0; ii < *num_written; ++ii) {
4207 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4208 }
4209 }
[email protected]656dcaad2010-05-07 17:18:374210 return true;
[email protected]b273e432010-04-12 17:23:584211 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4212 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104213 if (params) {
[email protected]302ce6d2011-07-07 23:28:114214 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104215 }
[email protected]b273e432010-04-12 17:23:584216 return true;
4217 case GL_NUM_SHADER_BINARY_FORMATS:
4218 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104219 if (params) {
[email protected]302ce6d2011-07-07 23:28:114220 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104221 }
[email protected]b273e432010-04-12 17:23:584222 return true;
4223 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114224 *num_written = validators_->shader_binary_format.GetValues().size();
4225 if (params) {
4226 for (GLint ii = 0; ii < *num_written; ++ii) {
4227 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4228 }
4229 }
4230 return true;
[email protected]b273e432010-04-12 17:23:584231 case GL_SHADER_COMPILER:
4232 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104233 if (params) {
4234 *params = GL_TRUE;
4235 }
[email protected]b273e432010-04-12 17:23:584236 return true;
[email protected]6b8cf1a2010-05-06 16:13:584237 case GL_ARRAY_BUFFER_BINDING:
4238 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104239 if (params) {
[email protected]e259eb412012-10-13 05:47:244240 if (state_.bound_array_buffer) {
[email protected]4e8a5b122010-05-08 22:00:104241 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244242 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104243 &client_id);
4244 *params = client_id;
4245 } else {
4246 *params = 0;
4247 }
[email protected]6b8cf1a2010-05-06 16:13:584248 }
4249 return true;
4250 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4251 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104252 if (params) {
[email protected]e259eb412012-10-13 05:47:244253 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104254 GLuint client_id = 0;
4255 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254256 state_.vertex_attrib_manager->element_array_buffer()->
4257 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104258 *params = client_id;
4259 } else {
4260 *params = 0;
4261 }
[email protected]6b8cf1a2010-05-06 16:13:584262 }
4263 return true;
4264 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304265 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584266 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104267 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354268 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454269 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204270 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104271 GLuint client_id = 0;
4272 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204273 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304274 *params = client_id;
4275 } else {
4276 *params = 0;
4277 }
4278 }
4279 return true;
[email protected]ebfb73c2012-08-15 02:37:454280 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304281 *num_written = 1;
4282 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354283 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454284 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204285 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304286 GLuint client_id = 0;
4287 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204288 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104289 *params = client_id;
4290 } else {
4291 *params = 0;
4292 }
[email protected]6b8cf1a2010-05-06 16:13:584293 }
4294 return true;
4295 case GL_RENDERBUFFER_BINDING:
4296 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104297 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354298 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204299 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4300 if (renderbuffer) {
[email protected]4e8a5b122010-05-08 22:00:104301 GLuint client_id = 0;
4302 renderbuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204303 renderbuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104304 *params = client_id;
4305 } else {
4306 *params = 0;
4307 }
[email protected]6b8cf1a2010-05-06 16:13:584308 }
4309 return true;
4310 case GL_CURRENT_PROGRAM:
4311 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104312 if (params) {
[email protected]e259eb412012-10-13 05:47:244313 if (state_.current_program) {
[email protected]4e8a5b122010-05-08 22:00:104314 GLuint client_id = 0;
4315 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244316 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104317 *params = client_id;
4318 } else {
4319 *params = 0;
4320 }
[email protected]6b8cf1a2010-05-06 16:13:584321 }
4322 return true;
[email protected]bf835842012-11-19 15:21:514323 case GL_VERTEX_ARRAY_BINDING_OES:
4324 *num_written = 1;
4325 if (params) {
4326 if (state_.vertex_attrib_manager != default_vertex_attrib_manager_) {
4327 GLuint client_id = 0;
4328 vertex_array_manager_->GetClientId(
4329 state_.vertex_attrib_manager->service_id(), &client_id);
4330 *params = client_id;
4331 } else {
4332 *params = 0;
4333 }
4334 }
4335 return true;
[email protected]4e8a5b122010-05-08 22:00:104336 case GL_TEXTURE_BINDING_2D:
4337 *num_written = 1;
4338 if (params) {
[email protected]e259eb412012-10-13 05:47:244339 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584340 if (unit.bound_texture_2d) {
4341 GLuint client_id = 0;
4342 texture_manager()->GetClientId(
4343 unit.bound_texture_2d->service_id(), &client_id);
4344 *params = client_id;
4345 } else {
4346 *params = 0;
4347 }
[email protected]6b8cf1a2010-05-06 16:13:584348 }
[email protected]4e8a5b122010-05-08 22:00:104349 return true;
4350 case GL_TEXTURE_BINDING_CUBE_MAP:
4351 *num_written = 1;
4352 if (params) {
[email protected]e259eb412012-10-13 05:47:244353 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584354 if (unit.bound_texture_cube_map) {
4355 GLuint client_id = 0;
4356 texture_manager()->GetClientId(
4357 unit.bound_texture_cube_map->service_id(), &client_id);
4358 *params = client_id;
4359 } else {
4360 *params = 0;
4361 }
[email protected]6b8cf1a2010-05-06 16:13:584362 }
[email protected]4e8a5b122010-05-08 22:00:104363 return true;
[email protected]61eeb33f2011-07-26 15:30:314364 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4365 *num_written = 1;
4366 if (params) {
[email protected]e259eb412012-10-13 05:47:244367 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]61eeb33f2011-07-26 15:30:314368 if (unit.bound_texture_external_oes) {
4369 GLuint client_id = 0;
4370 texture_manager()->GetClientId(
4371 unit.bound_texture_external_oes->service_id(), &client_id);
4372 *params = client_id;
4373 } else {
4374 *params = 0;
4375 }
4376 }
4377 return true;
[email protected]e51bdf32011-11-23 22:21:464378 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4379 *num_written = 1;
4380 if (params) {
[email protected]e259eb412012-10-13 05:47:244381 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]e51bdf32011-11-23 22:21:464382 if (unit.bound_texture_rectangle_arb) {
4383 GLuint client_id = 0;
4384 texture_manager()->GetClientId(
4385 unit.bound_texture_rectangle_arb->service_id(), &client_id);
4386 *params = client_id;
4387 } else {
4388 *params = 0;
4389 }
4390 }
4391 return true;
[email protected]6c75c712012-06-19 15:43:174392 case GL_UNPACK_FLIP_Y_CHROMIUM:
4393 *num_written = 1;
4394 if (params) {
4395 params[0] = unpack_flip_y_;
4396 }
4397 return true;
4398 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4399 *num_written = 1;
4400 if (params) {
4401 params[0] = unpack_premultiply_alpha_;
4402 }
4403 return true;
4404 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4405 *num_written = 1;
4406 if (params) {
4407 params[0] = unpack_unpremultiply_alpha_;
4408 }
4409 return true;
[email protected]b273e432010-04-12 17:23:584410 default:
[email protected]2f143d482013-03-14 18:04:494411 if (pname >= GL_DRAW_BUFFER0_ARB &&
4412 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4413 *num_written = 1;
4414 if (params) {
4415 Framebuffer* framebuffer =
4416 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4417 if (framebuffer) {
4418 params[0] = framebuffer->GetDrawBuffer(pname);
4419 } else { // backbuffer
4420 if (pname == GL_DRAW_BUFFER0_ARB)
4421 params[0] = group_->draw_buffer();
4422 else
4423 params[0] = GL_NONE;
4424 }
4425 }
4426 return true;
4427 }
[email protected]4e8a5b122010-05-08 22:00:104428 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534429 return false;
[email protected]b273e432010-04-12 17:23:584430 }
4431}
4432
[email protected]4e8a5b122010-05-08 22:00:104433bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4434 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264435 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534436 return true;
4437 }
[email protected]4e8a5b122010-05-08 22:00:104438 return GetHelper(pname, NULL, num_values);
4439}
4440
[email protected]b273e432010-04-12 17:23:584441void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4442 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104443 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534444 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]4e8a5b122010-05-08 22:00:104445 scoped_array<GLint> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264446 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534447 GetHelper(pname, values.get(), &num_written);
4448 }
[email protected]b273e432010-04-12 17:23:584449 for (GLsizei ii = 0; ii < num_written; ++ii) {
4450 params[ii] = static_cast<GLboolean>(values[ii]);
4451 }
4452 } else {
4453 glGetBooleanv(pname, params);
4454 }
4455}
4456
4457void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4458 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104459 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264460 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534461 if (GetHelper(pname, NULL, &num_written)) {
4462 scoped_array<GLint> values(new GLint[num_written]);
4463 GetHelper(pname, values.get(), &num_written);
4464 for (GLsizei ii = 0; ii < num_written; ++ii) {
4465 params[ii] = static_cast<GLfloat>(values[ii]);
4466 }
4467 } else {
4468 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584469 }
[email protected]b273e432010-04-12 17:23:584470 }
4471}
4472
4473void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4474 DCHECK(params);
4475 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264476 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534477 !GetHelper(pname, params, &num_written)) {
[email protected]b273e432010-04-12 17:23:584478 glGetIntegerv(pname, params);
4479 }
4480}
4481
[email protected]a0c3e972010-04-21 00:49:134482void GLES2DecoderImpl::DoGetProgramiv(
4483 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424484 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4485 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134486 return;
4487 }
[email protected]df37b9932013-03-08 05:21:424488 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134489}
4490
[email protected]17cfbe0e2013-03-07 01:26:084491void GLES2DecoderImpl::DoGetBufferParameteriv(
4492 GLenum target, GLenum pname, GLint* params) {
4493 Buffer* buffer = GetBufferInfoForTarget(target);
4494 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:514495 LOCAL_SET_GL_ERROR(
[email protected]17cfbe0e2013-03-07 01:26:084496 GL_INVALID_OPERATION, "glGetBufferParameteriv",
4497 "no buffer bound for target");
4498 return;
4499 }
4500 switch (pname) {
4501 case GL_BUFFER_SIZE:
4502 *params = buffer->size();
4503 break;
4504 case GL_BUFFER_USAGE:
4505 *params = buffer->usage();
4506 break;
4507 default:
4508 NOTREACHED();
4509 }
4510}
4511
[email protected]258a3313f2011-10-18 20:13:574512void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424513 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574514 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514515 LOCAL_SET_GL_ERROR(
4516 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574517 return;
4518 }
[email protected]68dcb1f2012-04-07 00:14:564519 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514520 LOCAL_SET_GL_ERROR(
4521 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564522 return;
4523 }
4524 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514525 LOCAL_SET_GL_ERROR(
4526 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564527 return;
4528 }
[email protected]df37b9932013-03-08 05:21:424529 Program* program = GetProgramInfoNotShader(
4530 program_id, "glBindAttribLocation");
4531 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574532 return;
[email protected]558847a2010-03-24 07:02:544533 }
[email protected]df37b9932013-03-08 05:21:424534 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4535 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574536}
4537
4538error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354539 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574540 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544541 GLuint index = static_cast<GLuint>(c.index);
4542 uint32 name_size = c.data_size;
4543 const char* name = GetSharedMemoryAs<const char*>(
4544 c.name_shm_id, c.name_shm_offset, name_size);
4545 if (name == NULL) {
4546 return error::kOutOfBounds;
4547 }
4548 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574549 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544550 return error::kNoError;
4551}
4552
4553error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:354554 uint32 immediate_data_size, const cmds::BindAttribLocationImmediate& c) {
[email protected]6b8cf1a2010-05-06 16:13:584555 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544556 GLuint index = static_cast<GLuint>(c.index);
4557 uint32 name_size = c.data_size;
4558 const char* name = GetImmediateDataAs<const char*>(
4559 c, name_size, immediate_data_size);
4560 if (name == NULL) {
4561 return error::kOutOfBounds;
4562 }
4563 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574564 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544565 return error::kNoError;
4566}
4567
4568error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354569 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584570 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544571 GLuint index = static_cast<GLuint>(c.index);
4572 Bucket* bucket = GetBucket(c.name_bucket_id);
4573 if (!bucket || bucket->size() == 0) {
4574 return error::kInvalidArguments;
4575 }
4576 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184577 if (!bucket->GetAsString(&name_str)) {
4578 return error::kInvalidArguments;
4579 }
[email protected]258a3313f2011-10-18 20:13:574580 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544581 return error::kNoError;
4582}
4583
[email protected]2be6abf32012-06-26 00:28:334584void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424585 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334586 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514587 LOCAL_SET_GL_ERROR(
4588 GL_INVALID_VALUE,
4589 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334590 return;
4591 }
4592 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514593 LOCAL_SET_GL_ERROR(
4594 GL_INVALID_OPERATION,
4595 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334596 return;
4597 }
4598 if (location < 0 || static_cast<uint32>(location) >=
4599 (group_->max_fragment_uniform_vectors() +
4600 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514601 LOCAL_SET_GL_ERROR(
4602 GL_INVALID_VALUE,
4603 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334604 return;
4605 }
[email protected]df37b9932013-03-08 05:21:424606 Program* program = GetProgramInfoNotShader(
4607 program_id, "glBindUniformLocationCHROMIUM");
4608 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334609 return;
4610 }
[email protected]df37b9932013-03-08 05:21:424611 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514612 LOCAL_SET_GL_ERROR(
4613 GL_INVALID_VALUE,
4614 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334615 }
4616}
4617
4618error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354619 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334620 GLuint program = static_cast<GLuint>(c.program);
4621 GLint location = static_cast<GLint>(c.location);
4622 uint32 name_size = c.data_size;
4623 const char* name = GetSharedMemoryAs<const char*>(
4624 c.name_shm_id, c.name_shm_offset, name_size);
4625 if (name == NULL) {
4626 return error::kOutOfBounds;
4627 }
4628 String name_str(name, name_size);
4629 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4630 return error::kNoError;
4631}
4632
4633error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4634 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354635 const cmds::BindUniformLocationCHROMIUMImmediate& c) {
[email protected]2be6abf32012-06-26 00:28:334636 GLuint program = static_cast<GLuint>(c.program);
4637 GLint location = static_cast<GLint>(c.location);
4638 uint32 name_size = c.data_size;
4639 const char* name = GetImmediateDataAs<const char*>(
4640 c, name_size, immediate_data_size);
4641 if (name == NULL) {
4642 return error::kOutOfBounds;
4643 }
4644 String name_str(name, name_size);
4645 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4646 return error::kNoError;
4647}
4648
4649error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4650 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354651 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334652 GLuint program = static_cast<GLuint>(c.program);
4653 GLint location = static_cast<GLint>(c.location);
4654 Bucket* bucket = GetBucket(c.name_bucket_id);
4655 if (!bucket || bucket->size() == 0) {
4656 return error::kInvalidArguments;
4657 }
4658 std::string name_str;
4659 if (!bucket->GetAsString(&name_str)) {
4660 return error::kInvalidArguments;
4661 }
4662 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4663 return error::kNoError;
4664}
4665
[email protected]f7a64ee2010-02-01 22:24:144666error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354667 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034668 GLuint client_id = c.shader;
4669 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424670 Shader* shader = GetShader(client_id);
4671 if (shader) {
4672 if (!shader->IsDeleted()) {
4673 glDeleteShader(shader->service_id());
4674 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144675 }
[email protected]ae51d192010-04-27 00:48:034676 } else {
[email protected]ab09b612013-03-11 22:11:514677 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034678 }
[email protected]96449d2c2009-11-25 00:01:324679 }
[email protected]f7a64ee2010-02-01 22:24:144680 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324681}
4682
[email protected]f7a64ee2010-02-01 22:24:144683error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354684 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034685 GLuint client_id = c.program;
4686 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424687 Program* program = GetProgram(client_id);
4688 if (program) {
4689 if (!program->IsDeleted()) {
4690 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144691 }
[email protected]ae51d192010-04-27 00:48:034692 } else {
[email protected]ab09b612013-03-11 22:11:514693 LOCAL_SET_GL_ERROR(
4694 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034695 }
[email protected]96449d2c2009-11-25 00:01:324696 }
[email protected]f7a64ee2010-02-01 22:24:144697 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324698}
4699
[email protected]269200b12010-11-18 22:53:064700void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104701 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574702 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104703 for (GLsizei ii = 0; ii < n; ++ii) {
4704 id_allocator->FreeID(ids[ii]);
4705 }
4706}
4707
[email protected]269200b12010-11-18 22:53:064708error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354709 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104710 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4711 GLsizei n = static_cast<GLsizei>(c.n);
4712 uint32 data_size;
4713 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4714 return error::kOutOfBounds;
4715 }
4716 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4717 c.ids_shm_id, c.ids_shm_offset, data_size);
4718 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514719 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104720 return error::kNoError;
4721 }
4722 if (ids == NULL) {
4723 return error::kOutOfBounds;
4724 }
[email protected]269200b12010-11-18 22:53:064725 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104726 return error::kNoError;
4727}
4728
[email protected]269200b12010-11-18 22:53:064729void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104730 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574731 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104732 if (id_offset == 0) {
4733 for (GLsizei ii = 0; ii < n; ++ii) {
4734 ids[ii] = id_allocator->AllocateID();
4735 }
4736 } else {
4737 for (GLsizei ii = 0; ii < n; ++ii) {
4738 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4739 id_offset = ids[ii] + 1;
4740 }
4741 }
4742}
4743
[email protected]269200b12010-11-18 22:53:064744error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354745 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104746 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4747 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4748 GLsizei n = static_cast<GLsizei>(c.n);
4749 uint32 data_size;
4750 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4751 return error::kOutOfBounds;
4752 }
4753 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4754 c.ids_shm_id, c.ids_shm_offset, data_size);
4755 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514756 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104757 return error::kNoError;
4758 }
4759 if (ids == NULL) {
4760 return error::kOutOfBounds;
4761 }
[email protected]269200b12010-11-18 22:53:064762 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104763 return error::kNoError;
4764}
4765
[email protected]269200b12010-11-18 22:53:064766void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104767 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574768 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104769 for (GLsizei ii = 0; ii < n; ++ii) {
4770 if (!id_allocator->MarkAsUsed(ids[ii])) {
4771 for (GLsizei jj = 0; jj < ii; ++jj) {
4772 id_allocator->FreeID(ids[jj]);
4773 }
[email protected]ab09b612013-03-11 22:11:514774 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434775 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4776 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104777 return;
4778 }
4779 }
4780}
4781
[email protected]269200b12010-11-18 22:53:064782error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354783 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104784 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4785 GLsizei n = static_cast<GLsizei>(c.n);
4786 uint32 data_size;
4787 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4788 return error::kOutOfBounds;
4789 }
4790 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4791 c.ids_shm_id, c.ids_shm_offset, data_size);
4792 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514793 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104794 return error::kNoError;
4795 }
4796 if (ids == NULL) {
4797 return error::kOutOfBounds;
4798 }
[email protected]269200b12010-11-18 22:53:064799 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104800 return error::kNoError;
4801}
4802
[email protected]a7266a92012-06-28 02:11:084803error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444804 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204805 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]e259eb412012-10-13 05:47:244806 UNSHIPPED_TRACE_EVENT_INSTANT2(
4807 "test_gpu", "DoClear",
[email protected]c76faea2013-03-26 07:42:424808 TRACE_EVENT_SCOPE_THREAD,
[email protected]e259eb412012-10-13 05:47:244809 "red", state_.color_clear_red,
4810 "green", state_.color_clear_green);
[email protected]297ca1c2011-06-20 23:08:464811 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274812 glClear(mask);
4813 }
[email protected]a7266a92012-06-28 02:11:084814 return error::kNoError;
4815}
4816
[email protected]36cef8ce2010-03-16 07:34:454817void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4818 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034819 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064820 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4821 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514822 LOCAL_SET_GL_ERROR(
4823 GL_INVALID_OPERATION,
4824 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454825 return;
4826 }
[email protected]ae51d192010-04-27 00:48:034827 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274828 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034829 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274830 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4831 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514832 LOCAL_SET_GL_ERROR(
4833 GL_INVALID_OPERATION,
4834 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034835 return;
4836 }
[email protected]ee2a79c32013-03-10 03:50:274837 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034838 }
[email protected]ab09b612013-03-11 22:11:514839 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034840 glFramebufferRenderbufferEXT(
4841 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514842 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264843 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274844 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284845 }
[email protected]4d8f0dd2013-03-09 14:37:064846 if (framebuffer == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424847 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464848 }
[email protected]81fc9d02013-03-14 23:53:324849 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284850}
4851
[email protected]3a2e7c7b2010-08-06 01:12:284852void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464853 if (SetCapabilityState(cap, false)) {
4854 glDisable(cap);
4855 }
[email protected]3a2e7c7b2010-08-06 01:12:284856}
4857
4858void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464859 if (SetCapabilityState(cap, true)) {
4860 glEnable(cap);
4861 }
[email protected]3a2e7c7b2010-08-06 01:12:284862}
4863
[email protected]88a61bf2012-10-27 13:00:424864void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4865 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4866 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4867 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284868}
4869
[email protected]88a61bf2012-10-27 13:00:424870void GLES2DecoderImpl::DoHint(GLenum target, GLenum mode) {
4871 switch (target) {
4872 case GL_GENERATE_MIPMAP_HINT:
4873 state_.hint_generate_mipmap = mode;
4874 break;
4875 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4876 state_.hint_fragment_shader_derivative = mode;
4877 break;
4878 default:
4879 NOTREACHED();
4880 }
4881 glHint(target, mode);
4882}
4883
[email protected]b04e24c2013-01-08 18:35:254884void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424885 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4886 state_.sample_coverage_invert = (invert != 0);
4887 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284888}
4889
[email protected]0d6bfdc2011-11-02 01:32:204890// Assumes framebuffer is complete.
4891void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064892 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304893 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204894 // bind this to the DRAW point, clear then bind back to READ
4895 // TODO(gman): I don't think there is any guarantee that an FBO that
4896 // is complete on the READ attachment will be complete as a DRAW
4897 // attachment.
4898 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064899 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304900 }
[email protected]3a2e7c7b2010-08-06 01:12:284901 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064902 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464903 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204904 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464905 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064906 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4907 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284908 glColorMask(true, true, true, true);
4909 clear_bits |= GL_COLOR_BUFFER_BIT;
4910 }
4911
[email protected]4d8f0dd2013-03-09 14:37:064912 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4913 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284914 glClearStencil(0);
4915 glStencilMask(-1);
4916 clear_bits |= GL_STENCIL_BUFFER_BIT;
4917 }
4918
[email protected]4d8f0dd2013-03-09 14:37:064919 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4920 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284921 glClearDepth(1.0f);
4922 glDepthMask(true);
4923 clear_bits |= GL_DEPTH_BUFFER_BIT;
4924 }
4925
4926 glDisable(GL_SCISSOR_TEST);
4927 glClear(clear_bits);
4928
[email protected]968351b2011-12-20 08:26:514929 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064930 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284931
[email protected]c007aa02010-09-02 22:22:404932 RestoreClearState();
4933
4934 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064935 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4936 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484937 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064938 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4939 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484940 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404941 }
4942}
4943
4944void GLES2DecoderImpl::RestoreClearState() {
[email protected]88a61bf2012-10-27 13:00:424945 clear_state_dirty_ = true;
[email protected]e259eb412012-10-13 05:47:244946 glClearColor(
4947 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4948 state_.color_clear_alpha);
4949 glClearStencil(state_.stencil_clear);
4950 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224951 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284952 glEnable(GL_SCISSOR_TEST);
4953 }
[email protected]36cef8ce2010-03-16 07:34:454954}
4955
4956GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354957 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304958 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204959 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454960 return GL_FRAMEBUFFER_COMPLETE;
4961 }
[email protected]0d6bfdc2011-11-02 01:32:204962 GLenum completeness = framebuffer->IsPossiblyComplete();
4963 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4964 return completeness;
4965 }
[email protected]73276522012-11-09 05:50:204966 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454967}
4968
4969void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034970 GLenum target, GLenum attachment, GLenum textarget,
4971 GLuint client_texture_id, GLint level) {
[email protected]4d8f0dd2013-03-09 14:37:064972 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4973 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514974 LOCAL_SET_GL_ERROR(
4975 GL_INVALID_OPERATION,
4976 "glFramebufferTexture2D", "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454977 return;
4978 }
[email protected]ae51d192010-04-27 00:48:034979 GLuint service_id = 0;
[email protected]02965c22013-03-09 02:40:074980 Texture* texture = NULL;
[email protected]ae51d192010-04-27 00:48:034981 if (client_texture_id) {
[email protected]02965c22013-03-09 02:40:074982 texture = GetTexture(client_texture_id);
4983 if (!texture) {
[email protected]ab09b612013-03-11 22:11:514984 LOCAL_SET_GL_ERROR(
4985 GL_INVALID_OPERATION,
4986 "glFramebufferTexture2D", "unknown texture");
[email protected]ae51d192010-04-27 00:48:034987 return;
4988 }
[email protected]02965c22013-03-09 02:40:074989 service_id = texture->service_id();
[email protected]ae51d192010-04-27 00:48:034990 }
[email protected]0d6bfdc2011-11-02 01:32:204991
[email protected]80eb6b52012-01-19 00:14:414992 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:514993 LOCAL_SET_GL_ERROR(
4994 GL_INVALID_VALUE,
4995 "glFramebufferTexture2D", "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204996 return;
4997 }
4998
[email protected]ab09b612013-03-11 22:11:514999 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferTexture2D");
[email protected]ae51d192010-04-27 00:48:035000 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
[email protected]ab09b612013-03-11 22:11:515001 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferTexture2D");
[email protected]9edc6b22010-12-23 02:00:265002 if (error == GL_NO_ERROR) {
[email protected]4d8f0dd2013-03-09 14:37:065003 framebuffer->AttachTexture(attachment, texture, textarget, level);
[email protected]3a2e7c7b2010-08-06 01:12:285004 }
[email protected]4d8f0dd2013-03-09 14:37:065005 if (framebuffer == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:425006 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:465007 }
[email protected]81fc9d02013-03-14 23:53:325008 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455009}
5010
5011void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5012 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065013 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5014 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515015 LOCAL_SET_GL_ERROR(
5016 GL_INVALID_OPERATION,
5017 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455018 return;
5019 }
5020 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575021 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
5022 GLint type = 0;
5023 GLuint client_id = 0;
5024 glGetFramebufferAttachmentParameterivEXT(
5025 target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
5026 switch (type) {
5027 case GL_RENDERBUFFER: {
5028 renderbuffer_manager()->GetClientId(*params, &client_id);
5029 break;
5030 }
5031 case GL_TEXTURE: {
5032 texture_manager()->GetClientId(*params, &client_id);
5033 break;
5034 }
5035 default:
5036 break;
5037 }
5038 *params = client_id;
5039 }
[email protected]36cef8ce2010-03-16 07:34:455040}
5041
5042void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5043 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355044 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205045 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5046 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515047 LOCAL_SET_GL_ERROR(
5048 GL_INVALID_OPERATION,
5049 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455050 return;
5051 }
[email protected]3a03a8f2011-03-19 00:51:275052 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435053 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5054 *params = renderbuffer->internal_format();
5055 break;
5056 case GL_RENDERBUFFER_WIDTH:
5057 *params = renderbuffer->width();
5058 break;
5059 case GL_RENDERBUFFER_HEIGHT:
5060 *params = renderbuffer->height();
5061 break;
5062 default:
5063 glGetRenderbufferParameterivEXT(target, pname, params);
5064 break;
[email protected]b71f52c2010-06-18 22:20:205065 }
[email protected]36cef8ce2010-03-16 07:34:455066}
5067
[email protected]8e3e0662010-08-23 18:46:305068void GLES2DecoderImpl::DoBlitFramebufferEXT(
5069 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5070 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5071 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445072 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:155073 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:515074 LOCAL_SET_GL_ERROR(
5075 GL_INVALID_OPERATION,
5076 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:305077 }
[email protected]0c16343f2013-03-08 20:40:165078
5079 if (!CheckBoundFramebuffersValid("glBlitFramebufferEXT")) {
5080 return;
5081 }
5082
[email protected]d058bca2012-11-26 10:27:265083 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:245084 if (IsAngle()) {
5085 glBlitFramebufferANGLE(
5086 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5087 } else {
5088 glBlitFramebufferEXT(
5089 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5090 }
[email protected]d058bca2012-11-26 10:27:265091 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]c76faea2013-03-26 07:42:425092 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", TRACE_EVENT_SCOPE_THREAD,
5093 "width", srcX1 - srcX0);
[email protected]8e3e0662010-08-23 18:46:305094}
5095
5096void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
5097 GLenum target, GLsizei samples, GLenum internalformat,
5098 GLsizei width, GLsizei height) {
[email protected]62e155e2012-10-23 22:43:155099 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:515100 LOCAL_SET_GL_ERROR(
5101 GL_INVALID_OPERATION,
5102 "glRenderbufferStorageMultisample", "function not available");
[email protected]8e3e0662010-08-23 18:46:305103 return;
5104 }
[email protected]8e3e0662010-08-23 18:46:305105
[email protected]ed9f9cd2013-02-27 21:12:355106 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205107 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5108 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515109 LOCAL_SET_GL_ERROR(
5110 GL_INVALID_OPERATION,
5111 "glRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:205112 return;
5113 }
5114
[email protected]84afefa2011-10-19 21:45:535115 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515116 LOCAL_SET_GL_ERROR(
5117 GL_INVALID_VALUE,
5118 "glRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:535119 return;
5120 }
5121
5122 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5123 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515124 LOCAL_SET_GL_ERROR(
5125 GL_INVALID_VALUE,
5126 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535127 return;
5128 }
5129
[email protected]7989c9e2013-01-23 06:39:265130 uint32 estimated_size = 0;
5131 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5132 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515133 LOCAL_SET_GL_ERROR(
5134 GL_OUT_OF_MEMORY,
5135 "glRenderbufferStorageMultsample", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265136 return;
[email protected]8e3e0662010-08-23 18:46:305137 }
5138
[email protected]7989c9e2013-01-23 06:39:265139 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515140 LOCAL_SET_GL_ERROR(
5141 GL_OUT_OF_MEMORY,
5142 "glRenderbufferStorageMultsample", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265143 return;
5144 }
5145
5146 GLenum impl_format = RenderbufferManager::
5147 InternalRenderbufferFormatToImplFormat(internalformat);
[email protected]ab09b612013-03-11 22:11:515148 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisample");
[email protected]866b91c52011-03-23 14:38:085149 if (IsAngle()) {
5150 glRenderbufferStorageMultisampleANGLE(
5151 target, samples, impl_format, width, height);
5152 } else {
5153 glRenderbufferStorageMultisampleEXT(
5154 target, samples, impl_format, width, height);
5155 }
[email protected]ab09b612013-03-11 22:11:515156 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisample");
[email protected]9edc6b22010-12-23 02:00:265157 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515158 // TODO(gman): If renderbuffers tracked which framebuffers they were
5159 // attached to we could just mark those framebuffers as not complete.
5160 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205161 renderbuffer_manager()->SetInfo(
5162 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265163 }
[email protected]8e3e0662010-08-23 18:46:305164}
5165
[email protected]36cef8ce2010-03-16 07:34:455166void GLES2DecoderImpl::DoRenderbufferStorage(
5167 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355168 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205169 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5170 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515171 LOCAL_SET_GL_ERROR(
5172 GL_INVALID_OPERATION,
5173 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455174 return;
5175 }
[email protected]876f6fee2010-08-02 23:10:325176
[email protected]84afefa2011-10-19 21:45:535177 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5178 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515179 LOCAL_SET_GL_ERROR(
5180 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535181 return;
5182 }
5183
[email protected]7989c9e2013-01-23 06:39:265184 uint32 estimated_size = 0;
5185 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5186 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515187 LOCAL_SET_GL_ERROR(
5188 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265189 return;
5190 }
5191
5192 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515193 LOCAL_SET_GL_ERROR(
5194 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265195 return;
[email protected]b71f52c2010-06-18 22:20:205196 }
[email protected]876f6fee2010-08-02 23:10:325197
[email protected]ab09b612013-03-11 22:11:515198 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265199 glRenderbufferStorageEXT(
5200 target, RenderbufferManager::
5201 InternalRenderbufferFormatToImplFormat(internalformat),
5202 width, height);
[email protected]ab09b612013-03-11 22:11:515203 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265204 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515205 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5206 // we could just mark those framebuffers as not complete.
5207 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205208 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265209 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265210 }
[email protected]36cef8ce2010-03-16 07:34:455211}
5212
[email protected]df37b9932013-03-08 05:21:425213void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385214 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425215 Program* program = GetProgramInfoNotShader(
5216 program_id, "glLinkProgram");
5217 if (!program) {
[email protected]a93bb842010-02-16 23:03:475218 return;
5219 }
[email protected]05afda12011-01-20 00:17:345220
[email protected]df37b9932013-03-08 05:21:425221 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395222 ShaderTranslator* vertex_translator = NULL;
5223 ShaderTranslator* fragment_translator = NULL;
5224 if (use_shader_translator_) {
5225 vertex_translator = vertex_translator_;
5226 fragment_translator = fragment_translator_;
5227 }
[email protected]df37b9932013-03-08 05:21:425228 if (program->Link(shader_manager(),
[email protected]65dfc602012-07-23 20:39:395229 vertex_translator,
5230 fragment_translator,
[email protected]e3932abb2013-03-13 00:01:375231 feature_info_,
5232 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425233 if (program == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:155234 if (workarounds().use_current_program_after_successful_link) {
[email protected]df37b9932013-03-08 05:21:425235 glUseProgram(program->service_id());
[email protected]c2a3caf12012-10-23 19:32:005236 }
[email protected]df37b9932013-03-08 05:21:425237 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545238 }
5239 }
[email protected]07f54fcc2009-12-22 02:46:305240};
5241
[email protected]3916c97e2010-02-25 03:20:505242void GLES2DecoderImpl::DoTexParameterf(
5243 GLenum target, GLenum pname, GLfloat param) {
[email protected]02965c22013-03-09 02:40:075244 Texture* texture = GetTextureInfoForTarget(target);
5245 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515246 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245247 return;
[email protected]07f54fcc2009-12-22 02:46:305248 }
[email protected]cbb22e42011-05-12 23:36:245249
[email protected]02965c22013-03-09 02:40:075250 texture_manager()->SetParameter(
5251 "glTexParameterf", this, texture, pname, static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305252}
5253
[email protected]3916c97e2010-02-25 03:20:505254void GLES2DecoderImpl::DoTexParameteri(
5255 GLenum target, GLenum pname, GLint param) {
[email protected]02965c22013-03-09 02:40:075256 Texture* texture = GetTextureInfoForTarget(target);
5257 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515258 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245259 return;
[email protected]3916c97e2010-02-25 03:20:505260 }
[email protected]cbb22e42011-05-12 23:36:245261
[email protected]02965c22013-03-09 02:40:075262 texture_manager()->SetParameter(
5263 "glTexParameteri", this, texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505264}
5265
5266void GLES2DecoderImpl::DoTexParameterfv(
5267 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]02965c22013-03-09 02:40:075268 Texture* texture = GetTextureInfoForTarget(target);
5269 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515270 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245271 return;
[email protected]3916c97e2010-02-25 03:20:505272 }
[email protected]cbb22e42011-05-12 23:36:245273
[email protected]02965c22013-03-09 02:40:075274 texture_manager()->SetParameter(
5275 "glTexParameterfv", this, texture, pname, static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505276}
5277
5278void GLES2DecoderImpl::DoTexParameteriv(
5279 GLenum target, GLenum pname, const GLint* params) {
[email protected]02965c22013-03-09 02:40:075280 Texture* texture = GetTextureInfoForTarget(target);
5281 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515282 LOCAL_SET_GL_ERROR(
5283 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245284 return;
[email protected]3916c97e2010-02-25 03:20:505285 }
[email protected]cbb22e42011-05-12 23:36:245286
[email protected]02965c22013-03-09 02:40:075287 texture_manager()->SetParameter(
5288 "glTexParameteriv", this, texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505289}
5290
[email protected]939e7362010-05-13 20:49:105291bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]e259eb412012-10-13 05:47:245292 if (!state_.current_program) {
[email protected]ad84a3a2012-06-08 21:42:435293 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515294 LOCAL_SET_GL_ERROR(
5295 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435296 return false;
[email protected]939e7362010-05-13 20:49:105297 }
[email protected]e259eb412012-10-13 05:47:245298 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515299 LOCAL_SET_GL_ERROR(
5300 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105301 return false;
5302 }
5303 return true;
5304}
5305
5306bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5307 GLint location, const char* function_name) {
5308 if (!CheckCurrentProgram(function_name)) {
5309 return false;
5310 }
5311 return location != -1;
5312}
5313
[email protected]476ccb72012-12-06 15:52:525314namespace {
5315
5316static const GLenum valid_int_vec1_types_list[] = {
5317 GL_INT,
5318 GL_BOOL,
5319 GL_SAMPLER_2D,
5320 GL_SAMPLER_2D_RECT_ARB,
5321 GL_SAMPLER_CUBE,
5322 GL_SAMPLER_EXTERNAL_OES,
5323};
5324
5325static const GLenum valid_int_vec2_types_list[] = {
5326 GL_INT_VEC2,
5327 GL_BOOL_VEC2,
5328};
5329
5330static const GLenum valid_int_vec3_types_list[] = {
5331 GL_INT_VEC3,
5332 GL_BOOL_VEC3,
5333};
5334
5335static const GLenum valid_int_vec4_types_list[] = {
5336 GL_INT_VEC4,
5337 GL_BOOL_VEC4,
5338};
5339
5340static const GLenum valid_float_vec1_types_list[] = {
5341 GL_FLOAT,
5342 GL_BOOL,
5343};
5344
5345static const GLenum valid_float_vec2_types_list[] = {
5346 GL_FLOAT_VEC2,
5347 GL_BOOL_VEC2,
5348};
5349
5350static const GLenum valid_float_vec3_types_list[] = {
5351 GL_FLOAT_VEC3,
5352 GL_BOOL_VEC3,
5353};
5354
5355static const GLenum valid_float_vec4_types_list[] = {
5356 GL_FLOAT_VEC4,
5357 GL_BOOL_VEC4,
5358};
5359
5360static const GLenum valid_float_mat2_types_list[] = {
5361 GL_FLOAT_MAT2,
5362};
5363
5364static const GLenum valid_float_mat3_types_list[] = {
5365 GL_FLOAT_MAT3,
5366};
5367
5368static const GLenum valid_float_mat4_types_list[] = {
5369 GL_FLOAT_MAT4,
5370};
5371
5372static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5373 valid_int_vec1_types_list,
5374 arraysize(valid_int_vec1_types_list),
5375};
5376
5377static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5378 valid_int_vec2_types_list,
5379 arraysize(valid_int_vec2_types_list),
5380};
5381
5382static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5383 valid_int_vec3_types_list,
5384 arraysize(valid_int_vec3_types_list),
5385};
5386
5387static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5388 valid_int_vec4_types_list,
5389 arraysize(valid_int_vec4_types_list),
5390};
5391
5392static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5393 valid_float_vec1_types_list,
5394 arraysize(valid_float_vec1_types_list),
5395};
5396
5397static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5398 valid_float_vec2_types_list,
5399 arraysize(valid_float_vec2_types_list),
5400};
5401
5402static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5403 valid_float_vec3_types_list,
5404 arraysize(valid_float_vec3_types_list),
5405};
5406
5407static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5408 valid_float_vec4_types_list,
5409 arraysize(valid_float_vec4_types_list),
5410};
5411
5412static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5413 valid_float_mat2_types_list,
5414 arraysize(valid_float_mat2_types_list),
5415};
5416
5417static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5418 valid_float_mat3_types_list,
5419 arraysize(valid_float_mat3_types_list),
5420};
5421
5422static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5423 valid_float_mat4_types_list,
5424 arraysize(valid_float_mat4_types_list),
5425};
5426
5427} // anonymous namespace.
5428
[email protected]43c2f1f2011-03-25 18:35:365429bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125430 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525431 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125432 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365433 DCHECK(type);
5434 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125435 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525436
[email protected]1b0a6752012-02-22 03:44:125437 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105438 return false;
5439 }
[email protected]43c2f1f2011-03-25 18:35:365440 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355441 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245442 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125443 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365444 if (!info) {
[email protected]ab09b612013-03-11 22:11:515445 LOCAL_SET_GL_ERROR(
5446 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105447 return false;
5448 }
[email protected]476ccb72012-12-06 15:52:525449 bool okay = false;
5450 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5451 if (base_info.valid_types[ii] == info->type) {
5452 okay = true;
5453 break;
5454 }
5455 }
5456 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515457 LOCAL_SET_GL_ERROR(
5458 GL_INVALID_OPERATION, function_name,
5459 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525460 return false;
5461 }
[email protected]43c2f1f2011-03-25 18:35:365462 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515463 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435464 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365465 return false;
5466 }
5467 *count = std::min(info->size - array_index, *count);
5468 if (*count <= 0) {
5469 return false;
5470 }
5471 *type = info->type;
[email protected]939e7362010-05-13 20:49:105472 return true;
5473}
5474
[email protected]1b0a6752012-02-22 03:44:125475void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5476 GLenum type = 0;
5477 GLsizei count = 1;
5478 GLint real_location = -1;
5479 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525480 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5481 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505482 return;
5483 }
[email protected]e259eb412012-10-13 05:47:245484 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025485 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515486 LOCAL_SET_GL_ERROR(
5487 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465488 return;
5489 }
[email protected]1b0a6752012-02-22 03:44:125490 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505491}
5492
5493void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125494 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365495 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125496 GLint real_location = -1;
5497 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525498 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5499 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365500 return;
5501 }
[email protected]74727112012-06-13 21:18:085502 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5503 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245504 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025505 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515506 LOCAL_SET_GL_ERROR(
5507 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465508 return;
5509 }
[email protected]43c2f1f2011-03-25 18:35:365510 }
[email protected]1b0a6752012-02-22 03:44:125511 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505512}
5513
[email protected]939e7362010-05-13 20:49:105514void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125515 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365516 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125517 GLint real_location = -1;
5518 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525519 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5520 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105521 return;
5522 }
5523 if (type == GL_BOOL) {
5524 scoped_array<GLint> temp(new GLint[count]);
5525 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535526 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105527 }
[email protected]1b0a6752012-02-22 03:44:125528 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105529 } else {
[email protected]1b0a6752012-02-22 03:44:125530 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105531 }
5532}
5533
5534void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125535 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365536 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125537 GLint real_location = -1;
5538 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525539 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5540 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105541 return;
5542 }
5543 if (type == GL_BOOL_VEC2) {
5544 GLsizei num_values = count * 2;
5545 scoped_array<GLint> temp(new GLint[num_values]);
5546 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535547 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105548 }
[email protected]1b0a6752012-02-22 03:44:125549 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105550 } else {
[email protected]1b0a6752012-02-22 03:44:125551 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105552 }
5553}
5554
5555void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125556 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365557 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125558 GLint real_location = -1;
5559 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525560 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5561 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105562 return;
5563 }
5564 if (type == GL_BOOL_VEC3) {
5565 GLsizei num_values = count * 3;
5566 scoped_array<GLint> temp(new GLint[num_values]);
5567 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535568 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105569 }
[email protected]1b0a6752012-02-22 03:44:125570 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105571 } else {
[email protected]1b0a6752012-02-22 03:44:125572 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105573 }
5574}
5575
5576void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125577 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365578 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125579 GLint real_location = -1;
5580 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525581 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5582 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105583 return;
5584 }
5585 if (type == GL_BOOL_VEC4) {
5586 GLsizei num_values = count * 4;
5587 scoped_array<GLint> temp(new GLint[num_values]);
5588 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535589 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105590 }
[email protected]1b0a6752012-02-22 03:44:125591 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105592 } else {
[email protected]1b0a6752012-02-22 03:44:125593 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105594 }
5595}
5596
[email protected]43c2f1f2011-03-25 18:35:365597void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125598 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365599 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125600 GLint real_location = -1;
5601 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525602 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5603 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365604 return;
5605 }
[email protected]1b0a6752012-02-22 03:44:125606 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365607}
5608
5609void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125610 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365611 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125612 GLint real_location = -1;
5613 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525614 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5615 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365616 return;
5617 }
[email protected]1b0a6752012-02-22 03:44:125618 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365619}
5620
5621void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125622 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365623 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125624 GLint real_location = -1;
5625 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525626 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5627 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365628 return;
5629 }
[email protected]1b0a6752012-02-22 03:44:125630 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365631}
5632
5633void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125634 GLint fake_location, GLsizei count, GLboolean transpose,
5635 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365636 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125637 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365638 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525639 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5640 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365641 return;
5642 }
[email protected]1b0a6752012-02-22 03:44:125643 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365644}
5645
5646void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125647 GLint fake_location, GLsizei count, GLboolean transpose,
5648 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365649 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125650 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365651 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525652 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5653 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365654 return;
5655 }
[email protected]1b0a6752012-02-22 03:44:125656 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365657}
5658
5659void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125660 GLint fake_location, GLsizei count, GLboolean transpose,
5661 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365662 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125663 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365664 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525665 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5666 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365667 return;
5668 }
[email protected]1b0a6752012-02-22 03:44:125669 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365670}
5671
[email protected]df37b9932013-03-08 05:21:425672void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035673 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425674 Program* program = NULL;
5675 if (program_id) {
5676 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5677 if (!program) {
[email protected]ae51d192010-04-27 00:48:035678 return;
5679 }
[email protected]df37b9932013-03-08 05:21:425680 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505681 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515682 LOCAL_SET_GL_ERROR(
5683 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505684 return;
5685 }
[email protected]df37b9932013-03-08 05:21:425686 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505687 }
[email protected]e259eb412012-10-13 05:47:245688 if (state_.current_program) {
5689 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
[email protected]ca488e12010-12-13 20:06:145690 }
[email protected]df37b9932013-03-08 05:21:425691 state_.current_program = program;
5692 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545693 glUseProgram(service_id);
[email protected]e259eb412012-10-13 05:47:245694 if (state_.current_program) {
5695 program_manager()->UseProgram(state_.current_program);
[email protected]ca488e12010-12-13 20:06:145696 }
[email protected]3916c97e2010-02-25 03:20:505697}
5698
[email protected]efcdd2362012-07-09 21:07:005699uint32 GLES2DecoderImpl::GetGLError() {
[email protected]96449d2c2009-11-25 00:01:325700 // Check the GL error first, then our wrapped error.
5701 GLenum error = glGetError();
5702 if (error == GL_NO_ERROR && error_bits_ != 0) {
[email protected]03f882a2010-01-08 20:46:375703 for (uint32 mask = 1; mask != 0; mask = mask << 1) {
[email protected]96449d2c2009-11-25 00:01:325704 if ((error_bits_ & mask) != 0) {
[email protected]ddd968b82010-03-02 00:44:295705 error = GLES2Util::GLErrorBitToGLError(mask);
[email protected]96449d2c2009-11-25 00:01:325706 break;
5707 }
5708 }
5709 }
5710
5711 if (error != GL_NO_ERROR) {
5712 // There was an error, clear the corresponding wrapped error.
[email protected]ddd968b82010-03-02 00:44:295713 error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
[email protected]96449d2c2009-11-25 00:01:325714 }
5715 return error;
5716}
5717
[email protected]ab09b612013-03-11 22:11:515718unsigned GLES2DecoderImpl::PeekGLError(
5719 const char* filename, int line, const char* function_name) {
[email protected]1002c2d2011-06-28 22:39:045720 GLenum error = glGetError();
5721 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515722 SetGLError(filename, line, error, function_name, "");
[email protected]1002c2d2011-06-28 22:39:045723 }
5724 return error;
5725}
5726
[email protected]ad84a3a2012-06-08 21:42:435727void GLES2DecoderImpl::SetGLError(
[email protected]ab09b612013-03-11 22:11:515728 const char* filename, int line,
[email protected]e5dfab42013-03-05 09:27:425729 unsigned error, const char* function_name, const char* msg) {
[email protected]8eee29c2010-04-29 03:38:295730 if (msg) {
5731 last_error_ = msg;
[email protected]ab09b612013-03-11 22:11:515732 LogMessage(filename, line,
5733 GetLogPrefix() + ": " + std::string("GL ERROR :") +
[email protected]ad84a3a2012-06-08 21:42:435734 GLES2Util::GetStringEnum(error) + " : " +
5735 function_name + ": " + msg);
[email protected]8eee29c2010-04-29 03:38:295736 }
[email protected]ddd968b82010-03-02 00:44:295737 error_bits_ |= GLES2Util::GLErrorToErrorBit(error);
[email protected]96449d2c2009-11-25 00:01:325738}
5739
[email protected]f80e6e12012-08-31 00:43:535740void GLES2DecoderImpl::SetGLErrorInvalidEnum(
[email protected]ab09b612013-03-11 22:11:515741 const char* filename, int line,
[email protected]e5dfab42013-03-05 09:27:425742 const char* function_name, unsigned value, const char* label) {
[email protected]ab09b612013-03-11 22:11:515743 SetGLError(filename, line, GL_INVALID_ENUM, function_name,
[email protected]f80e6e12012-08-31 00:43:535744 (std::string(label) + " was " +
5745 GLES2Util::GetStringEnum(value)).c_str());
5746}
5747
[email protected]445a8762012-12-06 15:43:215748void GLES2DecoderImpl::SetGLErrorInvalidParam(
[email protected]ab09b612013-03-11 22:11:515749 const char* filename,
5750 int line,
[email protected]e5dfab42013-03-05 09:27:425751 unsigned error,
[email protected]445a8762012-12-06 15:43:215752 const char* function_name,
[email protected]e5dfab42013-03-05 09:27:425753 unsigned pname,
5754 int param) {
[email protected]445a8762012-12-06 15:43:215755 if (error == GL_INVALID_ENUM) {
5756 SetGLError(
[email protected]ab09b612013-03-11 22:11:515757 filename, line, GL_INVALID_ENUM, function_name,
[email protected]445a8762012-12-06 15:43:215758 (std::string("trying to set ") +
5759 GLES2Util::GetStringEnum(pname) + " to " +
5760 GLES2Util::GetStringEnum(param)).c_str());
5761 } else {
5762 SetGLError(
[email protected]ab09b612013-03-11 22:11:515763 filename, line, error, function_name,
[email protected]445a8762012-12-06 15:43:215764 (std::string("trying to set ") +
5765 GLES2Util::GetStringEnum(pname) + " to " +
5766 base::StringPrintf("%d", param)).c_str());
5767 }
5768}
5769
[email protected]d2a0e1a2012-08-12 02:25:015770const std::string& GLES2DecoderImpl::GetLogPrefix() const {
5771 const std::string& prefix(debug_marker_manager_.GetMarker());
5772 return prefix.empty() ? this_in_hex_ : prefix;
5773}
5774
[email protected]ab09b612013-03-11 22:11:515775void GLES2DecoderImpl::LogMessage(
5776 const char* filename, int line, const std::string& msg) {
[email protected]0f8afe82012-05-14 23:43:015777 if (log_message_count_ < kMaxLogMessages ||
5778 CommandLine::ForCurrentProcess()->HasSwitch(
5779 switches::kDisableGLErrorLimit)) {
5780 ++log_message_count_;
5781 // LOG this unless logging is turned off as any chromium code that
5782 // generates these errors probably has a bug.
5783 if (log_synthesized_gl_errors()) {
[email protected]ab09b612013-03-11 22:11:515784 ::logging::LogMessage(
5785 filename, line, ::logging::LOG_ERROR).stream() << msg;
[email protected]0f8afe82012-05-14 23:43:015786 }
5787 if (!msg_callback_.is_null()) {
5788 msg_callback_.Run(0, msg);
5789 }
5790 } else {
5791 if (log_message_count_ == kMaxLogMessages) {
5792 ++log_message_count_;
5793 LOG(ERROR)
5794 << "Too many GL errors, not reporting any more for this context."
5795 << " use --disable-gl-error-limit to see all errors.";
5796 }
5797 }
5798}
5799
[email protected]ab09b612013-03-11 22:11:515800void GLES2DecoderImpl::RenderWarning(
5801 const char* filename, int line, const std::string& msg) {
5802 LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015803}
5804
[email protected]ab09b612013-03-11 22:11:515805void GLES2DecoderImpl::PerformanceWarning(
5806 const char* filename, int line, const std::string& msg) {
5807 LogMessage(filename, line, std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015808}
5809
[email protected]df37b9932013-03-08 05:21:425810void GLES2DecoderImpl::ForceCompileShaderIfPending(Shader* shader) {
5811 if (shader->compilation_status() ==
[email protected]ed9f9cd2013-02-27 21:12:355812 Shader::PENDING_DEFERRED_COMPILE) {
[email protected]c447acd2012-07-23 23:48:415813 ShaderTranslator* translator = NULL;
5814 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:425815 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]c447acd2012-07-23 23:48:415816 vertex_translator_.get() : fragment_translator_.get();
5817 }
5818 // We know there will be no errors, because we only defer compilation on
5819 // shaders that were previously compiled successfully.
[email protected]df37b9932013-03-08 05:21:425820 program_manager()->ForceCompileShader(shader->deferred_compilation_source(),
5821 shader,
[email protected]c447acd2012-07-23 23:48:415822 translator,
5823 feature_info_);
5824 }
5825}
5826
[email protected]ab09b612013-03-11 22:11:515827void GLES2DecoderImpl::CopyRealGLErrorsToWrapper(
5828 const char* filename, int line, const char* function_name) {
[email protected]07f54fcc2009-12-22 02:46:305829 GLenum error;
5830 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515831 SetGLError(filename, line, error, function_name,
5832 "<- error from previous GL command");
[email protected]07f54fcc2009-12-22 02:46:305833 }
5834}
5835
[email protected]ab09b612013-03-11 22:11:515836void GLES2DecoderImpl::ClearRealGLErrors(
5837 const char* filename, int line, const char* function_name) {
[email protected]6217d392010-03-25 22:08:355838 GLenum error;
5839 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]3ed14d112011-12-13 22:05:515840 if (error != GL_OUT_OF_MEMORY) {
5841 // GL_OUT_OF_MEMORY can legally happen on lost device.
[email protected]ab09b612013-03-11 22:11:515842 LogMessage(filename, line,
5843 GetLogPrefix() + ": " + std::string("GL ERROR :") +
5844 GLES2Util::GetStringEnum(error) + " : " +
5845 function_name + ": was unhandled");
[email protected]3ed14d112011-12-13 22:05:515846 NOTREACHED() << "GL error " << error << " was unhandled.";
5847 }
[email protected]6217d392010-03-25 22:08:355848 }
5849}
5850
[email protected]ef526492010-06-02 23:12:255851bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245852 DCHECK(state_.current_program);
[email protected]ef526492010-06-02 23:12:255853 // Only check if there are some unrenderable textures.
5854 if (!texture_manager()->HaveUnrenderableTextures()) {
5855 return false;
5856 }
5857 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:355858 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245859 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505860 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355861 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245862 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505863 DCHECK(uniform_info);
5864 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5865 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025866 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245867 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]02965c22013-03-09 02:40:075868 Texture* texture =
[email protected]61eeb33f2011-07-26 15:30:315869 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]02965c22013-03-09 02:40:075870 if (!texture || !texture_manager()->CanRender(texture)) {
[email protected]ef526492010-06-02 23:12:255871 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505872 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5873 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315874 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495875 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:515876 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:015877 std::string("texture bound to texture unit ") +
5878 base::IntToString(texture_unit_index) +
5879 " is not renderable. It maybe non-power-of-2 and have "
5880 " incompatible texture filtering or is not "
5881 "'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505882 }
5883 }
5884 // else: should this be an error?
5885 }
5886 }
[email protected]ef526492010-06-02 23:12:255887 return textures_set;
[email protected]3916c97e2010-02-25 03:20:505888}
5889
5890void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245891 DCHECK(state_.current_program);
[email protected]ed9f9cd2013-02-27 21:12:355892 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245893 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505894 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355895 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245896 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505897 DCHECK(uniform_info);
5898 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5899 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025900 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245901 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]02965c22013-03-09 02:40:075902 Texture* texture = uniform_info->type == GL_SAMPLER_2D ?
5903 texture_unit.bound_texture_2d :
5904 texture_unit.bound_texture_cube_map;
5905 if (!texture || !texture_manager()->CanRender(texture)) {
[email protected]3916c97e2010-02-25 03:20:505906 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5907 // Get the texture info that was previously bound here.
[email protected]02965c22013-03-09 02:40:075908 texture = texture_unit.bind_target == GL_TEXTURE_2D ?
[email protected]3916c97e2010-02-25 03:20:505909 texture_unit.bound_texture_2d :
5910 texture_unit.bound_texture_cube_map;
5911 glBindTexture(texture_unit.bind_target,
[email protected]02965c22013-03-09 02:40:075912 texture ? texture->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505913 }
5914 }
5915 }
5916 }
5917 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245918 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305919}
5920
[email protected]0d6bfdc2011-11-02 01:32:205921bool GLES2DecoderImpl::ClearUnclearedTextures() {
5922 // Only check if there are some uncleared textures.
5923 if (!texture_manager()->HaveUnsafeTextures()) {
5924 return true;
5925 }
5926
5927 // 1: Check all textures we are about to render with.
[email protected]e259eb412012-10-13 05:47:245928 if (state_.current_program) {
[email protected]ed9f9cd2013-02-27 21:12:355929 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245930 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205931 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355932 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245933 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205934 DCHECK(uniform_info);
5935 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5936 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025937 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245938 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]02965c22013-03-09 02:40:075939 Texture* texture =
[email protected]0d6bfdc2011-11-02 01:32:205940 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]02965c22013-03-09 02:40:075941 if (texture && !texture->SafeToRenderFrom()) {
5942 if (!texture_manager()->ClearRenderableLevels(this, texture)) {
[email protected]0d6bfdc2011-11-02 01:32:205943 return false;
5944 }
5945 }
5946 }
5947 }
5948 }
5949 }
5950 return true;
5951}
5952
[email protected]c6aef902012-02-14 03:31:425953bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435954 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035955 // NOTE: We specifically do not check current_program->IsValid() because
5956 // it could never be invalid since glUseProgram would have failed. While
5957 // glLinkProgram could later mark the program as invalid the previous
5958 // valid program will still function if it is still the current program.
[email protected]e259eb412012-10-13 05:47:245959 if (!state_.current_program) {
[email protected]3916c97e2010-02-25 03:20:505960 // The program does not exist.
5961 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:515962 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505963 return false;
5964 }
[email protected]c6aef902012-02-14 03:31:425965
[email protected]17cfbe0e2013-03-07 01:26:085966 return state_.vertex_attrib_manager->ValidateBindings(
5967 function_name,
5968 this,
5969 feature_info_.get(),
5970 state_.current_program,
5971 max_vertex_accessed,
5972 primcount);
[email protected]b1122982010-05-17 23:04:245973}
5974
[email protected]c13e1da62011-09-09 21:48:305975bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435976 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305977 DCHECK(simulated);
5978 *simulated = false;
5979
[email protected]876f6fee2010-08-02 23:10:325980 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305981 return true;
[email protected]876f6fee2010-08-02 23:10:325982
[email protected]ac77603c72013-03-08 13:52:065983 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:355984 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:245985 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245986 bool attrib_0_used =
5987 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:065988 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305989 return true;
[email protected]b1122982010-05-17 23:04:245990 }
5991
[email protected]b1122982010-05-17 23:04:245992 // Make a buffer with a single repeated vec4 value enough to
5993 // simulate the constant value that is supposed to be here.
5994 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305995 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475996 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305997
5998 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475999 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306000 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516001 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306002 return false;
6003 }
6004
[email protected]ab09b612013-03-11 22:11:516005 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016006 "Attribute 0 is disabled. This has signficant performance penalty");
6007
[email protected]ab09b612013-03-11 22:11:516008 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306009 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6010
[email protected]8f0b86c2f2012-04-10 05:48:286011 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6012 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496013 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306014 GLenum error = glGetError();
6015 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516016 LOCAL_SET_GL_ERROR(
6017 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306018 return false;
6019 }
[email protected]fc753442011-02-04 19:49:496020 }
[email protected]af6380962012-11-29 23:24:136021
6022 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286023 if (new_buffer ||
6024 (attrib_0_used &&
6025 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136026 (value.v[0] != attrib_0_value_.v[0] ||
6027 value.v[1] != attrib_0_value_.v[1] ||
6028 value.v[2] != attrib_0_value_.v[2] ||
6029 value.v[3] != attrib_0_value_.v[3])))) {
6030 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496031 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6032 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136033 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246034 attrib_0_size_ = size_needed;
6035 }
6036
6037 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6038
[email protected]ac77603c72013-03-08 13:52:066039 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426040 glVertexAttribDivisorANGLE(0, 0);
6041
[email protected]c13e1da62011-09-09 21:48:306042 *simulated = true;
[email protected]b1122982010-05-17 23:04:246043 return true;
[email protected]b1122982010-05-17 23:04:246044}
6045
[email protected]ac77603c72013-03-08 13:52:066046void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
6047 const VertexAttrib* attrib =
6048 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
6049 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6050 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:076051 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:246052 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066053 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6054 attrib->gl_stride(), ptr);
6055 if (attrib->divisor())
6056 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246057 glBindBuffer(
6058 GL_ARRAY_BUFFER,
6059 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286060
[email protected]265f8992012-07-20 01:03:146061 // Never touch vertex attribute 0's state (in particular, never
6062 // disable it) when running on desktop GL because it will never be
6063 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066064 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146065 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066066 if (attrib->enabled()) {
6067 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146068 } else {
[email protected]ac77603c72013-03-08 13:52:066069 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146070 }
[email protected]43410e92012-04-20 17:06:286071 }
[email protected]b1122982010-05-17 23:04:246072}
[email protected]07f54fcc2009-12-22 02:46:306073
[email protected]8fbedc02010-11-18 18:43:406074bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436075 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426076 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406077 DCHECK(simulated);
6078 *simulated = false;
6079 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6080 return true;
6081
[email protected]e259eb412012-10-13 05:47:246082 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406083 return true;
6084 }
6085
[email protected]ab09b612013-03-11 22:11:516086 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016087 "GL_FIXED attributes have a signficant performance penalty");
6088
[email protected]8fbedc02010-11-18 18:43:406089 // NOTE: we could be smart and try to check if a buffer is used
6090 // twice in 2 different attribs, find the overlapping parts and therefore
6091 // duplicate the minimum amount of data but this whole code path is not meant
6092 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6093 // tests so we just add to the buffer attrib used.
6094
[email protected]c13e1da62011-09-09 21:48:306095 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066096 const VertexAttribManager::VertexAttribList& enabled_attribs =
6097 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6098 for (VertexAttribManager::VertexAttribList::const_iterator it =
6099 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6100 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356101 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066102 state_.current_program->GetAttribInfoByLocation(attrib->index());
6103 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6104 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426105 GLuint num_vertices = max_accessed + 1;
6106 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516107 LOCAL_SET_GL_ERROR(
6108 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426109 return false;
6110 }
[email protected]8fbedc02010-11-18 18:43:406111 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066112 attrib->CanAccess(max_accessed) &&
6113 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476114 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066115 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476116 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516117 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436118 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406119 return false;
6120 }
6121 }
6122 }
6123
[email protected]3aad1a32012-09-07 20:54:476124 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6125 uint32 size_needed = 0;
6126 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306127 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516128 LOCAL_SET_GL_ERROR(
6129 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406130 return false;
6131 }
6132
[email protected]ab09b612013-03-11 22:11:516133 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406134
6135 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306136 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406137 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306138 GLenum error = glGetError();
6139 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516140 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436141 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306142 return false;
6143 }
[email protected]8fbedc02010-11-18 18:43:406144 }
6145
6146 // Copy the elements and convert to float
6147 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066148 for (VertexAttribManager::VertexAttribList::const_iterator it =
6149 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6150 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356151 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066152 state_.current_program->GetAttribInfoByLocation(attrib->index());
6153 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426154 max_vertex_accessed);
6155 GLuint num_vertices = max_accessed + 1;
6156 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516157 LOCAL_SET_GL_ERROR(
6158 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426159 return false;
6160 }
[email protected]8fbedc02010-11-18 18:43:406161 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066162 attrib->CanAccess(max_accessed) &&
6163 attrib->type() == GL_FIXED) {
6164 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406165 int size = num_elements * num_vertices;
6166 scoped_array<float> data(new float[size]);
6167 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066168 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406169 const int32* end = src + num_elements;
6170 float* dst = data.get();
6171 while (src != end) {
6172 *dst++ = static_cast<float>(*src++) / 65536.0f;
6173 }
6174 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6175 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066176 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406177 reinterpret_cast<GLvoid*>(offset));
6178 offset += size;
6179 }
6180 }
6181 *simulated = true;
6182 return true;
6183}
6184
6185void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6186 // There's no need to call glVertexAttribPointer because we shadow all the
6187 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246188 glBindBuffer(
6189 GL_ARRAY_BUFFER,
6190 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]8fbedc02010-11-18 18:43:406191}
6192
[email protected]ad84a3a2012-06-08 21:42:436193error::Error GLES2DecoderImpl::DoDrawArrays(
6194 const char* function_name,
6195 bool instanced,
6196 GLenum mode,
6197 GLint first,
6198 GLsizei count,
6199 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086200 if (ShouldDeferDraws())
6201 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:436202 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516203 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436204 return error::kNoError;
6205 }
6206 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516207 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436208 return error::kNoError;
6209 }
[email protected]c6aef902012-02-14 03:31:426210 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516211 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426212 return error::kNoError;
6213 }
[email protected]ad84a3a2012-06-08 21:42:436214 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436215 return error::kNoError;
6216 }
6217 // We have to check this here because the prototype for glDrawArrays
6218 // is GLint not GLsizei.
6219 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516220 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436221 return error::kNoError;
6222 }
6223
[email protected]c6aef902012-02-14 03:31:426224 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:516225 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436226 return error::kNoError;
6227 }
6228
6229 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:436230 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206231 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516232 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206233 return error::kNoError;
6234 }
[email protected]c13e1da62011-09-09 21:48:306235 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436236 if (!SimulateAttrib0(
6237 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306238 return error::kNoError;
6239 }
[email protected]38d139d2011-07-14 00:38:436240 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436241 if (SimulateFixedAttribs(
6242 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6243 primcount)) {
[email protected]38d139d2011-07-14 00:38:436244 bool textures_set = SetBlackTextureForNonRenderableTextures();
6245 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:426246 if (!instanced) {
6247 glDrawArrays(mode, first, count);
6248 } else {
6249 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6250 }
[email protected]22e3f552012-03-13 01:54:196251 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:436252 if (textures_set) {
6253 RestoreStateForNonRenderableTextures();
6254 }
6255 if (simulated_fixed_attribs) {
6256 RestoreStateForSimulatedFixedAttribs();
6257 }
6258 }
6259 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286260 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436261 }
[email protected]38d139d2011-07-14 00:38:436262 }
6263 return error::kNoError;
6264}
6265
[email protected]c6aef902012-02-14 03:31:426266error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356267 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436268 return DoDrawArrays("glDrawArrays",
6269 false,
[email protected]c6aef902012-02-14 03:31:426270 static_cast<GLenum>(c.mode),
6271 static_cast<GLint>(c.first),
6272 static_cast<GLsizei>(c.count),
6273 0);
6274}
6275
6276error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356277 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156278 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516279 LOCAL_SET_GL_ERROR(
6280 GL_INVALID_OPERATION,
6281 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426282 return error::kNoError;
6283 }
[email protected]ad84a3a2012-06-08 21:42:436284 return DoDrawArrays("glDrawArraysIntancedANGLE",
6285 true,
[email protected]c6aef902012-02-14 03:31:426286 static_cast<GLenum>(c.mode),
6287 static_cast<GLint>(c.first),
6288 static_cast<GLsizei>(c.count),
6289 static_cast<GLsizei>(c.primcount));
6290}
6291
[email protected]ad84a3a2012-06-08 21:42:436292error::Error GLES2DecoderImpl::DoDrawElements(
6293 const char* function_name,
6294 bool instanced,
6295 GLenum mode,
6296 GLsizei count,
6297 GLenum type,
6298 int32 offset,
6299 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086300 if (ShouldDeferDraws())
6301 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:246302 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516303 LOCAL_SET_GL_ERROR(
6304 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296305 return error::kNoError;
6306 }
6307
[email protected]8eee29c2010-04-29 03:38:296308 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516309 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296310 return error::kNoError;
6311 }
6312 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516313 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296314 return error::kNoError;
6315 }
[email protected]9438b012010-06-15 22:55:056316 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516317 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296318 return error::kNoError;
6319 }
[email protected]9438b012010-06-15 22:55:056320 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516321 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296322 return error::kNoError;
6323 }
[email protected]c6aef902012-02-14 03:31:426324 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516325 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426326 return error::kNoError;
6327 }
[email protected]8eee29c2010-04-29 03:38:296328
[email protected]ad84a3a2012-06-08 21:42:436329 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276330 return error::kNoError;
6331 }
6332
[email protected]c6aef902012-02-14 03:31:426333 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316334 return error::kNoError;
6335 }
6336
[email protected]8eee29c2010-04-29 03:38:296337 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086338 Buffer* element_array_buffer =
6339 state_.vertex_attrib_manager->element_array_buffer();
6340
6341 if (!element_array_buffer->GetMaxValueForRange(
6342 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516343 LOCAL_SET_GL_ERROR(
6344 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296345 return error::kNoError;
6346 }
6347
[email protected]ad84a3a2012-06-08 21:42:436348 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206349 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516350 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206351 return error::kNoError;
6352 }
[email protected]c13e1da62011-09-09 21:48:306353 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436354 if (!SimulateAttrib0(
6355 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306356 return error::kNoError;
6357 }
[email protected]8fbedc02010-11-18 18:43:406358 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436359 if (SimulateFixedAttribs(
6360 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6361 primcount)) {
[email protected]8fbedc02010-11-18 18:43:406362 bool textures_set = SetBlackTextureForNonRenderableTextures();
[email protected]297ca1c2011-06-20 23:08:466363 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086364 // TODO(gman): Refactor to hide these details in BufferManager or
6365 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406366 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086367 bool used_client_side_array = false;
6368 if (element_array_buffer->IsClientSideArray()) {
6369 used_client_side_array = true;
6370 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6371 indices = element_array_buffer->GetRange(offset, 0);
6372 }
6373
[email protected]c6aef902012-02-14 03:31:426374 if (!instanced) {
6375 glDrawElements(mode, count, type, indices);
6376 } else {
6377 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6378 }
[email protected]17cfbe0e2013-03-07 01:26:086379
6380 if (used_client_side_array) {
6381 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6382 element_array_buffer->service_id());
6383 }
6384
[email protected]22e3f552012-03-13 01:54:196385 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406386 if (textures_set) {
6387 RestoreStateForNonRenderableTextures();
6388 }
6389 if (simulated_fixed_attribs) {
6390 RestoreStateForSimulatedFixedAttribs();
6391 }
[email protected]ba3176a2009-12-16 18:19:466392 }
[email protected]b1122982010-05-17 23:04:246393 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286394 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246395 }
[email protected]96449d2c2009-11-25 00:01:326396 }
[email protected]f7a64ee2010-02-01 22:24:146397 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326398}
6399
[email protected]c6aef902012-02-14 03:31:426400error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356401 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436402 return DoDrawElements("glDrawElements",
6403 false,
[email protected]c6aef902012-02-14 03:31:426404 static_cast<GLenum>(c.mode),
6405 static_cast<GLsizei>(c.count),
6406 static_cast<GLenum>(c.type),
6407 static_cast<int32>(c.index_offset),
6408 0);
6409}
6410
6411error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356412 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156413 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516414 LOCAL_SET_GL_ERROR(
6415 GL_INVALID_OPERATION,
6416 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426417 return error::kNoError;
6418 }
[email protected]ad84a3a2012-06-08 21:42:436419 return DoDrawElements("glDrawElementsInstancedANGLE",
6420 true,
[email protected]c6aef902012-02-14 03:31:426421 static_cast<GLenum>(c.mode),
6422 static_cast<GLsizei>(c.count),
6423 static_cast<GLenum>(c.type),
6424 static_cast<int32>(c.index_offset),
6425 static_cast<GLsizei>(c.primcount));
6426}
6427
[email protected]269200b12010-11-18 22:53:066428GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236429 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6430 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076431 Buffer* buffer = GetBuffer(buffer_id);
6432 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036433 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516434 LOCAL_SET_GL_ERROR(
6435 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236436 } else {
[email protected]b10492f2013-03-08 05:24:076437 if (!buffer->GetMaxValueForRange(
6438 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036439 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516440 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066441 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436442 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236443 }
6444 }
6445 return max_vertex_accessed;
6446}
6447
[email protected]96449d2c2009-11-25 00:01:326448// Calls glShaderSource for the various versions of the ShaderSource command.
6449// Assumes that data / data_size points to a piece of memory that is in range
6450// of whatever context it came from (shared memory, immediate memory, bucket
6451// memory.)
[email protected]45bf5152010-02-12 00:11:316452error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036453 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576454 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426455 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6456 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316457 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326458 }
[email protected]45bf5152010-02-12 00:11:316459 // Note: We don't actually call glShaderSource here. We wait until
6460 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426461 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146462 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326463}
6464
[email protected]f7a64ee2010-02-01 22:24:146465error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356466 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326467 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316468 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326469 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466470 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146471 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326472 }
[email protected]ae51d192010-04-27 00:48:036473 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326474}
6475
[email protected]f7a64ee2010-02-01 22:24:146476error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]ed9f9cd2013-02-27 21:12:356477 uint32 immediate_data_size, const cmds::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:326478 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316479 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:306480 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:466481 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146482 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326483 }
[email protected]ae51d192010-04-27 00:48:036484 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:316485}
6486
[email protected]558847a2010-03-24 07:02:546487error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356488 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546489 Bucket* bucket = GetBucket(c.data_bucket_id);
6490 if (!bucket || bucket->size() == 0) {
6491 return error::kInvalidArguments;
6492 }
6493 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036494 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546495 bucket->size() - 1);
6496}
6497
[email protected]ae51d192010-04-27 00:48:036498void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386499 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426500 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6501 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316502 return;
6503 }
[email protected]f57bb282010-11-12 00:51:346504 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186505 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426506 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456507 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416508 }
[email protected]de17df392010-04-23 21:09:416509
[email protected]df37b9932013-03-08 05:21:426510 program_manager()->DoCompileShader(shader, translator, feature_info_);
[email protected]45bf5152010-02-12 00:11:316511};
6512
[email protected]ddd968b82010-03-02 00:44:296513void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426514 GLuint shader_id, GLenum pname, GLint* params) {
6515 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6516 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296517 return;
6518 }
[email protected]8f1ccdac2010-05-19 21:01:486519 switch (pname) {
6520 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426521 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486522 return;
6523 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426524 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416525 return;
[email protected]8f1ccdac2010-05-19 21:01:486526 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426527 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416528 return;
[email protected]d6a53e42011-10-05 00:09:366529 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426530 ForceCompileShaderIfPending(shader);
6531 *params = shader->translated_source() ?
6532 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366533 return;
[email protected]8f1ccdac2010-05-19 21:01:486534 default:
6535 break;
[email protected]ddd968b82010-03-02 00:44:296536 }
[email protected]df37b9932013-03-08 05:21:426537 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296538}
6539
[email protected]ae51d192010-04-27 00:48:036540error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356541 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426542 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036543 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6544 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426545 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6546 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296547 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296548 return error::kNoError;
6549 }
[email protected]df37b9932013-03-08 05:21:426550 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036551 return error::kNoError;
6552}
6553
[email protected]d6a53e42011-10-05 00:09:366554error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6555 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356556 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426557 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366558 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6559 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426560 Shader* shader = GetShaderInfoNotProgram(
6561 shader_id, "glTranslatedGetShaderSourceANGLE");
6562 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366563 bucket->SetSize(0);
6564 return error::kNoError;
6565 }
[email protected]df37b9932013-03-08 05:21:426566 ForceCompileShaderIfPending(shader);
[email protected]d6a53e42011-10-05 00:09:366567
[email protected]df37b9932013-03-08 05:21:426568 bucket->SetFromString(shader->translated_source() ?
6569 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366570 return error::kNoError;
6571}
6572
[email protected]ae51d192010-04-27 00:48:036573error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356574 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426575 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586576 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6577 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426578 Program* program = GetProgramInfoNotShader(
6579 program_id, "glGetProgramInfoLog");
6580 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466581 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036582 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316583 }
[email protected]df37b9932013-03-08 05:21:426584 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036585 return error::kNoError;
6586}
6587
6588error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356589 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426590 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586591 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6592 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426593 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6594 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466595 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036596 return error::kNoError;
6597 }
[email protected]df37b9932013-03-08 05:21:426598 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036599 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326600}
6601
[email protected]d058bca2012-11-26 10:27:266602bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6603 return state_.GetEnabled(cap);
6604}
6605
[email protected]1958e0e2010-04-22 05:17:156606bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216607 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106608 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156609}
6610
6611bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356612 const Framebuffer* framebuffer =
6613 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106614 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156615}
6616
6617bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366618 // IsProgram is true for programs as soon as they are created, until they are
6619 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356620 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106621 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156622}
6623
6624bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356625 const Renderbuffer* renderbuffer =
6626 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106627 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156628}
6629
6630bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366631 // IsShader is true for shaders as soon as they are created, until they
6632 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356633 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106634 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156635}
6636
6637bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356638 const Texture* texture = GetTexture(client_id);
[email protected]a0b78dc2011-11-11 10:43:106639 return texture && texture->IsValid() && !texture->IsDeleted();
[email protected]ae51d192010-04-27 00:48:036640}
6641
6642void GLES2DecoderImpl::DoAttachShader(
6643 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426644 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586645 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426646 if (!program) {
[email protected]ae51d192010-04-27 00:48:036647 return;
[email protected]1958e0e2010-04-22 05:17:156648 }
[email protected]df37b9932013-03-08 05:21:426649 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6650 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036651 return;
6652 }
[email protected]df37b9932013-03-08 05:21:426653 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516654 LOCAL_SET_GL_ERROR(
6655 GL_INVALID_OPERATION,
6656 "glAttachShader",
6657 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316658 return;
6659 }
[email protected]df37b9932013-03-08 05:21:426660 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036661}
6662
6663void GLES2DecoderImpl::DoDetachShader(
6664 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426665 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586666 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426667 if (!program) {
[email protected]ae51d192010-04-27 00:48:036668 return;
6669 }
[email protected]df37b9932013-03-08 05:21:426670 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6671 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036672 return;
6673 }
[email protected]df37b9932013-03-08 05:21:426674 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516675 LOCAL_SET_GL_ERROR(
6676 GL_INVALID_OPERATION,
6677 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226678 return;
6679 }
[email protected]df37b9932013-03-08 05:21:426680 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036681}
6682
6683void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426684 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586685 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426686 if (!program) {
[email protected]ae51d192010-04-27 00:48:036687 return;
6688 }
[email protected]df37b9932013-03-08 05:21:426689 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156690}
6691
[email protected]ac77603c72013-03-08 13:52:066692void GLES2DecoderImpl::GetVertexAttribHelper(
6693 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246694 switch (pname) {
6695 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066696 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246697 if (buffer && !buffer->IsDeleted()) {
6698 GLuint client_id;
6699 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6700 *params = client_id;
6701 }
6702 break;
6703 }
6704 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066705 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246706 break;
6707 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066708 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246709 break;
6710 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066711 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246712 break;
6713 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066714 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246715 break;
6716 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066717 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246718 break;
[email protected]c6aef902012-02-14 03:31:426719 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066720 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426721 break;
[email protected]ac77603c72013-03-08 13:52:066722 default:
6723 NOTREACHED();
6724 break;
6725 }
6726}
6727
6728void GLES2DecoderImpl::DoGetVertexAttribfv(
6729 GLuint index, GLenum pname, GLfloat* params) {
6730 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6731 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516732 LOCAL_SET_GL_ERROR(
6733 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066734 return;
6735 }
6736 switch (pname) {
6737 case GL_CURRENT_VERTEX_ATTRIB: {
6738 const Vec4& value = state_.attrib_values[index];
6739 params[0] = value.v[0];
6740 params[1] = value.v[1];
6741 params[2] = value.v[2];
6742 params[3] = value.v[3];
6743 break;
6744 }
6745 default: {
6746 GLint value = 0;
6747 GetVertexAttribHelper(attrib, pname, &value);
6748 *params = static_cast<GLfloat>(value);
6749 break;
6750 }
6751 }
6752}
6753
6754void GLES2DecoderImpl::DoGetVertexAttribiv(
6755 GLuint index, GLenum pname, GLint* params) {
6756 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6757 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516758 LOCAL_SET_GL_ERROR(
6759 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066760 return;
6761 }
6762 switch (pname) {
[email protected]af6380962012-11-29 23:24:136763 case GL_CURRENT_VERTEX_ATTRIB: {
6764 const Vec4& value = state_.attrib_values[index];
6765 params[0] = static_cast<GLint>(value.v[0]);
6766 params[1] = static_cast<GLint>(value.v[1]);
6767 params[2] = static_cast<GLint>(value.v[2]);
6768 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246769 break;
[email protected]af6380962012-11-29 23:24:136770 }
[email protected]b1122982010-05-17 23:04:246771 default:
[email protected]ac77603c72013-03-08 13:52:066772 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246773 break;
6774 }
6775}
6776
[email protected]af6380962012-11-29 23:24:136777bool GLES2DecoderImpl::SetVertexAttribValue(
6778 const char* function_name, GLuint index, const GLfloat* value) {
6779 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516780 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136781 return false;
[email protected]b1122982010-05-17 23:04:246782 }
[email protected]af6380962012-11-29 23:24:136783 Vec4& v = state_.attrib_values[index];
6784 v.v[0] = value[0];
6785 v.v[1] = value[1];
6786 v.v[2] = value[2];
6787 v.v[3] = value[3];
6788 return true;
6789}
6790
6791void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6792 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6793 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6794 glVertexAttrib1f(index, v0);
6795 }
[email protected]b1122982010-05-17 23:04:246796}
6797
6798void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136799 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6800 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6801 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246802 }
[email protected]b1122982010-05-17 23:04:246803}
6804
6805void GLES2DecoderImpl::DoVertexAttrib3f(
6806 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136807 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6808 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6809 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246810 }
[email protected]b1122982010-05-17 23:04:246811}
6812
6813void GLES2DecoderImpl::DoVertexAttrib4f(
6814 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136815 GLfloat v[4] = { v0, v1, v2, v3, };
6816 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6817 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246818 }
[email protected]b1122982010-05-17 23:04:246819}
6820
6821void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136822 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6823 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6824 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246825 }
[email protected]b1122982010-05-17 23:04:246826}
6827
6828void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136829 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6830 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6831 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246832 }
[email protected]b1122982010-05-17 23:04:246833}
6834
6835void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136836 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6837 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6838 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246839 }
[email protected]b1122982010-05-17 23:04:246840}
6841
6842void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136843 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6844 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246845 }
[email protected]b1122982010-05-17 23:04:246846}
6847
[email protected]f7a64ee2010-02-01 22:24:146848error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:356849 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466850
[email protected]e259eb412012-10-13 05:47:246851 if (!state_.bound_array_buffer || state_.bound_array_buffer->IsDeleted()) {
6852 if (state_.vertex_attrib_manager == default_vertex_attrib_manager_) {
[email protected]ab09b612013-03-11 22:11:516853 LOCAL_SET_GL_ERROR(
6854 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:466855 return error::kNoError;
6856 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:516857 LOCAL_SET_GL_ERROR(
6858 GL_INVALID_VALUE,
6859 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:466860 return error::kNoError;
6861 }
[email protected]96449d2c2009-11-25 00:01:326862 }
[email protected]8eee29c2010-04-29 03:38:296863
6864 GLuint indx = c.indx;
6865 GLint size = c.size;
6866 GLenum type = c.type;
6867 GLboolean normalized = c.normalized;
6868 GLsizei stride = c.stride;
6869 GLsizei offset = c.offset;
6870 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056871 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516872 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296873 return error::kNoError;
6874 }
[email protected]9438b012010-06-15 22:55:056875 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:516876 LOCAL_SET_GL_ERROR(
6877 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296878 return error::kNoError;
6879 }
6880 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516881 LOCAL_SET_GL_ERROR(
6882 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296883 return error::kNoError;
6884 }
6885 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:516886 LOCAL_SET_GL_ERROR(
6887 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296888 return error::kNoError;
6889 }
6890 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:516891 LOCAL_SET_GL_ERROR(
6892 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296893 return error::kNoError;
6894 }
6895 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516896 LOCAL_SET_GL_ERROR(
6897 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296898 return error::kNoError;
6899 }
6900 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316901 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296902 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516903 LOCAL_SET_GL_ERROR(
6904 GL_INVALID_OPERATION,
6905 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316906 return error::kNoError;
6907 }
6908 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516909 LOCAL_SET_GL_ERROR(
6910 GL_INVALID_OPERATION,
6911 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296912 return error::kNoError;
6913 }
[email protected]e259eb412012-10-13 05:47:246914 state_.vertex_attrib_manager->SetAttribInfo(
[email protected]8fbedc02010-11-18 18:43:406915 indx,
[email protected]e259eb412012-10-13 05:47:246916 state_.bound_array_buffer,
[email protected]8eee29c2010-04-29 03:38:296917 size,
6918 type,
[email protected]b1122982010-05-17 23:04:246919 normalized,
6920 stride,
6921 stride != 0 ? stride : component_size * size,
[email protected]8eee29c2010-04-29 03:38:296922 offset);
[email protected]8fbedc02010-11-18 18:43:406923 if (type != GL_FIXED) {
6924 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6925 }
[email protected]f7a64ee2010-02-01 22:24:146926 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326927}
6928
[email protected]43410e92012-04-20 17:06:286929void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6930 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246931 state_.viewport_x = x;
6932 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026933 state_.viewport_width = std::min(width, viewport_max_width_);
6934 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286935 glViewport(x, y, width, height);
6936}
6937
[email protected]c6aef902012-02-14 03:31:426938error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356939 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156940 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516941 LOCAL_SET_GL_ERROR(
6942 GL_INVALID_OPERATION,
6943 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426944 }
6945 GLuint index = c.index;
6946 GLuint divisor = c.divisor;
6947 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516948 LOCAL_SET_GL_ERROR(
6949 GL_INVALID_VALUE,
6950 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426951 return error::kNoError;
6952 }
6953
[email protected]e259eb412012-10-13 05:47:246954 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426955 index,
6956 divisor);
6957 glVertexAttribDivisorANGLE(index, divisor);
6958 return error::kNoError;
6959}
6960
[email protected]f7a64ee2010-02-01 22:24:146961error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:356962 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:446963 if (ShouldDeferReads())
6964 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:316965 GLint x = c.x;
6966 GLint y = c.y;
6967 GLsizei width = c.width;
6968 GLsizei height = c.height;
6969 GLenum format = c.format;
6970 GLenum type = c.type;
[email protected]57f223832010-03-19 01:57:566971 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:516972 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566973 return error::kNoError;
6974 }
[email protected]ed9f9cd2013-02-27 21:12:356975 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186976 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346977 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246978 width, height, format, type, state_.pack_alignment, &pixels_size,
6979 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186980 return error::kOutOfBounds;
6981 }
[email protected]612d2f82009-12-08 20:49:316982 void* pixels = GetSharedMemoryAs<void*>(
6983 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:106984 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:146985 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466986 }
[email protected]de43f082013-04-02 01:16:106987 Result* result = NULL;
6988 if (c.result_shm_id != 0) {
6989 result = GetSharedMemoryAs<Result*>(
6990 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6991 if (!result) {
6992 return error::kOutOfBounds;
6993 }
6994 }
[email protected]a51788e2010-02-24 21:54:256995
[email protected]9438b012010-06-15 22:55:056996 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:516997 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296998 return error::kNoError;
6999 }
[email protected]9438b012010-06-15 22:55:057000 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517001 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127002 return error::kNoError;
7003 }
[email protected]57f223832010-03-19 01:57:567004 if (width == 0 || height == 0) {
7005 return error::kNoError;
7006 }
7007
[email protected]57f223832010-03-19 01:57:567008 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307009 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567010
[email protected]3aad1a32012-09-07 20:54:477011 int32 max_x;
7012 int32 max_y;
7013 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517014 LOCAL_SET_GL_ERROR(
7015 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147016 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317017 }
[email protected]57f223832010-03-19 01:57:567018
[email protected]0d6bfdc2011-11-02 01:32:207019 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7020 return error::kNoError;
7021 }
7022
[email protected]ab09b612013-03-11 22:11:517023 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel");
[email protected]a0b78dc2011-11-11 10:43:107024
7025 ScopedResolvedFrameBufferBinder binder(this, false, true);
7026
[email protected]d37231fa2010-04-09 21:16:027027 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567028 // The user requested an out of range area. Get the results 1 line
7029 // at a time.
7030 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347031 uint32 unpadded_row_size;
7032 uint32 padded_row_size;
7033 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247034 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347035 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517036 LOCAL_SET_GL_ERROR(
7037 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567038 return error::kNoError;
7039 }
7040
7041 GLint dest_x_offset = std::max(-x, 0);
7042 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347043 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247044 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7045 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517046 LOCAL_SET_GL_ERROR(
7047 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567048 return error::kNoError;
7049 }
7050
7051 // Copy each row into the larger dest rect.
7052 int8* dst = static_cast<int8*>(pixels);
7053 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027054 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567055 GLint read_width = read_end_x - read_x;
7056 for (GLint yy = 0; yy < height; ++yy) {
7057 GLint ry = y + yy;
7058
7059 // Clear the row.
7060 memset(dst, 0, unpadded_row_size);
7061
7062 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027063 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567064 glReadPixels(
7065 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7066 }
7067 dst += padded_row_size;
7068 }
7069 } else {
7070 glReadPixels(x, y, width, height, format, type, pixels);
7071 }
[email protected]ab09b612013-03-11 22:11:517072 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257073 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107074 if (result != NULL) {
7075 *result = true;
7076 }
[email protected]4848b9f82011-03-10 18:37:567077
7078 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7079 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
[email protected]84eb4252012-06-29 22:56:447080 if ((channels_exist & 0x0008) == 0 &&
[email protected]62e155e2012-10-23 22:43:157081 workarounds().clear_alpha_in_readpixels) {
[email protected]4848b9f82011-03-10 18:37:567082 // Set the alpha to 255 because some drivers are buggy in this regard.
7083 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347084
7085 uint32 unpadded_row_size;
7086 uint32 padded_row_size;
7087 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247088 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347089 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517090 LOCAL_SET_GL_ERROR(
7091 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]4848b9f82011-03-10 18:37:567092 return error::kNoError;
7093 }
7094 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
7095 // of this implementation.
7096 if (type != GL_UNSIGNED_BYTE) {
[email protected]ab09b612013-03-11 22:11:517097 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437098 GL_INVALID_OPERATION, "glReadPixels",
7099 "unsupported readPixel format");
[email protected]4848b9f82011-03-10 18:37:567100 return error::kNoError;
7101 }
7102 switch (format) {
7103 case GL_RGBA:
[email protected]297ca1c2011-06-20 23:08:467104 case GL_BGRA_EXT:
[email protected]4848b9f82011-03-10 18:37:567105 case GL_ALPHA: {
7106 int offset = (format == GL_ALPHA) ? 0 : 3;
7107 int step = (format == GL_ALPHA) ? 1 : 4;
7108 uint8* dst = static_cast<uint8*>(pixels) + offset;
7109 for (GLint yy = 0; yy < height; ++yy) {
7110 uint8* end = dst + unpadded_row_size;
7111 for (uint8* d = dst; d < end; d += step) {
7112 *d = 255;
7113 }
7114 dst += padded_row_size;
7115 }
7116 break;
7117 }
7118 default:
7119 break;
7120 }
7121 }
[email protected]a51788e2010-02-24 21:54:257122 }
[email protected]4848b9f82011-03-10 18:37:567123
[email protected]f7a64ee2010-02-01 22:24:147124 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327125}
7126
[email protected]f7a64ee2010-02-01 22:24:147127error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:357128 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:197129 GLenum pname = c.pname;
7130 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057131 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517132 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127133 return error::kNoError;
7134 }
[email protected]222471d2011-11-30 18:06:397135 switch (pname) {
7136 case GL_PACK_ALIGNMENT:
7137 case GL_UNPACK_ALIGNMENT:
7138 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517139 LOCAL_SET_GL_ERROR(
7140 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397141 return error::kNoError;
7142 }
[email protected]164d6d52012-05-05 00:55:037143 break;
[email protected]0a1e9ad2012-05-04 21:13:037144 case GL_UNPACK_FLIP_Y_CHROMIUM:
7145 unpack_flip_y_ = (param != 0);
7146 return error::kNoError;
7147 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7148 unpack_premultiply_alpha_ = (param != 0);
7149 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177150 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7151 unpack_unpremultiply_alpha_ = (param != 0);
7152 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397153 default:
7154 break;
[email protected]b9849abf2009-11-25 19:13:197155 }
7156 glPixelStorei(pname, param);
7157 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437158 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247159 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437160 break;
7161 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427162 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437163 break;
7164 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247165 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437166 break;
7167 default:
7168 // Validation should have prevented us from getting here.
7169 NOTREACHED();
7170 break;
[email protected]b9849abf2009-11-25 19:13:197171 }
[email protected]f7a64ee2010-02-01 22:24:147172 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197173}
7174
[email protected]1c75a3702011-11-11 14:15:287175error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:357176 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:387177 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:457178 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:517179 LOCAL_SET_GL_ERROR(
7180 GL_INVALID_OPERATION,
7181 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287182 return error::kNoError;
7183 }
[email protected]7794d512012-04-17 20:36:497184 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287185 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497186 } else {
7187 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287188 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497189 }
[email protected]1c75a3702011-11-11 14:15:287190}
7191
[email protected]558847a2010-03-24 07:02:547192error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7193 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7194 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577195 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517196 LOCAL_SET_GL_ERROR(
7197 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577198 return error::kNoError;
7199 }
[email protected]df37b9932013-03-08 05:21:427200 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587201 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427202 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147203 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197204 }
[email protected]df37b9932013-03-08 05:21:427205 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517206 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437207 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257208 return error::kNoError;
7209 }
[email protected]b9849abf2009-11-25 19:13:197210 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547211 location_shm_id, location_shm_offset, sizeof(GLint));
7212 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147213 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197214 }
[email protected]558847a2010-03-24 07:02:547215 // Require the client to init this incase the context is lost and we are no
7216 // longer executing commands.
7217 if (*location != -1) {
7218 return error::kGenericError;
7219 }
[email protected]df37b9932013-03-08 05:21:427220 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147221 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197222}
7223
[email protected]558847a2010-03-24 07:02:547224error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357225 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547226 uint32 name_size = c.data_size;
7227 const char* name = GetSharedMemoryAs<const char*>(
7228 c.name_shm_id, c.name_shm_offset, name_size);
7229 if (!name) {
7230 return error::kOutOfBounds;
7231 }
7232 String name_str(name, name_size);
7233 return GetAttribLocationHelper(
7234 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7235}
7236
[email protected]f7a64ee2010-02-01 22:24:147237error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357238 uint32 immediate_data_size, const cmds::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:547239 uint32 name_size = c.data_size;
7240 const char* name = GetImmediateDataAs<const char*>(
7241 c, name_size, immediate_data_size);
7242 if (!name) {
7243 return error::kOutOfBounds;
7244 }
7245 String name_str(name, name_size);
7246 return GetAttribLocationHelper(
7247 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7248}
7249
7250error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357251 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547252 Bucket* bucket = GetBucket(c.name_bucket_id);
7253 if (!bucket) {
7254 return error::kInvalidArguments;
7255 }
7256 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187257 if (!bucket->GetAsString(&name_str)) {
7258 return error::kInvalidArguments;
7259 }
[email protected]558847a2010-03-24 07:02:547260 return GetAttribLocationHelper(
7261 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7262}
7263
7264error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7265 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7266 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577267 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517268 LOCAL_SET_GL_ERROR(
7269 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577270 return error::kNoError;
7271 }
[email protected]df37b9932013-03-08 05:21:427272 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587273 client_id, "glUniformLocation");
[email protected]df37b9932013-03-08 05:21:427274 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147275 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197276 }
[email protected]df37b9932013-03-08 05:21:427277 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517278 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437279 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257280 return error::kNoError;
7281 }
[email protected]b9849abf2009-11-25 19:13:197282 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547283 location_shm_id, location_shm_offset, sizeof(GLint));
7284 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147285 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197286 }
[email protected]558847a2010-03-24 07:02:547287 // Require the client to init this incase the context is lost an we are no
7288 // longer executing commands.
7289 if (*location != -1) {
7290 return error::kGenericError;
7291 }
[email protected]df37b9932013-03-08 05:21:427292 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147293 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197294}
7295
[email protected]f7a64ee2010-02-01 22:24:147296error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357297 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197298 uint32 name_size = c.data_size;
7299 const char* name = GetSharedMemoryAs<const char*>(
7300 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547301 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147302 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197303 }
7304 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547305 return GetUniformLocationHelper(
7306 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197307}
7308
[email protected]f7a64ee2010-02-01 22:24:147309error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357310 uint32 immediate_data_size, const cmds::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197311 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:307312 const char* name = GetImmediateDataAs<const char*>(
7313 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:547314 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147315 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197316 }
7317 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547318 return GetUniformLocationHelper(
7319 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7320}
7321
7322error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357323 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547324 Bucket* bucket = GetBucket(c.name_bucket_id);
7325 if (!bucket) {
7326 return error::kInvalidArguments;
7327 }
7328 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187329 if (!bucket->GetAsString(&name_str)) {
7330 return error::kInvalidArguments;
7331 }
[email protected]558847a2010-03-24 07:02:547332 return GetUniformLocationHelper(
7333 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197334}
7335
[email protected]ddd968b82010-03-02 00:44:297336error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357337 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297338 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057339 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517340 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297341 return error::kNoError;
7342 }
[email protected]1958e0e2010-04-22 05:17:157343 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
7344 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:047345 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157346 switch (name) {
7347 case GL_VERSION:
7348 str = "OpenGL ES 2.0 Chromium";
7349 break;
7350 case GL_SHADING_LANGUAGE_VERSION:
7351 str = "OpenGL ES GLSL ES 1.0 Chromium";
7352 break;
[email protected]32939602012-05-09 06:25:167353 case GL_RENDERER:
7354 str = "Chromium";
7355 break;
7356 case GL_VENDOR:
7357 str = "Chromium";
7358 break;
[email protected]1958e0e2010-04-22 05:17:157359 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047360 {
7361 // For WebGL contexts, strip out the OES derivatives extension if it has
7362 // not been enabled.
7363 if (force_webgl_glsl_validation_ &&
7364 !derivatives_explicitly_enabled_) {
7365 extensions = feature_info_->extensions();
7366 size_t offset = extensions.find(kOESDerivativeExtension);
7367 if (std::string::npos != offset) {
7368 extensions.replace(offset,
7369 offset + arraysize(kOESDerivativeExtension),
7370 std::string());
7371 }
[email protected]f0d74742011-10-03 16:31:047372 } else {
[email protected]6f5fac9d12012-06-26 21:02:457373 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047374 }
[email protected]6f5fac9d12012-06-26 21:02:457375 std::string surface_extensions = surface_->GetExtensions();
7376 if (!surface_extensions.empty())
7377 extensions += " " + surface_extensions;
7378 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047379 }
[email protected]1958e0e2010-04-22 05:17:157380 break;
7381 default:
7382 str = gl_str;
7383 break;
7384 }
[email protected]ddd968b82010-03-02 00:44:297385 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157386 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297387 return error::kNoError;
7388}
7389
[email protected]0c86dbf2010-03-05 08:14:117390void GLES2DecoderImpl::DoBufferData(
[email protected]b9363b22010-06-09 22:06:157391 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
[email protected]9438b012010-06-15 22:55:057392 if (!validators_->buffer_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517393 LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferData", target, "target");
[email protected]8eee29c2010-04-29 03:38:297394 return;
7395 }
[email protected]9438b012010-06-15 22:55:057396 if (!validators_->buffer_usage.IsValid(usage)) {
[email protected]ab09b612013-03-11 22:11:517397 LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferData", usage, "usage");
[email protected]0c86dbf2010-03-05 08:14:117398 return;
[email protected]3b6ec202010-03-05 05:16:237399 }
7400 if (size < 0) {
[email protected]ab09b612013-03-11 22:11:517401 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferData", "size < 0");
[email protected]037896bd2010-04-21 19:07:287402 return;
[email protected]3b6ec202010-03-05 05:16:237403 }
[email protected]17cfbe0e2013-03-07 01:26:087404 Buffer* buffer = GetBufferInfoForTarget(target);
7405 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:517406 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287407 return;
[email protected]3b6ec202010-03-05 05:16:237408 }
[email protected]7989c9e2013-01-23 06:39:267409
7410 if (!EnsureGPUMemoryAvailable(size)) {
[email protected]ab09b612013-03-11 22:11:517411 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glBufferData", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267412 return;
7413 }
7414
[email protected]17cfbe0e2013-03-07 01:26:087415 buffer_manager()->DoBufferData(this, buffer, size, usage, data);
[email protected]0c86dbf2010-03-05 08:14:117416}
7417
7418error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357419 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117420 GLenum target = static_cast<GLenum>(c.target);
7421 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7422 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7423 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7424 GLenum usage = static_cast<GLenum>(c.usage);
7425 const void* data = NULL;
7426 if (data_shm_id != 0 || data_shm_offset != 0) {
7427 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7428 if (!data) {
7429 return error::kOutOfBounds;
7430 }
7431 }
7432 DoBufferData(target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147433 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197434}
7435
[email protected]f7a64ee2010-02-01 22:24:147436error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357437 uint32 immediate_data_size, const cmds::BufferDataImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197438 GLenum target = static_cast<GLenum>(c.target);
7439 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:307440 const void* data = GetImmediateDataAs<const void*>(
7441 c, size, immediate_data_size);
7442 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147443 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:307444 }
[email protected]b9849abf2009-11-25 19:13:197445 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0c86dbf2010-03-05 08:14:117446 DoBufferData(target, size, data, usage);
7447 return error::kNoError;
7448}
7449
7450void GLES2DecoderImpl::DoBufferSubData(
7451 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]17cfbe0e2013-03-07 01:26:087452 Buffer* buffer = GetBufferInfoForTarget(target);
7453 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:517454 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287455 return;
[email protected]a93bb842010-02-16 23:03:477456 }
[email protected]17cfbe0e2013-03-07 01:26:087457
7458 buffer_manager()->DoBufferSubData(this, buffer, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197459}
7460
[email protected]0d6bfdc2011-11-02 01:32:207461bool GLES2DecoderImpl::ClearLevel(
7462 unsigned service_id,
7463 unsigned bind_target,
7464 unsigned target,
7465 int level,
7466 unsigned format,
7467 unsigned type,
7468 int width,
[email protected]4502e6492011-12-14 19:39:157469 int height,
7470 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007471 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7472 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7473 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7474 // on depth formats.
7475 GLuint fb = 0;
7476 glGenFramebuffersEXT(1, &fb);
7477 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7478
7479 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7480 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7481 GL_DEPTH_ATTACHMENT;
7482
7483 glFramebufferTexture2DEXT(
7484 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7485 // ANGLE promises a depth only attachment ok.
7486 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7487 GL_FRAMEBUFFER_COMPLETE) {
7488 return false;
7489 }
7490 glClearStencil(0);
7491 glStencilMask(-1);
7492 glClearDepth(1.0f);
7493 glDepthMask(true);
7494 glDisable(GL_SCISSOR_TEST);
7495 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7496
7497 RestoreClearState();
7498
7499 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357500 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007501 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7502 GLuint fb_service_id =
7503 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7504 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7505 return true;
7506 }
7507
[email protected]45d15a62012-04-18 14:33:177508 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7509
7510 uint32 size;
7511 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347512 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247513 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177514 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207515 return false;
7516 }
[email protected]45d15a62012-04-18 14:33:177517
[email protected]a5d3dad2012-05-26 04:34:447518 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7519
[email protected]45d15a62012-04-18 14:33:177520 int tile_height;
7521
7522 if (size > kMaxZeroSize) {
7523 if (kMaxZeroSize < padded_row_size) {
7524 // That'd be an awfully large texture.
7525 return false;
7526 }
7527 // We should never have a large total size with a zero row size.
7528 DCHECK_GT(padded_row_size, 0U);
7529 tile_height = kMaxZeroSize / padded_row_size;
7530 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247531 width, tile_height, format, type, state_.unpack_alignment, &size,
7532 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177533 return false;
7534 }
[email protected]4502e6492011-12-14 19:39:157535 } else {
[email protected]45d15a62012-04-18 14:33:177536 tile_height = height;
7537 }
7538
7539 // Assumes the size has already been checked.
7540 scoped_array<char> zero(new char[size]);
7541 memset(zero.get(), 0, size);
7542 glBindTexture(bind_target, service_id);
7543
7544 GLint y = 0;
7545 while (y < height) {
7546 GLint h = y + tile_height > height ? height - y : tile_height;
7547 if (is_texture_immutable || h != height) {
7548 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7549 } else {
7550 WrappedTexImage2D(
7551 target, level, format, width, h, 0, format, type, zero.get());
7552 }
7553 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157554 }
[email protected]02965c22013-03-09 02:40:077555 Texture* texture = GetTextureInfoForTarget(bind_target);
7556 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207557 return true;
7558}
7559
[email protected]ad84a3a2012-06-08 21:42:437560namespace {
7561
7562const int kS3TCBlockWidth = 4;
7563const int kS3TCBlockHeight = 4;
7564const int kS3TCDXT1BlockSize = 8;
7565const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077566const int kETC1BlockWidth = 4;
7567const int kETC1BlockHeight = 4;
7568const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437569
7570bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517571 return (size == 1) ||
7572 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437573}
7574
7575} // anonymous namespace.
7576
7577bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7578 const char* function_name,
7579 GLsizei width, GLsizei height, GLenum format, size_t size) {
7580 unsigned int bytes_required = 0;
7581
7582 switch (format) {
7583 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7584 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7585 int num_blocks_across =
7586 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7587 int num_blocks_down =
7588 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7589 int num_blocks = num_blocks_across * num_blocks_down;
7590 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7591 break;
7592 }
7593 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7594 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7595 int num_blocks_across =
7596 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7597 int num_blocks_down =
7598 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7599 int num_blocks = num_blocks_across * num_blocks_down;
7600 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7601 break;
7602 }
[email protected]2d3765b2012-10-03 00:31:077603 case GL_ETC1_RGB8_OES: {
7604 int num_blocks_across =
7605 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7606 int num_blocks_down =
7607 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7608 int num_blocks = num_blocks_across * num_blocks_down;
7609 bytes_required = num_blocks * kETC1BlockSize;
7610 break;
7611 }
[email protected]ad84a3a2012-06-08 21:42:437612 default:
[email protected]ab09b612013-03-11 22:11:517613 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437614 return false;
7615 }
7616
7617 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517618 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437619 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7620 return false;
7621 }
7622
7623 return true;
7624}
7625
7626bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7627 const char* function_name,
7628 GLint level, GLsizei width, GLsizei height, GLenum format) {
7629 switch (format) {
7630 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7631 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7632 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7633 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7634 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517635 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437636 GL_INVALID_OPERATION, function_name,
7637 "width or height invalid for level");
7638 return false;
7639 }
7640 return true;
7641 }
[email protected]2d3765b2012-10-03 00:31:077642 case GL_ETC1_RGB8_OES:
7643 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517644 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077645 GL_INVALID_OPERATION, function_name,
7646 "width or height invalid for level");
7647 return false;
7648 }
7649 return true;
[email protected]ad84a3a2012-06-08 21:42:437650 default:
7651 return false;
7652 }
7653}
7654
7655bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7656 const char* function_name,
7657 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7658 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357659 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437660 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517661 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437662 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7663 return false;
7664 }
7665
7666 switch (format) {
7667 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7668 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7669 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7670 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7671 const int kBlockWidth = 4;
7672 const int kBlockHeight = 4;
7673 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517674 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437675 GL_INVALID_OPERATION, function_name,
7676 "xoffset or yoffset not multiple of 4");
7677 return false;
7678 }
7679 GLsizei tex_width = 0;
7680 GLsizei tex_height = 0;
7681 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7682 width - xoffset > tex_width ||
7683 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517684 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437685 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7686 return false;
7687 }
7688 return ValidateCompressedTexDimensions(
7689 function_name, level, width, height, format);
7690 }
[email protected]2d3765b2012-10-03 00:31:077691 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517692 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077693 GL_INVALID_OPERATION, function_name,
7694 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7695 return false;
7696 }
[email protected]ad84a3a2012-06-08 21:42:437697 default:
7698 return false;
7699 }
7700}
7701
[email protected]a93bb842010-02-16 23:03:477702error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7703 GLenum target,
7704 GLint level,
7705 GLenum internal_format,
7706 GLsizei width,
7707 GLsizei height,
7708 GLint border,
7709 GLsizei image_size,
7710 const void* data) {
[email protected]a93bb842010-02-16 23:03:477711 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057712 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517713 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7714 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297715 return error::kNoError;
7716 }
[email protected]9438b012010-06-15 22:55:057717 if (!validators_->compressed_texture_format.IsValid(
7718 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517719 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537720 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477721 return error::kNoError;
7722 }
[email protected]80eb6b52012-01-19 00:14:417723 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477724 border != 0) {
[email protected]ab09b612013-03-11 22:11:517725 LOCAL_SET_GL_ERROR(
7726 GL_INVALID_VALUE,
7727 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477728 return error::kNoError;
7729 }
[email protected]02965c22013-03-09 02:40:077730 Texture* texture = GetTextureInfoForTarget(target);
7731 if (!texture) {
[email protected]ab09b612013-03-11 22:11:517732 LOCAL_SET_GL_ERROR(
7733 GL_INVALID_VALUE,
7734 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477735 return error::kNoError;
7736 }
[email protected]02965c22013-03-09 02:40:077737 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517738 LOCAL_SET_GL_ERROR(
7739 GL_INVALID_OPERATION,
7740 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:437741 return error::kNoError;
7742 }
7743
7744 if (!ValidateCompressedTexDimensions(
7745 "glCompressedTexImage2D", level, width, height, internal_format) ||
7746 !ValidateCompressedTexFuncData(
7747 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177748 return error::kNoError;
7749 }
[email protected]968351b2011-12-20 08:26:517750
[email protected]7989c9e2013-01-23 06:39:267751 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:517752 LOCAL_SET_GL_ERROR(
7753 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267754 return error::kNoError;
7755 }
7756
[email protected]02965c22013-03-09 02:40:077757 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427758 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517759 // TODO(gman): If textures tracked which framebuffers they were attached to
7760 // we could just mark those framebuffers as not complete.
7761 framebuffer_manager()->IncFramebufferStateChangeCount();
7762 }
7763
[email protected]a93bb842010-02-16 23:03:477764 scoped_array<int8> zero;
7765 if (!data) {
7766 zero.reset(new int8[image_size]);
7767 memset(zero.get(), 0, image_size);
7768 data = zero.get();
7769 }
[email protected]ab09b612013-03-11 22:11:517770 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:477771 glCompressedTexImage2D(
7772 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:517773 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437774 if (error == GL_NO_ERROR) {
7775 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:077776 texture, target, level, internal_format, width, height, 1, border, 0, 0,
[email protected]0d6bfdc2011-11-02 01:32:207777 true);
[email protected]cadde4a2010-07-31 17:10:437778 }
[email protected]a93bb842010-02-16 23:03:477779 return error::kNoError;
7780}
7781
[email protected]f7a64ee2010-02-01 22:24:147782error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357783 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:197784 GLenum target = static_cast<GLenum>(c.target);
7785 GLint level = static_cast<GLint>(c.level);
7786 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7787 GLsizei width = static_cast<GLsizei>(c.width);
7788 GLsizei height = static_cast<GLsizei>(c.height);
7789 GLint border = static_cast<GLint>(c.border);
7790 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7791 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7792 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7793 const void* data = NULL;
7794 if (data_shm_id != 0 || data_shm_offset != 0) {
7795 data = GetSharedMemoryAs<const void*>(
7796 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467797 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147798 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197799 }
7800 }
[email protected]a93bb842010-02-16 23:03:477801 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197802 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197803}
7804
[email protected]f7a64ee2010-02-01 22:24:147805error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357806 uint32 immediate_data_size, const cmds::CompressedTexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197807 GLenum target = static_cast<GLenum>(c.target);
7808 GLint level = static_cast<GLint>(c.level);
7809 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7810 GLsizei width = static_cast<GLsizei>(c.width);
7811 GLsizei height = static_cast<GLsizei>(c.height);
7812 GLint border = static_cast<GLint>(c.border);
7813 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307814 const void* data = GetImmediateDataAs<const void*>(
7815 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467816 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147817 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467818 }
[email protected]a93bb842010-02-16 23:03:477819 return DoCompressedTexImage2D(
7820 target, level, internal_format, width, height, border, image_size, data);
7821}
7822
[email protected]b6140d02010-05-17 14:47:167823error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:357824 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167825 GLenum target = static_cast<GLenum>(c.target);
7826 GLint level = static_cast<GLint>(c.level);
7827 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7828 GLsizei width = static_cast<GLsizei>(c.width);
7829 GLsizei height = static_cast<GLsizei>(c.height);
7830 GLint border = static_cast<GLint>(c.border);
7831 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287832 if (!bucket) {
7833 return error::kInvalidArguments;
7834 }
7835 uint32 data_size = bucket->size();
7836 GLsizei imageSize = data_size;
7837 const void* data = bucket->GetData(0, data_size);
7838 if (!data) {
7839 return error::kInvalidArguments;
7840 }
[email protected]b6140d02010-05-17 14:47:167841 return DoCompressedTexImage2D(
7842 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287843 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167844}
7845
7846error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7847 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:357848 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167849 GLenum target = static_cast<GLenum>(c.target);
7850 GLint level = static_cast<GLint>(c.level);
7851 GLint xoffset = static_cast<GLint>(c.xoffset);
7852 GLint yoffset = static_cast<GLint>(c.yoffset);
7853 GLsizei width = static_cast<GLsizei>(c.width);
7854 GLsizei height = static_cast<GLsizei>(c.height);
7855 GLenum format = static_cast<GLenum>(c.format);
7856 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287857 if (!bucket) {
7858 return error::kInvalidArguments;
7859 }
[email protected]b6140d02010-05-17 14:47:167860 uint32 data_size = bucket->size();
7861 GLsizei imageSize = data_size;
7862 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287863 if (!data) {
7864 return error::kInvalidArguments;
7865 }
[email protected]9438b012010-06-15 22:55:057866 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517867 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:537868 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167869 return error::kNoError;
7870 }
[email protected]9438b012010-06-15 22:55:057871 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517872 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7873 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057874 return error::kNoError;
7875 }
[email protected]b6140d02010-05-17 14:47:167876 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:517877 LOCAL_SET_GL_ERROR(
7878 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167879 return error::kNoError;
7880 }
7881 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:517882 LOCAL_SET_GL_ERROR(
7883 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167884 return error::kNoError;
7885 }
7886 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:517887 LOCAL_SET_GL_ERROR(
7888 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167889 return error::kNoError;
7890 }
[email protected]cadde4a2010-07-31 17:10:437891 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167892 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7893 return error::kNoError;
7894}
7895
[email protected]81375742012-06-08 00:04:007896bool GLES2DecoderImpl::ValidateTextureParameters(
7897 const char* function_name,
7898 GLenum target, GLenum format, GLenum type, GLint level) {
7899 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517900 LOCAL_SET_GL_ERROR(
7901 GL_INVALID_OPERATION, function_name,
7902 (std::string("invalid type ") +
7903 GLES2Util::GetStringEnum(type) + " for format " +
7904 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007905 return false;
7906 }
7907
7908 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7909 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
[email protected]ab09b612013-03-11 22:11:517910 LOCAL_SET_GL_ERROR(
7911 GL_INVALID_OPERATION, function_name,
7912 (std::string("invalid type ") +
7913 GLES2Util::GetStringEnum(type) + " for format " +
7914 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007915 return false;
7916 }
7917 return true;
7918}
7919
[email protected]f598f422012-12-07 08:30:037920bool GLES2DecoderImpl::ValidateTexImage2D(
7921 const char* function_name,
7922 GLenum target,
7923 GLint level,
7924 GLenum internal_format,
7925 GLsizei width,
7926 GLsizei height,
7927 GLint border,
7928 GLenum format,
7929 GLenum type,
7930 const void* pixels,
7931 uint32 pixels_size) {
[email protected]9438b012010-06-15 22:55:057932 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517933 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:037934 return false;
[email protected]8eee29c2010-04-29 03:38:297935 }
[email protected]9438b012010-06-15 22:55:057936 if (!validators_->texture_format.IsValid(internal_format)) {
[email protected]ab09b612013-03-11 22:11:517937 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7938 function_name, internal_format, "internal_format");
[email protected]f598f422012-12-07 08:30:037939 return false;
[email protected]8eee29c2010-04-29 03:38:297940 }
[email protected]9438b012010-06-15 22:55:057941 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517942 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:037943 return false;
[email protected]8eee29c2010-04-29 03:38:297944 }
[email protected]9438b012010-06-15 22:55:057945 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517946 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:037947 return false;
[email protected]b9849abf2009-11-25 19:13:197948 }
[email protected]7b92c412010-07-20 17:48:257949 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:517950 LOCAL_SET_GL_ERROR(
7951 GL_INVALID_OPERATION, function_name, "format != internalFormat");
[email protected]f598f422012-12-07 08:30:037952 return false;
[email protected]7b92c412010-07-20 17:48:257953 }
[email protected]f598f422012-12-07 08:30:037954 if (!ValidateTextureParameters(function_name, target, format, type, level)) {
7955 return false;
[email protected]81375742012-06-08 00:04:007956 }
[email protected]80eb6b52012-01-19 00:14:417957 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477958 border != 0) {
[email protected]ab09b612013-03-11 22:11:517959 LOCAL_SET_GL_ERROR(
7960 GL_INVALID_VALUE, function_name, "dimensions out of range");
[email protected]f598f422012-12-07 08:30:037961 return false;
[email protected]a93bb842010-02-16 23:03:477962 }
[email protected]81375742012-06-08 00:04:007963 if ((GLES2Util::GetChannelsForFormat(format) &
7964 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
[email protected]ab09b612013-03-11 22:11:517965 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:007966 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037967 function_name, "can not supply data for depth or stencil textures");
7968 return false;
[email protected]81375742012-06-08 00:04:007969 }
[email protected]02965c22013-03-09 02:40:077970 Texture* texture = GetTextureInfoForTarget(target);
7971 if (!texture) {
[email protected]ab09b612013-03-11 22:11:517972 LOCAL_SET_GL_ERROR(
7973 GL_INVALID_OPERATION, function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:037974 return false;
[email protected]a93bb842010-02-16 23:03:477975 }
[email protected]02965c22013-03-09 02:40:077976 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517977 LOCAL_SET_GL_ERROR(
7978 GL_INVALID_OPERATION, function_name, "texture is immutable");
[email protected]f598f422012-12-07 08:30:037979 return false;
[email protected]97dc7cbe2011-12-06 17:26:177980 }
[email protected]f598f422012-12-07 08:30:037981 return true;
7982}
[email protected]97dc7cbe2011-12-06 17:26:177983
[email protected]f598f422012-12-07 08:30:037984void GLES2DecoderImpl::DoTexImage2D(
7985 GLenum target,
7986 GLint level,
7987 GLenum internal_format,
7988 GLsizei width,
7989 GLsizei height,
7990 GLint border,
7991 GLenum format,
7992 GLenum type,
7993 const void* pixels,
7994 uint32 pixels_size) {
7995 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format,
7996 width, height, border, format, type, pixels, pixels_size)) {
7997 return;
7998 }
[email protected]7989c9e2013-01-23 06:39:267999
8000 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:518001 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268002 return;
8003 }
8004
[email protected]02965c22013-03-09 02:40:078005 Texture* texture = GetTextureInfoForTarget(target);
[email protected]0226c112011-07-22 03:25:078006 GLsizei tex_width = 0;
8007 GLsizei tex_height = 0;
8008 GLenum tex_type = 0;
8009 GLenum tex_format = 0;
8010 bool level_is_same =
[email protected]02965c22013-03-09 02:40:078011 texture->GetLevelSize(target, level, &tex_width, &tex_height) &&
8012 texture->GetLevelType(target, level, &tex_type, &tex_format) &&
[email protected]0226c112011-07-22 03:25:078013 width == tex_width && height == tex_height &&
8014 type == tex_type && format == tex_format;
8015
8016 if (level_is_same && !pixels) {
[email protected]02965c22013-03-09 02:40:078017 // Just set the level texture but mark the texture as uncleared.
[email protected]1bed6222011-12-21 11:21:398018 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:078019 texture,
[email protected]1bed6222011-12-21 11:21:398020 target, level, internal_format, width, height, 1, border, format, type,
8021 false);
[email protected]ea72ed222011-08-17 18:58:438022 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:038023 return;
[email protected]0226c112011-07-22 03:25:078024 }
8025
[email protected]02965c22013-03-09 02:40:078026 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:428027 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:518028 // TODO(gman): If textures tracked which framebuffers they were attached to
8029 // we could just mark those framebuffers as not complete.
8030 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:468031 }
8032
[email protected]1bed6222011-12-21 11:21:398033 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) {
[email protected]0226c112011-07-22 03:25:078034 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
[email protected]02965c22013-03-09 02:40:078035 texture_manager()->SetLevelCleared(texture, target, level, true);
[email protected]0226c112011-07-22 03:25:078036 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:038037 return;
[email protected]7488d962010-07-16 02:41:588038 }
[email protected]876f6fee2010-08-02 23:10:328039
[email protected]ab09b612013-03-11 22:11:518040 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexImage2D");
[email protected]473c01ccb2011-06-07 01:33:308041 WrappedTexImage2D(
8042 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:478043 pixels);
[email protected]ab09b612013-03-11 22:11:518044 GLenum error = LOCAL_PEEK_GL_ERROR("glTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438045 if (error == GL_NO_ERROR) {
[email protected]0d6bfdc2011-11-02 01:32:208046 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:078047 texture,
[email protected]0d6bfdc2011-11-02 01:32:208048 target, level, internal_format, width, height, 1, border, format, type,
8049 pixels != NULL);
[email protected]b493ee622011-04-13 23:52:008050 tex_image_2d_failed_ = false;
[email protected]cadde4a2010-07-31 17:10:438051 }
[email protected]f598f422012-12-07 08:30:038052 return;
[email protected]b9849abf2009-11-25 19:13:198053}
8054
[email protected]f7a64ee2010-02-01 22:24:148055error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358056 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388057 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]b493ee622011-04-13 23:52:008058 tex_image_2d_failed_ = true;
[email protected]b9849abf2009-11-25 19:13:198059 GLenum target = static_cast<GLenum>(c.target);
8060 GLint level = static_cast<GLint>(c.level);
8061 GLint internal_format = static_cast<GLint>(c.internalformat);
8062 GLsizei width = static_cast<GLsizei>(c.width);
8063 GLsizei height = static_cast<GLsizei>(c.height);
8064 GLint border = static_cast<GLint>(c.border);
8065 GLenum format = static_cast<GLenum>(c.format);
8066 GLenum type = static_cast<GLenum>(c.type);
8067 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8068 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188069 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348070 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248071 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348072 NULL)) {
[email protected]a76b0052010-03-05 00:33:188073 return error::kOutOfBounds;
8074 }
[email protected]b9849abf2009-11-25 19:13:198075 const void* pixels = NULL;
8076 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8077 pixels = GetSharedMemoryAs<const void*>(
8078 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468079 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148080 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198081 }
8082 }
[email protected]f598f422012-12-07 08:30:038083
8084 DoTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198085 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:478086 pixels, pixels_size);
[email protected]f598f422012-12-07 08:30:038087 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198088}
8089
[email protected]f7a64ee2010-02-01 22:24:148090error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:358091 uint32 immediate_data_size, const cmds::TexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:198092 GLenum target = static_cast<GLenum>(c.target);
8093 GLint level = static_cast<GLint>(c.level);
[email protected]ba3176a2009-12-16 18:19:468094 GLint internal_format = static_cast<GLint>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198095 GLsizei width = static_cast<GLsizei>(c.width);
8096 GLsizei height = static_cast<GLsizei>(c.height);
8097 GLint border = static_cast<GLint>(c.border);
8098 GLenum format = static_cast<GLenum>(c.format);
8099 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:188100 uint32 size;
[email protected]3458a64a2012-04-10 17:39:348101 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248102 width, height, format, type, state_.unpack_alignment, &size,
8103 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:188104 return error::kOutOfBounds;
8105 }
[email protected]07f54fcc2009-12-22 02:46:308106 const void* pixels = GetImmediateDataAs<const void*>(
8107 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:468108 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148109 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:468110 }
[email protected]a93bb842010-02-16 23:03:478111 DoTexImage2D(
[email protected]ba3176a2009-12-16 18:19:468112 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:478113 pixels, size);
[email protected]f7a64ee2010-02-01 22:24:148114 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328115}
8116
[email protected]cadde4a2010-07-31 17:10:438117void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8118 GLenum target,
8119 GLint level,
8120 GLint xoffset,
8121 GLint yoffset,
8122 GLsizei width,
8123 GLsizei height,
8124 GLenum format,
8125 GLsizei image_size,
8126 const void * data) {
[email protected]02965c22013-03-09 02:40:078127 Texture* texture = GetTextureInfoForTarget(target);
8128 if (!texture) {
[email protected]ab09b612013-03-11 22:11:518129 LOCAL_SET_GL_ERROR(
8130 GL_INVALID_OPERATION,
8131 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438132 return;
8133 }
8134 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528135 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078136 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518137 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528138 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438139 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528140 return;
8141 }
8142 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518143 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528144 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438145 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528146 return;
8147 }
[email protected]02965c22013-03-09 02:40:078148 if (!texture->ValidForTexture(
[email protected]df6cf1ad2011-01-29 01:20:528149 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518150 LOCAL_SET_GL_ERROR(
8151 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438152 return;
8153 }
[email protected]ad84a3a2012-06-08 21:42:438154
8155 if (!ValidateCompressedTexFuncData(
8156 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8157 !ValidateCompressedTexSubDimensions(
8158 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078159 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438160 return;
8161 }
8162
8163
[email protected]0d6bfdc2011-11-02 01:32:208164 // Note: There is no need to deal with texture cleared tracking here
8165 // because the validation above means you can only get here if the level
8166 // is already a matching compressed format and in that case
8167 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438168 glCompressedTexSubImage2D(
8169 target, level, xoffset, yoffset, width, height, format, image_size, data);
8170}
8171
[email protected]6e288612010-12-21 20:45:038172static void Clip(
8173 GLint start, GLint range, GLint sourceRange,
8174 GLint* out_start, GLint* out_range) {
8175 DCHECK(out_start);
8176 DCHECK(out_range);
8177 if (start < 0) {
8178 range += start;
8179 start = 0;
8180 }
8181 GLint end = start + range;
8182 if (end > sourceRange) {
8183 range -= end - sourceRange;
8184 }
8185 *out_start = start;
8186 *out_range = range;
8187}
8188
[email protected]cadde4a2010-07-31 17:10:438189void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448190 GLenum target,
8191 GLint level,
8192 GLenum internal_format,
8193 GLint x,
8194 GLint y,
8195 GLsizei width,
8196 GLsizei height,
8197 GLint border) {
[email protected]09e17272012-11-30 10:30:448198 DCHECK(!ShouldDeferReads());
[email protected]02965c22013-03-09 02:40:078199 Texture* texture = GetTextureInfoForTarget(target);
8200 if (!texture) {
[email protected]ab09b612013-03-11 22:11:518201 LOCAL_SET_GL_ERROR(
8202 GL_INVALID_OPERATION,
8203 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438204 return;
8205 }
[email protected]02965c22013-03-09 02:40:078206 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518207 LOCAL_SET_GL_ERROR(
8208 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:178209 }
[email protected]80eb6b52012-01-19 00:14:418210 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188211 border != 0) {
[email protected]ab09b612013-03-11 22:11:518212 LOCAL_SET_GL_ERROR(
8213 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188214 return;
8215 }
[email protected]81375742012-06-08 00:04:008216 if (!ValidateTextureParameters(
8217 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
8218 return;
8219 }
[email protected]f5719fb2010-08-04 18:27:188220
[email protected]9edc6b22010-12-23 02:00:268221 // Check we have compatible formats.
8222 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8223 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8224 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8225
8226 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518227 LOCAL_SET_GL_ERROR(
8228 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268229 return;
8230 }
8231
[email protected]81375742012-06-08 00:04:008232 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518233 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008234 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268235 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8236 return;
8237 }
8238
8239 uint32 estimated_size = 0;
8240 if (!GLES2Util::ComputeImageDataSizes(
8241 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8242 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518243 LOCAL_SET_GL_ERROR(
8244 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268245 return;
8246 }
8247
8248 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518249 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008250 return;
8251 }
8252
[email protected]a0b78dc2011-11-11 10:43:108253 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8254 return;
8255 }
8256
[email protected]ab09b612013-03-11 22:11:518257 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278258 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038259 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268260
[email protected]02965c22013-03-09 02:40:078261 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:428262 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:518263 // TODO(gman): If textures tracked which framebuffers they were attached to
8264 // we could just mark those framebuffers as not complete.
8265 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:468266 }
8267
[email protected]9edc6b22010-12-23 02:00:268268 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038269 GLint copyX = 0;
8270 GLint copyY = 0;
8271 GLint copyWidth = 0;
8272 GLint copyHeight = 0;
8273 Clip(x, width, size.width(), &copyX, &copyWidth);
8274 Clip(y, height, size.height(), &copyY, &copyHeight);
8275
8276 if (copyX != x ||
8277 copyY != y ||
8278 copyWidth != width ||
8279 copyHeight != height) {
8280 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208281 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078282 texture->service_id(), texture->target(),
[email protected]4502e6492011-12-14 19:39:158283 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
[email protected]02965c22013-03-09 02:40:078284 texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518285 LOCAL_SET_GL_ERROR(
8286 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038287 return;
8288 }
[email protected]6e288612010-12-21 20:45:038289 if (copyHeight > 0 && copyWidth > 0) {
8290 GLint dx = copyX - x;
8291 GLint dy = copyY - y;
8292 GLint destX = dx;
8293 GLint destY = dy;
8294 glCopyTexSubImage2D(target, level,
8295 destX, destY, copyX, copyY,
8296 copyWidth, copyHeight);
8297 }
8298 } else {
8299 glCopyTexImage2D(target, level, internal_format,
8300 copyX, copyY, copyWidth, copyHeight, border);
8301 }
[email protected]ab09b612013-03-11 22:11:518302 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438303 if (error == GL_NO_ERROR) {
8304 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:078305 texture, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208306 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438307 }
8308}
8309
8310void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448311 GLenum target,
8312 GLint level,
8313 GLint xoffset,
8314 GLint yoffset,
8315 GLint x,
8316 GLint y,
8317 GLsizei width,
8318 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448319 DCHECK(!ShouldDeferReads());
[email protected]02965c22013-03-09 02:40:078320 Texture* texture = GetTextureInfoForTarget(target);
8321 if (!texture) {
[email protected]ab09b612013-03-11 22:11:518322 LOCAL_SET_GL_ERROR(
8323 GL_INVALID_OPERATION,
8324 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438325 return;
8326 }
8327 GLenum type = 0;
8328 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078329 if (!texture->GetLevelType(target, level, &type, &format) ||
8330 !texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438331 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518332 LOCAL_SET_GL_ERROR(
8333 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438334 return;
8335 }
[email protected]02965c22013-03-09 02:40:078336 if (texture->AsyncTransferIsInProgress()) {
[email protected]ab09b612013-03-11 22:11:518337 LOCAL_SET_GL_ERROR(
8338 GL_INVALID_OPERATION,
8339 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598340 return;
8341 }
[email protected]9edc6b22010-12-23 02:00:268342
8343 // Check we have compatible formats.
8344 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8345 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8346 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8347
[email protected]2d3765b2012-10-03 00:31:078348 if (!channels_needed ||
8349 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518350 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438351 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268352 return;
8353 }
8354
[email protected]81375742012-06-08 00:04:008355 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518356 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008357 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438358 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008359 return;
8360 }
8361
[email protected]a0b78dc2011-11-11 10:43:108362 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8363 return;
8364 }
8365
[email protected]de26b3c2011-08-03 21:54:278366 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038367 gfx::Size size = GetBoundReadFrameBufferSize();
8368 GLint copyX = 0;
8369 GLint copyY = 0;
8370 GLint copyWidth = 0;
8371 GLint copyHeight = 0;
8372 Clip(x, width, size.width(), &copyX, &copyWidth);
8373 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208374
[email protected]02965c22013-03-09 02:40:078375 if (!texture_manager()->ClearTextureLevel(this, texture, target, level)) {
[email protected]ab09b612013-03-11 22:11:518376 LOCAL_SET_GL_ERROR(
8377 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208378 return;
8379 }
8380
[email protected]6e288612010-12-21 20:45:038381 if (copyX != x ||
8382 copyY != y ||
8383 copyWidth != width ||
8384 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208385 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038386 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348387 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248388 width, height, format, type, state_.unpack_alignment, &pixels_size,
8389 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518390 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438391 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038392 return;
8393 }
8394 scoped_array<char> zero(new char[pixels_size]);
8395 memset(zero.get(), 0, pixels_size);
8396 glTexSubImage2D(
8397 target, level, xoffset, yoffset, width, height,
8398 format, type, zero.get());
8399 }
[email protected]0d6bfdc2011-11-02 01:32:208400
[email protected]6e288612010-12-21 20:45:038401 if (copyHeight > 0 && copyWidth > 0) {
8402 GLint dx = copyX - x;
8403 GLint dy = copyY - y;
8404 GLint destX = xoffset + dx;
8405 GLint destY = yoffset + dy;
8406 glCopyTexSubImage2D(target, level,
8407 destX, destY, copyX, copyY,
8408 copyWidth, copyHeight);
8409 }
[email protected]cadde4a2010-07-31 17:10:438410}
8411
[email protected]f598f422012-12-07 08:30:038412bool GLES2DecoderImpl::ValidateTexSubImage2D(
8413 error::Error* error,
8414 const char* function_name,
8415 GLenum target,
8416 GLint level,
8417 GLint xoffset,
8418 GLint yoffset,
8419 GLsizei width,
8420 GLsizei height,
8421 GLenum format,
8422 GLenum type,
8423 const void * data) {
8424 (*error) = error::kNoError;
8425 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518426 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038427 return false;
8428 }
8429 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518430 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038431 return false;
8432 }
8433 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518434 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038435 return false;
8436 }
8437 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518438 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:038439 return false;
8440 }
8441 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518442 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:038443 return false;
8444 }
[email protected]02965c22013-03-09 02:40:078445 Texture* texture = GetTextureInfoForTarget(target);
8446 if (!texture) {
[email protected]ab09b612013-03-11 22:11:518447 LOCAL_SET_GL_ERROR(
8448 GL_INVALID_OPERATION,
8449 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038450 return false;
[email protected]cadde4a2010-07-31 17:10:438451 }
[email protected]df6cf1ad2011-01-29 01:20:528452 GLenum current_type = 0;
8453 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078454 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518455 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038456 GL_INVALID_OPERATION, function_name, "level does not exist.");
8457 return false;
[email protected]df6cf1ad2011-01-29 01:20:528458 }
8459 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:518460 LOCAL_SET_GL_ERROR(
8461 GL_INVALID_OPERATION,
8462 function_name, "format does not match internal format.");
[email protected]f598f422012-12-07 08:30:038463 return false;
[email protected]df6cf1ad2011-01-29 01:20:528464 }
8465 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518466 LOCAL_SET_GL_ERROR(
8467 GL_INVALID_OPERATION,
8468 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038469 return false;
[email protected]df6cf1ad2011-01-29 01:20:528470 }
[email protected]02965c22013-03-09 02:40:078471 if (texture->AsyncTransferIsInProgress()) {
[email protected]ab09b612013-03-11 22:11:518472 LOCAL_SET_GL_ERROR(
8473 GL_INVALID_OPERATION,
8474 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598475 return false;
8476 }
[email protected]02965c22013-03-09 02:40:078477 if (!texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438478 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518479 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038480 return false;
[email protected]cadde4a2010-07-31 17:10:438481 }
[email protected]81375742012-06-08 00:04:008482 if ((GLES2Util::GetChannelsForFormat(format) &
8483 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518484 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008485 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038486 function_name, "can not supply data for depth or stencil textures");
8487 return false;
[email protected]81375742012-06-08 00:04:008488 }
[email protected]f598f422012-12-07 08:30:038489 if (data == NULL) {
8490 (*error) = error::kOutOfBounds;
8491 return false;
8492 }
8493 return true;
8494}
[email protected]81375742012-06-08 00:04:008495
[email protected]f598f422012-12-07 08:30:038496error::Error GLES2DecoderImpl::DoTexSubImage2D(
8497 GLenum target,
8498 GLint level,
8499 GLint xoffset,
8500 GLint yoffset,
8501 GLsizei width,
8502 GLsizei height,
8503 GLenum format,
8504 GLenum type,
8505 const void * data) {
8506 error::Error error = error::kNoError;
8507 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8508 xoffset, yoffset, width, height, format, type, data)) {
8509 return error;
8510 }
[email protected]02965c22013-03-09 02:40:078511 Texture* texture = GetTextureInfoForTarget(target);
[email protected]4502e6492011-12-14 19:39:158512 GLsizei tex_width = 0;
8513 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078514 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158515 DCHECK(ok);
8516 if (xoffset != 0 || yoffset != 0 ||
8517 width != tex_width || height != tex_height) {
[email protected]02965c22013-03-09 02:40:078518 if (!texture_manager()->ClearTextureLevel(this, texture, target, level)) {
[email protected]ab09b612013-03-11 22:11:518519 LOCAL_SET_GL_ERROR(
8520 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038521 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308522 }
[email protected]63b465922012-09-06 02:04:528523 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158524 glTexSubImage2D(
8525 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038526 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208527 }
[email protected]4502e6492011-12-14 19:39:158528
[email protected]02965c22013-03-09 02:40:078529 if (teximage2d_faster_than_texsubimage2d_ && !texture->IsImmutable()) {
[email protected]63b465922012-09-06 02:04:528530 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158531 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8532 // same as internal_foramt. If that changes we'll need to look them up.
8533 WrappedTexImage2D(
8534 target, level, format, width, height, 0, format, type, data);
8535 } else {
[email protected]63b465922012-09-06 02:04:528536 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158537 glTexSubImage2D(
8538 target, level, xoffset, yoffset, width, height, format, type, data);
8539 }
[email protected]02965c22013-03-09 02:40:078540 texture_manager()->SetLevelCleared(texture, target, level, true);
[email protected]f598f422012-12-07 08:30:038541 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438542}
8543
[email protected]b493ee622011-04-13 23:52:008544error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358545 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388546 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008547 GLboolean internal = static_cast<GLboolean>(c.internal);
8548 if (internal == GL_TRUE && tex_image_2d_failed_)
8549 return error::kNoError;
8550
8551 GLenum target = static_cast<GLenum>(c.target);
8552 GLint level = static_cast<GLint>(c.level);
8553 GLint xoffset = static_cast<GLint>(c.xoffset);
8554 GLint yoffset = static_cast<GLint>(c.yoffset);
8555 GLsizei width = static_cast<GLsizei>(c.width);
8556 GLsizei height = static_cast<GLsizei>(c.height);
8557 GLenum format = static_cast<GLenum>(c.format);
8558 GLenum type = static_cast<GLenum>(c.type);
8559 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348560 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248561 width, height, format, type, state_.unpack_alignment, &data_size,
8562 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008563 return error::kOutOfBounds;
8564 }
8565 const void* pixels = GetSharedMemoryAs<const void*>(
8566 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038567 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008568 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008569}
8570
8571error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:358572 uint32 immediate_data_size, const cmds::TexSubImage2DImmediate& c) {
[email protected]b493ee622011-04-13 23:52:008573 GLboolean internal = static_cast<GLboolean>(c.internal);
8574 if (internal == GL_TRUE && tex_image_2d_failed_)
8575 return error::kNoError;
8576
8577 GLenum target = static_cast<GLenum>(c.target);
8578 GLint level = static_cast<GLint>(c.level);
8579 GLint xoffset = static_cast<GLint>(c.xoffset);
8580 GLint yoffset = static_cast<GLint>(c.yoffset);
8581 GLsizei width = static_cast<GLsizei>(c.width);
8582 GLsizei height = static_cast<GLsizei>(c.height);
8583 GLenum format = static_cast<GLenum>(c.format);
8584 GLenum type = static_cast<GLenum>(c.type);
8585 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348586 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248587 width, height, format, type, state_.unpack_alignment, &data_size,
8588 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008589 return error::kOutOfBounds;
8590 }
8591 const void* pixels = GetImmediateDataAs<const void*>(
8592 c, data_size, immediate_data_size);
[email protected]f598f422012-12-07 08:30:038593 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008594 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008595}
8596
[email protected]f7a64ee2010-02-01 22:24:148597error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358598 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368599 GLuint index = static_cast<GLuint>(c.index);
8600 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358601 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258602 Result* result = GetSharedMemoryAs<Result*>(
8603 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368604 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148605 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368606 }
[email protected]07d0cc82010-02-17 04:51:408607 // Check that the client initialized the result.
8608 if (result->size != 0) {
8609 return error::kInvalidArguments;
8610 }
[email protected]9438b012010-06-15 22:55:058611 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518612 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8613 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148614 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368615 }
[email protected]3916c97e2010-02-25 03:20:508616 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518617 LOCAL_SET_GL_ERROR(
8618 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148619 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368620 }
[email protected]0bfd9882010-02-05 23:02:258621 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088622 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358623 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148624 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328625}
8626
[email protected]f7b85372010-02-03 01:11:378627bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428628 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378629 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128630 error::Error* error, GLint* real_location,
8631 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108632 DCHECK(error);
8633 DCHECK(service_id);
8634 DCHECK(result_pointer);
8635 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128636 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378637 *error = error::kNoError;
8638 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258639 SizedResult<GLint>* result;
8640 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8641 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8642 if (!result) {
[email protected]f7b85372010-02-03 01:11:378643 *error = error::kOutOfBounds;
8644 return false;
8645 }
[email protected]0bfd9882010-02-05 23:02:258646 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378647 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258648 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428649 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8650 if (!program) {
[email protected]ae51d192010-04-27 00:48:038651 return false;
8652 }
[email protected]df37b9932013-03-08 05:21:428653 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378654 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518655 LOCAL_SET_GL_ERROR(
8656 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378657 return false;
8658 }
[email protected]df37b9932013-03-08 05:21:428659 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368660 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358661 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428662 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128663 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368664 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378665 // No such location.
[email protected]ab09b612013-03-11 22:11:518666 LOCAL_SET_GL_ERROR(
8667 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378668 return false;
8669 }
[email protected]43c2f1f2011-03-25 18:35:368670 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508671 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378672 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518673 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378674 return false;
8675 }
[email protected]0bfd9882010-02-05 23:02:258676 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8677 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8678 if (!result) {
[email protected]f7b85372010-02-03 01:11:378679 *error = error::kOutOfBounds;
8680 return false;
8681 }
[email protected]0bfd9882010-02-05 23:02:258682 result->size = size;
[email protected]939e7362010-05-13 20:49:108683 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378684 return true;
8685}
8686
[email protected]f7a64ee2010-02-01 22:24:148687error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358688 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378689 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338690 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378691 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108692 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128693 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378694 Error error;
[email protected]0bfd9882010-02-05 23:02:258695 void* result;
[email protected]f7b85372010-02-03 01:11:378696 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128697 program, fake_location, c.params_shm_id, c.params_shm_offset,
8698 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258699 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128700 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358701 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378702 }
8703 return error;
[email protected]96449d2c2009-11-25 00:01:328704}
8705
[email protected]f7a64ee2010-02-01 22:24:148706error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358707 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378708 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338709 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378710 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128711 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378712 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358713 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108714 Result* result;
8715 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378716 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128717 program, fake_location, c.params_shm_id, c.params_shm_offset,
8718 &error, &real_location, &service_id,
8719 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108720 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8721 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8722 GLsizei num_values = result->GetNumResults();
8723 scoped_array<GLint> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128724 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108725 GLfloat* dst = result->GetData();
8726 for (GLsizei ii = 0; ii < num_values; ++ii) {
8727 dst[ii] = (temp[ii] != 0);
8728 }
8729 } else {
[email protected]1b0a6752012-02-22 03:44:128730 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108731 }
[email protected]f7b85372010-02-03 01:11:378732 }
8733 return error;
[email protected]96449d2c2009-11-25 00:01:328734}
8735
[email protected]f7a64ee2010-02-01 22:24:148736error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358737 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258738 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8739 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358740 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258741 Result* result = GetSharedMemoryAs<Result*>(
8742 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8743 if (!result) {
8744 return error::kOutOfBounds;
8745 }
[email protected]07d0cc82010-02-17 04:51:408746 // Check that the client initialized the result.
8747 if (result->success != 0) {
8748 return error::kInvalidArguments;
8749 }
[email protected]9438b012010-06-15 22:55:058750 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518751 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538752 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298753 return error::kNoError;
8754 }
[email protected]9438b012010-06-15 22:55:058755 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518756 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538757 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298758 return error::kNoError;
8759 }
8760
8761 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408762
8763 GLint range[2] = {0, 0};
8764 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218765 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408766
8767 result->min_range = range[0];
8768 result->max_range = range[1];
8769 result->precision = precision;
8770
[email protected]f7a64ee2010-02-01 22:24:148771 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328772}
8773
[email protected]f7a64ee2010-02-01 22:24:148774error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358775 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258776 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428777 GLuint program_id = static_cast<GLuint>(c.program);
8778 Program* program = GetProgramInfoNotShader(
8779 program_id, "glGetAttachedShaders");
8780 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258781 return error::kNoError;
8782 }
[email protected]ed9f9cd2013-02-27 21:12:358783 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258784 uint32 max_count = Result::ComputeMaxResults(result_size);
8785 Result* result = GetSharedMemoryAs<Result*>(
8786 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8787 if (!result) {
8788 return error::kOutOfBounds;
8789 }
[email protected]07d0cc82010-02-17 04:51:408790 // Check that the client initialized the result.
8791 if (result->size != 0) {
8792 return error::kInvalidArguments;
8793 }
[email protected]0bfd9882010-02-05 23:02:258794 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038795 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428796 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258797 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038798 if (!shader_manager()->GetClientId(result->GetData()[ii],
8799 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258800 NOTREACHED();
8801 return error::kGenericError;
8802 }
8803 }
8804 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148805 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328806}
8807
[email protected]f7a64ee2010-02-01 22:24:148808error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358809 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428810 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258811 GLuint index = c.index;
8812 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358813 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258814 Result* result = GetSharedMemoryAs<Result*>(
8815 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8816 if (!result) {
8817 return error::kOutOfBounds;
8818 }
[email protected]07d0cc82010-02-17 04:51:408819 // Check that the client initialized the result.
8820 if (result->success != 0) {
8821 return error::kInvalidArguments;
8822 }
[email protected]df37b9932013-03-08 05:21:428823 Program* program = GetProgramInfoNotShader(
8824 program_id, "glGetActiveUniform");
8825 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258826 return error::kNoError;
8827 }
[email protected]ed9f9cd2013-02-27 21:12:358828 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428829 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258830 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518831 LOCAL_SET_GL_ERROR(
8832 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258833 return error::kNoError;
8834 }
8835 result->success = 1; // true.
8836 result->size = uniform_info->size;
8837 result->type = uniform_info->type;
8838 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298839 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148840 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328841}
8842
[email protected]f7a64ee2010-02-01 22:24:148843error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358844 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428845 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258846 GLuint index = c.index;
8847 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358848 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258849 Result* result = GetSharedMemoryAs<Result*>(
8850 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8851 if (!result) {
8852 return error::kOutOfBounds;
8853 }
[email protected]07d0cc82010-02-17 04:51:408854 // Check that the client initialized the result.
8855 if (result->success != 0) {
8856 return error::kInvalidArguments;
8857 }
[email protected]df37b9932013-03-08 05:21:428858 Program* program = GetProgramInfoNotShader(
8859 program_id, "glGetActiveAttrib");
8860 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258861 return error::kNoError;
8862 }
[email protected]ed9f9cd2013-02-27 21:12:358863 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428864 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258865 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518866 LOCAL_SET_GL_ERROR(
8867 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258868 return error::kNoError;
8869 }
8870 result->success = 1; // true.
8871 result->size = attrib_info->size;
8872 result->type = attrib_info->type;
8873 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298874 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148875 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328876}
8877
[email protected]b273e432010-04-12 17:23:588878error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358879 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588880#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518881 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588882 return error::kNoError;
8883#else
8884 GLsizei n = static_cast<GLsizei>(c.n);
8885 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518886 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588887 return error::kNoError;
8888 }
8889 GLsizei length = static_cast<GLsizei>(c.length);
8890 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518891 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588892 return error::kNoError;
8893 }
8894 uint32 data_size;
8895 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8896 return error::kOutOfBounds;
8897 }
8898 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8899 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8900 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8901 const void* binary = GetSharedMemoryAs<const void*>(
8902 c.binary_shm_id, c.binary_shm_offset, length);
8903 if (shaders == NULL || binary == NULL) {
8904 return error::kOutOfBounds;
8905 }
8906 scoped_array<GLuint> service_ids(new GLuint[n]);
8907 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428908 Shader* shader = GetShader(shaders[ii]);
8909 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518910 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588911 return error::kNoError;
8912 }
[email protected]df37b9932013-03-08 05:21:428913 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588914 }
8915 // TODO(gman): call glShaderBinary
8916 return error::kNoError;
8917#endif
8918}
8919
[email protected]6217d392010-03-25 22:08:358920error::Error GLES2DecoderImpl::HandleSwapBuffers(
[email protected]ed9f9cd2013-02-27 21:12:358921 uint32 immediate_data_size, const cmds::SwapBuffers& c) {
[email protected]64ace852011-05-19 21:49:498922 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088923
[email protected]64ace852011-05-19 21:49:498924 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428925 // TRACE_EVENT for gpu tests:
8926 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428927 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428928 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8929 "width", (is_offscreen ? offscreen_size_.width() :
8930 surface_->GetSize().width()));
[email protected]64ace852011-05-19 21:49:498931 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleSwapBuffers",
8932 "offscreen", is_offscreen,
8933 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358934 // If offscreen then don't actually SwapBuffers to the display. Just copy
8935 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498936 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318937 TRACE_EVENT2("gpu", "Offscreen",
8938 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538939 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8940 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8941 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8942 // fix this.
[email protected]62e155e2012-10-23 22:43:158943 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538944 offscreen_saved_frame_buffer_->Create();
8945 glFinish();
8946 }
8947
8948 // Allocate the offscreen saved color texture.
8949 DCHECK(offscreen_saved_color_format_);
8950 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098951 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538952
8953 offscreen_saved_frame_buffer_->AttachRenderTexture(
8954 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:058955 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
8956 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8957 GL_FRAMEBUFFER_COMPLETE) {
8958 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8959 << "because offscreen saved FBO was incomplete.";
8960 return error::kLostContext;
8961 }
[email protected]1fb8c482011-08-31 01:01:538962
[email protected]f0cfe752013-01-14 01:09:058963 // Clear the offscreen color texture.
8964 // TODO(piman): Is this still necessary?
8965 {
8966 ScopedFrameBufferBinder binder(this,
8967 offscreen_saved_frame_buffer_->id());
8968 glClearColor(0, 0, 0, 0);
8969 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8970 glDisable(GL_SCISSOR_TEST);
8971 glClear(GL_COLOR_BUFFER_BIT);
8972 RestoreClearState();
8973 }
[email protected]1fb8c482011-08-31 01:01:538974 }
8975
8976 UpdateParentTextureInfo();
8977 }
8978
[email protected]f0cfe752013-01-14 01:09:058979 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
8980 return error::kNoError;
[email protected]ab09b612013-03-11 22:11:518981 ScopedGLErrorSuppressor suppressor(
8982 "GLES2DecoderImpl::HandleSwapBuffers", this);
[email protected]6217d392010-03-25 22:08:358983
[email protected]34ff8b0c2010-10-01 20:06:028984 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138985 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278986 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]89d6ed02011-04-20 00:23:238987 return error::kNoError;
[email protected]b86b14982010-10-11 18:45:488988 } else {
[email protected]069944672012-04-25 20:52:238989 ScopedFrameBufferBinder binder(this,
8990 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138991
[email protected]069944672012-04-25 20:52:238992 if (offscreen_target_buffer_preserved_) {
8993 // Copy the target frame buffer to the saved offscreen texture.
8994 offscreen_saved_color_texture_->Copy(
8995 offscreen_saved_color_texture_->size(),
8996 offscreen_saved_color_format_);
8997 } else {
8998 // Flip the textures in the parent context via the texture manager.
8999 if (!!offscreen_saved_color_texture_info_.get())
9000 offscreen_saved_color_texture_info_->
9001 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569002
[email protected]069944672012-04-25 20:52:239003 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9004 offscreen_target_frame_buffer_->AttachRenderTexture(
9005 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489006 }
[email protected]069944672012-04-25 20:52:239007
9008 // Ensure the side effects of the copy are visible to the parent
9009 // context. There is no need to do this for ANGLE because it uses a
9010 // single D3D device for all contexts.
9011 if (!IsAngle())
9012 glFlush();
[email protected]89d6ed02011-04-20 00:23:239013 return error::kNoError;
[email protected]0c8c9d22010-06-25 17:36:399014 }
[email protected]6217d392010-03-25 22:08:359015 } else {
[email protected]111975c62012-09-06 01:37:319016 TRACE_EVENT2("gpu", "Onscreen",
9017 "width", surface_->GetSize().width(),
9018 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:159019 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019020 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]5259ead82010-09-10 18:02:029021 return error::kLostContext;
[email protected]d0498742010-09-20 20:27:019022 }
[email protected]6217d392010-03-25 22:08:359023 }
9024
[email protected]89d6ed02011-04-20 00:23:239025 return error::kNoError;
[email protected]6217d392010-03-25 22:08:359026}
9027
[email protected]d4239852011-08-12 04:51:229028error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359029 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:189030 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289031 if (!bucket || bucket->size() == 0) {
9032 return error::kInvalidArguments;
9033 }
[email protected]ed9f9cd2013-02-27 21:12:359034 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189035 Result* result = GetSharedMemoryAs<Result*>(
9036 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9037 if (!result) {
9038 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109039 }
[email protected]b1d2dcb2010-05-17 19:24:189040 // Check that the client initialized the result.
9041 if (*result != 0) {
9042 return error::kInvalidArguments;
9043 }
9044 std::string feature_str;
9045 if (!bucket->GetAsString(&feature_str)) {
9046 return error::kInvalidArguments;
9047 }
9048
9049 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229050 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189051 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229052 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409053 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9054 // TODO(gman): decide how to remove the need for this const_cast.
9055 // I could make validators_ non const but that seems bad as this is the only
9056 // place it is needed. I could make some special friend class of validators
9057 // just to allow this to set them. That seems silly. I could refactor this
9058 // code to use the extension mechanism or the initialization attributes to
9059 // turn this feature on. Given that the only real point of this is to make
9060 // the conformance tests pass and given that there is lots of real work that
9061 // needs to be done it seems like refactoring for one to one of those
9062 // methods is a very low priority.
9063 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049064 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9065 force_webgl_glsl_validation_ = true;
9066 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189067 } else {
9068 return error::kNoError;
9069 }
9070
9071 *result = 1; // true.
9072 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109073}
9074
[email protected]c2f8c8402010-12-06 18:07:249075error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9076 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359077 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249078 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359079 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:299080 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:249081 bucket->SetFromString(info->extensions().c_str());
9082 return error::kNoError;
9083}
9084
9085error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359086 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249087 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289088 if (!bucket || bucket->size() == 0) {
9089 return error::kInvalidArguments;
9090 }
[email protected]c2f8c8402010-12-06 18:07:249091 std::string feature_str;
9092 if (!bucket->GetAsString(&feature_str)) {
9093 return error::kInvalidArguments;
9094 }
9095
[email protected]4b7eba92013-01-08 02:23:569096 bool desire_webgl_glsl_validation =
9097 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9098 bool desire_standard_derivatives = false;
9099 if (force_webgl_glsl_validation_) {
9100 desire_standard_derivatives =
9101 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049102 }
9103
[email protected]4b7eba92013-01-08 02:23:569104 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
9105 desire_standard_derivatives != derivatives_explicitly_enabled_) {
9106 force_webgl_glsl_validation_ = desire_webgl_glsl_validation;
9107 derivatives_explicitly_enabled_ = desire_standard_derivatives;
[email protected]c2f8c8402010-12-06 18:07:249108 InitializeShaderTranslator();
9109 }
9110
[email protected]302ce6d2011-07-07 23:28:119111 UpdateCapabilities();
9112
[email protected]c2f8c8402010-12-06 18:07:249113 return error::kNoError;
9114}
9115
[email protected]372e0412011-06-28 16:08:569116error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359117 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:569118 GLuint count = c.count;
9119 uint32 pnames_size;
9120 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9121 return error::kOutOfBounds;
9122 }
9123 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9124 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9125 if (pnames == NULL) {
9126 return error::kOutOfBounds;
9127 }
9128
9129 // We have to copy them since we use them twice so the client
9130 // can't change them between the time we validate them and the time we use
9131 // them.
9132 scoped_array<GLenum> enums(new GLenum[count]);
9133 memcpy(enums.get(), pnames, pnames_size);
9134
9135 // Count up the space needed for the result.
9136 uint32 num_results = 0;
9137 for (GLuint ii = 0; ii < count; ++ii) {
9138 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9139 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519140 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9141 "glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569142 return error::kNoError;
9143 }
9144 // Num will never be more than 4.
9145 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479146 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569147 return error::kOutOfBounds;
9148 }
9149 }
9150
9151 uint32 result_size = 0;
9152 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9153 return error::kOutOfBounds;
9154 }
9155
9156 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519157 LOCAL_SET_GL_ERROR(
9158 GL_INVALID_VALUE,
9159 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569160 return error::kNoError;
9161 }
9162
9163 GLint* results = GetSharedMemoryAs<GLint*>(
9164 c.results_shm_id, c.results_shm_offset, result_size);
9165 if (results == NULL) {
9166 return error::kOutOfBounds;
9167 }
9168
9169 // Check the results have been cleared in case the context was lost.
9170 for (uint32 ii = 0; ii < num_results; ++ii) {
9171 if (results[ii]) {
9172 return error::kInvalidArguments;
9173 }
9174 }
9175
9176 // Get each result.
9177 GLint* start = results;
9178 for (GLuint ii = 0; ii < count; ++ii) {
9179 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269180 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539181 !GetHelper(enums[ii], results, &num_written)) {
[email protected]372e0412011-06-28 16:08:569182 glGetIntegerv(enums[ii], results);
9183 }
9184 results += num_written;
9185 }
9186
9187 // Just to verify. Should this be a DCHECK?
9188 if (static_cast<uint32>(results - start) != num_results) {
9189 return error::kOutOfBounds;
9190 }
9191
9192 return error::kNoError;
9193}
9194
[email protected]2318d342011-07-11 22:27:429195error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359196 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:429197 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429198 uint32 bucket_id = c.bucket_id;
9199 Bucket* bucket = CreateBucket(bucket_id);
9200 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429201 Program* program = NULL;
9202 program = GetProgram(program_id);
9203 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469204 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429205 }
[email protected]df37b9932013-03-08 05:21:429206 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429207 return error::kNoError;
9208}
9209
[email protected]38d139d2011-07-14 00:38:439210error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9211 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439212 case GL_NO_ERROR:
9213 // TODO(kbr): improve the precision of the error code in this case.
9214 // Consider delegating to context for error code if MakeCurrent fails.
9215 return error::kUnknown;
9216 case GL_GUILTY_CONTEXT_RESET_ARB:
9217 return error::kGuilty;
9218 case GL_INNOCENT_CONTEXT_RESET_ARB:
9219 return error::kInnocent;
9220 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9221 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439222 }
9223
9224 NOTREACHED();
9225 return error::kUnknown;
9226}
9227
9228bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099229 if (reset_status_ != GL_NO_ERROR) {
9230 return true;
9231 }
[email protected]706b69f2012-07-27 04:59:309232 if (context_->WasAllocatedUsingRobustnessExtension()) {
9233 GLenum status = GL_NO_ERROR;
9234 if (has_robustness_extension_)
9235 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439236 if (status != GL_NO_ERROR) {
9237 // The graphics card was reset. Signal a lost context to the application.
9238 reset_status_ = status;
9239 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099240 << " context lost via ARB/EXT_robustness. Reset status = "
9241 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439242 return true;
9243 }
9244 }
9245 return false;
9246}
9247
[email protected]c4485aad62012-12-17 10:19:099248void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9249 // Only loses the context once.
9250 if (reset_status_ != GL_NO_ERROR) {
9251 return;
9252 }
9253
9254 // Marks this context as lost.
9255 reset_status_ = reset_status;
9256 current_decoder_error_ = error::kLostContext;
9257
9258 // Loses the parent's context.
9259 if (parent_) {
9260 parent_->LoseContext(reset_status);
9261 }
9262
9263 // Loses any child contexts.
9264 for (ChildList::iterator it = children_.begin();
9265 it != children_.end();
9266 ++it) {
9267 (*it)->LoseContext(reset_status);
9268 }
9269}
9270
9271error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359272 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099273 GLenum current = static_cast<GLenum>(c.current);
9274 GLenum other = static_cast<GLenum>(c.other);
9275 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519276 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9277 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099278 }
9279 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519280 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099281 }
9282 group_->LoseContexts(other);
9283 reset_status_ = current;
9284 current_decoder_error_ = error::kLostContext;
9285 return error::kLostContext;
9286}
9287
[email protected]b096d032013-03-08 03:08:019288error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9289 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9290 return error::kUnknownCommand;
9291}
9292
[email protected]840a7e462013-02-27 01:29:519293error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359294 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:519295 if (wait_sync_point_callback_.is_null())
9296 return error::kNoError;
9297
9298 return wait_sync_point_callback_.Run(c.sync_point) ?
9299 error::kNoError : error::kDeferCommandUntilLater;
9300}
9301
[email protected]882ba1e22012-03-08 19:02:539302bool GLES2DecoderImpl::GenQueriesEXTHelper(
9303 GLsizei n, const GLuint* client_ids) {
9304 for (GLsizei ii = 0; ii < n; ++ii) {
9305 if (query_manager_->GetQuery(client_ids[ii])) {
9306 return false;
9307 }
9308 }
[email protected]c45f1972012-03-14 07:27:369309 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539310 return true;
9311}
9312
9313void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9314 GLsizei n, const GLuint* client_ids) {
9315 for (GLsizei ii = 0; ii < n; ++ii) {
9316 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9317 if (query && !query->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249318 if (query == state_.current_query) {
9319 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539320 }
[email protected]c45f1972012-03-14 07:27:369321 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539322 query_manager_->RemoveQuery(client_ids[ii]);
9323 }
9324 }
9325}
9326
[email protected]22e3f552012-03-13 01:54:199327bool GLES2DecoderImpl::ProcessPendingQueries() {
9328 if (query_manager_.get() == NULL) {
9329 return false;
9330 }
[email protected]c45f1972012-03-14 07:27:369331 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199332 current_decoder_error_ = error::kOutOfBounds;
9333 }
9334 return query_manager_->HavePendingQueries();
9335}
9336
[email protected]2b1767cf2013-03-16 09:25:059337bool GLES2DecoderImpl::HasMoreIdleWork() {
9338 return async_pixel_transfer_delegate_->NeedsProcessMorePendingTransfers();
9339}
9340
9341void GLES2DecoderImpl::PerformIdleWork() {
9342 if (!async_pixel_transfer_delegate_->NeedsProcessMorePendingTransfers())
9343 return;
9344 // TODO(reveman): We should avoid using a bool return value to determine
9345 // if we need to restore some state. crbug.com/196303
9346 if (async_pixel_transfer_delegate_->ProcessMorePendingTransfers())
9347 RestoreCurrentTexture2DBindings();
9348 ProcessFinishedAsyncTransfers();
9349}
9350
[email protected]882ba1e22012-03-08 19:02:539351error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359352 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539353 GLenum target = static_cast<GLenum>(c.target);
9354 GLuint client_id = static_cast<GLuint>(c.id);
9355 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9356 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9357
[email protected]c45f1972012-03-14 07:27:369358 switch (target) {
9359 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559360 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]0713f43d2012-12-14 22:41:309361 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009362 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369363 break;
9364 default:
[email protected]62e155e2012-10-23 22:43:159365 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519366 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009367 GL_INVALID_OPERATION, "glBeginQueryEXT",
9368 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369369 return error::kNoError;
9370 }
9371 break;
[email protected]882ba1e22012-03-08 19:02:539372 }
9373
[email protected]e259eb412012-10-13 05:47:249374 if (state_.current_query) {
[email protected]ab09b612013-03-11 22:11:519375 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439376 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539377 return error::kNoError;
9378 }
9379
9380 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519381 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539382 return error::kNoError;
9383 }
9384
9385 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9386 if (!query) {
[email protected]c45f1972012-03-14 07:27:369387 // TODO(gman): Decide if we need this check.
9388 //
[email protected]882ba1e22012-03-08 19:02:539389 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369390 //
9391 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9392 // for all Query ids but from the POV of the command buffer service maybe
9393 // you don't.
9394 //
9395 // The client can enforce this. I don't think the service cares.
9396 //
9397 // IdAllocatorInterface* id_allocator =
9398 // group_->GetIdAllocator(id_namespaces::kQueries);
9399 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519400 // LOCAL_SET_GL_ERROR(
9401 // GL_INVALID_OPERATION,
9402 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369403 // return error::kNoError;
9404 // }
9405 query = query_manager_->CreateQuery(
9406 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539407 }
9408
[email protected]c45f1972012-03-14 07:27:369409 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519410 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439411 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539412 return error::kNoError;
9413 } else if (query->shm_id() != sync_shm_id ||
9414 query->shm_offset() != sync_shm_offset) {
9415 DLOG(ERROR) << "Shared memory used by query not the same as before";
9416 return error::kInvalidArguments;
9417 }
9418
[email protected]c45f1972012-03-14 07:27:369419 if (!query_manager_->BeginQuery(query)) {
9420 return error::kOutOfBounds;
9421 }
[email protected]882ba1e22012-03-08 19:02:539422
[email protected]e259eb412012-10-13 05:47:249423 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539424 return error::kNoError;
9425}
9426
9427error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359428 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539429 GLenum target = static_cast<GLenum>(c.target);
9430 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9431
[email protected]e259eb412012-10-13 05:47:249432 if (!state_.current_query) {
[email protected]ab09b612013-03-11 22:11:519433 LOCAL_SET_GL_ERROR(
9434 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539435 return error::kNoError;
9436 }
[email protected]e259eb412012-10-13 05:47:249437 if (state_.current_query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519438 LOCAL_SET_GL_ERROR(
9439 GL_INVALID_OPERATION,
9440 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539441 return error::kNoError;
9442 }
[email protected]882ba1e22012-03-08 19:02:539443
[email protected]e259eb412012-10-13 05:47:249444 if (!query_manager_->EndQuery(state_.current_query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369445 return error::kOutOfBounds;
9446 }
9447
[email protected]fe8d73c2013-02-16 22:37:329448 query_manager_->ProcessPendingTransferQueries();
9449
[email protected]e259eb412012-10-13 05:47:249450 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539451 return error::kNoError;
9452}
9453
[email protected]944b62f32012-09-27 02:20:469454bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9455 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469456 for (GLsizei ii = 0; ii < n; ++ii) {
9457 if (GetVertexAttribManager(client_ids[ii])) {
9458 return false;
9459 }
9460 }
[email protected]ab4fd7282012-10-12 16:25:579461
[email protected]62e155e2012-10-23 22:43:159462 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579463 // Emulated VAO
9464 for (GLsizei ii = 0; ii < n; ++ii) {
9465 CreateVertexAttribManager(client_ids[ii], 0);
9466 }
9467 } else {
9468 scoped_array<GLuint> service_ids(new GLuint[n]);
9469
9470 glGenVertexArraysOES(n, service_ids.get());
9471 for (GLsizei ii = 0; ii < n; ++ii) {
9472 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9473 }
[email protected]944b62f32012-09-27 02:20:469474 }
[email protected]ab4fd7282012-10-12 16:25:579475
[email protected]944b62f32012-09-27 02:20:469476 return true;
9477}
9478
9479void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9480 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469481 for (GLsizei ii = 0; ii < n; ++ii) {
9482 VertexAttribManager* vao =
9483 GetVertexAttribManager(client_ids[ii]);
9484 if (vao && !vao->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249485 if (state_.vertex_attrib_manager == vao) {
9486 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469487 }
9488 RemoveVertexAttribManager(client_ids[ii]);
9489 }
9490 }
9491}
9492
9493void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469494 VertexAttribManager* vao = NULL;
9495 GLuint service_id = 0;
9496 if (client_id != 0) {
9497 vao = GetVertexAttribManager(client_id);
9498 if (!vao) {
9499 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9500 // only allows names that have been previously generated. As such, we do
9501 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519502 LOCAL_SET_GL_ERROR(
9503 GL_INVALID_OPERATION,
9504 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469505 current_decoder_error_ = error::kNoError;
9506 return;
9507 } else {
9508 service_id = vao->service_id();
9509 }
[email protected]944b62f32012-09-27 02:20:469510 } else {
[email protected]ab4fd7282012-10-12 16:25:579511 vao = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469512 }
9513
[email protected]ab4fd7282012-10-12 16:25:579514 // Only set the VAO state if it's changed
[email protected]e259eb412012-10-13 05:47:249515 if (state_.vertex_attrib_manager != vao) {
9516 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159517 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579518 EmulateVertexArrayState();
9519 } else {
9520 glBindVertexArrayOES(service_id);
9521 }
9522 }
9523}
9524
9525// Used when OES_vertex_array_object isn't natively supported
9526void GLES2DecoderImpl::EmulateVertexArrayState() {
9527 // Setup the Vertex attribute state
9528 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9529 RestoreStateForAttrib(vv);
9530 }
9531
9532 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219533 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249534 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579535 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9536 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469537}
9538
9539bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469540 const VertexAttribManager* vao =
9541 GetVertexAttribManager(client_id);
9542 return vao && vao->IsValid() && !vao->IsDeleted();
9543}
9544
[email protected]b0af4f52011-09-28 22:04:429545error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9546 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359547 const cmds::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159548 if (!features().chromium_stream_texture) {
[email protected]ab09b612013-03-11 22:11:519549 LOCAL_SET_GL_ERROR(
9550 GL_INVALID_OPERATION,
9551 "glOpenStreamTextureCHROMIUM", "not supported.");
[email protected]b0af4f52011-09-28 22:04:429552 return error::kNoError;
9553 }
9554
9555 uint32 client_id = c.client_id;
[email protected]ed9f9cd2013-02-27 21:12:359556 typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
[email protected]b0af4f52011-09-28 22:04:429557 Result* result = GetSharedMemoryAs<Result*>(
9558 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9559
[email protected]e5081262012-01-05 23:09:039560 if (!result)
9561 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429562 *result = GL_ZERO;
[email protected]02965c22013-03-09 02:40:079563 Texture* texture = texture_manager()->GetTexture(client_id);
9564 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519565 LOCAL_SET_GL_ERROR(
9566 GL_INVALID_VALUE,
9567 "glCreateStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429568 return error::kNoError;
9569 }
9570
[email protected]02965c22013-03-09 02:40:079571 if (texture->IsStreamTexture()) {
[email protected]ab09b612013-03-11 22:11:519572 LOCAL_SET_GL_ERROR(
9573 GL_INVALID_OPERATION,
9574 "glCreateStreamTextureCHROMIUM", "is already a stream texture.");
[email protected]b0af4f52011-09-28 22:04:429575 return error::kNoError;
9576 }
9577
[email protected]02965c22013-03-09 02:40:079578 if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:519579 LOCAL_SET_GL_ERROR(
9580 GL_INVALID_OPERATION,
9581 "glCreateStreamTextureCHROMIUM",
9582 "is already bound to incompatible target.");
[email protected]b0af4f52011-09-28 22:04:429583 return error::kNoError;
9584 }
9585
9586 if (!stream_texture_manager_)
9587 return error::kInvalidArguments;
9588
9589 GLuint object_id = stream_texture_manager_->CreateStreamTexture(
[email protected]02965c22013-03-09 02:40:079590 texture->service_id(), client_id);
[email protected]b0af4f52011-09-28 22:04:429591
9592 if (object_id) {
[email protected]02965c22013-03-09 02:40:079593 texture->SetStreamTexture(true);
[email protected]b0af4f52011-09-28 22:04:429594 } else {
[email protected]ab09b612013-03-11 22:11:519595 LOCAL_SET_GL_ERROR(
9596 GL_OUT_OF_MEMORY,
9597 "glCreateStreamTextureCHROMIUM", "failed to create platform texture.");
[email protected]b0af4f52011-09-28 22:04:429598 }
9599
9600 *result = object_id;
9601 return error::kNoError;
9602}
9603
9604error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9605 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359606 const cmds::DestroyStreamTextureCHROMIUM& c) {
[email protected]b0af4f52011-09-28 22:04:429607 GLuint client_id = c.texture;
[email protected]02965c22013-03-09 02:40:079608 Texture* texture = texture_manager()->GetTexture(client_id);
9609 if (texture && texture->IsStreamTexture()) {
[email protected]b0af4f52011-09-28 22:04:429610 if (!stream_texture_manager_)
9611 return error::kInvalidArguments;
9612
[email protected]02965c22013-03-09 02:40:079613 stream_texture_manager_->DestroyStreamTexture(texture->service_id());
9614 texture->SetStreamTexture(false);
[email protected]b0af4f52011-09-28 22:04:429615 } else {
[email protected]ab09b612013-03-11 22:11:519616 LOCAL_SET_GL_ERROR(
9617 GL_INVALID_VALUE,
9618 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429619 }
9620
9621 return error::kNoError;
9622}
9623
[email protected]e51bdf32011-11-23 22:21:469624#if defined(OS_MACOSX)
9625void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9626 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9627 texture_id);
9628 if (it != texture_to_io_surface_map_.end()) {
9629 // Found a previous IOSurface bound to this texture; release it.
9630 CFTypeRef surface = it->second;
9631 CFRelease(surface);
9632 texture_to_io_surface_map_.erase(it);
9633 }
9634}
9635#endif
9636
9637void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9638 GLenum target, GLsizei width, GLsizei height,
9639 GLuint io_surface_id, GLuint plane) {
9640#if defined(OS_MACOSX)
9641 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519642 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439643 GL_INVALID_OPERATION,
9644 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469645 return;
9646 }
9647
9648 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9649 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519650 LOCAL_SET_GL_ERROR(
9651 GL_INVALID_OPERATION,
9652 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469653 return;
9654 }
9655
9656 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9657 // This might be supported in the future, and if we could require
9658 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9659 // could delete a lot of code. For now, perform strict validation so we
9660 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519661 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469662 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439663 "glTexImageIOSurface2DCHROMIUM",
9664 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469665 return;
9666 }
9667
[email protected]09d50362012-10-18 20:54:379668 // Default target might be conceptually valid, but disallow it to avoid
9669 // accidents.
[email protected]02965c22013-03-09 02:40:079670 Texture* texture = GetTextureInfoForTargetUnlessDefault(target);
9671 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519672 LOCAL_SET_GL_ERROR(
9673 GL_INVALID_OPERATION,
9674 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469675 return;
9676 }
[email protected]e51bdf32011-11-23 22:21:469677
9678 // Look up the new IOSurface. Note that because of asynchrony
9679 // between processes this might fail; during live resizing the
9680 // plugin process might allocate and release an IOSurface before
9681 // this process gets a chance to look it up. Hold on to any old
9682 // IOSurface in this case.
9683 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9684 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519685 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439686 GL_INVALID_OPERATION,
9687 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469688 return;
9689 }
9690
9691 // Release any IOSurface previously bound to this texture.
[email protected]02965c22013-03-09 02:40:079692 ReleaseIOSurfaceForTexture(texture->service_id());
[email protected]e51bdf32011-11-23 22:21:469693
9694 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9695 texture_to_io_surface_map_.insert(
[email protected]02965c22013-03-09 02:40:079696 std::make_pair(texture->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469697
9698 CGLContextObj context =
9699 static_cast<CGLContextObj>(context_->GetHandle());
9700
9701 CGLError err = surface_support->CGLTexImageIOSurface2D(
9702 context,
9703 target,
9704 GL_RGBA,
9705 width,
9706 height,
9707 GL_BGRA,
9708 GL_UNSIGNED_INT_8_8_8_8_REV,
9709 surface,
9710 plane);
9711
9712 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519713 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469714 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439715 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469716 return;
9717 }
9718
9719 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:079720 texture, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469721 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9722
9723#else
[email protected]ab09b612013-03-11 22:11:519724 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439725 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469726#endif
9727}
9728
[email protected]97dc7cbe2011-12-06 17:26:179729static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9730 switch (internalformat) {
9731 case GL_RGB565:
9732 return GL_RGB;
9733 case GL_RGBA4:
9734 return GL_RGBA;
9735 case GL_RGB5_A1:
9736 return GL_RGBA;
9737 case GL_RGB8_OES:
9738 return GL_RGB;
9739 case GL_RGBA8_OES:
9740 return GL_RGBA;
9741 case GL_LUMINANCE8_ALPHA8_EXT:
9742 return GL_LUMINANCE_ALPHA;
9743 case GL_LUMINANCE8_EXT:
9744 return GL_LUMINANCE;
9745 case GL_ALPHA8_EXT:
9746 return GL_ALPHA;
9747 case GL_RGBA32F_EXT:
9748 return GL_RGBA;
9749 case GL_RGB32F_EXT:
9750 return GL_RGB;
9751 case GL_ALPHA32F_EXT:
9752 return GL_ALPHA;
9753 case GL_LUMINANCE32F_EXT:
9754 return GL_LUMINANCE;
9755 case GL_LUMINANCE_ALPHA32F_EXT:
9756 return GL_LUMINANCE_ALPHA;
9757 case GL_RGBA16F_EXT:
9758 return GL_RGBA;
9759 case GL_RGB16F_EXT:
9760 return GL_RGB;
9761 case GL_ALPHA16F_EXT:
9762 return GL_ALPHA;
9763 case GL_LUMINANCE16F_EXT:
9764 return GL_LUMINANCE;
9765 case GL_LUMINANCE_ALPHA16F_EXT:
9766 return GL_LUMINANCE_ALPHA;
9767 case GL_BGRA8_EXT:
9768 return GL_BGRA_EXT;
9769 default:
9770 return GL_NONE;
9771 }
9772}
9773
[email protected]43410e92012-04-20 17:06:289774void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039775 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
9776 GLenum internal_format) {
[email protected]02965c22013-03-09 02:40:079777 Texture* dest_texture = GetTexture(dest_id);
9778 Texture* source_texture = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289779
[email protected]02965c22013-03-09 02:40:079780 if (!source_texture || !dest_texture) {
[email protected]ab09b612013-03-11 22:11:519781 LOCAL_SET_GL_ERROR(
9782 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289783 return;
9784 }
9785
9786 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519787 LOCAL_SET_GL_ERROR(
9788 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289789 return;
9790 }
9791
[email protected]02965c22013-03-09 02:40:079792 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259793 (source_texture->target() != GL_TEXTURE_2D &&
9794 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]ab09b612013-03-11 22:11:519795 LOCAL_SET_GL_ERROR(
9796 GL_INVALID_VALUE,
9797 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039798 return;
9799 }
9800
[email protected]43410e92012-04-20 17:06:289801 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289802
[email protected]9bc9a2e82013-04-03 03:56:259803 // When the source texture is GL_TEXTURE_EXTERNAL_OES, we assume width
9804 // and height are the same as destination texture. The caller needs to
9805 // make sure they allocate a destination texture which is the same size
9806 // as the source. This is due to the limitation of the StreamTexture.
9807 // There is no way to find out the size of the texture from the GL consumer
9808 // side. But StreamTextures are unique per video stream and should never
9809 // change, so we could find out the size of the video stream and allocate
9810 // a equal size RGBA texture for copy. TODO(hkuang): Add support to get
9811 // width/height of StreamTexture crbug.com/225781.
9812 if (source_texture->target() == GL_TEXTURE_2D) {
9813 if (!source_texture->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
9814 &source_height)) {
9815 LOCAL_SET_GL_ERROR(
9816 GL_INVALID_VALUE,
9817 "glCopyTextureChromium", "source texture has no level 0");
9818 return;
9819 }
9820
9821 // Check that this type of texture is allowed.
9822 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
9823 source_height, 1)) {
9824 LOCAL_SET_GL_ERROR(
9825 GL_INVALID_VALUE,
9826 "glCopyTextureCHROMIUM", "Bad dimensions");
9827 return;
9828 }
[email protected]43410e92012-04-20 17:06:289829 }
9830
[email protected]cf6b8f62012-05-25 21:43:379831 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9832 // needed because it takes 10s of milliseconds to initialize.
9833 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519834 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379835 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279836 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379837 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519838 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379839 return;
9840 }
9841
[email protected]0a1e9ad2012-05-04 21:13:039842 GLenum dest_type;
9843 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079844 bool dest_level_defined = dest_texture->GetLevelSize(
9845 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289846
[email protected]0a1e9ad2012-05-04 21:13:039847 if (dest_level_defined) {
[email protected]02965c22013-03-09 02:40:079848 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type,
9849 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039850 } else {
9851 GLenum source_internal_format;
[email protected]02965c22013-03-09 02:40:079852 source_texture->GetLevelType(GL_TEXTURE_2D, 0, &dest_type,
9853 &source_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039854 }
9855
[email protected]9bc9a2e82013-04-03 03:56:259856 // Set source texture's width and height to be the same as
9857 // destination texture when source is GL_TEXTURE_EXTERNAL_OES.
9858 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9859 source_width = dest_width;
9860 source_height = dest_height;
9861 }
9862
[email protected]0a1e9ad2012-05-04 21:13:039863 // Resize the destination texture to the dimensions of the source texture.
9864 if (!dest_level_defined || dest_width != source_width ||
9865 dest_height != source_height ||
9866 dest_internal_format != internal_format) {
[email protected]43410e92012-04-20 17:06:289867 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519868 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079869 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]43410e92012-04-20 17:06:289870 WrappedTexImage2D(
9871 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039872 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519873 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039874 if (error != GL_NO_ERROR) {
9875 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289876 return;
[email protected]0a1e9ad2012-05-04 21:13:039877 }
[email protected]43410e92012-04-20 17:06:289878
9879 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:079880 dest_texture, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039881 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259882 } else {
[email protected]02965c22013-03-09 02:40:079883 texture_manager()->SetLevelCleared(
9884 dest_texture, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289885 }
9886
[email protected]07a0cc32013-02-28 00:36:279887 copy_texture_CHROMIUM_->DoCopyTexture(this,
[email protected]02965c22013-03-09 02:40:079888 source_texture->target(),
9889 dest_texture->target(),
9890 source_texture->service_id(),
9891 dest_texture->service_id(), level,
[email protected]07a0cc32013-02-28 00:36:279892 source_width, source_height,
[email protected]43410e92012-04-20 17:06:289893 unpack_flip_y_,
[email protected]6c75c712012-06-19 15:43:179894 unpack_premultiply_alpha_,
9895 unpack_unpremultiply_alpha_);
[email protected]43410e92012-04-20 17:06:289896}
9897
[email protected]97dc7cbe2011-12-06 17:26:179898static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9899 switch (internalformat) {
9900 case GL_RGB565:
9901 return GL_UNSIGNED_SHORT_5_6_5;
9902 case GL_RGBA4:
9903 return GL_UNSIGNED_SHORT_4_4_4_4;
9904 case GL_RGB5_A1:
9905 return GL_UNSIGNED_SHORT_5_5_5_1;
9906 case GL_RGB8_OES:
9907 return GL_UNSIGNED_BYTE;
9908 case GL_RGBA8_OES:
9909 return GL_UNSIGNED_BYTE;
9910 case GL_LUMINANCE8_ALPHA8_EXT:
9911 return GL_UNSIGNED_BYTE;
9912 case GL_LUMINANCE8_EXT:
9913 return GL_UNSIGNED_BYTE;
9914 case GL_ALPHA8_EXT:
9915 return GL_UNSIGNED_BYTE;
9916 case GL_RGBA32F_EXT:
9917 return GL_FLOAT;
9918 case GL_RGB32F_EXT:
9919 return GL_FLOAT;
9920 case GL_ALPHA32F_EXT:
9921 return GL_FLOAT;
9922 case GL_LUMINANCE32F_EXT:
9923 return GL_FLOAT;
9924 case GL_LUMINANCE_ALPHA32F_EXT:
9925 return GL_FLOAT;
9926 case GL_RGBA16F_EXT:
9927 return GL_HALF_FLOAT_OES;
9928 case GL_RGB16F_EXT:
9929 return GL_HALF_FLOAT_OES;
9930 case GL_ALPHA16F_EXT:
9931 return GL_HALF_FLOAT_OES;
9932 case GL_LUMINANCE16F_EXT:
9933 return GL_HALF_FLOAT_OES;
9934 case GL_LUMINANCE_ALPHA16F_EXT:
9935 return GL_HALF_FLOAT_OES;
9936 case GL_BGRA8_EXT:
9937 return GL_UNSIGNED_BYTE;
9938 default:
9939 return GL_NONE;
9940 }
9941}
9942
9943void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449944 GLenum target,
9945 GLint levels,
9946 GLenum internal_format,
9947 GLsizei width,
9948 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389949 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419950 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179951 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:519952 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439953 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179954 return;
9955 }
[email protected]02965c22013-03-09 02:40:079956 Texture* texture = GetTextureInfoForTarget(target);
9957 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519958 LOCAL_SET_GL_ERROR(
9959 GL_INVALID_OPERATION,
9960 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179961 return;
9962 }
[email protected]02965c22013-03-09 02:40:079963 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:429964 clear_state_dirty_ = true;
[email protected]97dc7cbe2011-12-06 17:26:179965 }
[email protected]02965c22013-03-09 02:40:079966 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519967 LOCAL_SET_GL_ERROR(
9968 GL_INVALID_OPERATION,
9969 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179970 return;
9971 }
[email protected]7989c9e2013-01-23 06:39:269972
9973 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9974 GLenum type = ExtractTypeFromStorageFormat(internal_format);
9975
9976 {
9977 GLsizei level_width = width;
9978 GLsizei level_height = height;
9979 uint32 estimated_size = 0;
9980 for (int ii = 0; ii < levels; ++ii) {
9981 uint32 level_size = 0;
9982 if (!GLES2Util::ComputeImageDataSizes(
9983 level_width, level_height, format, type, state_.unpack_alignment,
9984 &estimated_size, NULL, NULL) ||
9985 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519986 LOCAL_SET_GL_ERROR(
9987 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269988 return;
9989 }
9990 level_width = std::max(1, level_width >> 1);
9991 level_height = std::max(1, level_height >> 1);
9992 }
9993 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519994 LOCAL_SET_GL_ERROR(
9995 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269996 return;
9997 }
9998 }
9999
[email protected]ab09b612013-03-11 22:11:5110000 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]f0e6a34f2012-01-04 20:53:4010001 glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format),
10002 width, height);
[email protected]ab09b612013-03-11 22:11:5110003 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710004 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510005 GLsizei level_width = width;
10006 GLsizei level_height = height;
10007 for (int ii = 0; ii < levels; ++ii) {
10008 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:0710009 texture, target, ii, format, level_width, level_height, 1, 0, format,
[email protected]80eb6b52012-01-19 00:14:4110010 type, false);
[email protected]4502e6492011-12-14 19:39:1510011 level_width = std::max(1, level_width >> 1);
10012 level_height = std::max(1, level_height >> 1);
10013 }
[email protected]02965c22013-03-09 02:40:0710014 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710015 }
[email protected]97dc7cbe2011-12-06 17:26:1710016}
[email protected]e51bdf32011-11-23 22:21:4610017
[email protected]78b514b2012-05-01 21:50:5910018error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510019 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]78b514b2012-05-01 21:50:5910020 MailboxName name;
10021 mailbox_manager()->GenerateMailboxName(&name);
10022 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
10023 Bucket* bucket = CreateBucket(bucket_id);
10024
10025 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
10026 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
10027
10028 return error::kNoError;
10029}
10030
10031void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
10032 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:0210033 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
10034 "context", GetLogPrefix(),
10035 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
10036
[email protected]02965c22013-03-09 02:40:0710037 Texture* texture = GetTextureInfoForTarget(target);
10038 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110039 LOCAL_SET_GL_ERROR(
10040 GL_INVALID_OPERATION,
10041 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910042 return;
10043 }
10044
[email protected]02965c22013-03-09 02:40:0710045 TextureDefinition* definition = texture_manager()->Save(texture);
[email protected]78b514b2012-05-01 21:50:5910046 if (!definition) {
[email protected]ab09b612013-03-11 22:11:5110047 LOCAL_SET_GL_ERROR(
10048 GL_INVALID_OPERATION,
10049 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:5910050 return;
10051 }
10052
10053 if (!group_->mailbox_manager()->ProduceTexture(
10054 target,
10055 *reinterpret_cast<const MailboxName*>(mailbox),
10056 definition,
10057 texture_manager())) {
[email protected]02965c22013-03-09 02:40:0710058 bool success = texture_manager()->Restore(
10059 "glProductTextureCHROMIUM", this, texture, definition);
[email protected]78b514b2012-05-01 21:50:5910060 DCHECK(success);
[email protected]ab09b612013-03-11 22:11:5110061 LOCAL_SET_GL_ERROR(
10062 GL_INVALID_OPERATION,
10063 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910064 return;
10065 }
10066
[email protected]02965c22013-03-09 02:40:0710067 glBindTexture(texture->target(), texture->service_id());
[email protected]78b514b2012-05-01 21:50:5910068}
10069
10070void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
10071 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:0210072 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
10073 "context", GetLogPrefix(),
10074 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
10075
[email protected]02965c22013-03-09 02:40:0710076 Texture* texture = GetTextureInfoForTarget(target);
10077 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110078 LOCAL_SET_GL_ERROR(
10079 GL_INVALID_OPERATION,
10080 "glConsumeTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910081 return;
10082 }
10083
10084 scoped_ptr<TextureDefinition> definition(
10085 group_->mailbox_manager()->ConsumeTexture(
10086 target,
10087 *reinterpret_cast<const MailboxName*>(mailbox)));
10088 if (!definition.get()) {
[email protected]ab09b612013-03-11 22:11:5110089 LOCAL_SET_GL_ERROR(
10090 GL_INVALID_OPERATION,
10091 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910092 return;
10093 }
10094
[email protected]02965c22013-03-09 02:40:0710095 if (!texture_manager()->Restore(
10096 "glConsumeTextureCHROMIUM", this, texture, definition.release())) {
[email protected]ab09b612013-03-11 22:11:5110097 LOCAL_SET_GL_ERROR(
10098 GL_INVALID_OPERATION,
10099 "glConsumeTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:5910100 return;
10101 }
[email protected]78b514b2012-05-01 21:50:5910102}
10103
[email protected]d2a0e1a2012-08-12 02:25:0110104void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10105 GLsizei length, const GLchar* marker) {
10106 if (!marker) {
10107 marker = "";
10108 }
10109 debug_marker_manager_.SetMarker(
10110 length ? std::string(marker, length) : std::string(marker));
10111}
10112
10113void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10114 GLsizei length, const GLchar* marker) {
10115 if (!marker) {
10116 marker = "";
10117 }
10118 debug_marker_manager_.PushGroup(
10119 length ? std::string(marker, length) : std::string(marker));
10120}
10121
10122void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10123 debug_marker_manager_.PopGroup();
10124}
10125
[email protected]09d50362012-10-18 20:54:3710126void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10127 GLenum target, GLint image_id) {
10128 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
10129 if (target != GL_TEXTURE_2D) {
10130 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:5110131 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:3710132 GL_INVALID_OPERATION,
10133 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
10134 return;
10135 }
10136
10137 // Default target might be conceptually valid, but disallow it to avoid
10138 // accidents.
[email protected]02965c22013-03-09 02:40:0710139 Texture* texture = GetTextureInfoForTargetUnlessDefault(target);
10140 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110141 LOCAL_SET_GL_ERROR(
10142 GL_INVALID_OPERATION,
10143 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710144 return;
10145 }
10146
10147 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10148 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110149 LOCAL_SET_GL_ERROR(
10150 GL_INVALID_OPERATION,
10151 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710152 return;
10153 }
10154
10155 if (!gl_image->BindTexImage()) {
[email protected]ab09b612013-03-11 22:11:5110156 LOCAL_SET_GL_ERROR(
10157 GL_INVALID_OPERATION,
10158 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
[email protected]09d50362012-10-18 20:54:3710159 return;
10160 }
10161
10162 gfx::Size size = gl_image->GetSize();
10163 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:0710164 texture, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710165 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]02965c22013-03-09 02:40:0710166 texture_manager()->SetLevelImage(texture, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710167}
10168
10169void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10170 GLenum target, GLint image_id) {
10171 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
10172 if (target != GL_TEXTURE_2D) {
10173 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:5110174 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:3710175 GL_INVALID_OPERATION,
10176 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
10177 return;
10178 }
10179
10180 // Default target might be conceptually valid, but disallow it to avoid
10181 // accidents.
[email protected]02965c22013-03-09 02:40:0710182 Texture* texture = GetTextureInfoForTargetUnlessDefault(target);
10183 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110184 LOCAL_SET_GL_ERROR(
10185 GL_INVALID_OPERATION,
10186 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710187 return;
10188 }
10189
10190 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10191 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110192 LOCAL_SET_GL_ERROR(
10193 GL_INVALID_OPERATION,
10194 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710195 return;
10196 }
10197
10198 // Do nothing when image is not currently bound.
[email protected]02965c22013-03-09 02:40:0710199 if (texture->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710200 return;
10201
10202 gl_image->ReleaseTexImage();
10203
10204 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:0710205 texture, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710206 GL_RGBA, GL_UNSIGNED_BYTE, false);
10207}
[email protected]d2a0e1a2012-08-12 02:25:0110208
[email protected]94307712012-11-16 23:26:1110209error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510210 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110211 Bucket* bucket = GetBucket(c.bucket_id);
10212 if (!bucket || bucket->size() == 0) {
10213 return error::kInvalidArguments;
10214 }
10215 std::string command_name;
10216 if (!bucket->GetAsString(&command_name)) {
10217 return error::kInvalidArguments;
10218 }
[email protected]fb97b662013-02-20 23:02:1410219 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
10220 if (!gpu_tracer_->Begin(command_name)) {
[email protected]ab09b612013-03-11 22:11:5110221 LOCAL_SET_GL_ERROR(
10222 GL_INVALID_OPERATION,
10223 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410224 return error::kNoError;
10225 }
[email protected]94307712012-11-16 23:26:1110226 return error::kNoError;
10227}
10228
10229void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410230 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110231 LOCAL_SET_GL_ERROR(
10232 GL_INVALID_OPERATION,
10233 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110234 return;
10235 }
[email protected]fb97b662013-02-20 23:02:1410236 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
10237 gpu_tracer_->End();
[email protected]94307712012-11-16 23:26:1110238}
10239
[email protected]2f143d482013-03-14 18:04:4910240void GLES2DecoderImpl::DoDrawBuffersEXT(
10241 GLsizei count, const GLenum* bufs) {
10242 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10243 LOCAL_SET_GL_ERROR(
10244 GL_INVALID_VALUE,
10245 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10246 return;
10247 }
10248
10249 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10250 if (framebuffer) {
10251 for (GLsizei i = 0; i < count; ++i) {
10252 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10253 bufs[i] != GL_NONE) {
10254 LOCAL_SET_GL_ERROR(
10255 GL_INVALID_OPERATION,
10256 "glDrawBuffersEXT",
10257 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10258 return;
10259 }
10260 }
10261 glDrawBuffersARB(count, bufs);
10262 framebuffer->SetDrawBuffers(count, bufs);
10263 } else { // backbuffer
10264 if (count > 1 ||
10265 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10266 LOCAL_SET_GL_ERROR(
10267 GL_INVALID_OPERATION,
10268 "glDrawBuffersEXT",
10269 "more than one buffer or bufs not GL_NONE or GL_BACK");
10270 return;
10271 }
10272 GLenum mapped_buf = bufs[0];
10273 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10274 bufs[0] == GL_BACK) {
10275 mapped_buf = GL_COLOR_ATTACHMENT0;
10276 }
10277 glDrawBuffersARB(count, &mapped_buf);
10278 group_->set_draw_buffer(bufs[0]);
10279 }
10280}
10281
[email protected]32145a92012-12-17 09:01:5910282bool GLES2DecoderImpl::ValidateAsyncTransfer(
10283 const char* function_name,
[email protected]02965c22013-03-09 02:40:0710284 Texture* texture,
[email protected]32145a92012-12-17 09:01:5910285 GLenum target,
10286 GLint level,
10287 const void * data) {
10288 // We only support async uploads to 2D textures for now.
10289 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110290 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910291 return false;
10292 }
10293 // We only support uploads to level zero for now.
10294 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110295 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910296 return false;
10297 }
10298 // A transfer buffer must be bound, even for asyncTexImage2D.
10299 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110300 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910301 return false;
10302 }
10303 // We only support one async transfer in progress.
[email protected]02965c22013-03-09 02:40:0710304 if (!texture || texture->AsyncTransferIsInProgress()) {
[email protected]ab09b612013-03-11 22:11:5110305 LOCAL_SET_GL_ERROR(
10306 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910307 function_name, "transfer already in progress");
10308 return false;
10309 }
10310 return true;
10311}
10312
[email protected]69023942012-11-30 19:57:1610313error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510314 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610315 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610316 GLenum target = static_cast<GLenum>(c.target);
10317 GLint level = static_cast<GLint>(c.level);
10318 GLint internal_format = static_cast<GLint>(c.internalformat);
10319 GLsizei width = static_cast<GLsizei>(c.width);
10320 GLsizei height = static_cast<GLsizei>(c.height);
10321 GLint border = static_cast<GLint>(c.border);
10322 GLenum format = static_cast<GLenum>(c.format);
10323 GLenum type = static_cast<GLenum>(c.type);
10324 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10325 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10326 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910327
10328 // TODO(epenner): Move this and copies of this memory validation
10329 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610330 if (!GLES2Util::ComputeImageDataSizes(
10331 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10332 NULL)) {
10333 return error::kOutOfBounds;
10334 }
10335 const void* pixels = NULL;
10336 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10337 pixels = GetSharedMemoryAs<const void*>(
10338 pixels_shm_id, pixels_shm_offset, pixels_size);
10339 if (!pixels) {
10340 return error::kOutOfBounds;
10341 }
10342 }
10343
[email protected]32145a92012-12-17 09:01:5910344 // All the normal glTexSubImage2D validation.
10345 if (!ValidateTexImage2D(
10346 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
10347 width, height, border, format, type, pixels, pixels_size)) {
10348 return error::kNoError;
10349 }
10350
10351 // Extra async validation.
[email protected]02965c22013-03-09 02:40:0710352 Texture* texture = GetTextureInfoForTarget(target);
[email protected]32145a92012-12-17 09:01:5910353 if (!ValidateAsyncTransfer(
[email protected]02965c22013-03-09 02:40:0710354 "glAsyncTexImage2DCHROMIUM", texture, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910355 return error::kNoError;
10356
10357 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710358 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110359 LOCAL_SET_GL_ERROR(
10360 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910361 "glAsyncTexImage2DCHROMIUM", "already defined");
10362 return error::kNoError;
10363 }
10364
[email protected]5b3a8e02013-03-13 05:36:4410365 // Since we don't allow async redefinition, this is the only
10366 // time the size of this texture can change while bound
10367 // as a frame-buffer.
10368 if (texture->IsAttachedToFramebuffer()) {
10369 // TODO(gman): If textures tracked which framebuffers they were attached to
10370 // we could just mark those framebuffers as not complete.
10371 framebuffer_manager()->IncFramebufferStateChangeCount();
10372 }
10373
[email protected]7989c9e2013-01-23 06:39:2610374 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110375 LOCAL_SET_GL_ERROR(
10376 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610377 return error::kNoError;
10378 }
10379
[email protected]32145a92012-12-17 09:01:5910380 // We know the memory/size is safe, so get the real shared memory since
10381 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110382 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910383 base::SharedMemory* shared_memory = buffer.shared_memory;
10384 uint32 shm_size = buffer.size;
10385 uint32 shm_data_offset = c.pixels_shm_offset;
10386 uint32 shm_data_size = pixels_size;
10387
[email protected]5b3a8e02013-03-13 05:36:4410388 // Setup the parameters.
[email protected]32145a92012-12-17 09:01:5910389 GLenum gl_internal_format =
10390 GetTexInternalFormat(internal_format, format, type);
10391 gfx::AsyncTexImage2DParams tex_params = {target, level, gl_internal_format,
10392 width, height, border, format, type};
10393 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
10394 shm_data_offset, shm_data_size};
10395
[email protected]5b3a8e02013-03-13 05:36:4410396 // Set up the async state if needed, and make the texture
10397 // immutable so the async state stays valid. The level info
10398 // is set up lazily when the transfer completes.
10399 DCHECK(!texture->GetAsyncTransferState());
10400 texture->SetAsyncTransferState(
10401 async_pixel_transfer_delegate_->
10402 CreatePixelTransferState(texture->service_id(),
10403 tex_params));
10404 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910405
10406 async_pixel_transfer_delegate_->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410407 texture->GetAsyncTransferState(),
10408 tex_params,
10409 mem_params,
10410 base::Bind(&TextureManager::SetLevelInfoFromParams,
10411 // The callback is only invoked if the transfer state
10412 // still exists, which implies through manager->info->state
10413 // ownership that both of these pointers are valid.
10414 base::Unretained(texture_manager()),
10415 base::Unretained(texture),
10416 tex_params));
[email protected]f598f422012-12-07 08:30:0310417 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610418}
10419
10420error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510421 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610422 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610423 GLenum target = static_cast<GLenum>(c.target);
10424 GLint level = static_cast<GLint>(c.level);
10425 GLint xoffset = static_cast<GLint>(c.xoffset);
10426 GLint yoffset = static_cast<GLint>(c.yoffset);
10427 GLsizei width = static_cast<GLsizei>(c.width);
10428 GLsizei height = static_cast<GLsizei>(c.height);
10429 GLenum format = static_cast<GLenum>(c.format);
10430 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910431
10432 // TODO(epenner): Move this and copies of this memory validation
10433 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610434 uint32 data_size;
10435 if (!GLES2Util::ComputeImageDataSizes(
10436 width, height, format, type, state_.unpack_alignment, &data_size,
10437 NULL, NULL)) {
10438 return error::kOutOfBounds;
10439 }
10440 const void* pixels = GetSharedMemoryAs<const void*>(
10441 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910442
10443 // All the normal glTexSubImage2D validation.
10444 error::Error error = error::kNoError;
10445 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10446 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10447 return error;
[email protected]69023942012-11-30 19:57:1610448 }
10449
[email protected]32145a92012-12-17 09:01:5910450 // Extra async validation.
[email protected]02965c22013-03-09 02:40:0710451 Texture* texture = GetTextureInfoForTarget(target);
[email protected]32145a92012-12-17 09:01:5910452 if (!ValidateAsyncTransfer(
[email protected]02965c22013-03-09 02:40:0710453 "glAsyncTexSubImage2DCHROMIUM", texture, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910454 return error::kNoError;
10455
10456 // Guarantee async textures are always 'cleared' as follows:
10457 // - AsyncTexImage2D can not redefine an existing texture
10458 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10459 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10460 // - Textures become immutable after an async call.
10461 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710462 if (!texture->SafeToRenderFrom()) {
10463 if (!texture_manager()->ClearTextureLevel(this, texture, target, level)) {
[email protected]ab09b612013-03-11 22:11:5110464 LOCAL_SET_GL_ERROR(
10465 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510466 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910467 return error::kNoError;
10468 }
10469 }
10470
10471 // We know the memory/size is safe, so get the real shared memory since
10472 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110473 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910474 base::SharedMemory* shared_memory = buffer.shared_memory;
10475 uint32 shm_size = buffer.size;
10476 uint32 shm_data_offset = c.data_shm_offset;
10477 uint32 shm_data_size = data_size;
10478
[email protected]5b3a8e02013-03-13 05:36:4410479 // Setup the parameters.
[email protected]32145a92012-12-17 09:01:5910480 gfx::AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
10481 width, height, format, type};
10482 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
10483 shm_data_offset, shm_data_size};
[email protected]5b3a8e02013-03-13 05:36:4410484 if (!texture->GetAsyncTransferState()) {
10485 // TODO(epenner): We may want to enforce exclusive use
10486 // of async APIs in which case this should become an error,
10487 // (the texture should have been async defined).
10488 gfx::AsyncTexImage2DParams define_params = {target, level,
10489 0, 0, 0, 0, 0, 0};
10490 texture->GetLevelSize(target, level, &define_params.width,
10491 &define_params.height);
10492 texture->GetLevelType(target, level, &define_params.type,
10493 &define_params.internal_format);
10494 // Set up the async state if needed, and make the texture
10495 // immutable so the async state stays valid.
10496 texture->SetAsyncTransferState(
10497 async_pixel_transfer_delegate_->
10498 CreatePixelTransferState(texture->service_id(),
10499 define_params));
10500 texture->SetImmutable(true);
10501 }
10502
[email protected]32145a92012-12-17 09:01:5910503 async_pixel_transfer_delegate_->AsyncTexSubImage2D(
[email protected]02965c22013-03-09 02:40:0710504 texture->GetAsyncTransferState(), tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910505 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610506}
10507
[email protected]a00c1f742013-03-05 17:02:1610508error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10509 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10510 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10511 GLenum target = static_cast<GLenum>(c.target);
10512
10513 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110514 LOCAL_SET_GL_ERROR(
10515 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610516 return error::kNoError;
10517 }
[email protected]02965c22013-03-09 02:40:0710518 Texture* texture = GetTextureInfoForTarget(target);
10519 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110520 LOCAL_SET_GL_ERROR(
10521 GL_INVALID_OPERATION,
10522 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610523 return error::kNoError;
10524 }
10525 async_pixel_transfer_delegate_->WaitForTransferCompletion(
[email protected]02965c22013-03-09 02:40:0710526 texture->GetAsyncTransferState());
[email protected]69a8701e2013-03-07 21:31:0910527 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610528 return error::kNoError;
10529}
10530
[email protected]96449d2c2009-11-25 00:01:3210531// Include the auto-generated part of this file. We split this because it means
10532// we can easily edit the non-auto generated parts right here in this file
10533// instead of having to edit some template or the code generator.
10534#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10535
10536} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510537} // namespace gpu