blob: 41d7c6de6f77135401f32618feb3d20c1dec6446 [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]f4390962013-06-11 07:29:2225#include "base/strings/string_number_conversions.h"
[email protected]d37231fa2010-04-09 21:16:0226#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3227#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2228#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3229#include "gpu/command_buffer/common/gles2_cmd_format.h"
30#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1031#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5132#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2233#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
34#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5035#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3236#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5037#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2438#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5039#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1140#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5841#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3242#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2843#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4644#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]e844ae22012-01-14 03:36:2645#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1446#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3747#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5948#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2549#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4750#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5351#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5852#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4753#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4554#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0455#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]b0af4f52011-09-28 22:04:4256#include "gpu/command_buffer/service/stream_texture.h"
57#include "gpu/command_buffer/service/stream_texture_manager.h"
[email protected]a93bb842010-02-16 23:03:4758#include "gpu/command_buffer/service/texture_manager.h"
[email protected]944b62f32012-09-27 02:20:4659#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2260#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]d8bc3ec2013-03-07 06:28:4061#include "ui/gl/gl_bindings.h"
[email protected]09d50362012-10-18 20:54:3762#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2763#include "ui/gl/gl_implementation.h"
64#include "ui/gl/gl_surface.h"
[email protected]e51bdf32011-11-23 22:21:4665#if defined(OS_MACOSX)
[email protected]d353541f2012-05-03 22:45:4166#include "ui/surface/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4667#endif
[email protected]de17df392010-04-23 21:09:4168
[email protected]693ca512012-11-13 18:09:1369// TODO(zmo): we can't include "City.h" due to type def conflicts.
70extern uint64 CityHash64(const char*, size_t);
71
[email protected]a7a27ace2009-12-12 00:11:2572namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3273namespace gles2 {
74
[email protected]f0d74742011-10-03 16:31:0475namespace {
[email protected]693ca512012-11-13 18:09:1376
[email protected]f0d74742011-10-03 16:31:0477static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4978static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1379static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]693ca512012-11-13 18:09:1380
[email protected]3d944a82013-02-12 19:09:0281#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]693ca512012-11-13 18:09:1382khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
83 return static_cast<khronos_uint64_t>(
84 CityHash64(name, static_cast<size_t>(len)));
85}
[email protected]3d944a82013-02-12 19:09:0286#endif
[email protected]693ca512012-11-13 18:09:1387
[email protected]448e459e2013-06-12 17:00:4188static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
89 GLint rangeMax,
90 GLint precision) {
91 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
92}
93
[email protected]8dc1bf92013-03-12 03:58:2194static void GetShaderPrecisionFormatImpl(GLenum shader_type,
95 GLenum precision_type,
96 GLint *range, GLint *precision) {
97 switch (precision_type) {
98 case GL_LOW_INT:
99 case GL_MEDIUM_INT:
100 case GL_HIGH_INT:
101 // These values are for a 32-bit twos-complement integer format.
102 range[0] = 31;
103 range[1] = 30;
104 *precision = 0;
105 break;
106 case GL_LOW_FLOAT:
107 case GL_MEDIUM_FLOAT:
108 case GL_HIGH_FLOAT:
109 // These values are for an IEEE single-precision floating-point format.
110 range[0] = 127;
111 range[1] = 127;
112 *precision = 23;
113 break;
114 default:
115 NOTREACHED();
116 break;
117 }
118
[email protected]8af4d5e2013-03-15 23:55:33119 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
120 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21121 // This function is sometimes defined even though it's really just
122 // a stub, so we need to set range and precision as if it weren't
123 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44124 // On Mac OS with some GPUs, calling this generates a
125 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
126 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21127 glGetShaderPrecisionFormat(shader_type, precision_type,
128 range, precision);
[email protected]448e459e2013-06-12 17:00:41129
130 // TODO(brianderson): Make the following official workarounds.
131
132 // Some drivers have bugs where they report the ranges as a negative number.
133 // Taking the absolute value here shouldn't hurt because negative numbers
134 // aren't expected anyway.
135 range[0] = abs(range[0]);
136 range[1] = abs(range[1]);
137
138 // If the driver reports a precision for highp float that isn't actually
139 // highp, don't pretend like it's supported because shader compilation will
140 // fail anyway.
141 if (precision_type == GL_HIGH_FLOAT &&
142 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
143 range[0] = 0;
144 range[1] = 0;
145 *precision = 0;
146 }
[email protected]8dc1bf92013-03-12 03:58:21147 }
148}
149
[email protected]b04e24c2013-01-08 18:35:25150} // namespace
[email protected]f0d74742011-10-03 16:31:04151
[email protected]6217d392010-03-25 22:08:35152class GLES2DecoderImpl;
153
[email protected]ab09b612013-03-11 22:11:51154// Local versions of the SET_GL_ERROR macros
155#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50156 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51157#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50158 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
159 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51160#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50161 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
162 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51163#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50164 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
165 function_name)
[email protected]ab09b612013-03-11 22:11:51166#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50167 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51168#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50169 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51170#define LOCAL_PERFORMANCE_WARNING(msg) \
171 PerformanceWarning(__FILE__, __LINE__, msg)
172#define LOCAL_RENDER_WARNING(msg) \
173 RenderWarning(__FILE__, __LINE__, msg)
174
[email protected]07f54fcc2009-12-22 02:46:30175// Check that certain assumptions the code makes are true. There are places in
176// the code where shared memory is passed direclty to GL. Example, glUniformiv,
177// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
178// a few others) are 32bits. If they are not 32bits the code will have to change
179// to call those GL functions with service side memory and then copy the results
180// to shared memory, converting the sizes.
181COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
182 GLint_not_same_size_as_uint32);
183COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
184 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37185COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
186 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30187
[email protected]43f28f832010-02-03 02:28:48188// TODO(kbr): the use of this anonymous namespace core dumps the
189// linker on Mac OS X 10.6 when the symbol ordering file is used
190// namespace {
[email protected]96449d2c2009-11-25 00:01:32191
192// Returns the address of the first byte after a struct.
193template <typename T>
194const void* AddressAfterStruct(const T& pod) {
195 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
196}
197
[email protected]07f54fcc2009-12-22 02:46:30198// Returns the address of the frst byte after the struct or NULL if size >
199// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32200template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30201RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
202 uint32 size,
203 uint32 immediate_data_size) {
204 return (size <= immediate_data_size) ?
205 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
206 NULL;
[email protected]96449d2c2009-11-25 00:01:32207}
208
[email protected]07f54fcc2009-12-22 02:46:30209// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18210bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32211 GLuint count,
212 size_t size,
[email protected]a76b0052010-03-05 00:33:18213 unsigned int elements_per_unit,
214 uint32* dst) {
215 uint32 value;
216 if (!SafeMultiplyUint32(count, size, &value)) {
217 return false;
218 }
219 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
220 return false;
221 }
222 *dst = value;
223 return true;
[email protected]96449d2c2009-11-25 00:01:32224}
225
226// A struct to hold info about each command.
227struct CommandInfo {
228 int arg_flags; // How to handle the arguments for this command
229 int arg_count; // How many arguments are expected for this command.
230};
231
232// A table of CommandInfo for all the commands.
233const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35234 #define GLES2_CMD_OP(name) { \
235 cmds::name::kArgFlags, \
236 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
[email protected]96449d2c2009-11-25 00:01:32237
238 GLES2_COMMAND_LIST(GLES2_CMD_OP)
239
240 #undef GLES2_CMD_OP
241};
242
[email protected]258a3313f2011-10-18 20:13:57243// Return true if a character belongs to the ASCII subset as defined in
244// GLSL ES 1.0 spec section 3.1.
245static bool CharacterIsValidForGLES(unsigned char c) {
246 // Printing characters are valid except " $ ` @ \ ' DEL.
247 if (c >= 32 && c <= 126 &&
248 c != '"' &&
249 c != '$' &&
250 c != '`' &&
251 c != '@' &&
252 c != '\\' &&
253 c != '\'') {
254 return true;
255 }
256 // Horizontal tab, line feed, vertical tab, form feed, carriage return
257 // are also valid.
258 if (c >= 9 && c <= 13) {
259 return true;
260 }
261
262 return false;
263}
264
265static bool StringIsValidForGLES(const char* str) {
266 for (; *str; ++str) {
267 if (!CharacterIsValidForGLES(*str)) {
268 return false;
269 }
270 }
271 return true;
272}
273
[email protected]297ca1c2011-06-20 23:08:46274// Wrapper for glEnable/glDisable that doesn't suck.
275static void EnableDisable(GLenum pname, bool enable) {
276 if (enable) {
277 glEnable(pname);
278 } else {
279 glDisable(pname);
280 }
281}
282
[email protected]6217d392010-03-25 22:08:35283// This class prevents any GL errors that occur when it is in scope from
284// being reported to the client.
285class ScopedGLErrorSuppressor {
286 public:
[email protected]ab09b612013-03-11 22:11:51287 explicit ScopedGLErrorSuppressor(
288 const char* function_name, GLES2DecoderImpl* decoder);
[email protected]6217d392010-03-25 22:08:35289 ~ScopedGLErrorSuppressor();
290 private:
[email protected]ab09b612013-03-11 22:11:51291 const char* function_name_;
[email protected]6217d392010-03-25 22:08:35292 GLES2DecoderImpl* decoder_;
293 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
294};
295
296// Temporarily changes a decoder's bound 2D texture and restore it when this
297// object goes out of scope. Also temporarily switches to using active texture
298// unit zero in case the client has changed that to something invalid.
299class ScopedTexture2DBinder {
300 public:
301 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
302 ~ScopedTexture2DBinder();
303
304 private:
305 GLES2DecoderImpl* decoder_;
306 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
307};
308
309// Temporarily changes a decoder's bound render buffer and restore it when this
310// object goes out of scope.
311class ScopedRenderBufferBinder {
312 public:
313 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
314 ~ScopedRenderBufferBinder();
315
316 private:
317 GLES2DecoderImpl* decoder_;
318 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
319};
320
321// Temporarily changes a decoder's bound frame buffer and restore it when this
322// object goes out of scope.
323class ScopedFrameBufferBinder {
324 public:
325 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
326 ~ScopedFrameBufferBinder();
327
328 private:
329 GLES2DecoderImpl* decoder_;
330 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
331};
332
[email protected]34ff8b0c2010-10-01 20:06:02333// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52334// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27335// if it is bound or enforce_internal_framebuffer is true. If internal is
336// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02337class ScopedResolvedFrameBufferBinder {
338 public:
[email protected]e7e38032011-07-26 17:25:25339 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27340 bool enforce_internal_framebuffer,
341 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02342 ~ScopedResolvedFrameBufferBinder();
343
344 private:
345 GLES2DecoderImpl* decoder_;
346 bool resolve_and_bind_;
347 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
348};
349
[email protected]63b465922012-09-06 02:04:52350// This class records texture upload time when in scope.
351class ScopedTextureUploadTimer {
352 public:
353 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder);
354 ~ScopedTextureUploadTimer();
355
356 private:
357 GLES2DecoderImpl* decoder_;
358 base::TimeTicks begin_time_;
359 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer);
360};
361
[email protected]6217d392010-03-25 22:08:35362// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35363class BackTexture {
[email protected]6217d392010-03-25 22:08:35364 public:
[email protected]ed9f9cd2013-02-27 21:12:35365 explicit BackTexture(GLES2DecoderImpl* decoder);
366 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35367
368 // Create a new render texture.
369 void Create();
370
371 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09372 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35373
374 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58375 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35376
377 // Destroy the render texture. This must be explicitly called before
378 // destroying this object.
379 void Destroy();
380
[email protected]97872062010-11-03 19:07:05381 // Invalidate the texture. This can be used when a context is lost and it is
382 // not possible to make it current in order to free the resource.
383 void Invalidate();
384
[email protected]6217d392010-03-25 22:08:35385 GLuint id() const {
386 return id_;
387 }
388
[email protected]d37231fa2010-04-09 21:16:02389 gfx::Size size() const {
390 return size_;
391 }
392
[email protected]1078f912011-12-23 13:12:14393 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25394 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14395 }
396
[email protected]6217d392010-03-25 22:08:35397 private:
398 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25399 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48400 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35401 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02402 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35403 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35404};
405
406// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35407class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35408 public:
[email protected]ed9f9cd2013-02-27 21:12:35409 explicit BackRenderbuffer(GLES2DecoderImpl* decoder);
410 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35411
412 // Create a new render buffer.
413 void Create();
414
415 // Set the initial size and format of a render buffer or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02416 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
[email protected]6217d392010-03-25 22:08:35417
418 // Destroy the render buffer. This must be explicitly called before destroying
419 // this object.
420 void Destroy();
421
[email protected]97872062010-11-03 19:07:05422 // Invalidate the render buffer. This can be used when a context is lost and
423 // it is not possible to make it current in order to free the resource.
424 void Invalidate();
425
[email protected]6217d392010-03-25 22:08:35426 GLuint id() const {
427 return id_;
428 }
429
[email protected]1078f912011-12-23 13:12:14430 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25431 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14432 }
433
[email protected]6217d392010-03-25 22:08:35434 private:
435 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25436 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48437 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35438 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35439 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35440};
441
442// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35443class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35444 public:
[email protected]ed9f9cd2013-02-27 21:12:35445 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
446 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35447
448 // Create a new frame buffer.
449 void Create();
450
451 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35452 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35453
[email protected]b9363b22010-06-09 22:06:15454 // Attach a render buffer to a frame buffer. Note that this unbinds any
455 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35456 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35457
[email protected]6217d392010-03-25 22:08:35458 // Destroy the frame buffer. This must be explicitly called before destroying
459 // this object.
460 void Destroy();
461
[email protected]97872062010-11-03 19:07:05462 // Invalidate the frame buffer. This can be used when a context is lost and it
463 // is not possible to make it current in order to free the resource.
464 void Invalidate();
465
[email protected]6217d392010-03-25 22:08:35466 // See glCheckFramebufferStatusEXT.
467 GLenum CheckStatus();
468
469 GLuint id() const {
470 return id_;
471 }
472
473 private:
474 GLES2DecoderImpl* decoder_;
475 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35476 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35477};
[email protected]34ff8b0c2010-10-01 20:06:02478
[email protected]43f28f832010-02-03 02:28:48479// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32480
[email protected]ddb1e5a2010-12-13 20:10:45481bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
482 uint32* service_texture_id) {
483 return false;
484}
485
[email protected]a3ded6d2010-10-19 06:44:39486GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06487 : initialized_(false),
488 debug_(false),
[email protected]1d82e822013-04-10 21:32:32489 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32490}
491
[email protected]3916c97e2010-02-25 03:20:50492GLES2Decoder::~GLES2Decoder() {
493}
494
[email protected]57edfdad2012-02-07 04:57:15495bool GLES2Decoder::testing_force_is_angle_;
496
497void GLES2Decoder::set_testing_force_is_angle(bool force) {
498 testing_force_is_angle_ = force;
499}
500
501bool GLES2Decoder::IsAngle() {
502#if defined(OS_WIN)
503 return testing_force_is_angle_ ||
504 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
505#else
506 return testing_force_is_angle_;
507#endif
508}
509
[email protected]f39f4b3f2010-05-12 17:04:08510// This class implements GLES2Decoder so we don't have to expose all the GLES2
511// cmd stuff to outside this class.
[email protected]ee1e6aa2012-11-29 09:24:10512class GLES2DecoderImpl : public GLES2Decoder {
[email protected]f39f4b3f2010-05-12 17:04:08513 public:
[email protected]476ccb72012-12-06 15:52:52514 // Used by PrepForSetUniformByLocation to validate types.
515 struct BaseUniformInfo {
516 const GLenum* const valid_types;
517 size_t num_valid_types;
518 };
519
[email protected]aa7666122011-09-02 19:45:52520 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00521 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08522
[email protected]96449d2c2009-11-25 00:01:32523 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14524 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50525 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00526 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32527
528 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00529 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32530
531 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38532 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
533 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23534 bool offscreen,
[email protected]6217d392010-03-25 22:08:35535 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29536 const DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39537 const char* allowed_extensions,
[email protected]b8e97b62012-09-30 15:09:00538 const std::vector<int32>& attribs) OVERRIDE;
539 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38540 virtual void SetSurface(
541 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]2ad674132013-06-05 07:48:51542 virtual bool ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00543 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39544 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00545 virtual bool MakeCurrent() OVERRIDE;
546 virtual void ReleaseCurrent() OVERRIDE;
547 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
548 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
549 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]1868a342012-11-07 15:56:02550 virtual void RestoreState() const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06551
552 virtual void RestoreActiveTexture() const OVERRIDE {
553 state_.RestoreActiveTexture();
554 }
[email protected]217004512013-05-10 21:25:55555 virtual void RestoreAllTextureUnitBindings() const OVERRIDE {
556 state_.RestoreAllTextureUnitBindings();
557 }
[email protected]29a4d902013-02-26 20:18:06558 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
559 state_.RestoreAttribute(index);
560 }
561 virtual void RestoreBufferBindings() const OVERRIDE {
562 state_.RestoreBufferBindings();
563 }
564 virtual void RestoreGlobalState() const OVERRIDE {
565 state_.RestoreGlobalState();
566 }
567 virtual void RestoreProgramBindings() const OVERRIDE {
568 state_.RestoreProgramBindings();
569 }
570 virtual void RestoreRenderbufferBindings() const OVERRIDE {
571 state_.RestoreRenderbufferBindings();
572 }
573 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
574 state_.RestoreTextureUnitBindings(unit);
575 }
576 virtual void RestoreFramebufferBindings() const OVERRIDE;
577 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
578
[email protected]b8e97b62012-09-30 15:09:00579 virtual QueryManager* GetQueryManager() OVERRIDE {
580 return query_manager_.get();
581 }
582 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46583 return vertex_array_manager_.get();
584 }
[email protected]b8e97b62012-09-30 15:09:00585 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05586 virtual bool HasMoreIdleWork() OVERRIDE;
587 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48588
[email protected]9d37f062011-11-22 01:24:52589 virtual void SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:07590 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00591
[email protected]1d82e822013-04-10 21:32:32592 virtual Logger* GetLogger() OVERRIDE;
[email protected]d3eba342013-04-18 21:11:50593 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]1d82e822013-04-10 21:32:32594
[email protected]e3932abb2013-03-13 00:01:37595 virtual void SetShaderCacheCallback(
596 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51597 virtual void SetWaitSyncPointCallback(
598 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00599
[email protected]b8e97b62012-09-30 15:09:00600 virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE;
[email protected]32145a92012-12-17 09:01:59601
[email protected]85a4ac22013-05-31 01:58:47602 virtual AsyncPixelTransferManager*
603 GetAsyncPixelTransferManager() OVERRIDE;
604 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]498b5c072013-06-04 19:30:07605 virtual void SetAsyncPixelTransferManagerForTest(
606 AsyncPixelTransferManager* manager) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09607 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59608
[email protected]1318e922010-09-17 22:03:16609 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00610 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48611
[email protected]63b465922012-09-06 02:04:52612 virtual uint32 GetTextureUploadCount() OVERRIDE;
613 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
614 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30615 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52616
[email protected]8e3e0662010-08-23 18:46:30617 // Restores the current state to the user's settings.
618 void RestoreCurrentFramebufferBindings();
619 void RestoreCurrentRenderbufferBindings();
620 void RestoreCurrentTexture2DBindings();
621
[email protected]297ca1c2011-06-20 23:08:46622 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
623 void ApplyDirtyState();
624
625 // These check the state of the currently bound framebuffer or the
626 // backbuffer if no framebuffer is bound.
627 bool BoundFramebufferHasColorAttachmentWithAlpha();
628 bool BoundFramebufferHasDepthAttachment();
629 bool BoundFramebufferHasStencilAttachment();
630
[email protected]b8e97b62012-09-30 15:09:00631 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43632
[email protected]96449d2c2009-11-25 00:01:32633 private:
[email protected]70d34263c2013-01-09 00:27:45634 friend class ScopedFrameBufferBinder;
[email protected]6217d392010-03-25 22:08:35635 friend class ScopedGLErrorSuppressor;
[email protected]34ff8b0c2010-10-01 20:06:02636 friend class ScopedResolvedFrameBufferBinder;
[email protected]63b465922012-09-06 02:04:52637 friend class ScopedTextureUploadTimer;
[email protected]ed9f9cd2013-02-27 21:12:35638 friend class BackTexture;
639 friend class BackRenderbuffer;
640 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35641
[email protected]c2f8c8402010-12-06 18:07:24642 // Initialize or re-initialize the shader translator.
643 bool InitializeShaderTranslator();
644
[email protected]302ce6d2011-07-07 23:28:11645 void UpdateCapabilities();
646
[email protected]ae51d192010-04-27 00:48:03647 // Helpers for the glGen and glDelete functions.
648 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
649 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
650 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
651 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
652 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
653 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
654 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
655 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53656 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
657 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46658 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
659 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47660
[email protected]70d34263c2013-01-09 00:27:45661 // Workarounds
662 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51663 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45664
[email protected]3916c97e2010-02-25 03:20:50665 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50666 BufferManager* buffer_manager() {
667 return group_->buffer_manager();
668 }
669
[email protected]a25fa872010-03-25 02:57:58670 RenderbufferManager* renderbuffer_manager() {
671 return group_->renderbuffer_manager();
672 }
673
674 FramebufferManager* framebuffer_manager() {
675 return group_->framebuffer_manager();
676 }
677
[email protected]3916c97e2010-02-25 03:20:50678 ProgramManager* program_manager() {
679 return group_->program_manager();
680 }
681
682 ShaderManager* shader_manager() {
683 return group_->shader_manager();
684 }
685
[email protected]29a4d902013-02-26 20:18:06686 const TextureManager* texture_manager() const {
687 return group_->texture_manager();
688 }
689
[email protected]3916c97e2010-02-25 03:20:50690 TextureManager* texture_manager() {
691 return group_->texture_manager();
692 }
693
[email protected]78b514b2012-05-01 21:50:59694 MailboxManager* mailbox_manager() {
695 return group_->mailbox_manager();
696 }
697
[email protected]09d50362012-10-18 20:54:37698 ImageManager* image_manager() {
699 return group_->image_manager();
700 }
701
[email protected]944b62f32012-09-27 02:20:46702 VertexArrayManager* vertex_array_manager() {
703 return vertex_array_manager_.get();
704 }
705
[email protected]7989c9e2013-01-23 06:39:26706 MemoryTracker* memory_tracker() {
707 return group_->memory_tracker();
708 }
709
710 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
711 MemoryTracker* tracker = memory_tracker();
712 if (tracker) {
713 return tracker->EnsureGPUMemoryAvailable(estimated_size);
714 }
715 return true;
716 }
717
[email protected]34ff8b0c2010-10-01 20:06:02718 bool IsOffscreenBufferMultisampled() const {
719 return offscreen_target_samples_ > 1;
720 }
721
[email protected]ed9f9cd2013-02-27 21:12:35722 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49723 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03724 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35725 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47726 }
727
728 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49729 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07730 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47731 }
732
733 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35734 void RemoveTexture(GLuint client_id) {
735 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50736 }
[email protected]a93bb842010-02-16 23:03:47737
[email protected]d37231fa2010-04-09 21:16:02738 // Get the size (in pixels) of the currently bound frame buffer (either FBO
739 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30740 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02741
[email protected]9edc6b22010-12-23 02:00:26742 // Get the format of the currently bound frame buffer (either FBO or regular
743 // back buffer)
744 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46745 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26746
[email protected]a93bb842010-02-16 23:03:47747 // Wrapper for CompressedTexImage2D commands.
748 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37749 GLenum target,
750 GLint level,
751 GLenum internal_format,
752 GLsizei width,
753 GLsizei height,
754 GLint border,
755 GLsizei image_size,
756 const void* data);
[email protected]a93bb842010-02-16 23:03:47757
[email protected]cadde4a2010-07-31 17:10:43758 // Wrapper for CompressedTexSubImage2D.
759 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37760 GLenum target,
761 GLint level,
762 GLint xoffset,
763 GLint yoffset,
764 GLsizei width,
765 GLsizei height,
766 GLenum format,
767 GLsizei imageSize,
768 const void * data);
[email protected]cadde4a2010-07-31 17:10:43769
770 // Wrapper for CopyTexImage2D.
771 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37772 GLenum target,
773 GLint level,
774 GLenum internal_format,
775 GLint x,
776 GLint y,
777 GLsizei width,
778 GLsizei height,
779 GLint border);
[email protected]cadde4a2010-07-31 17:10:43780
[email protected]6d792ee12013-05-15 00:40:56781 // Wrapper for SwapBuffers.
782 void DoSwapBuffers();
783
[email protected]cadde4a2010-07-31 17:10:43784 // Wrapper for CopyTexSubImage2D.
785 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37786 GLenum target,
787 GLint level,
788 GLint xoffset,
789 GLint yoffset,
790 GLint x,
791 GLint y,
792 GLsizei width,
793 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43794
[email protected]f598f422012-12-07 08:30:03795 // Validation for TexImage2D commands.
796 bool ValidateTexImage2D(
797 const char* function_name,
[email protected]09d50362012-10-18 20:54:37798 GLenum target,
799 GLint level,
800 GLenum internal_format,
801 GLsizei width,
802 GLsizei height,
803 GLint border,
804 GLenum format,
805 GLenum type,
806 const void* pixels,
807 uint32 pixels_size);
[email protected]a93bb842010-02-16 23:03:47808
[email protected]f598f422012-12-07 08:30:03809 // Wrapper for TexImage2D commands.
810 void DoTexImage2D(
811 GLenum target,
812 GLint level,
813 GLenum internal_format,
814 GLsizei width,
815 GLsizei height,
816 GLint border,
817 GLenum format,
818 GLenum type,
819 const void* pixels,
820 uint32 pixels_size);
821
822 // Validation for TexSubImage2D.
823 bool ValidateTexSubImage2D(
824 error::Error* error,
825 const char* function_name,
826 GLenum target,
827 GLint level,
828 GLint xoffset,
829 GLint yoffset,
830 GLsizei width,
831 GLsizei height,
832 GLenum format,
833 GLenum type,
834 const void * data);
835
[email protected]cadde4a2010-07-31 17:10:43836 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03837 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37838 GLenum target,
839 GLint level,
840 GLint xoffset,
841 GLint yoffset,
842 GLsizei width,
843 GLsizei height,
844 GLenum format,
845 GLenum type,
846 const void * data);
[email protected]cadde4a2010-07-31 17:10:43847
[email protected]32145a92012-12-17 09:01:59848 // Extra validation for async tex(Sub)Image2D.
849 bool ValidateAsyncTransfer(
850 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47851 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59852 GLenum target,
853 GLint level,
854 const void * data);
855
[email protected]e51bdf32011-11-23 22:21:46856 // Wrapper for TexImageIOSurface2DCHROMIUM.
857 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37858 GLenum target,
859 GLsizei width,
860 GLsizei height,
861 GLuint io_surface_id,
862 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46863
[email protected]43410e92012-04-20 17:06:28864 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37865 GLenum target,
866 GLuint source_id,
867 GLuint target_id,
868 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54869 GLenum internal_format,
870 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28871
[email protected]97dc7cbe2011-12-06 17:26:17872 // Wrapper for TexStorage2DEXT.
873 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37874 GLenum target,
875 GLint levels,
876 GLenum internal_format,
877 GLsizei width,
878 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17879
[email protected]78b514b2012-05-01 21:50:59880 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
881 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
882
[email protected]09d50362012-10-18 20:54:37883 void DoBindTexImage2DCHROMIUM(
884 GLenum target,
885 GLint image_id);
886 void DoReleaseTexImage2DCHROMIUM(
887 GLenum target,
888 GLint image_id);
889
[email protected]94307712012-11-16 23:26:11890 void DoTraceEndCHROMIUM(void);
891
[email protected]2f143d482013-03-14 18:04:49892 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
893
[email protected]ed9f9cd2013-02-27 21:12:35894 // Creates a Program for the given program.
895 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57896 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35897 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47898 }
899
[email protected]07f54fcc2009-12-22 02:46:30900 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35901 Program* GetProgram(GLuint client_id) {
902 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46903 }
[email protected]07f54fcc2009-12-22 02:46:30904
[email protected]cae20172012-12-07 00:06:19905#if defined(NDEBUG)
906 void LogClientServiceMapping(
907 const char* /* function_name */,
908 GLuint /* client_id */,
909 GLuint /* service_id */) {
910 }
911 template<typename T>
912 void LogClientServiceForInfo(
913 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
914 }
915#else
916 void LogClientServiceMapping(
917 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26918 if (service_logging_) {
[email protected]1d82e822013-04-10 21:32:32919 DLOG(INFO) << "[" << logger_.GetLogPrefix() << "] " << function_name
[email protected]2a22fe72012-12-07 04:21:26920 << ": client_id = " << client_id
921 << ", service_id = " << service_id;
922 }
[email protected]cae20172012-12-07 00:06:19923 }
924 template<typename T>
925 void LogClientServiceForInfo(
926 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26927 if (info) {
[email protected]cae20172012-12-07 00:06:19928 LogClientServiceMapping(function_name, client_id, info->service_id());
929 }
930 }
931#endif
932
[email protected]6b8cf1a2010-05-06 16:13:58933 // Gets the program info for the given program. If it's not a program
934 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35935 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58936 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42937 Program* program = GetProgram(client_id);
938 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35939 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51940 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43941 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58942 } else {
[email protected]ab09b612013-03-11 22:11:51943 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58944 }
945 }
[email protected]df37b9932013-03-08 05:21:42946 LogClientServiceForInfo(program, client_id, function_name);
947 return program;
[email protected]6b8cf1a2010-05-06 16:13:58948 }
949
950
[email protected]ed9f9cd2013-02-27 21:12:35951 // Creates a Shader for the given shader.
952 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57953 GLuint client_id,
954 GLuint service_id,
955 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:35956 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:57957 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31958 }
959
960 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35961 Shader* GetShader(GLuint client_id) {
962 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:31963 }
964
[email protected]6b8cf1a2010-05-06 16:13:58965 // Gets the shader info for the given shader. If it's not a shader generates a
966 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:35967 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:58968 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42969 Shader* shader = GetShader(client_id);
970 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:35971 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:51972 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43973 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58974 } else {
[email protected]ab09b612013-03-11 22:11:51975 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43976 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58977 }
978 }
[email protected]df37b9932013-03-08 05:21:42979 LogClientServiceForInfo(shader, client_id, function_name);
980 return shader;
[email protected]6b8cf1a2010-05-06 16:13:58981 }
982
[email protected]a93bb842010-02-16 23:03:47983 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:35984 void CreateBuffer(GLuint client_id, GLuint service_id) {
985 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47986 }
987
[email protected]07f54fcc2009-12-22 02:46:30988 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:21989 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:07990 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
991 return buffer;
[email protected]1d32bc82010-01-13 22:06:46992 }
[email protected]07f54fcc2009-12-22 02:46:30993
[email protected]a93bb842010-02-16 23:03:47994 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
995 // on glDeleteBuffers so we can make sure the user does not try to render
996 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:35997 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:47998
[email protected]a25fa872010-03-25 02:57:58999 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351000 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1001 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581002 }
1003
1004 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061005 Framebuffer* GetFramebuffer(GLuint client_id) {
1006 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581007 }
1008
1009 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351010 void RemoveFramebuffer(GLuint client_id) {
1011 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581012 }
1013
1014 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351015 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1016 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031017 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581018 }
1019
1020 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271021 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1022 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581023 }
1024
1025 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351026 void RemoveRenderbuffer(GLuint client_id) {
1027 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581028 }
1029
[email protected]944b62f32012-09-27 02:20:461030 // Gets the vertex attrib manager for the given vertex array.
1031 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1032 VertexAttribManager* info =
1033 vertex_array_manager()->GetVertexAttribManager(client_id);
1034 return info;
1035 }
1036
1037 // Removes the vertex attrib manager for the given vertex array.
1038 void RemoveVertexAttribManager(GLuint client_id) {
1039 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1040 }
1041
1042 // Creates a vertex attrib manager for the given vertex array.
1043 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1044 return vertex_array_manager()->CreateVertexAttribManager(
1045 client_id, service_id, group_->max_vertex_attribs());
1046 }
1047
[email protected]258a3313f2011-10-18 20:13:571048 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331049 void DoBindUniformLocationCHROMIUM(
1050 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571051
[email protected]558847a2010-03-24 07:02:541052 error::Error GetAttribLocationHelper(
1053 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1054 const std::string& name_str);
1055
1056 error::Error GetUniformLocationHelper(
1057 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1058 const std::string& name_str);
1059
[email protected]3916c97e2010-02-25 03:20:501060 // Helper for glShaderSource.
1061 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031062 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301063
[email protected]0d6bfdc2011-11-02 01:32:201064 // Clear any textures used by the current program.
1065 bool ClearUnclearedTextures();
1066
1067 // Clear any uncleared level in texture.
1068 // Returns false if there was a generated GL error.
[email protected]02965c22013-03-09 02:40:071069 bool ClearTexture(Texture* texture);
[email protected]0d6bfdc2011-11-02 01:32:201070
1071 // Clears any uncleared attachments attached to the given frame buffer.
1072 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061073 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281074
[email protected]0d6bfdc2011-11-02 01:32:201075 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001076 virtual bool ClearLevel(unsigned service_id,
1077 unsigned bind_target,
1078 unsigned target,
1079 int level,
1080 unsigned format,
1081 unsigned type,
1082 int width,
1083 int height,
1084 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201085
[email protected]c007aa02010-09-02 22:22:401086 // Restore all GL state that affects clearing.
1087 void RestoreClearState();
1088
[email protected]3a2e7c7b2010-08-06 01:12:281089 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461090 // Returns: true if glEnable/glDisable should actually be called.
1091 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281092
[email protected]0d6bfdc2011-11-02 01:32:201093 // Check that the currently bound framebuffers are valid.
1094 // Generates GL error if not.
1095 bool CheckBoundFramebuffersValid(const char* func_name);
1096
1097 // Check if a framebuffer meets our requirements.
1098 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351099 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201100 GLenum target,
1101 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271102
[email protected]939e7362010-05-13 20:49:101103 // Checks if the current program exists and is valid. If not generates the
1104 // appropriate GL error. Returns true if the current program is in a usable
1105 // state.
1106 bool CheckCurrentProgram(const char* function_name);
1107
1108 // Checks if the current program exists and is valid and that location is not
1109 // -1. If the current program is not valid generates the appropriate GL
1110 // error. Returns true if the current program is in a usable state and
1111 // location is not -1.
1112 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1113
1114 // Gets the type of a uniform for a location in the current program. Sets GL
1115 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361116 // program is valid and the location exists. Adjusts count so it
1117 // does not overflow the uniform.
1118 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121119 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521120 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121121 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101122
[email protected]b177ae22011-11-01 03:29:111123 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021124 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111125
[email protected]b273e432010-04-12 17:23:581126 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1127 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1128
[email protected]ac77603c72013-03-08 13:52:061129 // Helper for glGetVertexAttrib
1130 void GetVertexAttribHelper(
1131 const VertexAttrib* attrib, GLenum pname, GLint* param);
1132
[email protected]96449d2c2009-11-25 00:01:321133 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031134 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321135
1136 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031137 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321138
[email protected]3916c97e2010-02-25 03:20:501139 // Wrapper for glActiveTexture
1140 void DoActiveTexture(GLenum texture_unit);
1141
[email protected]ae51d192010-04-27 00:48:031142 // Wrapper for glAttachShader
1143 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1144
[email protected]96449d2c2009-11-25 00:01:321145 // Wrapper for glBindBuffer since we need to track the current targets.
1146 void DoBindBuffer(GLenum target, GLuint buffer);
1147
[email protected]86093972010-03-11 00:13:561148 // Wrapper for glBindFramebuffer since we need to track the current targets.
1149 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1150
1151 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1152 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1153
[email protected]a93bb842010-02-16 23:03:471154 // Wrapper for glBindTexture since we need to track the current targets.
1155 void DoBindTexture(GLenum target, GLuint texture);
1156
[email protected]944b62f32012-09-27 02:20:461157 // Wrapper for glBindVertexArrayOES
1158 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571159 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461160
[email protected]8e3e0662010-08-23 18:46:301161 // Wrapper for glBlitFramebufferEXT.
1162 void DoBlitFramebufferEXT(
1163 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1164 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1165 GLbitfield mask, GLenum filter);
1166
[email protected]36cef8ce2010-03-16 07:34:451167 // Wrapper for glBufferData.
[email protected]0c86dbf2010-03-05 08:14:111168 void DoBufferData(
1169 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
1170
[email protected]36cef8ce2010-03-16 07:34:451171 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111172 void DoBufferSubData(
1173 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1174
[email protected]36cef8ce2010-03-16 07:34:451175 // Wrapper for glCheckFramebufferStatus
1176 GLenum DoCheckFramebufferStatus(GLenum target);
1177
[email protected]3a03a8f2011-03-19 00:51:271178 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081179 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271180
[email protected]88a61bf2012-10-27 13:00:421181 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421182 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251183 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281184
[email protected]45bf5152010-02-12 00:11:311185 // Wrapper for glCompileShader.
1186 void DoCompileShader(GLuint shader);
1187
[email protected]269200b12010-11-18 22:53:061188 // Helper for DeleteSharedIdsCHROMIUM commands.
1189 void DoDeleteSharedIdsCHROMIUM(
1190 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101191
[email protected]ae51d192010-04-27 00:48:031192 // Wrapper for glDetachShader
1193 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1194
[email protected]3a2e7c7b2010-08-06 01:12:281195 // Wrapper for glDisable
1196 void DoDisable(GLenum cap);
1197
[email protected]07f54fcc2009-12-22 02:46:301198 // Wrapper for glDisableVertexAttribArray.
1199 void DoDisableVertexAttribArray(GLuint index);
1200
[email protected]60f22d32012-12-12 00:31:581201 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1202 // attachments.
1203 void DoDiscardFramebufferEXT(GLenum target,
1204 GLsizei numAttachments,
1205 const GLenum* attachments);
1206
[email protected]3a2e7c7b2010-08-06 01:12:281207 // Wrapper for glEnable
1208 void DoEnable(GLenum cap);
1209
[email protected]07f54fcc2009-12-22 02:46:301210 // Wrapper for glEnableVertexAttribArray.
1211 void DoEnableVertexAttribArray(GLuint index);
1212
[email protected]882ba1e22012-03-08 19:02:531213 // Wrapper for glFinish.
1214 void DoFinish();
1215
1216 // Wrapper for glFlush.
1217 void DoFlush();
1218
[email protected]36cef8ce2010-03-16 07:34:451219 // Wrapper for glFramebufferRenderbufffer.
1220 void DoFramebufferRenderbuffer(
1221 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1222 GLuint renderbuffer);
1223
1224 // Wrapper for glFramebufferTexture2D.
1225 void DoFramebufferTexture2D(
1226 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1227 GLint level);
1228
[email protected]a93bb842010-02-16 23:03:471229 // Wrapper for glGenerateMipmap
1230 void DoGenerateMipmap(GLenum target);
1231
[email protected]269200b12010-11-18 22:53:061232 // Helper for GenSharedIdsCHROMIUM commands.
1233 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101234 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1235
[email protected]b273e432010-04-12 17:23:581236 // Wrapper for DoGetBooleanv.
1237 void DoGetBooleanv(GLenum pname, GLboolean* params);
1238
1239 // Wrapper for DoGetFloatv.
1240 void DoGetFloatv(GLenum pname, GLfloat* params);
1241
[email protected]36cef8ce2010-03-16 07:34:451242 // Wrapper for glGetFramebufferAttachmentParameteriv.
1243 void DoGetFramebufferAttachmentParameteriv(
1244 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1245
[email protected]a0c3e972010-04-21 00:49:131246 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581247 void DoGetIntegerv(GLenum pname, GLint* params);
1248
[email protected]29a9eb52010-04-13 09:04:231249 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061250 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231251 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1252
[email protected]17cfbe0e2013-03-07 01:26:081253 // Wrapper for glGetBufferParameteriv.
1254 void DoGetBufferParameteriv(
1255 GLenum target, GLenum pname, GLint* params);
1256
[email protected]a0c3e972010-04-21 00:49:131257 // Wrapper for glGetProgramiv.
1258 void DoGetProgramiv(
1259 GLuint program_id, GLenum pname, GLint* params);
1260
[email protected]36cef8ce2010-03-16 07:34:451261 // Wrapper for glRenderbufferParameteriv.
1262 void DoGetRenderbufferParameteriv(
1263 GLenum target, GLenum pname, GLint* params);
1264
[email protected]ddd968b82010-03-02 00:44:291265 // Wrapper for glGetShaderiv
1266 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1267
[email protected]b1122982010-05-17 23:04:241268 // Wrappers for glGetVertexAttrib.
1269 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1270 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1271
[email protected]1958e0e2010-04-22 05:17:151272 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241273 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151274 bool DoIsBuffer(GLuint client_id);
1275 bool DoIsFramebuffer(GLuint client_id);
1276 bool DoIsProgram(GLuint client_id);
1277 bool DoIsRenderbuffer(GLuint client_id);
1278 bool DoIsShader(GLuint client_id);
1279 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461280 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151281
[email protected]07f54fcc2009-12-22 02:46:301282 // Wrapper for glLinkProgram
1283 void DoLinkProgram(GLuint program);
1284
[email protected]269200b12010-11-18 22:53:061285 // Helper for RegisterSharedIdsCHROMIUM.
1286 void DoRegisterSharedIdsCHROMIUM(
1287 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101288
[email protected]36cef8ce2010-03-16 07:34:451289 // Wrapper for glRenderbufferStorage.
1290 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031291 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451292
[email protected]8e3e0662010-08-23 18:46:301293 // Wrapper for glRenderbufferStorageMultisampleEXT.
1294 void DoRenderbufferStorageMultisample(
1295 GLenum target, GLsizei samples, GLenum internalformat,
1296 GLsizei width, GLsizei height);
1297
[email protected]b273e432010-04-12 17:23:581298 // Wrapper for glReleaseShaderCompiler.
1299 void DoReleaseShaderCompiler() { }
1300
[email protected]3916c97e2010-02-25 03:20:501301 // Wrappers for glTexParameter functions.
1302 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1303 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1304 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1305 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1306
1307 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1308 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121309 void DoUniform1i(GLint fake_location, GLint v0);
1310 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1311 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1312 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1313 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101314
1315 // Wrappers for glUniformfv because some drivers don't correctly accept
1316 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121317 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1318 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1319 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1320 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501321
[email protected]43c2f1f2011-03-25 18:35:361322 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121323 GLint fake_location, GLsizei count, GLboolean transpose,
1324 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361325 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121326 GLint fake_location, GLsizei count, GLboolean transpose,
1327 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361328 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121329 GLint fake_location, GLsizei count, GLboolean transpose,
1330 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361331
[email protected]af6380962012-11-29 23:24:131332 bool SetVertexAttribValue(
1333 const char* function_name, GLuint index, const GLfloat* value);
1334
[email protected]b1122982010-05-17 23:04:241335 // Wrappers for glVertexAttrib??
1336 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1337 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1338 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1339 void DoVertexAttrib4f(
1340 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1341 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1342 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1343 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1344 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1345
[email protected]43410e92012-04-20 17:06:281346 // Wrapper for glViewport
1347 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1348
[email protected]07f54fcc2009-12-22 02:46:301349 // Wrapper for glUseProgram
1350 void DoUseProgram(GLuint program);
1351
[email protected]ae51d192010-04-27 00:48:031352 // Wrapper for glValidateProgram.
1353 void DoValidateProgram(GLuint program_client_id);
1354
[email protected]d2a0e1a2012-08-12 02:25:011355 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1356 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1357 void DoPopGroupMarkerEXT(void);
1358
[email protected]4e8a5b122010-05-08 22:00:101359 // Gets the number of values that will be returned by glGetXXX. Returns
1360 // false if pname is unknown.
1361 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1362
[email protected]07f54fcc2009-12-22 02:46:301363 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431364 bool IsDrawValid(
1365 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301366
[email protected]c13e1da62011-09-09 21:48:301367 // Returns true if successful, simulated will be true if attrib0 was
1368 // simulated.
[email protected]c6aef902012-02-14 03:31:421369 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431370 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281371 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241372
[email protected]ef526492010-06-02 23:12:251373 // Returns true if textures were set.
1374 bool SetBlackTextureForNonRenderableTextures();
[email protected]3916c97e2010-02-25 03:20:501375 void RestoreStateForNonRenderableTextures();
1376
[email protected]8fbedc02010-11-18 18:43:401377 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421378 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431379 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421380 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401381 void RestoreStateForSimulatedFixedAttribs();
1382
[email protected]c6aef902012-02-14 03:31:421383 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1384 // cases (primcount is 0 for non-instanced).
1385 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431386 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421387 bool instanced, GLenum mode, GLint first, GLsizei count,
1388 GLsizei primcount);
1389 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431390 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421391 bool instanced, GLenum mode, GLsizei count, GLenum type,
1392 int32 offset, GLsizei primcount);
1393
[email protected]07f54fcc2009-12-22 02:46:301394 // Gets the buffer id for a given target.
[email protected]16ccec12013-02-28 03:40:211395 Buffer* GetBufferInfoForTarget(GLenum target) {
[email protected]07f54fcc2009-12-22 02:46:301396 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
[email protected]944b62f32012-09-27 02:20:461397 if (target == GL_ARRAY_BUFFER) {
[email protected]7cd76fd2013-06-02 21:11:111398 return state_.bound_array_buffer.get();
[email protected]944b62f32012-09-27 02:20:461399 } else {
[email protected]e259eb412012-10-13 05:47:241400 return state_.vertex_attrib_manager->element_array_buffer();
[email protected]944b62f32012-09-27 02:20:461401 }
[email protected]07f54fcc2009-12-22 02:46:301402 }
1403
[email protected]a93bb842010-02-16 23:03:471404 // Gets the texture id for a given target.
[email protected]370eaf12013-05-18 09:19:491405 TextureRef* GetTextureInfoForTarget(GLenum target) {
[email protected]e259eb412012-10-13 05:47:241406 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]370eaf12013-05-18 09:19:491407 TextureRef* texture = NULL;
[email protected]a93bb842010-02-16 23:03:471408 switch (target) {
1409 case GL_TEXTURE_2D:
[email protected]7cd76fd2013-06-02 21:11:111410 texture = unit.bound_texture_2d.get();
[email protected]3916c97e2010-02-25 03:20:501411 break;
[email protected]a93bb842010-02-16 23:03:471412 case GL_TEXTURE_CUBE_MAP:
1413 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1414 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1415 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1416 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1417 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1418 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
[email protected]7cd76fd2013-06-02 21:11:111419 texture = unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:501420 break;
[email protected]61eeb33f2011-07-26 15:30:311421 case GL_TEXTURE_EXTERNAL_OES:
[email protected]7cd76fd2013-06-02 21:11:111422 texture = unit.bound_texture_external_oes.get();
[email protected]61eeb33f2011-07-26 15:30:311423 break;
[email protected]e51bdf32011-11-23 22:21:461424 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]7cd76fd2013-06-02 21:11:111425 texture = unit.bound_texture_rectangle_arb.get();
[email protected]e51bdf32011-11-23 22:21:461426 break;
[email protected]a93bb842010-02-16 23:03:471427 default:
1428 NOTREACHED();
[email protected]3916c97e2010-02-25 03:20:501429 return NULL;
[email protected]a93bb842010-02-16 23:03:471430 }
[email protected]02965c22013-03-09 02:40:071431 return texture;
[email protected]a93bb842010-02-16 23:03:471432 }
1433
[email protected]370eaf12013-05-18 09:19:491434 TextureRef* GetTextureInfoForTargetUnlessDefault(
[email protected]09d50362012-10-18 20:54:371435 GLenum target) {
[email protected]370eaf12013-05-18 09:19:491436 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:071437 if (!texture)
[email protected]09d50362012-10-18 20:54:371438 return NULL;
[email protected]02965c22013-03-09 02:40:071439 if (texture == texture_manager()->GetDefaultTextureInfo(target))
[email protected]09d50362012-10-18 20:54:371440 return NULL;
[email protected]02965c22013-03-09 02:40:071441 return texture;
[email protected]09d50362012-10-18 20:54:371442 }
1443
[email protected]61eeb33f2011-07-26 15:30:311444 GLenum GetBindTargetForSamplerType(GLenum type) {
1445 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461446 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1447 switch (type) {
1448 case GL_SAMPLER_2D:
1449 return GL_TEXTURE_2D;
1450 case GL_SAMPLER_CUBE:
1451 return GL_TEXTURE_CUBE_MAP;
1452 case GL_SAMPLER_EXTERNAL_OES:
1453 return GL_TEXTURE_EXTERNAL_OES;
1454 case GL_SAMPLER_2D_RECT_ARB:
1455 return GL_TEXTURE_RECTANGLE_ARB;
1456 }
1457
1458 NOTREACHED();
1459 return 0;
[email protected]61eeb33f2011-07-26 15:30:311460 }
1461
[email protected]8e3e0662010-08-23 18:46:301462 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061463 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1464 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301465 switch (target) {
1466 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451467 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]7cd76fd2013-06-02 21:11:111468 framebuffer = state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301469 break;
[email protected]ebfb73c2012-08-15 02:37:451470 case GL_READ_FRAMEBUFFER_EXT:
[email protected]7cd76fd2013-06-02 21:11:111471 framebuffer = state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301472 break;
1473 default:
1474 NOTREACHED();
1475 break;
1476 }
[email protected]4d8f0dd2013-03-09 14:37:061477 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301478 }
1479
[email protected]ed9f9cd2013-02-27 21:12:351480 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201481 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271482 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201483 switch (target) {
1484 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111485 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201486 break;
1487 default:
1488 NOTREACHED();
1489 break;
1490 }
[email protected]ee2a79c32013-03-10 03:50:271491 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201492 }
1493
[email protected]f7b85372010-02-03 01:11:371494 // Validates the program and location for a glGetUniform call and returns
1495 // a SizeResult setup to receive the result. Returns true if glGetUniform
1496 // should be called.
1497 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121498 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371499 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121500 error::Error* error, GLint* real_location, GLuint* service_id,
1501 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371502
[email protected]1078f912011-12-23 13:12:141503 // Computes the estimated memory used for the backbuffer and passes it to
1504 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531505 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141506
[email protected]a10b4a02012-11-26 23:09:501507 virtual bool WasContextLost() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091508 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431509
[email protected]e51bdf32011-11-23 22:21:461510#if defined(OS_MACOSX)
1511 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1512#endif
1513
[email protected]81375742012-06-08 00:04:001514 // Validates the combination of texture parameters. For example validates that
1515 // for a given format the specific type, level and targets are valid.
1516 // Synthesizes the correct GL error if invalid. Returns true if valid.
1517 bool ValidateTextureParameters(
1518 const char* function_name,
1519 GLenum target, GLenum format, GLenum type, GLint level);
1520
[email protected]ad84a3a2012-06-08 21:42:431521 bool ValidateCompressedTexDimensions(
1522 const char* function_name,
1523 GLint level, GLsizei width, GLsizei height, GLenum format);
1524 bool ValidateCompressedTexFuncData(
1525 const char* function_name,
1526 GLsizei width, GLsizei height, GLenum format, size_t size);
1527 bool ValidateCompressedTexSubDimensions(
1528 const char* function_name,
1529 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1530 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351531 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431532
[email protected]ab09b612013-03-11 22:11:511533 void RenderWarning(const char* filename, int line, const std::string& msg);
1534 void PerformanceWarning(
1535 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011536
[email protected]62e155e2012-10-23 22:43:151537 const FeatureInfo::FeatureFlags& features() const {
1538 return feature_info_->feature_flags();
1539 }
1540
1541 const FeatureInfo::Workarounds& workarounds() const {
1542 return feature_info_->workarounds();
1543 }
1544
[email protected]a7266a92012-06-28 02:11:081545 bool ShouldDeferDraws() {
1546 return !offscreen_target_frame_buffer_.get() &&
[email protected]7cd76fd2013-06-02 21:11:111547 state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081548 surface_->DeferDraws();
1549 }
1550
[email protected]09e17272012-11-30 10:30:441551 bool ShouldDeferReads() {
1552 return !offscreen_target_frame_buffer_.get() &&
[email protected]7cd76fd2013-06-02 21:11:111553 state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441554 surface_->DeferDraws();
1555 }
1556
[email protected]df37b9932013-03-08 05:21:421557 void ForceCompileShaderIfPending(Shader* shader);
[email protected]c447acd2012-07-23 23:48:411558
[email protected]96449d2c2009-11-25 00:01:321559 // Generate a member function prototype for each command in an automated and
1560 // typesafe way.
1561 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141562 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351563 uint32 immediate_data_size, \
1564 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321565
1566 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1567
1568 #undef GLES2_CMD_OP
1569
[email protected]2f2d7042010-04-14 21:45:581570 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381571 scoped_refptr<gfx::GLSurface> surface_;
1572 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021573
[email protected]a3ded6d2010-10-19 06:44:391574 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351575 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391576
[email protected]1d82e822013-04-10 21:32:321577 DebugMarkerManager debug_marker_manager_;
1578 Logger logger_;
1579
[email protected]e259eb412012-10-13 05:47:241580 // All the state for this context.
1581 ContextState state_;
1582
[email protected]34ff8b0c2010-10-01 20:06:021583 // Current width and height of the offscreen frame buffer.
1584 gfx::Size offscreen_size_;
1585
[email protected]96449d2c2009-11-25 00:01:321586 // Util to help with GL.
1587 GLES2Util util_;
1588
[email protected]43410e92012-04-20 17:06:281589 // unpack flip y as last set by glPixelStorei
1590 bool unpack_flip_y_;
1591
[email protected]6c75c712012-06-19 15:43:171592 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281593 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171594 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281595
[email protected]944b62f32012-09-27 02:20:461596 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351597 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301598
[email protected]b1122982010-05-17 23:04:241599 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1600 GLuint attrib_0_buffer_id_;
1601
1602 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131603 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241604
[email protected]fc753442011-02-04 19:49:491605 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1606 bool attrib_0_buffer_matches_value_;
1607
[email protected]b1122982010-05-17 23:04:241608 // The size of attrib 0.
1609 GLsizei attrib_0_size_;
1610
[email protected]8fbedc02010-11-18 18:43:401611 // The buffer used to simulate GL_FIXED attribs.
1612 GLuint fixed_attrib_buffer_id_;
1613
1614 // The size of fiixed attrib buffer.
1615 GLsizei fixed_attrib_buffer_size_;
1616
[email protected]3a2e7c7b2010-08-06 01:12:281617 // state saved for clearing so we can clear render buffers and then
1618 // restore to these values.
[email protected]88a61bf2012-10-27 13:00:421619 bool clear_state_dirty_;
[email protected]3a2e7c7b2010-08-06 01:12:281620
[email protected]b9363b22010-06-09 22:06:151621 // The offscreen frame buffer that the client renders to. With EGL, the
1622 // depth and stencil buffers are separate. With regular GL there is a single
1623 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1624 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351625 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1626 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1627 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1628 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1629 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021630 GLenum offscreen_target_color_format_;
1631 GLenum offscreen_target_depth_format_;
1632 GLenum offscreen_target_stencil_format_;
1633 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561634 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351635
[email protected]de26b3c2011-08-03 21:54:271636 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351637 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1638 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491639 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351640 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271641
1642 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351643 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1644 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051645 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351646
[email protected]882ba1e22012-03-08 19:02:531647 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531648
[email protected]944b62f32012-09-27 02:20:461649 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1650
[email protected]729c0b42013-05-26 02:05:071651 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001652
[email protected]840a7e462013-02-27 01:29:511653 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481654
[email protected]e3932abb2013-03-13 00:01:371655 ShaderCacheCallback shader_cache_callback_;
1656
[email protected]b0af4f52011-09-28 22:04:421657 StreamTextureManager* stream_texture_manager_;
[email protected]85a4ac22013-05-31 01:58:471658 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421659
[email protected]32fe9aa2011-01-21 23:47:131660 // The format of the back buffer_
1661 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461662 bool back_buffer_has_depth_;
1663 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131664
[email protected]60f22d32012-12-12 00:31:581665 // Backbuffer attachments that are currently undefined.
1666 uint32 backbuffer_needs_clear_bits_;
1667
[email protected]473c01ccb2011-06-07 01:33:301668 bool teximage2d_faster_than_texsubimage2d_;
[email protected]473c01ccb2011-06-07 01:33:301669
[email protected]a3a93e7b2010-08-28 00:48:561670 // The current decoder error.
1671 error::Error current_decoder_error_;
1672
[email protected]b1d2dcb2010-05-17 19:24:181673 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041674 scoped_refptr<ShaderTranslator> vertex_translator_;
1675 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181676
[email protected]e82fb792011-09-22 00:33:291677 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411678
[email protected]915a59a12010-09-30 21:29:111679 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051680 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351681 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051682
[email protected]b493ee622011-04-13 23:52:001683 // This indicates all the following texSubImage2D calls that are part of the
1684 // failed texImage2D call should be ignored.
1685 bool tex_image_2d_failed_;
1686
[email protected]65225772011-05-12 21:10:241687 int frame_number_;
1688
[email protected]706b69f2012-07-27 04:59:301689 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431690 GLenum reset_status_;
1691
[email protected]f0d74742011-10-03 16:31:041692 // These flags are used to override the state of the shared feature_info_
1693 // member. Because the same FeatureInfo instance may be shared among many
1694 // contexts, the assumptions on the availablity of extensions in WebGL
1695 // contexts may be broken. These flags override the shared state to preserve
1696 // WebGL semantics.
1697 bool force_webgl_glsl_validation_;
1698 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491699 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131700 bool draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041701
[email protected]062c38b2012-01-18 03:25:101702 bool compile_shader_always_succeeds_;
1703
[email protected]cae20172012-12-07 00:06:191704 // Log extra info.
1705 bool service_logging_;
1706
[email protected]e51bdf32011-11-23 22:21:461707#if defined(OS_MACOSX)
1708 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1709 TextureToIOSurfaceMap texture_to_io_surface_map_;
1710#endif
1711
[email protected]43410e92012-04-20 17:06:281712 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1713
[email protected]1868a342012-11-07 15:56:021714 // Cached values of the currently assigned viewport dimensions.
1715 GLsizei viewport_max_width_;
1716 GLsizei viewport_max_height_;
1717
[email protected]63b465922012-09-06 02:04:521718 // Command buffer stats.
1719 int texture_upload_count_;
1720 base::TimeDelta total_texture_upload_time_;
1721 base::TimeDelta total_processing_commands_time_;
1722
[email protected]fb97b662013-02-20 23:02:141723 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]94307712012-11-16 23:26:111724
[email protected]96449d2c2009-11-25 00:01:321725 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1726};
1727
[email protected]ab09b612013-03-11 22:11:511728ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
1729 const char* function_name, GLES2DecoderImpl* decoder)
1730 : function_name_(function_name),
1731 decoder_(decoder) {
[email protected]d3eba342013-04-18 21:11:501732 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(),
1733 function_name_);
[email protected]6217d392010-03-25 22:08:351734}
1735
1736ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]d3eba342013-04-18 21:11:501737 ERRORSTATE_CLEAR_REAL_GL_ERRORS(decoder_->GetErrorState(), function_name_);
[email protected]6217d392010-03-25 22:08:351738}
1739
1740ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1741 GLuint id)
1742 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511743 ScopedGLErrorSuppressor suppressor(
1744 "ScopedTexture2DBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351745
1746 // TODO(apatrick): Check if there are any other states that need to be reset
1747 // before binding a new texture.
1748 glActiveTexture(GL_TEXTURE0);
1749 glBindTexture(GL_TEXTURE_2D, id);
1750}
1751
1752ScopedTexture2DBinder::~ScopedTexture2DBinder() {
[email protected]ab09b612013-03-11 22:11:511753 ScopedGLErrorSuppressor suppressor(
1754 "ScopedTexture2DBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301755 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351756}
1757
1758ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1759 GLuint id)
1760 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511761 ScopedGLErrorSuppressor suppressor(
1762 "ScopedRenderBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351763 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1764}
1765
1766ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511767 ScopedGLErrorSuppressor suppressor(
1768 "ScopedRenderBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301769 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351770}
1771
1772ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1773 GLuint id)
1774 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511775 ScopedGLErrorSuppressor suppressor(
1776 "ScopedFrameBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351777 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451778 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351779}
1780
1781ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511782 ScopedGLErrorSuppressor suppressor(
1783 "ScopedFrameBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301784 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351785}
1786
[email protected]34ff8b0c2010-10-01 20:06:021787ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271788 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521789 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021790 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1791 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241792 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521793 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021794 if (!resolve_and_bind_)
1795 return;
1796
[email protected]ab09b612013-03-11 22:11:511797 ScopedGLErrorSuppressor suppressor(
1798 "ScopedResolvedFrameBufferBinder::ctor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021799 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1800 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271801 GLuint targetid;
1802 if (internal) {
1803 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1804 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351805 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271806 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351807 decoder_->offscreen_resolved_color_texture_.reset(
1808 new BackTexture(decoder_));
[email protected]de26b3c2011-08-03 21:54:271809 decoder_->offscreen_resolved_color_texture_->Create();
1810
1811 DCHECK(decoder_->offscreen_saved_color_format_);
1812 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091813 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1814 false);
[email protected]de26b3c2011-08-03 21:54:271815 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1816 decoder_->offscreen_resolved_color_texture_.get());
1817 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1818 GL_FRAMEBUFFER_COMPLETE) {
1819 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1820 << "because offscreen resolved FBO was incomplete.";
1821 return;
1822 }
1823 }
1824 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1825 } else {
1826 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1827 }
1828 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021829 const int width = decoder_->offscreen_size_.width();
1830 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181831 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151832 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021833 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1834 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1835 } else {
1836 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1837 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1838 }
[email protected]de26b3c2011-08-03 21:54:271839 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021840}
1841
1842ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1843 if (!resolve_and_bind_)
1844 return;
1845
[email protected]ab09b612013-03-11 22:11:511846 ScopedGLErrorSuppressor suppressor(
1847 "ScopedResolvedFrameBufferBinder::dtor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021848 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221849 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181850 glEnable(GL_SCISSOR_TEST);
1851 }
[email protected]34ff8b0c2010-10-01 20:06:021852}
1853
[email protected]63b465922012-09-06 02:04:521854ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder)
1855 : decoder_(decoder),
1856 begin_time_(base::TimeTicks::HighResNow()) {
1857}
1858
1859ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1860 decoder_->texture_upload_count_++;
1861 decoder_->total_texture_upload_time_ +=
1862 base::TimeTicks::HighResNow() - begin_time_;
1863}
1864
[email protected]ed9f9cd2013-02-27 21:12:351865BackTexture::BackTexture(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351866 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261867 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481868 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251869 id_(0) {
[email protected]6217d392010-03-25 22:08:351870}
1871
[email protected]ed9f9cd2013-02-27 21:12:351872BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351873 // This does not destroy the render texture because that would require that
1874 // the associated GL context was current. Just check that it was explicitly
1875 // destroyed.
1876 DCHECK_EQ(id_, 0u);
1877}
1878
[email protected]ed9f9cd2013-02-27 21:12:351879void BackTexture::Create() {
[email protected]ab09b612013-03-11 22:11:511880 ScopedGLErrorSuppressor suppressor("BackTexture::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351881 Destroy();
1882 glGenTextures(1, &id_);
[email protected]3a4d0c52011-06-29 23:11:581883 ScopedTexture2DBinder binder(decoder_, id_);
1884 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1885 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1886 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1887 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161888
1889 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1890 // never called on an offscreen context, no data will ever be uploaded to the
1891 // saved offscreen color texture (it is deferred until to when SwapBuffers
1892 // is called). My idea is that some nvidia drivers might have a bug where
1893 // deleting a texture that has never been populated might cause a
1894 // crash.
1895 glTexImage2D(
1896 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481897
1898 bytes_allocated_ = 16u * 16u * 4u;
1899 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351900}
1901
[email protected]ed9f9cd2013-02-27 21:12:351902bool BackTexture::AllocateStorage(
1903 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351904 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511905 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351906 ScopedTexture2DBinder binder(decoder_, id_);
[email protected]678a73f2012-12-19 19:22:091907 uint32 image_size = 0;
1908 GLES2Util::ComputeImageDataSizes(
1909 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1910 NULL, NULL);
1911
[email protected]7989c9e2013-01-23 06:39:261912 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
1913 return false;
1914 }
1915
[email protected]40d90a22013-04-09 03:39:551916 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:091917 if (zero) {
1918 zero_data.reset(new char[image_size]);
1919 memset(zero_data.get(), 0, image_size);
1920 }
[email protected]6217d392010-03-25 22:08:351921
[email protected]8f1d2aa2013-05-10 23:45:381922 glTexImage2D(GL_TEXTURE_2D,
1923 0, // mip level
1924 format,
1925 size.width(),
1926 size.height(),
1927 0, // border
1928 format,
1929 GL_UNSIGNED_BYTE,
1930 zero_data.get());
[email protected]6217d392010-03-25 22:08:351931
[email protected]d37231fa2010-04-09 21:16:021932 size_ = size;
1933
[email protected]1078f912011-12-23 13:12:141934 bool success = glGetError() == GL_NO_ERROR;
1935 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481936 memory_tracker_.TrackMemFree(bytes_allocated_);
1937 bytes_allocated_ = image_size;
1938 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141939 }
1940 return success;
[email protected]6217d392010-03-25 22:08:351941}
1942
[email protected]ed9f9cd2013-02-27 21:12:351943void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351944 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511945 ScopedGLErrorSuppressor suppressor("BackTexture::Copy", decoder_);
[email protected]6217d392010-03-25 22:08:351946 ScopedTexture2DBinder binder(decoder_, id_);
1947 glCopyTexImage2D(GL_TEXTURE_2D,
1948 0, // level
[email protected]3a4d0c52011-06-29 23:11:581949 format,
[email protected]6217d392010-03-25 22:08:351950 0, 0,
1951 size.width(),
1952 size.height(),
1953 0); // border
1954}
1955
[email protected]ed9f9cd2013-02-27 21:12:351956void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:351957 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:511958 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:351959 glDeleteTextures(1, &id_);
1960 id_ = 0;
1961 }
[email protected]68e81a4a62012-12-13 01:16:481962 memory_tracker_.TrackMemFree(bytes_allocated_);
1963 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351964}
1965
[email protected]ed9f9cd2013-02-27 21:12:351966void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:051967 id_ = 0;
1968}
1969
[email protected]ed9f9cd2013-02-27 21:12:351970BackRenderbuffer::BackRenderbuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351971 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261972 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481973 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251974 id_(0) {
[email protected]6217d392010-03-25 22:08:351975}
1976
[email protected]ed9f9cd2013-02-27 21:12:351977BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:351978 // This does not destroy the render buffer because that would require that
1979 // the associated GL context was current. Just check that it was explicitly
1980 // destroyed.
1981 DCHECK_EQ(id_, 0u);
1982}
1983
[email protected]ed9f9cd2013-02-27 21:12:351984void BackRenderbuffer::Create() {
[email protected]ab09b612013-03-11 22:11:511985 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351986 Destroy();
1987 glGenRenderbuffersEXT(1, &id_);
1988}
1989
[email protected]ed9f9cd2013-02-27 21:12:351990bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format,
1991 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:511992 ScopedGLErrorSuppressor suppressor(
1993 "BackRenderbuffer::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351994 ScopedRenderBufferBinder binder(decoder_, id_);
[email protected]7989c9e2013-01-23 06:39:261995
1996 uint32 estimated_size = 0;
1997 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
1998 size.width(), size.height(), samples, format, &estimated_size)) {
1999 return false;
2000 }
2001
2002 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2003 return false;
2004 }
2005
[email protected]34ff8b0c2010-10-01 20:06:022006 if (samples <= 1) {
2007 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2008 format,
2009 size.width(),
2010 size.height());
2011 } else {
[email protected]57edfdad2012-02-07 04:57:152012 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:022013 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
2014 samples,
2015 format,
2016 size.width(),
2017 size.height());
2018 } else {
2019 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
2020 samples,
2021 format,
2022 size.width(),
2023 size.height());
2024 }
2025 }
[email protected]1078f912011-12-23 13:12:142026 bool success = glGetError() == GL_NO_ERROR;
2027 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482028 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262029 bytes_allocated_ = estimated_size;
[email protected]68e81a4a62012-12-13 01:16:482030 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142031 }
2032 return success;
[email protected]6217d392010-03-25 22:08:352033}
2034
[email protected]ed9f9cd2013-02-27 21:12:352035void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352036 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512037 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352038 glDeleteRenderbuffersEXT(1, &id_);
2039 id_ = 0;
2040 }
[email protected]68e81a4a62012-12-13 01:16:482041 memory_tracker_.TrackMemFree(bytes_allocated_);
2042 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352043}
2044
[email protected]ed9f9cd2013-02-27 21:12:352045void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052046 id_ = 0;
2047}
2048
[email protected]ed9f9cd2013-02-27 21:12:352049BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352050 : decoder_(decoder),
2051 id_(0) {
2052}
2053
[email protected]ed9f9cd2013-02-27 21:12:352054BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352055 // This does not destroy the frame buffer because that would require that
2056 // the associated GL context was current. Just check that it was explicitly
2057 // destroyed.
2058 DCHECK_EQ(id_, 0u);
2059}
2060
[email protected]ed9f9cd2013-02-27 21:12:352061void BackFramebuffer::Create() {
[email protected]ab09b612013-03-11 22:11:512062 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:352063 Destroy();
2064 glGenFramebuffersEXT(1, &id_);
2065}
2066
[email protected]ed9f9cd2013-02-27 21:12:352067void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352068 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512069 ScopedGLErrorSuppressor suppressor(
2070 "BackFramebuffer::AttachRenderTexture", decoder_);
[email protected]6217d392010-03-25 22:08:352071 ScopedFrameBufferBinder binder(decoder_, id_);
2072 GLuint attach_id = texture ? texture->id() : 0;
2073 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2074 GL_COLOR_ATTACHMENT0,
2075 GL_TEXTURE_2D,
2076 attach_id,
2077 0);
2078}
2079
[email protected]ed9f9cd2013-02-27 21:12:352080void BackFramebuffer::AttachRenderBuffer(GLenum target,
2081 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352082 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512083 ScopedGLErrorSuppressor suppressor(
2084 "BackFramebuffer::AttachRenderBuffer", decoder_);
[email protected]6217d392010-03-25 22:08:352085 ScopedFrameBufferBinder binder(decoder_, id_);
2086 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2087 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152088 target,
[email protected]6217d392010-03-25 22:08:352089 GL_RENDERBUFFER,
2090 attach_id);
2091}
2092
[email protected]ed9f9cd2013-02-27 21:12:352093void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352094 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512095 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352096 glDeleteFramebuffersEXT(1, &id_);
2097 id_ = 0;
2098 }
2099}
2100
[email protected]ed9f9cd2013-02-27 21:12:352101void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052102 id_ = 0;
2103}
2104
[email protected]ed9f9cd2013-02-27 21:12:352105GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352106 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512107 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", decoder_);
[email protected]6217d392010-03-25 22:08:352108 ScopedFrameBufferBinder binder(decoder_, id_);
2109 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2110}
2111
[email protected]aa7666122011-09-02 19:45:522112GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2113 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322114}
2115
[email protected]aa7666122011-09-02 19:45:522116GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392117 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572118 group_(group),
[email protected]1d82e822013-04-10 21:32:322119 logger_(&debug_marker_manager_),
[email protected]d3eba342013-04-18 21:11:502120 state_(group_->feature_info(), &logger_),
[email protected]43410e92012-04-20 17:06:282121 unpack_flip_y_(false),
2122 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172123 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242124 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492125 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242126 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402127 fixed_attrib_buffer_id_(0),
2128 fixed_attrib_buffer_size_(0),
[email protected]88a61bf2012-10-27 13:00:422129 clear_state_dirty_(true),
[email protected]34ff8b0c2010-10-01 20:06:022130 offscreen_target_color_format_(0),
2131 offscreen_target_depth_format_(0),
2132 offscreen_target_stencil_format_(0),
2133 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562134 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052135 offscreen_saved_color_format_(0),
[email protected]b0af4f52011-09-28 22:04:422136 stream_texture_manager_(NULL),
[email protected]32fe9aa2011-01-21 23:47:132137 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462138 back_buffer_has_depth_(false),
2139 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582140 backbuffer_needs_clear_bits_(0),
[email protected]473c01ccb2011-06-07 01:33:302141 teximage2d_faster_than_texsubimage2d_(true),
[email protected]a3a93e7b2010-08-28 00:48:562142 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052143 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112144 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002145 feature_info_(group_->feature_info()),
[email protected]65225772011-05-12 21:10:242146 tex_image_2d_failed_(false),
[email protected]38d139d2011-07-14 00:38:432147 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302148 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512149 reset_status_(GL_NO_ERROR),
[email protected]f0d74742011-10-03 16:31:042150 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102151 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492152 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132153 draw_buffers_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282154 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192155 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2156 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022157 viewport_max_width_(0),
2158 viewport_max_height_(0),
[email protected]63b465922012-09-06 02:04:522159 texture_upload_count_(0) {
[email protected]3b1ecc262011-08-03 22:49:572160 DCHECK(group);
2161
[email protected]b1122982010-05-17 23:04:242162 attrib_0_value_.v[0] = 0.0f;
2163 attrib_0_value_.v[1] = 0.0f;
2164 attrib_0_value_.v[2] = 0.0f;
2165 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152166
[email protected]c2f8c8402010-12-06 18:07:242167 // The shader translator is used for WebGL even when running on EGL
2168 // because additional restrictions are needed (like only enabling
2169 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562170 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2171 // the empty string to CompileShader and this is not a valid shader.
2172 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002173 CommandLine::ForCurrentProcess()->HasSwitch(
2174 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152175 use_shader_translator_ = false;
2176 }
[email protected]473c01ccb2011-06-07 01:33:302177
[email protected]a39370652012-09-25 21:52:132178 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:302179 if (IsAngle()) {
2180 teximage2d_faster_than_texsubimage2d_ = false;
[email protected]473c01ccb2011-06-07 01:33:302181 }
[email protected]96449d2c2009-11-25 00:01:322182}
2183
[email protected]80eb6b52012-01-19 00:14:412184GLES2DecoderImpl::~GLES2DecoderImpl() {
2185}
2186
[email protected]c410da802011-03-14 19:17:412187bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382188 const scoped_refptr<gfx::GLSurface>& surface,
2189 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232190 bool offscreen,
[email protected]c410da802011-03-14 19:17:412191 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292192 const DisallowedFeatures& disallowed_features,
[email protected]c410da802011-03-14 19:17:412193 const char* allowed_extensions,
[email protected]3c644d82011-06-20 19:58:242194 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322195 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382196 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302197 DCHECK(!context_.get());
2198
[email protected]55e136f2013-04-03 18:50:062199 set_initialized();
[email protected]fb97b662013-02-20 23:02:142200 gpu_tracer_ = GPUTracer::Create();
2201
[email protected]e844ae22012-01-14 03:36:262202 if (CommandLine::ForCurrentProcess()->HasSwitch(
2203 switches::kEnableGPUDebugging)) {
2204 set_debug(true);
2205 }
2206
[email protected]39ba4f02012-03-26 01:16:002207 if (CommandLine::ForCurrentProcess()->HasSwitch(
2208 switches::kEnableGPUCommandLogging)) {
2209 set_log_commands(true);
2210 }
2211
[email protected]062c38b2012-01-18 03:25:102212 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2213 switches::kCompileShaderAlwaysSucceeds);
2214
[email protected]f62a5ab2011-05-23 20:34:152215
[email protected]63c9b052012-05-17 18:27:382216 // Take ownership of the context and surface. The surface can be replaced with
2217 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382218 context_ = context;
[email protected]63c9b052012-05-17 18:27:382219 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182220
[email protected]c4485aad62012-12-17 10:19:092221 if (!group_->Initialize(this, disallowed_features, allowed_extensions)) {
[email protected]09ddb91f2011-04-14 23:16:222222 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392223 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422224 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382225 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032226 return false;
[email protected]a3ded6d2010-10-19 06:44:392227 }
[email protected]b64c24952012-04-19 03:20:272228 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282229
[email protected]e82fb792011-09-22 00:33:292230 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502231
[email protected]af6380962012-11-29 23:24:132232 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462233 default_vertex_attrib_manager_ = new VertexAttribManager();
2234 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2235
[email protected]ab4fd7282012-10-12 16:25:572236 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2237 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322238
[email protected]7cd76fd2013-06-02 21:11:112239 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]944b62f32012-09-27 02:20:462240 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532241
[email protected]302ce6d2011-07-07 23:28:112242 util_.set_num_compressed_texture_formats(
2243 validators_->compressed_texture_format.GetValues().size());
2244
[email protected]1071e572011-02-09 20:00:122245 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2246 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2247 // OpenGL ES 2.0 does not have this issue.
2248 glEnableVertexAttribArray(0);
2249 }
[email protected]b1122982010-05-17 23:04:242250 glGenBuffersARB(1, &attrib_0_buffer_id_);
2251 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2252 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2253 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402254 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082255
[email protected]1868a342012-11-07 15:56:022256 state_.texture_units.resize(group_->max_texture_units());
2257 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492258 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312259 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492260 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152261 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492262 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072263 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492264 state_.texture_units[tt].bound_texture_external_oes = ref;
2265 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id());
[email protected]61eeb33f2011-07-26 15:30:312266 }
[email protected]62e155e2012-10-23 22:43:152267 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492268 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072269 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492270 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2271 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id());
[email protected]e51bdf32011-11-23 22:21:462272 }
[email protected]370eaf12013-05-18 09:19:492273 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2274 state_.texture_units[tt].bound_texture_cube_map = ref;
2275 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id());
2276 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2277 state_.texture_units[tt].bound_texture_2d = ref;
2278 glBindTexture(GL_TEXTURE_2D, ref->service_id());
[email protected]1958e0e2010-04-22 05:17:152279 }
[email protected]00f893d2010-08-24 18:55:492280 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502281 CHECK_GL_ERROR();
2282
[email protected]297ca1c2011-06-20 23:08:462283 ContextCreationAttribParser attrib_parser;
2284 if (!attrib_parser.Parse(attribs))
2285 return false;
[email protected]41c56362011-06-14 16:47:432286
[email protected]069944672012-04-25 20:52:232287 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022288 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542289 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022290 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432291 // max_sample_count must be initialized to a sane value. If
2292 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2293 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022294 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2295 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2296 max_sample_count);
2297 } else {
2298 offscreen_target_samples_ = 1;
2299 }
[email protected]8a61d872012-01-20 12:43:562300 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022301
2302 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2303 const bool rgb8_supported =
2304 context_->HasExtension("GL_OES_rgb8_rgba8");
2305 // The only available default render buffer formats in GLES2 have very
2306 // little precision. Don't enable multisampling unless 8-bit render
2307 // buffer formats are available--instead fall back to 8-bit textures.
2308 if (rgb8_supported && offscreen_target_samples_ > 1) {
2309 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2310 GL_RGBA8 : GL_RGB8;
2311 } else {
2312 offscreen_target_samples_ = 1;
2313 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2314 GL_RGBA : GL_RGB;
2315 }
2316
2317 // ANGLE only supports packed depth/stencil formats, so use it if it is
2318 // available.
2319 const bool depth24_stencil8_supported =
2320 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272321 VLOG(1) << "GL_OES_packed_depth_stencil "
2322 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002323 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2324 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022325 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2326 offscreen_target_stencil_format_ = 0;
2327 } else {
2328 // It may be the case that this depth/stencil combination is not
2329 // supported, but this will be checked later by CheckFramebufferStatus.
2330 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2331 GL_DEPTH_COMPONENT16 : 0;
2332 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2333 GL_STENCIL_INDEX8 : 0;
2334 }
2335 } else {
2336 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2337 GL_RGBA : GL_RGB;
2338
2339 // If depth is requested at all, use the packed depth stencil format if
2340 // it's available, as some desktop GL drivers don't support any non-packed
2341 // formats for depth attachments.
2342 const bool depth24_stencil8_supported =
2343 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272344 VLOG(1) << "GL_EXT_packed_depth_stencil "
2345 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022346
[email protected]71ee3642010-10-14 18:08:002347 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2348 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022349 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2350 offscreen_target_stencil_format_ = 0;
2351 } else {
2352 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2353 GL_DEPTH_COMPONENT : 0;
2354 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2355 GL_STENCIL_INDEX : 0;
2356 }
2357 }
2358
[email protected]97872062010-11-03 19:07:052359 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2360 GL_RGBA : GL_RGB;
2361
[email protected]6217d392010-03-25 22:08:352362 // Create the target frame buffer. This is the one that the client renders
2363 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352364 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352365 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022366 // Due to GLES2 format limitations, either the color texture (for
2367 // non-multisampling) or the color render buffer (for multisampling) will be
2368 // attached to the offscreen frame buffer. The render buffer has more
2369 // limited formats available to it, but the texture can't do multisampling.
2370 if (IsOffscreenBufferMultisampled()) {
[email protected]ed9f9cd2013-02-27 21:12:352371 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022372 offscreen_target_color_render_buffer_->Create();
2373 } else {
[email protected]ed9f9cd2013-02-27 21:12:352374 offscreen_target_color_texture_.reset(new BackTexture(this));
[email protected]34ff8b0c2010-10-01 20:06:022375 offscreen_target_color_texture_->Create();
2376 }
[email protected]ed9f9cd2013-02-27 21:12:352377 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152378 offscreen_target_depth_render_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352379 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152380 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352381
2382 // Create the saved offscreen texture. The target frame buffer is copied
2383 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352384 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022385 offscreen_saved_frame_buffer_->Create();
2386 //
[email protected]ed9f9cd2013-02-27 21:12:352387 offscreen_saved_color_texture_.reset(new BackTexture(this));
[email protected]6217d392010-03-25 22:08:352388 offscreen_saved_color_texture_->Create();
2389
[email protected]6217d392010-03-25 22:08:352390 // Allocate the render buffers at their initial size and check the status
2391 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592392 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012393 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382394 Destroy(true);
[email protected]6217d392010-03-25 22:08:352395 return false;
2396 }
2397
[email protected]678a73f2012-12-19 19:22:092398 // Allocate the offscreen saved color texture.
2399 DCHECK(offscreen_saved_color_format_);
2400 offscreen_saved_color_texture_->AllocateStorage(
2401 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2402
2403 offscreen_saved_frame_buffer_->AttachRenderTexture(
2404 offscreen_saved_color_texture_.get());
2405 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2406 GL_FRAMEBUFFER_COMPLETE) {
2407 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2408 Destroy(true);
2409 return false;
2410 }
2411
[email protected]6217d392010-03-25 22:08:352412 // Bind to the new default frame buffer (the offscreen target frame buffer).
2413 // This should now be associated with ID zero.
2414 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102415 } else {
2416 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2417 // These are NOT if the back buffer has these proprorties. They are
2418 // if we want the command buffer to enforce them regardless of what
2419 // the real backbuffer is assuming the real back buffer gives us more than
2420 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2421 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2422 // can't do anything about that.
2423
2424 GLint v = 0;
2425 glGetIntegerv(GL_ALPHA_BITS, &v);
2426 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2427 // user requested RGB then RGB. If the user did not specify a preference
2428 // than use whatever we were given. Same for DEPTH and STENCIL.
2429 back_buffer_color_format_ =
2430 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2431 glGetIntegerv(GL_DEPTH_BITS, &v);
2432 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2433 glGetIntegerv(GL_STENCIL_BITS, &v);
2434 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
[email protected]6217d392010-03-25 22:08:352435 }
2436
[email protected]76a0ee102010-04-07 21:03:042437 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2438 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2439 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372440 // mailing list archives. It also implicitly enables the desktop GL
2441 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2442 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152443 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2444 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372445 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152446 }
[email protected]de17df392010-04-23 21:09:412447
[email protected]706b69f2012-07-27 04:59:302448 has_robustness_extension_ =
2449 context->HasExtension("GL_ARB_robustness") ||
2450 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432451
[email protected]c2f8c8402010-12-06 18:07:242452 if (!InitializeShaderTranslator()) {
2453 return false;
[email protected]de17df392010-04-23 21:09:412454 }
[email protected]76a0ee102010-04-07 21:03:042455
[email protected]e259eb412012-10-13 05:47:242456 state_.viewport_width = size.width();
2457 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282458
[email protected]5904806b2012-05-08 18:10:222459 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282460 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022461 viewport_max_width_ = viewport_params[0];
2462 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282463
[email protected]88a61bf2012-10-27 13:00:422464 state_.scissor_width = state_.viewport_width;
2465 state_.scissor_height = state_.viewport_height;
2466
[email protected]11f3e702012-06-19 19:00:012467 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222468 state_.InitCapabilities();
2469 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242470 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012471
2472 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2473 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2474 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2475 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2476
[email protected]561cc0a62013-05-07 18:34:452477 // Clear the backbuffer.
2478 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2479
[email protected]62e155e2012-10-23 22:43:152480 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462481 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2482 }
[email protected]dd289a5d62012-06-30 22:05:462483
[email protected]9b753992013-04-27 02:04:412484 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2485 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242486 }
[email protected]85cb4682013-04-20 00:54:242487
[email protected]97419c02013-04-10 02:52:382488 // Only compositor contexts are known to use only the subset of GL
2489 // that can be safely migrated between the iGPU and the dGPU. Mark
2490 // those contexts as safe to forcibly transition between the GPUs.
2491 // http://crbug.com/180876, http://crbug.com/227228
2492 if (!offscreen)
2493 context_->SetSafeToForceGpuSwitch();
2494
[email protected]85a4ac22013-05-31 01:58:472495 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072496 AsyncPixelTransferManager::Create(context.get()));
2497 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592498
[email protected]246a70452010-03-05 21:53:502499 return true;
[email protected]96449d2c2009-11-25 00:01:322500}
2501
[email protected]302ce6d2011-07-07 23:28:112502void GLES2DecoderImpl::UpdateCapabilities() {
2503 util_.set_num_compressed_texture_formats(
2504 validators_->compressed_texture_format.GetValues().size());
2505 util_.set_num_shader_binary_formats(
2506 validators_->shader_binary_format.GetValues().size());
2507}
2508
[email protected]c2f8c8402010-12-06 18:07:242509bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442510 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2511
[email protected]c2f8c8402010-12-06 18:07:242512 if (!use_shader_translator_) {
2513 return true;
2514 }
2515 ShBuiltInResources resources;
2516 ShInitBuiltInResources(&resources);
2517 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2518 resources.MaxVertexUniformVectors =
2519 group_->max_vertex_uniform_vectors();
2520 resources.MaxVaryingVectors = group_->max_varying_vectors();
2521 resources.MaxVertexTextureImageUnits =
2522 group_->max_vertex_texture_image_units();
2523 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2524 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2525 resources.MaxFragmentUniformVectors =
2526 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492527 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242528 resources.MaxExpressionComplexity = 256;
2529 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042530
[email protected]9e98f61b2013-03-05 02:21:142531#if (ANGLE_SH_VERSION >= 110)
[email protected]46c86752013-05-21 05:08:392532 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212533 GLint precision = 0;
2534 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2535 range, &precision);
[email protected]448e459e2013-06-12 17:00:412536 resources.FragmentPrecisionHigh =
2537 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142538#endif
2539
[email protected]f0d74742011-10-03 16:31:042540 if (force_webgl_glsl_validation_) {
2541 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492542 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132543 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:042544 } else {
2545 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152546 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462547 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152548 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062549 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152550 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492551 resources.EXT_draw_buffers =
2552 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492553 resources.EXT_frag_depth =
2554 features().ext_frag_depth ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042555 }
2556
[email protected]26b61442013-03-17 16:12:012557 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2558 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052559 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022560#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052561 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022562#else
2563 resources.HashFunction = &CityHash64;
2564#endif
[email protected]6aedcdc2013-01-24 01:25:052565 else
2566 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122567 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2568 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2569 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2570 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
[email protected]62e155e2012-10-23 22:43:152571 workarounds().needs_glsl_built_in_function_emulation ?
[email protected]a2a0fe762011-09-20 00:59:122572 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
2573 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
[email protected]87fb6ab2012-06-13 22:28:042574
2575 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2576 vertex_translator_ = cache->GetTranslator(
2577 SH_VERTEX_SHADER, shader_spec, &resources,
2578 implementation_type, function_behavior);
2579 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242580 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382581 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242582 return false;
2583 }
[email protected]87fb6ab2012-06-13 22:28:042584
2585 fragment_translator_ = cache->GetTranslator(
2586 SH_FRAGMENT_SHADER, shader_spec, &resources,
2587 implementation_type, function_behavior);
2588 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242589 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382590 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242591 return false;
2592 }
2593 return true;
2594}
2595
[email protected]ae51d192010-04-27 00:48:032596bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472597 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352598 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032599 return false;
2600 }
2601 }
[email protected]40d90a22013-04-09 03:39:552602 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032603 glGenBuffersARB(n, service_ids.get());
2604 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352605 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032606 }
2607 return true;
2608}
2609
2610bool GLES2DecoderImpl::GenFramebuffersHelper(
2611 GLsizei n, const GLuint* client_ids) {
2612 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352613 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032614 return false;
2615 }
2616 }
[email protected]40d90a22013-04-09 03:39:552617 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032618 glGenFramebuffersEXT(n, service_ids.get());
2619 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352620 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032621 }
2622 return true;
2623}
2624
2625bool GLES2DecoderImpl::GenRenderbuffersHelper(
2626 GLsizei n, const GLuint* client_ids) {
2627 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352628 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032629 return false;
2630 }
2631 }
[email protected]40d90a22013-04-09 03:39:552632 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032633 glGenRenderbuffersEXT(n, service_ids.get());
2634 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352635 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032636 }
2637 return true;
2638}
2639
2640bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2641 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352642 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032643 return false;
2644 }
2645 }
[email protected]40d90a22013-04-09 03:39:552646 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032647 glGenTextures(n, service_ids.get());
2648 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352649 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032650 }
2651 return true;
2652}
2653
2654void GLES2DecoderImpl::DeleteBuffersHelper(
2655 GLsizei n, const GLuint* client_ids) {
2656 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212657 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102658 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242659 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112660 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242661 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102662 }
[email protected]ed9f9cd2013-02-27 21:12:352663 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032664 }
[email protected]a93bb842010-02-16 23:03:472665 }
[email protected]07f54fcc2009-12-22 02:46:302666}
2667
[email protected]ae51d192010-04-27 00:48:032668void GLES2DecoderImpl::DeleteFramebuffersHelper(
2669 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452670 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152671 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112672
[email protected]a25fa872010-03-25 02:57:582673 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352674 Framebuffer* framebuffer =
2675 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102676 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112677 if (framebuffer == state_.bound_draw_framebuffer.get()) {
[email protected]e259eb412012-10-13 05:47:242678 state_.bound_draw_framebuffer = NULL;
[email protected]88a61bf2012-10-27 13:00:422679 clear_state_dirty_ = true;
[email protected]ebfb73c2012-08-15 02:37:452680 GLenum target = supports_separate_framebuffer_binds ?
2681 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112682 glBindFramebufferEXT(target, GetBackbufferServiceId());
2683 }
[email protected]7cd76fd2013-06-02 21:11:112684 if (framebuffer == state_.bound_read_framebuffer.get()) {
[email protected]e259eb412012-10-13 05:47:242685 state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452686 GLenum target = supports_separate_framebuffer_binds ?
2687 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112688 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462689 }
[email protected]70d34263c2013-01-09 00:27:452690 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352691 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032692 }
[email protected]a25fa872010-03-25 02:57:582693 }
[email protected]07f54fcc2009-12-22 02:46:302694}
2695
[email protected]ae51d192010-04-27 00:48:032696void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2697 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452698 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152699 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582700 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352701 Renderbuffer* renderbuffer =
2702 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102703 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112704 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242705 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102706 }
2707 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452708 if (supports_separate_framebuffer_binds) {
[email protected]7cd76fd2013-06-02 21:11:112709 if (state_.bound_read_framebuffer.get()) {
2710 state_.bound_read_framebuffer
2711 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102712 }
[email protected]7cd76fd2013-06-02 21:11:112713 if (state_.bound_draw_framebuffer.get()) {
2714 state_.bound_draw_framebuffer
2715 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102716 }
2717 } else {
[email protected]7cd76fd2013-06-02 21:11:112718 if (state_.bound_draw_framebuffer.get()) {
2719 state_.bound_draw_framebuffer
2720 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102721 }
2722 }
[email protected]88a61bf2012-10-27 13:00:422723 clear_state_dirty_ = true;
[email protected]ed9f9cd2013-02-27 21:12:352724 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032725 }
[email protected]a25fa872010-03-25 02:57:582726 }
[email protected]07f54fcc2009-12-22 02:46:302727}
2728
[email protected]ae51d192010-04-27 00:48:032729void GLES2DecoderImpl::DeleteTexturesHelper(
2730 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452731 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152732 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472733 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492734 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2735 if (texture_ref) {
2736 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102737 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:422738 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462739 }
[email protected]370eaf12013-05-18 09:19:492740 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:022741 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:492742 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102743 }
2744 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452745 if (supports_separate_framebuffer_binds) {
[email protected]7cd76fd2013-06-02 21:11:112746 if (state_.bound_read_framebuffer.get()) {
2747 state_.bound_read_framebuffer
2748 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102749 }
[email protected]7cd76fd2013-06-02 21:11:112750 if (state_.bound_draw_framebuffer.get()) {
2751 state_.bound_draw_framebuffer
2752 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102753 }
2754 } else {
[email protected]7cd76fd2013-06-02 21:11:112755 if (state_.bound_draw_framebuffer.get()) {
2756 state_.bound_draw_framebuffer
2757 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102758 }
2759 }
2760 GLuint service_id = texture->service_id();
2761 if (texture->IsStreamTexture() && stream_texture_manager_) {
[email protected]b0af4f52011-09-28 22:04:422762 stream_texture_manager_->DestroyStreamTexture(service_id);
2763 }
[email protected]e51bdf32011-11-23 22:21:462764#if defined(OS_MACOSX)
2765 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2766 ReleaseIOSurfaceForTexture(service_id);
2767 }
2768#endif
[email protected]ed9f9cd2013-02-27 21:12:352769 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032770 }
[email protected]a93bb842010-02-16 23:03:472771 }
[email protected]07f54fcc2009-12-22 02:46:302772}
2773
[email protected]43f28f832010-02-03 02:28:482774// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322775
[email protected]eb54a562010-01-20 21:55:182776bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382777 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2778 return false;
2779
2780 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432781 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292782
2783 // Some D3D drivers cannot recover from device lost in the GPU process
2784 // sandbox. Allow a new GPU process to launch.
2785 if (workarounds().exit_on_context_lost) {
2786 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2787 << " a D3D device in the Chrome GPU process sandbox.";
2788 exit(0);
2789 }
2790
[email protected]63c9b052012-05-17 18:27:382791 return false;
[email protected]38d139d2011-07-14 00:38:432792 }
2793
[email protected]69a8701e2013-03-07 21:31:092794 ProcessFinishedAsyncTransfers();
2795 if (workarounds().flush_on_context_switch)
2796 glFlush();
2797
[email protected]9b753992013-04-27 02:04:412798 // Rebind the FBO if it was unbound by the context.
2799 if (workarounds().unbind_fbo_on_context_switch)
2800 RestoreFramebufferBindings();
2801
[email protected]370eaf12013-05-18 09:19:492802 clear_state_dirty_ = true;
2803
[email protected]69a8701e2013-03-07 21:31:092804 return true;
2805}
2806
2807void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]fe8d73c2013-02-16 22:37:322808 if (engine() && query_manager_.get())
2809 query_manager_->ProcessPendingTransferQueries();
2810
[email protected]5b3a8e02013-03-13 05:36:442811 // TODO(epenner): Is there a better place to do this?
2812 // This needs to occur before we execute any batch of commands
2813 // from the client, as the client may have recieved an async
2814 // completion while issuing those commands.
2815 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:482816 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:182817}
2818
[email protected]a96a6022011-11-04 00:58:122819void GLES2DecoderImpl::ReleaseCurrent() {
2820 if (context_.get())
2821 context_->ReleaseCurrent(surface_.get());
2822}
2823
[email protected]8e3e0662010-08-23 18:46:302824void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
[email protected]ed9f9cd2013-02-27 21:12:352825 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:202826 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
[email protected]8e3e0662010-08-23 18:46:302827 glBindRenderbufferEXT(
[email protected]0d6bfdc2011-11-02 01:32:202828 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
[email protected]8e3e0662010-08-23 18:46:302829}
2830
2831static void RebindCurrentFramebuffer(
2832 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062833 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242834 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062835 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462836
[email protected]a3783712012-01-20 22:18:242837 if (framebuffer_id == 0) {
2838 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302839 }
[email protected]297ca1c2011-06-20 23:08:462840
[email protected]8e3e0662010-08-23 18:46:302841 glBindFramebufferEXT(target, framebuffer_id);
2842}
2843
2844void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]88a61bf2012-10-27 13:00:422845 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462846
[email protected]62e155e2012-10-23 22:43:152847 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302848 RebindCurrentFramebuffer(
2849 GL_FRAMEBUFFER,
[email protected]e259eb412012-10-13 05:47:242850 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242851 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302852 } else {
2853 RebindCurrentFramebuffer(
2854 GL_READ_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242855 state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242856 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302857 RebindCurrentFramebuffer(
2858 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242859 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242860 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302861 }
[email protected]70d34263c2013-01-09 00:27:452862 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302863}
2864
2865void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
[email protected]e259eb412012-10-13 05:47:242866 TextureUnit& info = state_.texture_units[0];
[email protected]8e3e0662010-08-23 18:46:302867 GLuint last_id;
[email protected]7cd76fd2013-06-02 21:11:112868 if (info.bound_texture_2d.get()) {
[email protected]8e3e0662010-08-23 18:46:302869 last_id = info.bound_texture_2d->service_id();
2870 } else {
2871 last_id = 0;
2872 }
2873
2874 glBindTexture(GL_TEXTURE_2D, last_id);
[email protected]e259eb412012-10-13 05:47:242875 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]8e3e0662010-08-23 18:46:302876}
2877
[email protected]0d6bfdc2011-11-02 01:32:202878bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352879 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202880 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102881 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582882 if (backbuffer_needs_clear_bits_) {
2883 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2884 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2885 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2886 glClearStencil(0);
2887 glStencilMask(-1);
2888 glClearDepth(1.0f);
2889 glDepthMask(true);
2890 glDisable(GL_SCISSOR_TEST);
2891 glClear(backbuffer_needs_clear_bits_);
2892 backbuffer_needs_clear_bits_ = 0;
2893 RestoreClearState();
2894 }
[email protected]0d6bfdc2011-11-02 01:32:202895 return true;
2896 }
2897
[email protected]968351b2011-12-20 08:26:512898 if (framebuffer_manager()->IsComplete(framebuffer)) {
2899 return true;
2900 }
2901
[email protected]0d6bfdc2011-11-02 01:32:202902 GLenum completeness = framebuffer->IsPossiblyComplete();
2903 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512904 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432905 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272906 return false;
2907 }
[email protected]0d6bfdc2011-11-02 01:32:202908
2909 // Are all the attachments cleared?
2910 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2911 texture_manager()->HaveUnclearedMips()) {
2912 if (!framebuffer->IsCleared()) {
2913 // Can we clear them?
[email protected]73276522012-11-09 05:50:202914 if (framebuffer->GetStatus(texture_manager(), target) !=
2915 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512916 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432917 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2918 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202919 return false;
2920 }
2921 ClearUnclearedAttachments(target, framebuffer);
2922 }
2923 }
2924
[email protected]968351b2011-12-20 08:26:512925 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202926 if (framebuffer->GetStatus(texture_manager(), target) !=
2927 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512928 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432929 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2930 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512931 return false;
2932 }
2933 framebuffer_manager()->MarkAsComplete(framebuffer);
2934 }
2935
[email protected]0d6bfdc2011-11-02 01:32:202936 // NOTE: At this point we don't know if the framebuffer is complete but
2937 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272938 return true;
2939}
2940
[email protected]0d6bfdc2011-11-02 01:32:202941bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:152942 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:512943 bool valid = CheckFramebufferValid(
[email protected]7cd76fd2013-06-02 21:11:112944 state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT, func_name);
[email protected]28718a92013-04-04 12:12:512945
2946 if (valid)
2947 OnUseFramebuffer();
2948
2949 return valid;
[email protected]0d6bfdc2011-11-02 01:32:202950 }
[email protected]7cd76fd2013-06-02 21:11:112951 return CheckFramebufferValid(state_.bound_draw_framebuffer.get(),
2952 GL_DRAW_FRAMEBUFFER_EXT,
2953 func_name) &&
2954 CheckFramebufferValid(state_.bound_read_framebuffer.get(),
2955 GL_READ_FRAMEBUFFER_EXT,
2956 func_name);
[email protected]0d6bfdc2011-11-02 01:32:202957}
2958
[email protected]8e3e0662010-08-23 18:46:302959gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:352960 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452961 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202962 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:352963 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:202964 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:262965 if (attachment) {
2966 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:502967 }
[email protected]9edc6b22010-12-23 02:00:262968 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:022969 } else if (offscreen_target_frame_buffer_.get()) {
2970 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:352971 } else {
[email protected]f62a5ab2011-05-23 20:34:152972 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:022973 }
[email protected]246a70452010-03-05 21:53:502974}
2975
[email protected]9edc6b22010-12-23 02:00:262976GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352977 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452978 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202979 if (framebuffer != NULL) {
2980 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:462981 } else if (offscreen_target_frame_buffer_.get()) {
2982 return offscreen_target_color_format_;
2983 } else {
2984 return back_buffer_color_format_;
2985 }
2986}
2987
2988GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352989 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452990 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202991 if (framebuffer != NULL) {
2992 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:262993 } else if (offscreen_target_frame_buffer_.get()) {
2994 return offscreen_target_color_format_;
2995 } else {
[email protected]32fe9aa2011-01-21 23:47:132996 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:262997 }
2998}
2999
[email protected]9a5afa432011-07-22 18:16:393000void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513001 if (!offscreen_saved_color_texture_info_.get())
3002 return;
3003 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3004 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3005 texture_manager()->SetLevelInfo(
3006 offscreen_saved_color_texture_info_.get(),
3007 GL_TEXTURE_2D,
3008 0, // level
3009 GL_RGBA,
3010 offscreen_size_.width(),
3011 offscreen_size_.height(),
3012 1, // depth
3013 0, // border
3014 GL_RGBA,
3015 GL_UNSIGNED_BYTE,
3016 true);
3017 texture_manager()->SetParameter(
3018 "UpdateParentTextureInfo",
3019 GetErrorState(),
3020 offscreen_saved_color_texture_info_.get(),
3021 GL_TEXTURE_MAG_FILTER,
3022 GL_NEAREST);
3023 texture_manager()->SetParameter(
3024 "UpdateParentTextureInfo",
3025 GetErrorState(),
3026 offscreen_saved_color_texture_info_.get(),
3027 GL_TEXTURE_MIN_FILTER,
3028 GL_NEAREST);
3029 texture_manager()->SetParameter(
3030 "UpdateParentTextureInfo",
3031 GetErrorState(),
3032 offscreen_saved_color_texture_info_.get(),
3033 GL_TEXTURE_WRAP_S,
3034 GL_CLAMP_TO_EDGE);
3035 texture_manager()->SetParameter(
3036 "UpdateParentTextureInfo",
3037 GetErrorState(),
3038 offscreen_saved_color_texture_info_.get(),
3039 GL_TEXTURE_WRAP_T,
3040 GL_CLAMP_TO_EDGE);
3041 TextureRef* texture_ref = GetTextureInfoForTarget(target);
3042 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353043}
3044
[email protected]799b4b22011-08-22 17:09:593045void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073046 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523047 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003048}
3049
[email protected]1d82e822013-04-10 21:32:323050Logger* GLES2DecoderImpl::GetLogger() {
3051 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523052}
3053
[email protected]d3eba342013-04-18 21:11:503054ErrorState* GLES2DecoderImpl::GetErrorState() {
3055 return state_.GetErrorState();
3056}
3057
[email protected]e3932abb2013-03-13 00:01:373058void GLES2DecoderImpl::SetShaderCacheCallback(
3059 const ShaderCacheCallback& callback) {
3060 shader_cache_callback_ = callback;
3061}
3062
[email protected]840a7e462013-02-27 01:29:513063void GLES2DecoderImpl::SetWaitSyncPointCallback(
3064 const WaitSyncPointCallback& callback) {
3065 wait_sync_point_callback_ = callback;
3066}
3067
[email protected]b0af4f52011-09-28 22:04:423068void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) {
3069 stream_texture_manager_ = manager;
3070}
3071
[email protected]85a4ac22013-05-31 01:58:473072AsyncPixelTransferManager*
3073 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3074 return async_pixel_transfer_manager_.get();
3075}
3076
3077void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3078 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593079}
3080
[email protected]498b5c072013-06-04 19:30:073081void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3082 AsyncPixelTransferManager* manager) {
3083 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3084}
3085
[email protected]1318e922010-09-17 22:03:163086bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3087 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493088 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3089 if (texture_ref) {
3090 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163091 return true;
3092 }
3093 return false;
3094}
3095
[email protected]63b465922012-09-06 02:04:523096uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]b9804322013-01-08 17:54:123097 return texture_upload_count_ +
[email protected]b68b100752013-06-05 08:34:483098 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523099}
3100
3101base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]b9804322013-01-08 17:54:123102 return total_texture_upload_time_ +
[email protected]b68b100752013-06-05 08:34:483103 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523104}
3105
3106base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3107 return total_processing_commands_time_;
3108}
3109
[email protected]dc25dda2012-09-27 21:36:303110void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3111 total_processing_commands_time_ += time;
3112}
3113
[email protected]63c9b052012-05-17 18:27:383114void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063115 if (!initialized())
3116 return;
3117
[email protected]63c9b052012-05-17 18:27:383118 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053119
[email protected]80eb6b52012-01-19 00:14:413120 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243121 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463122 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023123 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243124 state_.bound_array_buffer = NULL;
3125 state_.current_query = NULL;
3126 state_.current_program = NULL;
3127 state_.bound_read_framebuffer = NULL;
3128 state_.bound_draw_framebuffer = NULL;
3129 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413130
[email protected]cadac622013-06-11 16:46:363131 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513132 DCHECK(offscreen_target_color_texture_);
3133 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3134 offscreen_saved_color_texture_->id());
3135 offscreen_saved_color_texture_->Invalidate();
3136 offscreen_saved_color_texture_info_ = NULL;
3137 }
[email protected]eadc96792010-10-27 19:39:393138 if (have_context) {
[email protected]c322e882012-05-23 18:06:183139 if (copy_texture_CHROMIUM_.get()) {
3140 copy_texture_CHROMIUM_->Destroy();
3141 copy_texture_CHROMIUM_.reset();
3142 }
[email protected]43410e92012-04-20 17:06:283143
[email protected]7cd76fd2013-06-02 21:11:113144 if (state_.current_program.get()) {
3145 program_manager()->UnuseProgram(shader_manager(),
3146 state_.current_program.get());
[email protected]e259eb412012-10-13 05:47:243147 state_.current_program = NULL;
[email protected]ca488e12010-12-13 20:06:143148 }
3149
[email protected]b1122982010-05-17 23:04:243150 if (attrib_0_buffer_id_) {
3151 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3152 }
[email protected]8fbedc02010-11-18 18:43:403153 if (fixed_attrib_buffer_id_) {
3154 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3155 }
[email protected]b1122982010-05-17 23:04:243156
[email protected]97872062010-11-03 19:07:053157 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543158 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053159 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543160 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053161 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023162 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053163 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153164 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053165 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153166 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053167 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023168 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053169 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543170 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273171 if (offscreen_resolved_frame_buffer_.get())
3172 offscreen_resolved_frame_buffer_->Destroy();
3173 if (offscreen_resolved_color_texture_.get())
3174 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053175 } else {
3176 if (offscreen_target_frame_buffer_.get())
3177 offscreen_target_frame_buffer_->Invalidate();
3178 if (offscreen_target_color_texture_.get())
3179 offscreen_target_color_texture_->Invalidate();
3180 if (offscreen_target_color_render_buffer_.get())
3181 offscreen_target_color_render_buffer_->Invalidate();
3182 if (offscreen_target_depth_render_buffer_.get())
3183 offscreen_target_depth_render_buffer_->Invalidate();
3184 if (offscreen_target_stencil_render_buffer_.get())
3185 offscreen_target_stencil_render_buffer_->Invalidate();
3186 if (offscreen_saved_frame_buffer_.get())
3187 offscreen_saved_frame_buffer_->Invalidate();
3188 if (offscreen_saved_color_texture_.get())
3189 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273190 if (offscreen_resolved_frame_buffer_.get())
3191 offscreen_resolved_frame_buffer_->Invalidate();
3192 if (offscreen_resolved_color_texture_.get())
3193 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023194 }
[email protected]43410e92012-04-20 17:06:283195 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053196
[email protected]882ba1e22012-03-08 19:02:533197 if (query_manager_.get()) {
3198 query_manager_->Destroy(have_context);
3199 query_manager_.reset();
3200 }
3201
[email protected]944b62f32012-09-27 02:20:463202 if (vertex_array_manager_ .get()) {
3203 vertex_array_manager_->Destroy(have_context);
3204 vertex_array_manager_.reset();
3205 }
3206
[email protected]97872062010-11-03 19:07:053207 offscreen_target_frame_buffer_.reset();
3208 offscreen_target_color_texture_.reset();
3209 offscreen_target_color_render_buffer_.reset();
3210 offscreen_target_depth_render_buffer_.reset();
3211 offscreen_target_stencil_render_buffer_.reset();
3212 offscreen_saved_frame_buffer_.reset();
3213 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273214 offscreen_resolved_frame_buffer_.reset();
3215 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463216
[email protected]85a4ac22013-05-31 01:58:473217 // Should destroy the transfer manager before the texture manager held
3218 // by the context group.
3219 async_pixel_transfer_manager_.reset();
3220
[email protected]7cd76fd2013-06-02 21:11:113221 if (group_.get()) {
[email protected]2d9d3b92013-01-18 01:07:233222 group_->Destroy(this, have_context);
3223 group_ = NULL;
3224 }
3225
3226 if (context_.get()) {
3227 context_->ReleaseCurrent(NULL);
3228 context_ = NULL;
3229 }
3230
[email protected]e51bdf32011-11-23 22:21:463231#if defined(OS_MACOSX)
3232 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3233 it != texture_to_io_surface_map_.end(); ++it) {
3234 CFRelease(it->second);
3235 }
3236 texture_to_io_surface_map_.clear();
3237#endif
[email protected]96449d2c2009-11-25 00:01:323238}
3239
[email protected]63c9b052012-05-17 18:27:383240void GLES2DecoderImpl::SetSurface(
3241 const scoped_refptr<gfx::GLSurface>& surface) {
3242 DCHECK(context_->IsCurrent(NULL));
3243 DCHECK(surface_.get());
3244 surface_ = surface;
3245 RestoreCurrentFramebufferBindings();
3246}
3247
[email protected]2ad674132013-06-05 07:48:513248bool GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
[email protected]9a5afa432011-07-22 18:16:393249 if (!offscreen_saved_color_texture_.get())
3250 return false;
[email protected]2ad674132013-06-05 07:48:513251 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243252 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073253 offscreen_saved_color_texture_info_ = TextureRef::Create(
3254 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513255 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3256 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393257 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243258 }
[email protected]2ad674132013-06-05 07:48:513259 gpu::gles2::MailboxName name;
3260 memcpy(name.key, mailbox.name, sizeof(mailbox.name));
3261 return mailbox_manager()->ProduceTexture(
3262 GL_TEXTURE_2D, name, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243263}
3264
[email protected]260ddc4e2012-06-28 00:01:533265size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143266 size_t total = 0;
3267 if (offscreen_target_frame_buffer_.get()) {
3268 if (offscreen_target_color_texture_.get()) {
3269 total += offscreen_target_color_texture_->estimated_size();
3270 }
3271 if (offscreen_target_color_render_buffer_.get()) {
3272 total += offscreen_target_color_render_buffer_->estimated_size();
3273 }
3274 if (offscreen_target_depth_render_buffer_.get()) {
3275 total += offscreen_target_depth_render_buffer_->estimated_size();
3276 }
3277 if (offscreen_target_stencil_render_buffer_.get()) {
3278 total += offscreen_target_stencil_render_buffer_->estimated_size();
3279 }
3280 if (offscreen_saved_color_texture_.get()) {
3281 total += offscreen_saved_color_texture_->estimated_size();
3282 }
3283 if (offscreen_resolved_color_texture_.get()) {
3284 total += offscreen_resolved_color_texture_->estimated_size();
3285 }
3286 } else {
3287 gfx::Size size = surface_->GetSize();
3288 total += size.width() * size.height() *
3289 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3290 }
[email protected]260ddc4e2012-06-28 00:01:533291 return total;
[email protected]1078f912011-12-23 13:12:143292}
3293
[email protected]799b4b22011-08-22 17:09:593294bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3295 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3296 if (!is_offscreen) {
3297 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3298 << " with an onscreen framebuffer.";
3299 return false;
3300 }
3301
3302 if (offscreen_size_ == size)
3303 return true;
3304
3305 offscreen_size_ = size;
3306 int w = offscreen_size_.width();
3307 int h = offscreen_size_.height();
3308 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3309 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3310 << "to allocate storage due to excessive dimensions.";
3311 return false;
3312 }
3313
3314 // Reallocate the offscreen target buffers.
3315 DCHECK(offscreen_target_color_format_);
3316 if (IsOffscreenBufferMultisampled()) {
3317 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3318 offscreen_size_, offscreen_target_color_format_,
3319 offscreen_target_samples_)) {
3320 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3321 << "to allocate storage for offscreen target color buffer.";
3322 return false;
3323 }
3324 } else {
3325 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093326 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593327 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3328 << "to allocate storage for offscreen target color texture.";
3329 return false;
3330 }
3331 }
3332 if (offscreen_target_depth_format_ &&
3333 !offscreen_target_depth_render_buffer_->AllocateStorage(
3334 offscreen_size_, offscreen_target_depth_format_,
3335 offscreen_target_samples_)) {
3336 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3337 << "to allocate storage for offscreen target depth buffer.";
3338 return false;
3339 }
3340 if (offscreen_target_stencil_format_ &&
3341 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3342 offscreen_size_, offscreen_target_stencil_format_,
3343 offscreen_target_samples_)) {
3344 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3345 << "to allocate storage for offscreen target stencil buffer.";
3346 return false;
3347 }
3348
3349 // Attach the offscreen target buffers to the target frame buffer.
3350 if (IsOffscreenBufferMultisampled()) {
3351 offscreen_target_frame_buffer_->AttachRenderBuffer(
3352 GL_COLOR_ATTACHMENT0,
3353 offscreen_target_color_render_buffer_.get());
3354 } else {
3355 offscreen_target_frame_buffer_->AttachRenderTexture(
3356 offscreen_target_color_texture_.get());
3357 }
3358 if (offscreen_target_depth_format_) {
3359 offscreen_target_frame_buffer_->AttachRenderBuffer(
3360 GL_DEPTH_ATTACHMENT,
3361 offscreen_target_depth_render_buffer_.get());
3362 }
3363 const bool packed_depth_stencil =
3364 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3365 if (packed_depth_stencil) {
3366 offscreen_target_frame_buffer_->AttachRenderBuffer(
3367 GL_STENCIL_ATTACHMENT,
3368 offscreen_target_depth_render_buffer_.get());
3369 } else if (offscreen_target_stencil_format_) {
3370 offscreen_target_frame_buffer_->AttachRenderBuffer(
3371 GL_STENCIL_ATTACHMENT,
3372 offscreen_target_stencil_render_buffer_.get());
3373 }
3374
3375 if (offscreen_target_frame_buffer_->CheckStatus() !=
3376 GL_FRAMEBUFFER_COMPLETE) {
3377 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3378 << "because offscreen FBO was incomplete.";
3379 return false;
3380 }
3381
3382 // Clear the target frame buffer.
3383 {
3384 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3385 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3386 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3387 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3388 glClearStencil(0);
3389 glStencilMaskSeparate(GL_FRONT, -1);
3390 glStencilMaskSeparate(GL_BACK, -1);
3391 glClearDepth(0);
3392 glDepthMask(GL_TRUE);
3393 glDisable(GL_SCISSOR_TEST);
3394 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3395 RestoreClearState();
3396 }
[email protected]d85ef76d2011-09-08 22:21:433397
3398 // Destroy the offscreen resolved framebuffers.
3399 if (offscreen_resolved_frame_buffer_.get())
3400 offscreen_resolved_frame_buffer_->Destroy();
3401 if (offscreen_resolved_color_texture_.get())
3402 offscreen_resolved_color_texture_->Destroy();
3403 offscreen_resolved_color_texture_.reset();
3404 offscreen_resolved_frame_buffer_.reset();
3405
[email protected]799b4b22011-08-22 17:09:593406 return true;
[email protected]6217d392010-03-25 22:08:353407}
3408
[email protected]799b4b22011-08-22 17:09:593409error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353410 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443411 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023412 return error::kDeferCommandUntilLater;
3413
[email protected]799b4b22011-08-22 17:09:593414 GLuint width = static_cast<GLuint>(c.width);
3415 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073416 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593417 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413418
3419 width = std::max(1U, width);
3420 height = std::max(1U, height);
3421
[email protected]a0d989162011-11-22 13:15:073422#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3423 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003424 // Make sure that we are done drawing to the back buffer before resizing.
3425 glFinish();
3426#endif
[email protected]799b4b22011-08-22 17:09:593427 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3428 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493429 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3430 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3431 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593432 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493433 }
[email protected]7ff86b92010-11-25 17:50:003434 }
[email protected]799b4b22011-08-22 17:09:593435
[email protected]9d37f062011-11-22 01:24:523436 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073437 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443438 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493439 if (!context_->IsCurrent(surface_.get())) {
3440 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3441 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053442 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493443 }
[email protected]658f7562011-09-09 05:24:053444 }
[email protected]799b4b22011-08-22 17:09:593445
3446 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393447}
3448
[email protected]96449d2c2009-11-25 00:01:323449const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3450 if (command_id > kStartPoint && command_id < kNumCommands) {
3451 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3452 }
3453 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3454}
3455
3456// Decode command with its arguments, and call the corresponding GL function.
3457// Note: args is a pointer to the command buffer. As such, it could be changed
3458// by a (malicious) client at any time, so if validation has to happen, it
3459// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143460error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323461 unsigned int command,
3462 unsigned int arg_count,
3463 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143464 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263465 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003466 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3467 // LOG(INFO), tried VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323468 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013469 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193470 }
[email protected]96449d2c2009-11-25 00:01:323471 unsigned int command_index = command - kStartPoint - 1;
3472 if (command_index < arraysize(g_command_info)) {
3473 const CommandInfo& info = g_command_info[command_index];
3474 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3475 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3476 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193477 uint32 immediate_data_size =
3478 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323479 switch (command) {
3480 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353481 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193482 result = Handle ## name( \
3483 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353484 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193485 break; \
[email protected]96449d2c2009-11-25 00:01:323486
3487 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323488 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383489 }
3490 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303491 GLenum error;
3492 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323493 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003494 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3495 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513496 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193497 }
[email protected]96449d2c2009-11-25 00:01:323498 }
3499 } else {
[email protected]f7a64ee2010-02-01 22:24:143500 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323501 }
[email protected]b9849abf2009-11-25 19:13:193502 } else {
3503 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323504 }
[email protected]a3a93e7b2010-08-28 00:48:563505 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3506 result = current_decoder_error_;
3507 current_decoder_error_ = error::kNoError;
3508 }
[email protected]b9849abf2009-11-25 19:13:193509 return result;
[email protected]96449d2c2009-11-25 00:01:323510}
3511
[email protected]ed9f9cd2013-02-27 21:12:353512void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3513 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503514}
3515
[email protected]ae51d192010-04-27 00:48:033516bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353517 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033518 return false;
3519 }
[email protected]96449d2c2009-11-25 00:01:323520 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033521 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353522 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323523 }
[email protected]ae51d192010-04-27 00:48:033524 return true;
[email protected]96449d2c2009-11-25 00:01:323525}
3526
[email protected]ae51d192010-04-27 00:48:033527bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353528 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033529 return false;
[email protected]96449d2c2009-11-25 00:01:323530 }
[email protected]ae51d192010-04-27 00:48:033531 GLuint service_id = glCreateShader(type);
3532 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353533 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033534 }
3535 return true;
[email protected]96449d2c2009-11-25 00:01:323536}
3537
[email protected]882ba1e22012-03-08 19:02:533538void GLES2DecoderImpl::DoFinish() {
3539 glFinish();
[email protected]22e3f552012-03-13 01:54:193540 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533541}
3542
3543void GLES2DecoderImpl::DoFlush() {
3544 glFlush();
[email protected]22e3f552012-03-13 01:54:193545 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533546}
3547
[email protected]3916c97e2010-02-25 03:20:503548void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453549 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023550 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513551 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533552 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503553 return;
3554 }
[email protected]e259eb412012-10-13 05:47:243555 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453556 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503557}
3558
[email protected]051b1372010-04-12 02:42:083559void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073560 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083561 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033562 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073563 buffer = GetBuffer(client_id);
3564 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353565 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153566 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3567 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353568 return;
3569 }
3570
[email protected]b10492f2013-03-08 05:24:073571 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033572 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353573 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073574 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573575 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103576 group_->GetIdAllocator(id_namespaces::kBuffers);
3577 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033578 }
[email protected]051b1372010-04-12 02:42:083579 }
[email protected]b10492f2013-03-08 05:24:073580 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3581 if (buffer) {
3582 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513583 LOCAL_SET_GL_ERROR(
3584 GL_INVALID_OPERATION,
3585 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473586 return;
3587 }
[email protected]b10492f2013-03-08 05:24:073588 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473589 }
[email protected]96449d2c2009-11-25 00:01:323590 switch (target) {
3591 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073592 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323593 break;
3594 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073595 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323596 break;
3597 default:
[email protected]a93bb842010-02-16 23:03:473598 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323599 break;
3600 }
[email protected]051b1372010-04-12 02:42:083601 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323602}
3603
[email protected]297ca1c2011-06-20 23:08:463604bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
3605 return (GLES2Util::GetChannelsForFormat(
3606 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3607}
3608
3609bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353610 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453611 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203612 if (framebuffer) {
3613 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463614 }
3615 if (offscreen_target_frame_buffer_.get()) {
3616 return offscreen_target_depth_format_ != 0;
3617 }
3618 return back_buffer_has_depth_;
3619}
3620
3621bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353622 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453623 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203624 if (framebuffer) {
3625 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463626 }
3627 if (offscreen_target_frame_buffer_.get()) {
3628 return offscreen_target_stencil_format_ != 0 ||
3629 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3630 }
3631 return back_buffer_has_stencil_;
3632}
3633
3634void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]88a61bf2012-10-27 13:00:423635 if (clear_state_dirty_) {
[email protected]297ca1c2011-06-20 23:08:463636 glColorMask(
[email protected]e259eb412012-10-13 05:47:243637 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3638 state_.color_mask_alpha &&
3639 BoundFramebufferHasColorAttachmentWithAlpha());
[email protected]297ca1c2011-06-20 23:08:463640 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243641 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223642 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463643 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243644 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423645 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243646 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423647 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223648 EnableDisable(
3649 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3650 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3651 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3652 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]88a61bf2012-10-27 13:00:423653 clear_state_dirty_ = false;
[email protected]297ca1c2011-06-20 23:08:463654 }
3655}
3656
[email protected]1868a342012-11-07 15:56:023657GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:113658 return (offscreen_target_frame_buffer_.get())
3659 ? offscreen_target_frame_buffer_->id()
3660 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:023661}
3662
3663void GLES2DecoderImpl::RestoreState() const {
[email protected]962bfbe72013-05-24 11:16:143664 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3665 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:063666 // Restore the Framebuffer first because of bugs in Intel drivers.
3667 // Intel drivers incorrectly clip the viewport settings to
3668 // the size of the current framebuffer object.
3669 RestoreFramebufferBindings();
3670 state_.RestoreState();
3671}
3672
3673void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]7cd76fd2013-06-02 21:11:113674 GLuint service_id = state_.bound_draw_framebuffer.get()
3675 ? state_.bound_draw_framebuffer->service_id()
3676 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063677 if (!features().chromium_framebuffer_multisample) {
3678 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3679 } else {
3680 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]7cd76fd2013-06-02 21:11:113681 service_id = state_.bound_read_framebuffer.get()
3682 ? state_.bound_read_framebuffer->service_id()
3683 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063684 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3685 }
[email protected]70d34263c2013-01-09 00:27:453686 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063687}
3688
3689void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:103690 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3691 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:253692 GLenum target = texture->target();
3693 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063694 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253695 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063696 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253697 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063698 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253699 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063700 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253701 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063702 RestoreTextureUnitBindings(state_.active_texture_unit);
3703 }
[email protected]70d34263c2013-01-09 00:27:453704}
3705
3706void GLES2DecoderImpl::OnFboChanged() const {
3707 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513708 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3709}
3710
3711// Called after the FBO is checked for completeness.
3712void GLES2DecoderImpl::OnUseFramebuffer() const {
3713 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3714 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323715 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513716 glScissor(state_.scissor_x,
3717 state_.scissor_y,
3718 state_.scissor_width,
3719 state_.scissor_height);
3720
3721 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3722 // it's unclear how this bug works.
3723 glFlush();
3724 }
[email protected]b177ae22011-11-01 03:29:113725}
3726
[email protected]051b1372010-04-12 02:42:083727void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063728 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083729 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033730 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063731 framebuffer = GetFramebuffer(client_id);
3732 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353733 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153734 LOG(ERROR)
3735 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3736 current_decoder_error_ = error::kGenericError;
3737 return;
[email protected]bf5a8d132011-08-16 08:39:353738 }
3739
[email protected]4d8f0dd2013-03-09 14:37:063740 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033741 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353742 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063743 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573744 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103745 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3746 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033747 } else {
[email protected]4d8f0dd2013-03-09 14:37:063748 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083749 }
[email protected]4d8f0dd2013-03-09 14:37:063750 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083751 }
[email protected]4d8f0dd2013-03-09 14:37:063752 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303753
3754 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063755 state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303756 }
3757 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063758 state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303759 }
[email protected]6217d392010-03-25 22:08:353760
[email protected]88a61bf2012-10-27 13:00:423761 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:463762
[email protected]b177ae22011-11-01 03:29:113763 // If we are rendering to the backbuffer get the FBO id for any simulated
3764 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063765 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113766 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463767 }
[email protected]6217d392010-03-25 22:08:353768
[email protected]051b1372010-04-12 02:42:083769 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453770 OnFboChanged();
[email protected]86093972010-03-11 00:13:563771}
3772
[email protected]051b1372010-04-12 02:42:083773void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273774 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083775 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033776 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273777 renderbuffer = GetRenderbuffer(client_id);
3778 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353779 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153780 LOG(ERROR)
3781 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3782 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353783 return;
3784 }
3785
[email protected]ee2a79c32013-03-10 03:50:273786 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033787 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353788 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273789 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573790 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103791 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3792 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033793 } else {
[email protected]ee2a79c32013-03-10 03:50:273794 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083795 }
[email protected]ee2a79c32013-03-10 03:50:273796 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083797 }
[email protected]ee2a79c32013-03-10 03:50:273798 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer");
3799 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083800 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563801}
3802
[email protected]051b1372010-04-12 02:42:083803void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:493804 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:083805 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033806 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:493807 texture_ref = GetTexture(client_id);
3808 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:353809 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153810 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3811 current_decoder_error_ = error::kGenericError;
3812 return;
[email protected]bf5a8d132011-08-16 08:39:353813 }
3814
[email protected]02965c22013-03-09 02:40:073815 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033816 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413817 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353818 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:493819 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:573820 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103821 group_->GetIdAllocator(id_namespaces::kTextures);
3822 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033823 }
3824 } else {
[email protected]370eaf12013-05-18 09:19:493825 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083826 }
[email protected]370eaf12013-05-18 09:19:493827 Texture* texture = texture_ref->texture();
[email protected]ae51d192010-04-27 00:48:033828
[email protected]1958e0e2010-04-22 05:17:153829 // Check the texture exists
3830 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073831 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513832 LOCAL_SET_GL_ERROR(
3833 GL_INVALID_OPERATION,
3834 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153835 return;
3836 }
[email protected]02965c22013-03-09 02:40:073837 if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:513838 LOCAL_SET_GL_ERROR(
3839 GL_INVALID_OPERATION,
3840 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423841 return;
3842 }
[email protected]02965c22013-03-09 02:40:073843 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3844 if (texture->target() == 0) {
[email protected]370eaf12013-05-18 09:19:493845 texture_manager()->SetTarget(texture_ref, target);
[email protected]a93bb842010-02-16 23:03:473846 }
[email protected]02965c22013-03-09 02:40:073847 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593848
[email protected]e259eb412012-10-13 05:47:243849 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503850 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473851 switch (target) {
3852 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:493853 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:473854 break;
3855 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:493856 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:473857 break;
[email protected]61eeb33f2011-07-26 15:30:313858 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:493859 unit.bound_texture_external_oes = texture_ref;
[email protected]02965c22013-03-09 02:40:073860 if (texture->IsStreamTexture()) {
[email protected]b0af4f52011-09-28 22:04:423861 DCHECK(stream_texture_manager_);
3862 StreamTexture* stream_tex =
[email protected]02965c22013-03-09 02:40:073863 stream_texture_manager_->LookupStreamTexture(texture->service_id());
[email protected]b0af4f52011-09-28 22:04:423864 if (stream_tex)
3865 stream_tex->Update();
3866 }
[email protected]61eeb33f2011-07-26 15:30:313867 break;
[email protected]e51bdf32011-11-23 22:21:463868 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:493869 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:463870 break;
[email protected]a93bb842010-02-16 23:03:473871 default:
3872 NOTREACHED(); // Validation should prevent us getting here.
3873 break;
3874 }
3875}
3876
[email protected]07f54fcc2009-12-22 02:46:303877void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243878 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123879 if (index != 0 ||
3880 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243881 glDisableVertexAttribArray(index);
3882 }
[email protected]07f54fcc2009-12-22 02:46:303883 } else {
[email protected]ab09b612013-03-11 22:11:513884 LOCAL_SET_GL_ERROR(
3885 GL_INVALID_VALUE,
3886 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303887 }
3888}
3889
[email protected]60f22d32012-12-12 00:31:583890void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3891 GLsizei numAttachments,
3892 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:353893 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:583894 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3895
3896 // Validates the attachments. If one of them fails
3897 // the whole command fails.
3898 for (GLsizei i = 0; i < numAttachments; ++i) {
3899 if ((framebuffer &&
3900 !validators_->attachment.IsValid(attachments[i])) ||
3901 (!framebuffer &&
3902 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:513903 LOCAL_SET_GL_ERROR_INVALID_ENUM(
3904 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:583905 return;
3906 }
3907 }
3908
3909 // Marks each one of them as not cleared
3910 for (GLsizei i = 0; i < numAttachments; ++i) {
3911 if (framebuffer) {
3912 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3913 texture_manager(),
3914 attachments[i],
3915 false);
3916 } else {
3917 switch (attachments[i]) {
3918 case GL_COLOR_EXT:
3919 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3920 break;
3921 case GL_DEPTH_EXT:
3922 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
3923 case GL_STENCIL_EXT:
3924 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
3925 break;
3926 default:
3927 NOTREACHED();
3928 break;
3929 }
3930 }
3931 }
3932
3933 glDiscardFramebufferEXT(target, numAttachments, attachments);
3934}
3935
[email protected]07f54fcc2009-12-22 02:46:303936void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243937 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:303938 glEnableVertexAttribArray(index);
3939 } else {
[email protected]ab09b612013-03-11 22:11:513940 LOCAL_SET_GL_ERROR(
3941 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303942 }
3943}
3944
[email protected]a93bb842010-02-16 23:03:473945void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]370eaf12013-05-18 09:19:493946 TextureRef* texture_ref = GetTextureInfoForTarget(target);
3947 if (!texture_ref ||
3948 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:513949 LOCAL_SET_GL_ERROR(
3950 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:473951 return;
3952 }
[email protected]38c0a972012-05-12 00:48:023953
[email protected]12d95352012-12-14 07:23:543954 if (target == GL_TEXTURE_CUBE_MAP) {
3955 for (int i = 0; i < 6; ++i) {
3956 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:493957 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:513958 LOCAL_SET_GL_ERROR(
3959 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:543960 return;
3961 }
3962 }
3963 } else {
[email protected]370eaf12013-05-18 09:19:493964 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:513965 LOCAL_SET_GL_ERROR(
3966 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:543967 return;
3968 }
[email protected]7687479c2012-05-14 23:54:043969 }
3970
[email protected]ab09b612013-03-11 22:11:513971 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:193972 // Workaround for Mac driver bug. In the large scheme of things setting
3973 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:563974 // hit so there's probably no need to make this conditional. The bug appears
3975 // to be that if the filtering mode is set to something that doesn't require
3976 // mipmaps for rendering, or is never set to something other than the default,
3977 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:153978 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193979 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3980 }
[email protected]a93bb842010-02-16 23:03:473981 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:153982 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:493983 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
3984 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:193985 }
[email protected]ab09b612013-03-11 22:11:513986 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:023987 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:493988 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:023989 }
[email protected]a93bb842010-02-16 23:03:473990}
3991
[email protected]b273e432010-04-12 17:23:583992bool GLES2DecoderImpl::GetHelper(
3993 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:583994 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:153995 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
3996 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:433997 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3998 *num_written = 1;
3999 if (params) {
4000 *params = GL_RGBA; // We don't support other formats.
4001 }
4002 return true;
4003 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4004 *num_written = 1;
4005 if (params) {
4006 *params = GL_UNSIGNED_BYTE; // We don't support other types.
4007 }
4008 return true;
4009 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4010 *num_written = 1;
4011 if (params) {
4012 *params = group_->max_fragment_uniform_vectors();
4013 }
4014 return true;
4015 case GL_MAX_VARYING_VECTORS:
4016 *num_written = 1;
4017 if (params) {
4018 *params = group_->max_varying_vectors();
4019 }
4020 return true;
4021 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4022 *num_written = 1;
4023 if (params) {
4024 *params = group_->max_vertex_uniform_vectors();
4025 }
4026 return true;
[email protected]4e8a5b122010-05-08 22:00:104027 }
[email protected]5cb735d2011-10-13 01:37:234028 }
4029 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244030 case GL_MAX_VIEWPORT_DIMS:
4031 if (offscreen_target_frame_buffer_.get()) {
4032 *num_written = 2;
4033 if (params) {
4034 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4035 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4036 }
4037 return true;
4038 }
[email protected]5cb735d2011-10-13 01:37:234039 return false;
[email protected]84afefa2011-10-19 21:45:534040 case GL_MAX_SAMPLES:
4041 *num_written = 1;
4042 if (params) {
4043 params[0] = renderbuffer_manager()->max_samples();
4044 }
4045 return true;
4046 case GL_MAX_RENDERBUFFER_SIZE:
4047 *num_written = 1;
4048 if (params) {
4049 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4050 }
4051 return true;
[email protected]5cb735d2011-10-13 01:37:234052 case GL_MAX_TEXTURE_SIZE:
4053 *num_written = 1;
4054 if (params) {
4055 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4056 }
4057 return true;
4058 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4059 *num_written = 1;
4060 if (params) {
4061 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4062 }
4063 return true;
[email protected]2f143d482013-03-14 18:04:494064 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4065 *num_written = 1;
4066 if (params) {
4067 params[0] = group_->max_color_attachments();
4068 }
4069 return true;
4070 case GL_MAX_DRAW_BUFFERS_ARB:
4071 *num_written = 1;
4072 if (params) {
4073 params[0] = group_->max_draw_buffers();
4074 }
4075 return true;
[email protected]297ca1c2011-06-20 23:08:464076 case GL_ALPHA_BITS:
4077 *num_written = 1;
4078 if (params) {
4079 GLint v = 0;
4080 glGetIntegerv(GL_ALPHA_BITS, &v);
4081 params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0;
4082 }
4083 return true;
4084 case GL_DEPTH_BITS:
4085 *num_written = 1;
4086 if (params) {
4087 GLint v = 0;
4088 glGetIntegerv(GL_DEPTH_BITS, &v);
4089 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4090 }
4091 return true;
4092 case GL_STENCIL_BITS:
4093 *num_written = 1;
4094 if (params) {
4095 GLint v = 0;
4096 glGetIntegerv(GL_STENCIL_BITS, &v);
4097 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4098 }
4099 return true;
[email protected]656dcaad2010-05-07 17:18:374100 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114101 *num_written = validators_->compressed_texture_format.GetValues().size();
4102 if (params) {
4103 for (GLint ii = 0; ii < *num_written; ++ii) {
4104 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4105 }
4106 }
[email protected]656dcaad2010-05-07 17:18:374107 return true;
[email protected]b273e432010-04-12 17:23:584108 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4109 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104110 if (params) {
[email protected]302ce6d2011-07-07 23:28:114111 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104112 }
[email protected]b273e432010-04-12 17:23:584113 return true;
4114 case GL_NUM_SHADER_BINARY_FORMATS:
4115 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104116 if (params) {
[email protected]302ce6d2011-07-07 23:28:114117 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104118 }
[email protected]b273e432010-04-12 17:23:584119 return true;
4120 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114121 *num_written = validators_->shader_binary_format.GetValues().size();
4122 if (params) {
4123 for (GLint ii = 0; ii < *num_written; ++ii) {
4124 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4125 }
4126 }
4127 return true;
[email protected]b273e432010-04-12 17:23:584128 case GL_SHADER_COMPILER:
4129 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104130 if (params) {
4131 *params = GL_TRUE;
4132 }
[email protected]b273e432010-04-12 17:23:584133 return true;
[email protected]6b8cf1a2010-05-06 16:13:584134 case GL_ARRAY_BUFFER_BINDING:
4135 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104136 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114137 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104138 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244139 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104140 &client_id);
4141 *params = client_id;
4142 } else {
4143 *params = 0;
4144 }
[email protected]6b8cf1a2010-05-06 16:13:584145 }
4146 return true;
4147 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4148 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104149 if (params) {
[email protected]e259eb412012-10-13 05:47:244150 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104151 GLuint client_id = 0;
4152 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254153 state_.vertex_attrib_manager->element_array_buffer()->
4154 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104155 *params = client_id;
4156 } else {
4157 *params = 0;
4158 }
[email protected]6b8cf1a2010-05-06 16:13:584159 }
4160 return true;
4161 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304162 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584163 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104164 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354165 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454166 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204167 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104168 GLuint client_id = 0;
4169 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204170 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304171 *params = client_id;
4172 } else {
4173 *params = 0;
4174 }
4175 }
4176 return true;
[email protected]ebfb73c2012-08-15 02:37:454177 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304178 *num_written = 1;
4179 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354180 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454181 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204182 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304183 GLuint client_id = 0;
4184 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204185 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104186 *params = client_id;
4187 } else {
4188 *params = 0;
4189 }
[email protected]6b8cf1a2010-05-06 16:13:584190 }
4191 return true;
4192 case GL_RENDERBUFFER_BINDING:
4193 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104194 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354195 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204196 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4197 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104198 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104199 } else {
4200 *params = 0;
4201 }
[email protected]6b8cf1a2010-05-06 16:13:584202 }
4203 return true;
4204 case GL_CURRENT_PROGRAM:
4205 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104206 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114207 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104208 GLuint client_id = 0;
4209 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244210 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104211 *params = client_id;
4212 } else {
4213 *params = 0;
4214 }
[email protected]6b8cf1a2010-05-06 16:13:584215 }
4216 return true;
[email protected]bf835842012-11-19 15:21:514217 case GL_VERTEX_ARRAY_BINDING_OES:
4218 *num_written = 1;
4219 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114220 if (state_.vertex_attrib_manager.get() !=
4221 default_vertex_attrib_manager_.get()) {
[email protected]bf835842012-11-19 15:21:514222 GLuint client_id = 0;
4223 vertex_array_manager_->GetClientId(
4224 state_.vertex_attrib_manager->service_id(), &client_id);
4225 *params = client_id;
4226 } else {
4227 *params = 0;
4228 }
4229 }
4230 return true;
[email protected]4e8a5b122010-05-08 22:00:104231 case GL_TEXTURE_BINDING_2D:
4232 *num_written = 1;
4233 if (params) {
[email protected]e259eb412012-10-13 05:47:244234 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114235 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104236 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584237 } else {
4238 *params = 0;
4239 }
[email protected]6b8cf1a2010-05-06 16:13:584240 }
[email protected]4e8a5b122010-05-08 22:00:104241 return true;
4242 case GL_TEXTURE_BINDING_CUBE_MAP:
4243 *num_written = 1;
4244 if (params) {
[email protected]e259eb412012-10-13 05:47:244245 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114246 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104247 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584248 } else {
4249 *params = 0;
4250 }
[email protected]6b8cf1a2010-05-06 16:13:584251 }
[email protected]4e8a5b122010-05-08 22:00:104252 return true;
[email protected]61eeb33f2011-07-26 15:30:314253 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4254 *num_written = 1;
4255 if (params) {
[email protected]e259eb412012-10-13 05:47:244256 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114257 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104258 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314259 } else {
4260 *params = 0;
4261 }
4262 }
4263 return true;
[email protected]e51bdf32011-11-23 22:21:464264 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4265 *num_written = 1;
4266 if (params) {
[email protected]e259eb412012-10-13 05:47:244267 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114268 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104269 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464270 } else {
4271 *params = 0;
4272 }
4273 }
4274 return true;
[email protected]6c75c712012-06-19 15:43:174275 case GL_UNPACK_FLIP_Y_CHROMIUM:
4276 *num_written = 1;
4277 if (params) {
4278 params[0] = unpack_flip_y_;
4279 }
4280 return true;
4281 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4282 *num_written = 1;
4283 if (params) {
4284 params[0] = unpack_premultiply_alpha_;
4285 }
4286 return true;
4287 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4288 *num_written = 1;
4289 if (params) {
4290 params[0] = unpack_unpremultiply_alpha_;
4291 }
4292 return true;
[email protected]b273e432010-04-12 17:23:584293 default:
[email protected]2f143d482013-03-14 18:04:494294 if (pname >= GL_DRAW_BUFFER0_ARB &&
4295 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4296 *num_written = 1;
4297 if (params) {
4298 Framebuffer* framebuffer =
4299 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4300 if (framebuffer) {
4301 params[0] = framebuffer->GetDrawBuffer(pname);
4302 } else { // backbuffer
4303 if (pname == GL_DRAW_BUFFER0_ARB)
4304 params[0] = group_->draw_buffer();
4305 else
4306 params[0] = GL_NONE;
4307 }
4308 }
4309 return true;
4310 }
[email protected]4e8a5b122010-05-08 22:00:104311 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534312 return false;
[email protected]b273e432010-04-12 17:23:584313 }
4314}
4315
[email protected]4e8a5b122010-05-08 22:00:104316bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4317 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264318 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534319 return true;
4320 }
[email protected]4e8a5b122010-05-08 22:00:104321 return GetHelper(pname, NULL, num_values);
4322}
4323
[email protected]b273e432010-04-12 17:23:584324void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4325 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104326 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534327 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554328 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264329 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534330 GetHelper(pname, values.get(), &num_written);
4331 }
[email protected]b273e432010-04-12 17:23:584332 for (GLsizei ii = 0; ii < num_written; ++ii) {
4333 params[ii] = static_cast<GLboolean>(values[ii]);
4334 }
4335 } else {
4336 glGetBooleanv(pname, params);
4337 }
4338}
4339
4340void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4341 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104342 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264343 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534344 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554345 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534346 GetHelper(pname, values.get(), &num_written);
4347 for (GLsizei ii = 0; ii < num_written; ++ii) {
4348 params[ii] = static_cast<GLfloat>(values[ii]);
4349 }
4350 } else {
4351 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584352 }
[email protected]b273e432010-04-12 17:23:584353 }
4354}
4355
4356void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4357 DCHECK(params);
4358 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264359 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534360 !GetHelper(pname, params, &num_written)) {
[email protected]b273e432010-04-12 17:23:584361 glGetIntegerv(pname, params);
4362 }
4363}
4364
[email protected]a0c3e972010-04-21 00:49:134365void GLES2DecoderImpl::DoGetProgramiv(
4366 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424367 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4368 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134369 return;
4370 }
[email protected]df37b9932013-03-08 05:21:424371 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134372}
4373
[email protected]17cfbe0e2013-03-07 01:26:084374void GLES2DecoderImpl::DoGetBufferParameteriv(
4375 GLenum target, GLenum pname, GLint* params) {
4376 Buffer* buffer = GetBufferInfoForTarget(target);
4377 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:514378 LOCAL_SET_GL_ERROR(
[email protected]17cfbe0e2013-03-07 01:26:084379 GL_INVALID_OPERATION, "glGetBufferParameteriv",
4380 "no buffer bound for target");
4381 return;
4382 }
4383 switch (pname) {
4384 case GL_BUFFER_SIZE:
4385 *params = buffer->size();
4386 break;
4387 case GL_BUFFER_USAGE:
4388 *params = buffer->usage();
4389 break;
4390 default:
4391 NOTREACHED();
4392 }
4393}
4394
[email protected]258a3313f2011-10-18 20:13:574395void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424396 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574397 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514398 LOCAL_SET_GL_ERROR(
4399 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574400 return;
4401 }
[email protected]68dcb1f2012-04-07 00:14:564402 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514403 LOCAL_SET_GL_ERROR(
4404 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564405 return;
4406 }
4407 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514408 LOCAL_SET_GL_ERROR(
4409 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564410 return;
4411 }
[email protected]df37b9932013-03-08 05:21:424412 Program* program = GetProgramInfoNotShader(
4413 program_id, "glBindAttribLocation");
4414 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574415 return;
[email protected]558847a2010-03-24 07:02:544416 }
[email protected]df37b9932013-03-08 05:21:424417 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4418 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574419}
4420
4421error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354422 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574423 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544424 GLuint index = static_cast<GLuint>(c.index);
4425 uint32 name_size = c.data_size;
4426 const char* name = GetSharedMemoryAs<const char*>(
4427 c.name_shm_id, c.name_shm_offset, name_size);
4428 if (name == NULL) {
4429 return error::kOutOfBounds;
4430 }
4431 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574432 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544433 return error::kNoError;
4434}
4435
4436error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:354437 uint32 immediate_data_size, const cmds::BindAttribLocationImmediate& c) {
[email protected]6b8cf1a2010-05-06 16:13:584438 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544439 GLuint index = static_cast<GLuint>(c.index);
4440 uint32 name_size = c.data_size;
4441 const char* name = GetImmediateDataAs<const char*>(
4442 c, name_size, immediate_data_size);
4443 if (name == NULL) {
4444 return error::kOutOfBounds;
4445 }
4446 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574447 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544448 return error::kNoError;
4449}
4450
4451error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354452 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584453 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544454 GLuint index = static_cast<GLuint>(c.index);
4455 Bucket* bucket = GetBucket(c.name_bucket_id);
4456 if (!bucket || bucket->size() == 0) {
4457 return error::kInvalidArguments;
4458 }
4459 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184460 if (!bucket->GetAsString(&name_str)) {
4461 return error::kInvalidArguments;
4462 }
[email protected]258a3313f2011-10-18 20:13:574463 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544464 return error::kNoError;
4465}
4466
[email protected]2be6abf32012-06-26 00:28:334467void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424468 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334469 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514470 LOCAL_SET_GL_ERROR(
4471 GL_INVALID_VALUE,
4472 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334473 return;
4474 }
4475 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514476 LOCAL_SET_GL_ERROR(
4477 GL_INVALID_OPERATION,
4478 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334479 return;
4480 }
4481 if (location < 0 || static_cast<uint32>(location) >=
4482 (group_->max_fragment_uniform_vectors() +
4483 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514484 LOCAL_SET_GL_ERROR(
4485 GL_INVALID_VALUE,
4486 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334487 return;
4488 }
[email protected]df37b9932013-03-08 05:21:424489 Program* program = GetProgramInfoNotShader(
4490 program_id, "glBindUniformLocationCHROMIUM");
4491 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334492 return;
4493 }
[email protected]df37b9932013-03-08 05:21:424494 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514495 LOCAL_SET_GL_ERROR(
4496 GL_INVALID_VALUE,
4497 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334498 }
4499}
4500
4501error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354502 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334503 GLuint program = static_cast<GLuint>(c.program);
4504 GLint location = static_cast<GLint>(c.location);
4505 uint32 name_size = c.data_size;
4506 const char* name = GetSharedMemoryAs<const char*>(
4507 c.name_shm_id, c.name_shm_offset, name_size);
4508 if (name == NULL) {
4509 return error::kOutOfBounds;
4510 }
4511 String name_str(name, name_size);
4512 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4513 return error::kNoError;
4514}
4515
4516error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4517 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354518 const cmds::BindUniformLocationCHROMIUMImmediate& c) {
[email protected]2be6abf32012-06-26 00:28:334519 GLuint program = static_cast<GLuint>(c.program);
4520 GLint location = static_cast<GLint>(c.location);
4521 uint32 name_size = c.data_size;
4522 const char* name = GetImmediateDataAs<const char*>(
4523 c, name_size, immediate_data_size);
4524 if (name == NULL) {
4525 return error::kOutOfBounds;
4526 }
4527 String name_str(name, name_size);
4528 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4529 return error::kNoError;
4530}
4531
4532error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4533 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354534 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334535 GLuint program = static_cast<GLuint>(c.program);
4536 GLint location = static_cast<GLint>(c.location);
4537 Bucket* bucket = GetBucket(c.name_bucket_id);
4538 if (!bucket || bucket->size() == 0) {
4539 return error::kInvalidArguments;
4540 }
4541 std::string name_str;
4542 if (!bucket->GetAsString(&name_str)) {
4543 return error::kInvalidArguments;
4544 }
4545 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4546 return error::kNoError;
4547}
4548
[email protected]f7a64ee2010-02-01 22:24:144549error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354550 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034551 GLuint client_id = c.shader;
4552 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424553 Shader* shader = GetShader(client_id);
4554 if (shader) {
4555 if (!shader->IsDeleted()) {
4556 glDeleteShader(shader->service_id());
4557 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144558 }
[email protected]ae51d192010-04-27 00:48:034559 } else {
[email protected]ab09b612013-03-11 22:11:514560 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034561 }
[email protected]96449d2c2009-11-25 00:01:324562 }
[email protected]f7a64ee2010-02-01 22:24:144563 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324564}
4565
[email protected]f7a64ee2010-02-01 22:24:144566error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354567 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034568 GLuint client_id = c.program;
4569 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424570 Program* program = GetProgram(client_id);
4571 if (program) {
4572 if (!program->IsDeleted()) {
4573 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144574 }
[email protected]ae51d192010-04-27 00:48:034575 } else {
[email protected]ab09b612013-03-11 22:11:514576 LOCAL_SET_GL_ERROR(
4577 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034578 }
[email protected]96449d2c2009-11-25 00:01:324579 }
[email protected]f7a64ee2010-02-01 22:24:144580 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324581}
4582
[email protected]269200b12010-11-18 22:53:064583void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104584 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574585 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104586 for (GLsizei ii = 0; ii < n; ++ii) {
4587 id_allocator->FreeID(ids[ii]);
4588 }
4589}
4590
[email protected]269200b12010-11-18 22:53:064591error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354592 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104593 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4594 GLsizei n = static_cast<GLsizei>(c.n);
4595 uint32 data_size;
4596 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4597 return error::kOutOfBounds;
4598 }
4599 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4600 c.ids_shm_id, c.ids_shm_offset, data_size);
4601 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514602 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104603 return error::kNoError;
4604 }
4605 if (ids == NULL) {
4606 return error::kOutOfBounds;
4607 }
[email protected]269200b12010-11-18 22:53:064608 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104609 return error::kNoError;
4610}
4611
[email protected]269200b12010-11-18 22:53:064612void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104613 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574614 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104615 if (id_offset == 0) {
4616 for (GLsizei ii = 0; ii < n; ++ii) {
4617 ids[ii] = id_allocator->AllocateID();
4618 }
4619 } else {
4620 for (GLsizei ii = 0; ii < n; ++ii) {
4621 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4622 id_offset = ids[ii] + 1;
4623 }
4624 }
4625}
4626
[email protected]269200b12010-11-18 22:53:064627error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354628 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104629 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4630 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4631 GLsizei n = static_cast<GLsizei>(c.n);
4632 uint32 data_size;
4633 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4634 return error::kOutOfBounds;
4635 }
4636 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4637 c.ids_shm_id, c.ids_shm_offset, data_size);
4638 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514639 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104640 return error::kNoError;
4641 }
4642 if (ids == NULL) {
4643 return error::kOutOfBounds;
4644 }
[email protected]269200b12010-11-18 22:53:064645 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104646 return error::kNoError;
4647}
4648
[email protected]269200b12010-11-18 22:53:064649void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104650 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574651 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104652 for (GLsizei ii = 0; ii < n; ++ii) {
4653 if (!id_allocator->MarkAsUsed(ids[ii])) {
4654 for (GLsizei jj = 0; jj < ii; ++jj) {
4655 id_allocator->FreeID(ids[jj]);
4656 }
[email protected]ab09b612013-03-11 22:11:514657 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434658 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4659 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104660 return;
4661 }
4662 }
4663}
4664
[email protected]269200b12010-11-18 22:53:064665error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354666 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104667 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4668 GLsizei n = static_cast<GLsizei>(c.n);
4669 uint32 data_size;
4670 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4671 return error::kOutOfBounds;
4672 }
4673 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4674 c.ids_shm_id, c.ids_shm_offset, data_size);
4675 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514676 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104677 return error::kNoError;
4678 }
4679 if (ids == NULL) {
4680 return error::kOutOfBounds;
4681 }
[email protected]269200b12010-11-18 22:53:064682 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104683 return error::kNoError;
4684}
4685
[email protected]a7266a92012-06-28 02:11:084686error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444687 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204688 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]e259eb412012-10-13 05:47:244689 UNSHIPPED_TRACE_EVENT_INSTANT2(
4690 "test_gpu", "DoClear",
[email protected]c76faea2013-03-26 07:42:424691 TRACE_EVENT_SCOPE_THREAD,
[email protected]e259eb412012-10-13 05:47:244692 "red", state_.color_clear_red,
4693 "green", state_.color_clear_green);
[email protected]297ca1c2011-06-20 23:08:464694 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274695 glClear(mask);
4696 }
[email protected]a7266a92012-06-28 02:11:084697 return error::kNoError;
4698}
4699
[email protected]36cef8ce2010-03-16 07:34:454700void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4701 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034702 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064703 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4704 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514705 LOCAL_SET_GL_ERROR(
4706 GL_INVALID_OPERATION,
4707 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454708 return;
4709 }
[email protected]ae51d192010-04-27 00:48:034710 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274711 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034712 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274713 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4714 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514715 LOCAL_SET_GL_ERROR(
4716 GL_INVALID_OPERATION,
4717 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034718 return;
4719 }
[email protected]ee2a79c32013-03-10 03:50:274720 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034721 }
[email protected]ab09b612013-03-11 22:11:514722 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034723 glFramebufferRenderbufferEXT(
4724 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514725 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264726 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274727 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284728 }
[email protected]7cd76fd2013-06-02 21:11:114729 if (framebuffer == state_.bound_draw_framebuffer.get()) {
[email protected]88a61bf2012-10-27 13:00:424730 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464731 }
[email protected]81fc9d02013-03-14 23:53:324732 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284733}
4734
[email protected]3a2e7c7b2010-08-06 01:12:284735void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464736 if (SetCapabilityState(cap, false)) {
4737 glDisable(cap);
4738 }
[email protected]3a2e7c7b2010-08-06 01:12:284739}
4740
4741void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464742 if (SetCapabilityState(cap, true)) {
4743 glEnable(cap);
4744 }
[email protected]3a2e7c7b2010-08-06 01:12:284745}
4746
[email protected]88a61bf2012-10-27 13:00:424747void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4748 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4749 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4750 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284751}
4752
[email protected]b04e24c2013-01-08 18:35:254753void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424754 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4755 state_.sample_coverage_invert = (invert != 0);
4756 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284757}
4758
[email protected]0d6bfdc2011-11-02 01:32:204759// Assumes framebuffer is complete.
4760void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064761 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304762 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204763 // bind this to the DRAW point, clear then bind back to READ
4764 // TODO(gman): I don't think there is any guarantee that an FBO that
4765 // is complete on the READ attachment will be complete as a DRAW
4766 // attachment.
4767 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064768 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304769 }
[email protected]3a2e7c7b2010-08-06 01:12:284770 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064771 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464772 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204773 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464774 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064775 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4776 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284777 glColorMask(true, true, true, true);
4778 clear_bits |= GL_COLOR_BUFFER_BIT;
4779 }
4780
[email protected]4d8f0dd2013-03-09 14:37:064781 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4782 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284783 glClearStencil(0);
4784 glStencilMask(-1);
4785 clear_bits |= GL_STENCIL_BUFFER_BIT;
4786 }
4787
[email protected]4d8f0dd2013-03-09 14:37:064788 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4789 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284790 glClearDepth(1.0f);
4791 glDepthMask(true);
4792 clear_bits |= GL_DEPTH_BUFFER_BIT;
4793 }
4794
4795 glDisable(GL_SCISSOR_TEST);
4796 glClear(clear_bits);
4797
[email protected]968351b2011-12-20 08:26:514798 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064799 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284800
[email protected]c007aa02010-09-02 22:22:404801 RestoreClearState();
4802
4803 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064804 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4805 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484806 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064807 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4808 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484809 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404810 }
4811}
4812
4813void GLES2DecoderImpl::RestoreClearState() {
[email protected]88a61bf2012-10-27 13:00:424814 clear_state_dirty_ = true;
[email protected]e259eb412012-10-13 05:47:244815 glClearColor(
4816 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4817 state_.color_clear_alpha);
4818 glClearStencil(state_.stencil_clear);
4819 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224820 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284821 glEnable(GL_SCISSOR_TEST);
4822 }
[email protected]36cef8ce2010-03-16 07:34:454823}
4824
4825GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354826 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304827 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204828 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454829 return GL_FRAMEBUFFER_COMPLETE;
4830 }
[email protected]0d6bfdc2011-11-02 01:32:204831 GLenum completeness = framebuffer->IsPossiblyComplete();
4832 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4833 return completeness;
4834 }
[email protected]73276522012-11-09 05:50:204835 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454836}
4837
4838void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034839 GLenum target, GLenum attachment, GLenum textarget,
4840 GLuint client_texture_id, GLint level) {
[email protected]4d8f0dd2013-03-09 14:37:064841 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4842 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514843 LOCAL_SET_GL_ERROR(
4844 GL_INVALID_OPERATION,
4845 "glFramebufferTexture2D", "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454846 return;
4847 }
[email protected]ae51d192010-04-27 00:48:034848 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:494849 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:034850 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:494851 texture_ref = GetTexture(client_texture_id);
4852 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:514853 LOCAL_SET_GL_ERROR(
4854 GL_INVALID_OPERATION,
[email protected]370eaf12013-05-18 09:19:494855 "glFramebufferTexture2D", "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:034856 return;
4857 }
[email protected]370eaf12013-05-18 09:19:494858 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:034859 }
[email protected]0d6bfdc2011-11-02 01:32:204860
[email protected]80eb6b52012-01-19 00:14:414861 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:514862 LOCAL_SET_GL_ERROR(
4863 GL_INVALID_VALUE,
4864 "glFramebufferTexture2D", "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204865 return;
4866 }
4867
[email protected]ab09b612013-03-11 22:11:514868 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferTexture2D");
[email protected]ae51d192010-04-27 00:48:034869 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
[email protected]ab09b612013-03-11 22:11:514870 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferTexture2D");
[email protected]9edc6b22010-12-23 02:00:264871 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494872 framebuffer->AttachTexture(attachment, texture_ref, textarget, level);
[email protected]3a2e7c7b2010-08-06 01:12:284873 }
[email protected]7cd76fd2013-06-02 21:11:114874 if (framebuffer == state_.bound_draw_framebuffer.get()) {
[email protected]88a61bf2012-10-27 13:00:424875 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464876 }
[email protected]81fc9d02013-03-14 23:53:324877 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:454878}
4879
4880void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4881 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:064882 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4883 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514884 LOCAL_SET_GL_ERROR(
4885 GL_INVALID_OPERATION,
4886 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454887 return;
4888 }
[email protected]74c1ec42010-08-12 01:55:574889 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:104890 const Framebuffer::Attachment* attachment_object =
4891 framebuffer->GetAttachment(attachment);
4892 *params = attachment_object ? attachment_object->object_name() : 0;
4893 } else {
4894 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:574895 }
[email protected]36cef8ce2010-03-16 07:34:454896}
4897
4898void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
4899 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:354900 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204901 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4902 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514903 LOCAL_SET_GL_ERROR(
4904 GL_INVALID_OPERATION,
4905 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454906 return;
4907 }
[email protected]3a03a8f2011-03-19 00:51:274908 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434909 case GL_RENDERBUFFER_INTERNAL_FORMAT:
4910 *params = renderbuffer->internal_format();
4911 break;
4912 case GL_RENDERBUFFER_WIDTH:
4913 *params = renderbuffer->width();
4914 break;
4915 case GL_RENDERBUFFER_HEIGHT:
4916 *params = renderbuffer->height();
4917 break;
4918 default:
4919 glGetRenderbufferParameterivEXT(target, pname, params);
4920 break;
[email protected]b71f52c2010-06-18 22:20:204921 }
[email protected]36cef8ce2010-03-16 07:34:454922}
4923
[email protected]8e3e0662010-08-23 18:46:304924void GLES2DecoderImpl::DoBlitFramebufferEXT(
4925 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4926 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4927 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:444928 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:154929 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:514930 LOCAL_SET_GL_ERROR(
4931 GL_INVALID_OPERATION,
4932 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304933 }
[email protected]0c16343f2013-03-08 20:40:164934
4935 if (!CheckBoundFramebuffersValid("glBlitFramebufferEXT")) {
4936 return;
4937 }
4938
[email protected]d058bca2012-11-26 10:27:264939 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:244940 if (IsAngle()) {
4941 glBlitFramebufferANGLE(
4942 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4943 } else {
4944 glBlitFramebufferEXT(
4945 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4946 }
[email protected]d058bca2012-11-26 10:27:264947 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]c76faea2013-03-26 07:42:424948 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", TRACE_EVENT_SCOPE_THREAD,
4949 "width", srcX1 - srcX0);
[email protected]8e3e0662010-08-23 18:46:304950}
4951
4952void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
4953 GLenum target, GLsizei samples, GLenum internalformat,
4954 GLsizei width, GLsizei height) {
[email protected]62e155e2012-10-23 22:43:154955 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:514956 LOCAL_SET_GL_ERROR(
4957 GL_INVALID_OPERATION,
4958 "glRenderbufferStorageMultisample", "function not available");
[email protected]8e3e0662010-08-23 18:46:304959 return;
4960 }
[email protected]8e3e0662010-08-23 18:46:304961
[email protected]ed9f9cd2013-02-27 21:12:354962 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204963 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4964 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514965 LOCAL_SET_GL_ERROR(
4966 GL_INVALID_OPERATION,
4967 "glRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:204968 return;
4969 }
4970
[email protected]84afefa2011-10-19 21:45:534971 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:514972 LOCAL_SET_GL_ERROR(
4973 GL_INVALID_VALUE,
4974 "glRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:534975 return;
4976 }
4977
4978 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
4979 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:514980 LOCAL_SET_GL_ERROR(
4981 GL_INVALID_VALUE,
4982 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:534983 return;
4984 }
4985
[email protected]7989c9e2013-01-23 06:39:264986 uint32 estimated_size = 0;
4987 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
4988 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:514989 LOCAL_SET_GL_ERROR(
4990 GL_OUT_OF_MEMORY,
4991 "glRenderbufferStorageMultsample", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:264992 return;
[email protected]8e3e0662010-08-23 18:46:304993 }
4994
[email protected]7989c9e2013-01-23 06:39:264995 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:514996 LOCAL_SET_GL_ERROR(
4997 GL_OUT_OF_MEMORY,
4998 "glRenderbufferStorageMultsample", "out of memory");
[email protected]7989c9e2013-01-23 06:39:264999 return;
5000 }
5001
5002 GLenum impl_format = RenderbufferManager::
5003 InternalRenderbufferFormatToImplFormat(internalformat);
[email protected]ab09b612013-03-11 22:11:515004 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisample");
[email protected]866b91c52011-03-23 14:38:085005 if (IsAngle()) {
5006 glRenderbufferStorageMultisampleANGLE(
5007 target, samples, impl_format, width, height);
5008 } else {
5009 glRenderbufferStorageMultisampleEXT(
5010 target, samples, impl_format, width, height);
5011 }
[email protected]ab09b612013-03-11 22:11:515012 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisample");
[email protected]9edc6b22010-12-23 02:00:265013 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515014 // TODO(gman): If renderbuffers tracked which framebuffers they were
5015 // attached to we could just mark those framebuffers as not complete.
5016 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205017 renderbuffer_manager()->SetInfo(
5018 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265019 }
[email protected]8e3e0662010-08-23 18:46:305020}
5021
[email protected]36cef8ce2010-03-16 07:34:455022void GLES2DecoderImpl::DoRenderbufferStorage(
5023 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355024 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205025 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5026 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515027 LOCAL_SET_GL_ERROR(
5028 GL_INVALID_OPERATION,
5029 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455030 return;
5031 }
[email protected]876f6fee2010-08-02 23:10:325032
[email protected]84afefa2011-10-19 21:45:535033 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5034 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515035 LOCAL_SET_GL_ERROR(
5036 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535037 return;
5038 }
5039
[email protected]7989c9e2013-01-23 06:39:265040 uint32 estimated_size = 0;
5041 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5042 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515043 LOCAL_SET_GL_ERROR(
5044 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265045 return;
5046 }
5047
5048 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515049 LOCAL_SET_GL_ERROR(
5050 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265051 return;
[email protected]b71f52c2010-06-18 22:20:205052 }
[email protected]876f6fee2010-08-02 23:10:325053
[email protected]ab09b612013-03-11 22:11:515054 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265055 glRenderbufferStorageEXT(
5056 target, RenderbufferManager::
5057 InternalRenderbufferFormatToImplFormat(internalformat),
5058 width, height);
[email protected]ab09b612013-03-11 22:11:515059 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265060 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515061 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5062 // we could just mark those framebuffers as not complete.
5063 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205064 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265065 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265066 }
[email protected]36cef8ce2010-03-16 07:34:455067}
5068
[email protected]df37b9932013-03-08 05:21:425069void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385070 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425071 Program* program = GetProgramInfoNotShader(
5072 program_id, "glLinkProgram");
5073 if (!program) {
[email protected]a93bb842010-02-16 23:03:475074 return;
5075 }
[email protected]05afda12011-01-20 00:17:345076
[email protected]df37b9932013-03-08 05:21:425077 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395078 ShaderTranslator* vertex_translator = NULL;
5079 ShaderTranslator* fragment_translator = NULL;
5080 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115081 vertex_translator = vertex_translator_.get();
5082 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395083 }
[email protected]df37b9932013-03-08 05:21:425084 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115085 vertex_translator,
5086 fragment_translator,
5087 feature_info_.get(),
5088 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425089 if (program == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:155090 if (workarounds().use_current_program_after_successful_link) {
[email protected]df37b9932013-03-08 05:21:425091 glUseProgram(program->service_id());
[email protected]c2a3caf12012-10-23 19:32:005092 }
[email protected]df37b9932013-03-08 05:21:425093 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545094 }
5095 }
[email protected]07f54fcc2009-12-22 02:46:305096};
5097
[email protected]3916c97e2010-02-25 03:20:505098void GLES2DecoderImpl::DoTexParameterf(
5099 GLenum target, GLenum pname, GLfloat param) {
[email protected]370eaf12013-05-18 09:19:495100 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075101 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515102 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245103 return;
[email protected]07f54fcc2009-12-22 02:46:305104 }
[email protected]cbb22e42011-05-12 23:36:245105
[email protected]02965c22013-03-09 02:40:075106 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505107 "glTexParameterf", GetErrorState(), texture, pname,
5108 static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305109}
5110
[email protected]3916c97e2010-02-25 03:20:505111void GLES2DecoderImpl::DoTexParameteri(
5112 GLenum target, GLenum pname, GLint param) {
[email protected]370eaf12013-05-18 09:19:495113 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075114 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515115 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245116 return;
[email protected]3916c97e2010-02-25 03:20:505117 }
[email protected]cbb22e42011-05-12 23:36:245118
[email protected]02965c22013-03-09 02:40:075119 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505120 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505121}
5122
5123void GLES2DecoderImpl::DoTexParameterfv(
5124 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]370eaf12013-05-18 09:19:495125 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075126 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515127 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245128 return;
[email protected]3916c97e2010-02-25 03:20:505129 }
[email protected]cbb22e42011-05-12 23:36:245130
[email protected]02965c22013-03-09 02:40:075131 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505132 "glTexParameterfv", GetErrorState(), texture, pname,
5133 static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505134}
5135
5136void GLES2DecoderImpl::DoTexParameteriv(
5137 GLenum target, GLenum pname, const GLint* params) {
[email protected]370eaf12013-05-18 09:19:495138 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075139 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515140 LOCAL_SET_GL_ERROR(
5141 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245142 return;
[email protected]3916c97e2010-02-25 03:20:505143 }
[email protected]cbb22e42011-05-12 23:36:245144
[email protected]02965c22013-03-09 02:40:075145 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505146 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505147}
5148
[email protected]939e7362010-05-13 20:49:105149bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115150 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435151 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515152 LOCAL_SET_GL_ERROR(
5153 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435154 return false;
[email protected]939e7362010-05-13 20:49:105155 }
[email protected]e259eb412012-10-13 05:47:245156 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515157 LOCAL_SET_GL_ERROR(
5158 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105159 return false;
5160 }
5161 return true;
5162}
5163
5164bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5165 GLint location, const char* function_name) {
5166 if (!CheckCurrentProgram(function_name)) {
5167 return false;
5168 }
5169 return location != -1;
5170}
5171
[email protected]476ccb72012-12-06 15:52:525172namespace {
5173
5174static const GLenum valid_int_vec1_types_list[] = {
5175 GL_INT,
5176 GL_BOOL,
5177 GL_SAMPLER_2D,
5178 GL_SAMPLER_2D_RECT_ARB,
5179 GL_SAMPLER_CUBE,
5180 GL_SAMPLER_EXTERNAL_OES,
5181};
5182
5183static const GLenum valid_int_vec2_types_list[] = {
5184 GL_INT_VEC2,
5185 GL_BOOL_VEC2,
5186};
5187
5188static const GLenum valid_int_vec3_types_list[] = {
5189 GL_INT_VEC3,
5190 GL_BOOL_VEC3,
5191};
5192
5193static const GLenum valid_int_vec4_types_list[] = {
5194 GL_INT_VEC4,
5195 GL_BOOL_VEC4,
5196};
5197
5198static const GLenum valid_float_vec1_types_list[] = {
5199 GL_FLOAT,
5200 GL_BOOL,
5201};
5202
5203static const GLenum valid_float_vec2_types_list[] = {
5204 GL_FLOAT_VEC2,
5205 GL_BOOL_VEC2,
5206};
5207
5208static const GLenum valid_float_vec3_types_list[] = {
5209 GL_FLOAT_VEC3,
5210 GL_BOOL_VEC3,
5211};
5212
5213static const GLenum valid_float_vec4_types_list[] = {
5214 GL_FLOAT_VEC4,
5215 GL_BOOL_VEC4,
5216};
5217
5218static const GLenum valid_float_mat2_types_list[] = {
5219 GL_FLOAT_MAT2,
5220};
5221
5222static const GLenum valid_float_mat3_types_list[] = {
5223 GL_FLOAT_MAT3,
5224};
5225
5226static const GLenum valid_float_mat4_types_list[] = {
5227 GL_FLOAT_MAT4,
5228};
5229
5230static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5231 valid_int_vec1_types_list,
5232 arraysize(valid_int_vec1_types_list),
5233};
5234
5235static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5236 valid_int_vec2_types_list,
5237 arraysize(valid_int_vec2_types_list),
5238};
5239
5240static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5241 valid_int_vec3_types_list,
5242 arraysize(valid_int_vec3_types_list),
5243};
5244
5245static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5246 valid_int_vec4_types_list,
5247 arraysize(valid_int_vec4_types_list),
5248};
5249
5250static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5251 valid_float_vec1_types_list,
5252 arraysize(valid_float_vec1_types_list),
5253};
5254
5255static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5256 valid_float_vec2_types_list,
5257 arraysize(valid_float_vec2_types_list),
5258};
5259
5260static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5261 valid_float_vec3_types_list,
5262 arraysize(valid_float_vec3_types_list),
5263};
5264
5265static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5266 valid_float_vec4_types_list,
5267 arraysize(valid_float_vec4_types_list),
5268};
5269
5270static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5271 valid_float_mat2_types_list,
5272 arraysize(valid_float_mat2_types_list),
5273};
5274
5275static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5276 valid_float_mat3_types_list,
5277 arraysize(valid_float_mat3_types_list),
5278};
5279
5280static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5281 valid_float_mat4_types_list,
5282 arraysize(valid_float_mat4_types_list),
5283};
5284
5285} // anonymous namespace.
5286
[email protected]43c2f1f2011-03-25 18:35:365287bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125288 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525289 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125290 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365291 DCHECK(type);
5292 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125293 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525294
[email protected]1b0a6752012-02-22 03:44:125295 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105296 return false;
5297 }
[email protected]43c2f1f2011-03-25 18:35:365298 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355299 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245300 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125301 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365302 if (!info) {
[email protected]ab09b612013-03-11 22:11:515303 LOCAL_SET_GL_ERROR(
5304 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105305 return false;
5306 }
[email protected]476ccb72012-12-06 15:52:525307 bool okay = false;
5308 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5309 if (base_info.valid_types[ii] == info->type) {
5310 okay = true;
5311 break;
5312 }
5313 }
5314 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515315 LOCAL_SET_GL_ERROR(
5316 GL_INVALID_OPERATION, function_name,
5317 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525318 return false;
5319 }
[email protected]43c2f1f2011-03-25 18:35:365320 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515321 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435322 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365323 return false;
5324 }
5325 *count = std::min(info->size - array_index, *count);
5326 if (*count <= 0) {
5327 return false;
5328 }
5329 *type = info->type;
[email protected]939e7362010-05-13 20:49:105330 return true;
5331}
5332
[email protected]1b0a6752012-02-22 03:44:125333void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5334 GLenum type = 0;
5335 GLsizei count = 1;
5336 GLint real_location = -1;
5337 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525338 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5339 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505340 return;
5341 }
[email protected]e259eb412012-10-13 05:47:245342 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025343 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515344 LOCAL_SET_GL_ERROR(
5345 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465346 return;
5347 }
[email protected]1b0a6752012-02-22 03:44:125348 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505349}
5350
5351void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125352 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365353 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125354 GLint real_location = -1;
5355 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525356 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5357 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365358 return;
5359 }
[email protected]74727112012-06-13 21:18:085360 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5361 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245362 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025363 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515364 LOCAL_SET_GL_ERROR(
5365 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465366 return;
5367 }
[email protected]43c2f1f2011-03-25 18:35:365368 }
[email protected]1b0a6752012-02-22 03:44:125369 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505370}
5371
[email protected]939e7362010-05-13 20:49:105372void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125373 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365374 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125375 GLint real_location = -1;
5376 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525377 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5378 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105379 return;
5380 }
5381 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555382 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105383 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535384 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105385 }
[email protected]1b0a6752012-02-22 03:44:125386 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105387 } else {
[email protected]1b0a6752012-02-22 03:44:125388 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105389 }
5390}
5391
5392void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125393 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365394 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125395 GLint real_location = -1;
5396 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525397 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5398 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105399 return;
5400 }
5401 if (type == GL_BOOL_VEC2) {
5402 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555403 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105404 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535405 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105406 }
[email protected]1b0a6752012-02-22 03:44:125407 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105408 } else {
[email protected]1b0a6752012-02-22 03:44:125409 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105410 }
5411}
5412
5413void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125414 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365415 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125416 GLint real_location = -1;
5417 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525418 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5419 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105420 return;
5421 }
5422 if (type == GL_BOOL_VEC3) {
5423 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555424 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105425 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535426 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105427 }
[email protected]1b0a6752012-02-22 03:44:125428 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105429 } else {
[email protected]1b0a6752012-02-22 03:44:125430 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105431 }
5432}
5433
5434void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125435 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365436 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125437 GLint real_location = -1;
5438 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525439 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5440 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105441 return;
5442 }
5443 if (type == GL_BOOL_VEC4) {
5444 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555445 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105446 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535447 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105448 }
[email protected]1b0a6752012-02-22 03:44:125449 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105450 } else {
[email protected]1b0a6752012-02-22 03:44:125451 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105452 }
5453}
5454
[email protected]43c2f1f2011-03-25 18:35:365455void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125456 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365457 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125458 GLint real_location = -1;
5459 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525460 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5461 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365462 return;
5463 }
[email protected]1b0a6752012-02-22 03:44:125464 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365465}
5466
5467void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125468 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365469 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125470 GLint real_location = -1;
5471 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525472 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5473 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365474 return;
5475 }
[email protected]1b0a6752012-02-22 03:44:125476 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365477}
5478
5479void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125480 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365481 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125482 GLint real_location = -1;
5483 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525484 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5485 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365486 return;
5487 }
[email protected]1b0a6752012-02-22 03:44:125488 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365489}
5490
5491void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125492 GLint fake_location, GLsizei count, GLboolean transpose,
5493 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365494 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125495 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365496 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525497 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5498 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365499 return;
5500 }
[email protected]1b0a6752012-02-22 03:44:125501 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365502}
5503
5504void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125505 GLint fake_location, GLsizei count, GLboolean transpose,
5506 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365507 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125508 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365509 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525510 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5511 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365512 return;
5513 }
[email protected]1b0a6752012-02-22 03:44:125514 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365515}
5516
5517void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125518 GLint fake_location, GLsizei count, GLboolean transpose,
5519 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365520 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125521 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365522 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525523 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5524 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365525 return;
5526 }
[email protected]1b0a6752012-02-22 03:44:125527 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365528}
5529
[email protected]df37b9932013-03-08 05:21:425530void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035531 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425532 Program* program = NULL;
5533 if (program_id) {
5534 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5535 if (!program) {
[email protected]ae51d192010-04-27 00:48:035536 return;
5537 }
[email protected]df37b9932013-03-08 05:21:425538 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505539 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515540 LOCAL_SET_GL_ERROR(
5541 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505542 return;
5543 }
[email protected]df37b9932013-03-08 05:21:425544 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505545 }
[email protected]7cd76fd2013-06-02 21:11:115546 if (state_.current_program.get()) {
5547 program_manager()->UnuseProgram(shader_manager(),
5548 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145549 }
[email protected]df37b9932013-03-08 05:21:425550 state_.current_program = program;
5551 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545552 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:115553 if (state_.current_program.get()) {
5554 program_manager()->UseProgram(state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145555 }
[email protected]3916c97e2010-02-25 03:20:505556}
5557
[email protected]ab09b612013-03-11 22:11:515558void GLES2DecoderImpl::RenderWarning(
5559 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325560 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015561}
5562
[email protected]ab09b612013-03-11 22:11:515563void GLES2DecoderImpl::PerformanceWarning(
5564 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505565 logger_.LogMessage(filename, line,
5566 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015567}
5568
[email protected]df37b9932013-03-08 05:21:425569void GLES2DecoderImpl::ForceCompileShaderIfPending(Shader* shader) {
5570 if (shader->compilation_status() ==
[email protected]ed9f9cd2013-02-27 21:12:355571 Shader::PENDING_DEFERRED_COMPILE) {
[email protected]c447acd2012-07-23 23:48:415572 ShaderTranslator* translator = NULL;
5573 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:425574 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]c447acd2012-07-23 23:48:415575 vertex_translator_.get() : fragment_translator_.get();
5576 }
5577 // We know there will be no errors, because we only defer compilation on
5578 // shaders that were previously compiled successfully.
[email protected]df37b9932013-03-08 05:21:425579 program_manager()->ForceCompileShader(shader->deferred_compilation_source(),
5580 shader,
[email protected]c447acd2012-07-23 23:48:415581 translator,
[email protected]7cd76fd2013-06-02 21:11:115582 feature_info_.get());
[email protected]c447acd2012-07-23 23:48:415583 }
5584}
5585
[email protected]ef526492010-06-02 23:12:255586bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
[email protected]7cd76fd2013-06-02 21:11:115587 DCHECK(state_.current_program.get());
[email protected]ef526492010-06-02 23:12:255588 // Only check if there are some unrenderable textures.
5589 if (!texture_manager()->HaveUnrenderableTextures()) {
5590 return false;
5591 }
[email protected]e2367b42013-05-31 03:37:215592
[email protected]ef526492010-06-02 23:12:255593 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:355594 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245595 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505596 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355597 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245598 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505599 DCHECK(uniform_info);
5600 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5601 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025602 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245603 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495604 TextureRef* texture =
[email protected]cadac622013-06-11 16:46:365605 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]02965c22013-03-09 02:40:075606 if (!texture || !texture_manager()->CanRender(texture)) {
[email protected]ef526492010-06-02 23:12:255607 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505608 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5609 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315610 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495611 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:515612 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:015613 std::string("texture bound to texture unit ") +
5614 base::IntToString(texture_unit_index) +
5615 " is not renderable. It maybe non-power-of-2 and have "
5616 " incompatible texture filtering or is not "
5617 "'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505618 }
5619 }
5620 // else: should this be an error?
5621 }
5622 }
[email protected]ef526492010-06-02 23:12:255623 return textures_set;
[email protected]3916c97e2010-02-25 03:20:505624}
5625
5626void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]7cd76fd2013-06-02 21:11:115627 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:355628 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:115629 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505630 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355631 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245632 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505633 DCHECK(uniform_info);
5634 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5635 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025636 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245637 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:115638 TextureRef* texture_ref =
5639 uniform_info->type == GL_SAMPLER_2D
5640 ? texture_unit.bound_texture_2d.get()
5641 : texture_unit.bound_texture_cube_map.get();
[email protected]370eaf12013-05-18 09:19:495642 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:505643 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:495644 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:115645 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
5646 ? texture_unit.bound_texture_2d.get()
5647 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:505648 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:495649 texture_ref ? texture_ref->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505650 }
5651 }
5652 }
5653 }
5654 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245655 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305656}
5657
[email protected]0d6bfdc2011-11-02 01:32:205658bool GLES2DecoderImpl::ClearUnclearedTextures() {
5659 // Only check if there are some uncleared textures.
5660 if (!texture_manager()->HaveUnsafeTextures()) {
5661 return true;
5662 }
5663
5664 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:115665 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:355666 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:115667 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205668 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355669 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245670 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205671 DCHECK(uniform_info);
5672 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5673 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025674 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245675 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495676 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:365677 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:495678 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
5679 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:205680 return false;
5681 }
5682 }
5683 }
5684 }
5685 }
5686 }
5687 return true;
5688}
5689
[email protected]c6aef902012-02-14 03:31:425690bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435691 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035692 // NOTE: We specifically do not check current_program->IsValid() because
5693 // it could never be invalid since glUseProgram would have failed. While
5694 // glLinkProgram could later mark the program as invalid the previous
5695 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:115696 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:505697 // The program does not exist.
5698 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:515699 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505700 return false;
5701 }
[email protected]c6aef902012-02-14 03:31:425702
[email protected]7cd76fd2013-06-02 21:11:115703 return state_.vertex_attrib_manager
5704 ->ValidateBindings(function_name,
5705 this,
5706 feature_info_.get(),
5707 state_.current_program.get(),
5708 max_vertex_accessed,
5709 primcount);
[email protected]b1122982010-05-17 23:04:245710}
5711
[email protected]c13e1da62011-09-09 21:48:305712bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435713 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305714 DCHECK(simulated);
5715 *simulated = false;
5716
[email protected]876f6fee2010-08-02 23:10:325717 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305718 return true;
[email protected]876f6fee2010-08-02 23:10:325719
[email protected]ac77603c72013-03-08 13:52:065720 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:355721 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:245722 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245723 bool attrib_0_used =
5724 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:065725 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305726 return true;
[email protected]b1122982010-05-17 23:04:245727 }
5728
[email protected]b1122982010-05-17 23:04:245729 // Make a buffer with a single repeated vec4 value enough to
5730 // simulate the constant value that is supposed to be here.
5731 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305732 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475733 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305734
5735 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475736 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305737 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515738 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305739 return false;
5740 }
5741
[email protected]ab09b612013-03-11 22:11:515742 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015743 "Attribute 0 is disabled. This has signficant performance penalty");
5744
[email protected]ab09b612013-03-11 22:11:515745 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:305746 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5747
[email protected]8f0b86c2f2012-04-10 05:48:285748 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5749 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495750 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305751 GLenum error = glGetError();
5752 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515753 LOCAL_SET_GL_ERROR(
5754 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305755 return false;
5756 }
[email protected]fc753442011-02-04 19:49:495757 }
[email protected]af6380962012-11-29 23:24:135758
5759 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:285760 if (new_buffer ||
5761 (attrib_0_used &&
5762 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:135763 (value.v[0] != attrib_0_value_.v[0] ||
5764 value.v[1] != attrib_0_value_.v[1] ||
5765 value.v[2] != attrib_0_value_.v[2] ||
5766 value.v[3] != attrib_0_value_.v[3])))) {
5767 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:495768 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
5769 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:135770 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:245771 attrib_0_size_ = size_needed;
5772 }
5773
5774 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
5775
[email protected]ac77603c72013-03-08 13:52:065776 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:425777 glVertexAttribDivisorANGLE(0, 0);
5778
[email protected]c13e1da62011-09-09 21:48:305779 *simulated = true;
[email protected]b1122982010-05-17 23:04:245780 return true;
[email protected]b1122982010-05-17 23:04:245781}
5782
[email protected]ac77603c72013-03-08 13:52:065783void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
5784 const VertexAttrib* attrib =
5785 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
5786 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
5787 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:075788 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:245789 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065790 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
5791 attrib->gl_stride(), ptr);
5792 if (attrib->divisor())
5793 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:245794 glBindBuffer(
5795 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:115796 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
5797 : 0);
[email protected]43410e92012-04-20 17:06:285798
[email protected]265f8992012-07-20 01:03:145799 // Never touch vertex attribute 0's state (in particular, never
5800 // disable it) when running on desktop GL because it will never be
5801 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:065802 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:145803 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:065804 if (attrib->enabled()) {
5805 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145806 } else {
[email protected]ac77603c72013-03-08 13:52:065807 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145808 }
[email protected]43410e92012-04-20 17:06:285809 }
[email protected]b1122982010-05-17 23:04:245810}
[email protected]07f54fcc2009-12-22 02:46:305811
[email protected]8fbedc02010-11-18 18:43:405812bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:435813 const char* function_name,
[email protected]c6aef902012-02-14 03:31:425814 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:405815 DCHECK(simulated);
5816 *simulated = false;
5817 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
5818 return true;
5819
[email protected]e259eb412012-10-13 05:47:245820 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:405821 return true;
5822 }
5823
[email protected]ab09b612013-03-11 22:11:515824 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015825 "GL_FIXED attributes have a signficant performance penalty");
5826
[email protected]8fbedc02010-11-18 18:43:405827 // NOTE: we could be smart and try to check if a buffer is used
5828 // twice in 2 different attribs, find the overlapping parts and therefore
5829 // duplicate the minimum amount of data but this whole code path is not meant
5830 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
5831 // tests so we just add to the buffer attrib used.
5832
[email protected]c13e1da62011-09-09 21:48:305833 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:065834 const VertexAttribManager::VertexAttribList& enabled_attribs =
5835 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
5836 for (VertexAttribManager::VertexAttribList::const_iterator it =
5837 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5838 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355839 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065840 state_.current_program->GetAttribInfoByLocation(attrib->index());
5841 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
5842 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:425843 GLuint num_vertices = max_accessed + 1;
5844 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515845 LOCAL_SET_GL_ERROR(
5846 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425847 return false;
5848 }
[email protected]8fbedc02010-11-18 18:43:405849 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065850 attrib->CanAccess(max_accessed) &&
5851 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:475852 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:065853 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:475854 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:515855 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435856 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405857 return false;
5858 }
5859 }
5860 }
5861
[email protected]3aad1a32012-09-07 20:54:475862 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
5863 uint32 size_needed = 0;
5864 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305865 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515866 LOCAL_SET_GL_ERROR(
5867 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405868 return false;
5869 }
5870
[email protected]ab09b612013-03-11 22:11:515871 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:405872
5873 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:305874 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:405875 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305876 GLenum error = glGetError();
5877 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515878 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435879 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:305880 return false;
5881 }
[email protected]8fbedc02010-11-18 18:43:405882 }
5883
5884 // Copy the elements and convert to float
5885 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:065886 for (VertexAttribManager::VertexAttribList::const_iterator it =
5887 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5888 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355889 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065890 state_.current_program->GetAttribInfoByLocation(attrib->index());
5891 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:425892 max_vertex_accessed);
5893 GLuint num_vertices = max_accessed + 1;
5894 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515895 LOCAL_SET_GL_ERROR(
5896 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425897 return false;
5898 }
[email protected]8fbedc02010-11-18 18:43:405899 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065900 attrib->CanAccess(max_accessed) &&
5901 attrib->type() == GL_FIXED) {
5902 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:405903 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:555904 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:405905 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:065906 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:405907 const int32* end = src + num_elements;
5908 float* dst = data.get();
5909 while (src != end) {
5910 *dst++ = static_cast<float>(*src++) / 65536.0f;
5911 }
5912 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
5913 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065914 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:405915 reinterpret_cast<GLvoid*>(offset));
5916 offset += size;
5917 }
5918 }
5919 *simulated = true;
5920 return true;
5921}
5922
5923void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
5924 // There's no need to call glVertexAttribPointer because we shadow all the
5925 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:245926 glBindBuffer(
5927 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:115928 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
5929 : 0);
[email protected]8fbedc02010-11-18 18:43:405930}
5931
[email protected]ad84a3a2012-06-08 21:42:435932error::Error GLES2DecoderImpl::DoDrawArrays(
5933 const char* function_name,
5934 bool instanced,
5935 GLenum mode,
5936 GLint first,
5937 GLsizei count,
5938 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:085939 if (ShouldDeferDraws())
5940 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:435941 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:515942 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:435943 return error::kNoError;
5944 }
5945 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:515946 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:435947 return error::kNoError;
5948 }
[email protected]c6aef902012-02-14 03:31:425949 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:515950 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:425951 return error::kNoError;
5952 }
[email protected]ad84a3a2012-06-08 21:42:435953 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:435954 return error::kNoError;
5955 }
5956 // We have to check this here because the prototype for glDrawArrays
5957 // is GLint not GLsizei.
5958 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:515959 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:435960 return error::kNoError;
5961 }
5962
[email protected]c6aef902012-02-14 03:31:425963 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:515964 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:435965 return error::kNoError;
5966 }
5967
5968 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:435969 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:205970 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:515971 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:205972 return error::kNoError;
5973 }
[email protected]c13e1da62011-09-09 21:48:305974 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:435975 if (!SimulateAttrib0(
5976 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:305977 return error::kNoError;
5978 }
[email protected]38d139d2011-07-14 00:38:435979 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:435980 if (SimulateFixedAttribs(
5981 function_name, max_vertex_accessed, &simulated_fixed_attribs,
5982 primcount)) {
[email protected]38d139d2011-07-14 00:38:435983 bool textures_set = SetBlackTextureForNonRenderableTextures();
5984 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:425985 if (!instanced) {
5986 glDrawArrays(mode, first, count);
5987 } else {
5988 glDrawArraysInstancedANGLE(mode, first, count, primcount);
5989 }
[email protected]22e3f552012-03-13 01:54:195990 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:435991 if (textures_set) {
5992 RestoreStateForNonRenderableTextures();
5993 }
5994 if (simulated_fixed_attribs) {
5995 RestoreStateForSimulatedFixedAttribs();
5996 }
5997 }
5998 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:285999 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436000 }
[email protected]38d139d2011-07-14 00:38:436001 }
6002 return error::kNoError;
6003}
6004
[email protected]c6aef902012-02-14 03:31:426005error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356006 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436007 return DoDrawArrays("glDrawArrays",
6008 false,
[email protected]c6aef902012-02-14 03:31:426009 static_cast<GLenum>(c.mode),
6010 static_cast<GLint>(c.first),
6011 static_cast<GLsizei>(c.count),
6012 0);
6013}
6014
6015error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356016 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156017 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516018 LOCAL_SET_GL_ERROR(
6019 GL_INVALID_OPERATION,
6020 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426021 return error::kNoError;
6022 }
[email protected]ad84a3a2012-06-08 21:42:436023 return DoDrawArrays("glDrawArraysIntancedANGLE",
6024 true,
[email protected]c6aef902012-02-14 03:31:426025 static_cast<GLenum>(c.mode),
6026 static_cast<GLint>(c.first),
6027 static_cast<GLsizei>(c.count),
6028 static_cast<GLsizei>(c.primcount));
6029}
6030
[email protected]ad84a3a2012-06-08 21:42:436031error::Error GLES2DecoderImpl::DoDrawElements(
6032 const char* function_name,
6033 bool instanced,
6034 GLenum mode,
6035 GLsizei count,
6036 GLenum type,
6037 int32 offset,
6038 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086039 if (ShouldDeferDraws())
6040 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:246041 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516042 LOCAL_SET_GL_ERROR(
6043 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296044 return error::kNoError;
6045 }
6046
[email protected]8eee29c2010-04-29 03:38:296047 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516048 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296049 return error::kNoError;
6050 }
6051 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516052 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296053 return error::kNoError;
6054 }
[email protected]9438b012010-06-15 22:55:056055 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516056 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296057 return error::kNoError;
6058 }
[email protected]9438b012010-06-15 22:55:056059 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516060 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296061 return error::kNoError;
6062 }
[email protected]c6aef902012-02-14 03:31:426063 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516064 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426065 return error::kNoError;
6066 }
[email protected]8eee29c2010-04-29 03:38:296067
[email protected]ad84a3a2012-06-08 21:42:436068 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276069 return error::kNoError;
6070 }
6071
[email protected]c6aef902012-02-14 03:31:426072 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316073 return error::kNoError;
6074 }
6075
[email protected]8eee29c2010-04-29 03:38:296076 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086077 Buffer* element_array_buffer =
6078 state_.vertex_attrib_manager->element_array_buffer();
6079
6080 if (!element_array_buffer->GetMaxValueForRange(
6081 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516082 LOCAL_SET_GL_ERROR(
6083 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296084 return error::kNoError;
6085 }
6086
[email protected]ad84a3a2012-06-08 21:42:436087 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206088 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516089 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206090 return error::kNoError;
6091 }
[email protected]c13e1da62011-09-09 21:48:306092 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436093 if (!SimulateAttrib0(
6094 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306095 return error::kNoError;
6096 }
[email protected]8fbedc02010-11-18 18:43:406097 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436098 if (SimulateFixedAttribs(
6099 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6100 primcount)) {
[email protected]8fbedc02010-11-18 18:43:406101 bool textures_set = SetBlackTextureForNonRenderableTextures();
[email protected]297ca1c2011-06-20 23:08:466102 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086103 // TODO(gman): Refactor to hide these details in BufferManager or
6104 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406105 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086106 bool used_client_side_array = false;
6107 if (element_array_buffer->IsClientSideArray()) {
6108 used_client_side_array = true;
6109 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6110 indices = element_array_buffer->GetRange(offset, 0);
6111 }
6112
[email protected]c6aef902012-02-14 03:31:426113 if (!instanced) {
6114 glDrawElements(mode, count, type, indices);
6115 } else {
6116 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6117 }
[email protected]17cfbe0e2013-03-07 01:26:086118
6119 if (used_client_side_array) {
6120 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6121 element_array_buffer->service_id());
6122 }
6123
[email protected]22e3f552012-03-13 01:54:196124 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406125 if (textures_set) {
6126 RestoreStateForNonRenderableTextures();
6127 }
6128 if (simulated_fixed_attribs) {
6129 RestoreStateForSimulatedFixedAttribs();
6130 }
[email protected]ba3176a2009-12-16 18:19:466131 }
[email protected]b1122982010-05-17 23:04:246132 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286133 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246134 }
[email protected]96449d2c2009-11-25 00:01:326135 }
[email protected]f7a64ee2010-02-01 22:24:146136 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326137}
6138
[email protected]c6aef902012-02-14 03:31:426139error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356140 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436141 return DoDrawElements("glDrawElements",
6142 false,
[email protected]c6aef902012-02-14 03:31:426143 static_cast<GLenum>(c.mode),
6144 static_cast<GLsizei>(c.count),
6145 static_cast<GLenum>(c.type),
6146 static_cast<int32>(c.index_offset),
6147 0);
6148}
6149
6150error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356151 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156152 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516153 LOCAL_SET_GL_ERROR(
6154 GL_INVALID_OPERATION,
6155 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426156 return error::kNoError;
6157 }
[email protected]ad84a3a2012-06-08 21:42:436158 return DoDrawElements("glDrawElementsInstancedANGLE",
6159 true,
[email protected]c6aef902012-02-14 03:31:426160 static_cast<GLenum>(c.mode),
6161 static_cast<GLsizei>(c.count),
6162 static_cast<GLenum>(c.type),
6163 static_cast<int32>(c.index_offset),
6164 static_cast<GLsizei>(c.primcount));
6165}
6166
[email protected]269200b12010-11-18 22:53:066167GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236168 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6169 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076170 Buffer* buffer = GetBuffer(buffer_id);
6171 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036172 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516173 LOCAL_SET_GL_ERROR(
6174 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236175 } else {
[email protected]b10492f2013-03-08 05:24:076176 if (!buffer->GetMaxValueForRange(
6177 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036178 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516179 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066180 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436181 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236182 }
6183 }
6184 return max_vertex_accessed;
6185}
6186
[email protected]96449d2c2009-11-25 00:01:326187// Calls glShaderSource for the various versions of the ShaderSource command.
6188// Assumes that data / data_size points to a piece of memory that is in range
6189// of whatever context it came from (shared memory, immediate memory, bucket
6190// memory.)
[email protected]45bf5152010-02-12 00:11:316191error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036192 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576193 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426194 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6195 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316196 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326197 }
[email protected]45bf5152010-02-12 00:11:316198 // Note: We don't actually call glShaderSource here. We wait until
6199 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426200 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146201 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326202}
6203
[email protected]f7a64ee2010-02-01 22:24:146204error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356205 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326206 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316207 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326208 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466209 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146210 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326211 }
[email protected]ae51d192010-04-27 00:48:036212 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326213}
6214
[email protected]f7a64ee2010-02-01 22:24:146215error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]ed9f9cd2013-02-27 21:12:356216 uint32 immediate_data_size, const cmds::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:326217 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316218 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:306219 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:466220 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146221 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326222 }
[email protected]ae51d192010-04-27 00:48:036223 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:316224}
6225
[email protected]558847a2010-03-24 07:02:546226error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356227 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546228 Bucket* bucket = GetBucket(c.data_bucket_id);
6229 if (!bucket || bucket->size() == 0) {
6230 return error::kInvalidArguments;
6231 }
6232 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036233 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546234 bucket->size() - 1);
6235}
6236
[email protected]ae51d192010-04-27 00:48:036237void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386238 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426239 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6240 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316241 return;
6242 }
[email protected]f57bb282010-11-12 00:51:346243 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186244 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426245 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456246 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416247 }
[email protected]de17df392010-04-23 21:09:416248
[email protected]7cd76fd2013-06-02 21:11:116249 program_manager()->DoCompileShader(shader, translator, feature_info_.get());
[email protected]45bf5152010-02-12 00:11:316250};
6251
[email protected]ddd968b82010-03-02 00:44:296252void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426253 GLuint shader_id, GLenum pname, GLint* params) {
6254 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6255 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296256 return;
6257 }
[email protected]8f1ccdac2010-05-19 21:01:486258 switch (pname) {
6259 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426260 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486261 return;
6262 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426263 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416264 return;
[email protected]8f1ccdac2010-05-19 21:01:486265 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426266 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416267 return;
[email protected]d6a53e42011-10-05 00:09:366268 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426269 ForceCompileShaderIfPending(shader);
6270 *params = shader->translated_source() ?
6271 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366272 return;
[email protected]8f1ccdac2010-05-19 21:01:486273 default:
6274 break;
[email protected]ddd968b82010-03-02 00:44:296275 }
[email protected]df37b9932013-03-08 05:21:426276 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296277}
6278
[email protected]ae51d192010-04-27 00:48:036279error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356280 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426281 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036282 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6283 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426284 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6285 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296286 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296287 return error::kNoError;
6288 }
[email protected]df37b9932013-03-08 05:21:426289 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036290 return error::kNoError;
6291}
6292
[email protected]d6a53e42011-10-05 00:09:366293error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6294 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356295 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426296 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366297 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6298 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426299 Shader* shader = GetShaderInfoNotProgram(
6300 shader_id, "glTranslatedGetShaderSourceANGLE");
6301 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366302 bucket->SetSize(0);
6303 return error::kNoError;
6304 }
[email protected]df37b9932013-03-08 05:21:426305 ForceCompileShaderIfPending(shader);
[email protected]d6a53e42011-10-05 00:09:366306
[email protected]df37b9932013-03-08 05:21:426307 bucket->SetFromString(shader->translated_source() ?
6308 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366309 return error::kNoError;
6310}
6311
[email protected]ae51d192010-04-27 00:48:036312error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356313 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426314 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586315 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6316 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426317 Program* program = GetProgramInfoNotShader(
6318 program_id, "glGetProgramInfoLog");
6319 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466320 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036321 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316322 }
[email protected]df37b9932013-03-08 05:21:426323 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036324 return error::kNoError;
6325}
6326
6327error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356328 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426329 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586330 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6331 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426332 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6333 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466334 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036335 return error::kNoError;
6336 }
[email protected]df37b9932013-03-08 05:21:426337 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036338 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326339}
6340
[email protected]d058bca2012-11-26 10:27:266341bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6342 return state_.GetEnabled(cap);
6343}
6344
[email protected]1958e0e2010-04-22 05:17:156345bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216346 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106347 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156348}
6349
6350bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356351 const Framebuffer* framebuffer =
6352 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106353 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156354}
6355
6356bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366357 // IsProgram is true for programs as soon as they are created, until they are
6358 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356359 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106360 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156361}
6362
6363bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356364 const Renderbuffer* renderbuffer =
6365 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106366 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156367}
6368
6369bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366370 // IsShader is true for shaders as soon as they are created, until they
6371 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356372 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106373 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156374}
6375
6376bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496377 const TextureRef* texture_ref = GetTexture(client_id);
6378 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036379}
6380
6381void GLES2DecoderImpl::DoAttachShader(
6382 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426383 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586384 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426385 if (!program) {
[email protected]ae51d192010-04-27 00:48:036386 return;
[email protected]1958e0e2010-04-22 05:17:156387 }
[email protected]df37b9932013-03-08 05:21:426388 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6389 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036390 return;
6391 }
[email protected]df37b9932013-03-08 05:21:426392 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516393 LOCAL_SET_GL_ERROR(
6394 GL_INVALID_OPERATION,
6395 "glAttachShader",
6396 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316397 return;
6398 }
[email protected]df37b9932013-03-08 05:21:426399 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036400}
6401
6402void GLES2DecoderImpl::DoDetachShader(
6403 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426404 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586405 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426406 if (!program) {
[email protected]ae51d192010-04-27 00:48:036407 return;
6408 }
[email protected]df37b9932013-03-08 05:21:426409 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6410 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036411 return;
6412 }
[email protected]df37b9932013-03-08 05:21:426413 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516414 LOCAL_SET_GL_ERROR(
6415 GL_INVALID_OPERATION,
6416 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226417 return;
6418 }
[email protected]df37b9932013-03-08 05:21:426419 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036420}
6421
6422void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426423 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586424 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426425 if (!program) {
[email protected]ae51d192010-04-27 00:48:036426 return;
6427 }
[email protected]df37b9932013-03-08 05:21:426428 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156429}
6430
[email protected]ac77603c72013-03-08 13:52:066431void GLES2DecoderImpl::GetVertexAttribHelper(
6432 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246433 switch (pname) {
6434 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066435 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246436 if (buffer && !buffer->IsDeleted()) {
6437 GLuint client_id;
6438 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6439 *params = client_id;
6440 }
6441 break;
6442 }
6443 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066444 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246445 break;
6446 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066447 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246448 break;
6449 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066450 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246451 break;
6452 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066453 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246454 break;
6455 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066456 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246457 break;
[email protected]c6aef902012-02-14 03:31:426458 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066459 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426460 break;
[email protected]ac77603c72013-03-08 13:52:066461 default:
6462 NOTREACHED();
6463 break;
6464 }
6465}
6466
6467void GLES2DecoderImpl::DoGetVertexAttribfv(
6468 GLuint index, GLenum pname, GLfloat* params) {
6469 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6470 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516471 LOCAL_SET_GL_ERROR(
6472 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066473 return;
6474 }
6475 switch (pname) {
6476 case GL_CURRENT_VERTEX_ATTRIB: {
6477 const Vec4& value = state_.attrib_values[index];
6478 params[0] = value.v[0];
6479 params[1] = value.v[1];
6480 params[2] = value.v[2];
6481 params[3] = value.v[3];
6482 break;
6483 }
6484 default: {
6485 GLint value = 0;
6486 GetVertexAttribHelper(attrib, pname, &value);
6487 *params = static_cast<GLfloat>(value);
6488 break;
6489 }
6490 }
6491}
6492
6493void GLES2DecoderImpl::DoGetVertexAttribiv(
6494 GLuint index, GLenum pname, GLint* params) {
6495 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6496 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516497 LOCAL_SET_GL_ERROR(
6498 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066499 return;
6500 }
6501 switch (pname) {
[email protected]af6380962012-11-29 23:24:136502 case GL_CURRENT_VERTEX_ATTRIB: {
6503 const Vec4& value = state_.attrib_values[index];
6504 params[0] = static_cast<GLint>(value.v[0]);
6505 params[1] = static_cast<GLint>(value.v[1]);
6506 params[2] = static_cast<GLint>(value.v[2]);
6507 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246508 break;
[email protected]af6380962012-11-29 23:24:136509 }
[email protected]b1122982010-05-17 23:04:246510 default:
[email protected]ac77603c72013-03-08 13:52:066511 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246512 break;
6513 }
6514}
6515
[email protected]af6380962012-11-29 23:24:136516bool GLES2DecoderImpl::SetVertexAttribValue(
6517 const char* function_name, GLuint index, const GLfloat* value) {
6518 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516519 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136520 return false;
[email protected]b1122982010-05-17 23:04:246521 }
[email protected]af6380962012-11-29 23:24:136522 Vec4& v = state_.attrib_values[index];
6523 v.v[0] = value[0];
6524 v.v[1] = value[1];
6525 v.v[2] = value[2];
6526 v.v[3] = value[3];
6527 return true;
6528}
6529
6530void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6531 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6532 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6533 glVertexAttrib1f(index, v0);
6534 }
[email protected]b1122982010-05-17 23:04:246535}
6536
6537void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136538 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6539 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6540 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246541 }
[email protected]b1122982010-05-17 23:04:246542}
6543
6544void GLES2DecoderImpl::DoVertexAttrib3f(
6545 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136546 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6547 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6548 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246549 }
[email protected]b1122982010-05-17 23:04:246550}
6551
6552void GLES2DecoderImpl::DoVertexAttrib4f(
6553 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136554 GLfloat v[4] = { v0, v1, v2, v3, };
6555 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6556 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246557 }
[email protected]b1122982010-05-17 23:04:246558}
6559
6560void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136561 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6562 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6563 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246564 }
[email protected]b1122982010-05-17 23:04:246565}
6566
6567void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136568 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6569 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6570 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246571 }
[email protected]b1122982010-05-17 23:04:246572}
6573
6574void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136575 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6576 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6577 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246578 }
[email protected]b1122982010-05-17 23:04:246579}
6580
6581void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136582 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6583 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246584 }
[email protected]b1122982010-05-17 23:04:246585}
6586
[email protected]f7a64ee2010-02-01 22:24:146587error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:356588 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466589
[email protected]7cd76fd2013-06-02 21:11:116590 if (!state_.bound_array_buffer.get() ||
6591 state_.bound_array_buffer->IsDeleted()) {
6592 if (state_.vertex_attrib_manager.get() ==
6593 default_vertex_attrib_manager_.get()) {
[email protected]ab09b612013-03-11 22:11:516594 LOCAL_SET_GL_ERROR(
6595 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:466596 return error::kNoError;
6597 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:516598 LOCAL_SET_GL_ERROR(
6599 GL_INVALID_VALUE,
6600 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:466601 return error::kNoError;
6602 }
[email protected]96449d2c2009-11-25 00:01:326603 }
[email protected]8eee29c2010-04-29 03:38:296604
6605 GLuint indx = c.indx;
6606 GLint size = c.size;
6607 GLenum type = c.type;
6608 GLboolean normalized = c.normalized;
6609 GLsizei stride = c.stride;
6610 GLsizei offset = c.offset;
6611 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056612 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516613 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296614 return error::kNoError;
6615 }
[email protected]9438b012010-06-15 22:55:056616 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:516617 LOCAL_SET_GL_ERROR(
6618 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296619 return error::kNoError;
6620 }
6621 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516622 LOCAL_SET_GL_ERROR(
6623 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296624 return error::kNoError;
6625 }
6626 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:516627 LOCAL_SET_GL_ERROR(
6628 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296629 return error::kNoError;
6630 }
6631 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:516632 LOCAL_SET_GL_ERROR(
6633 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296634 return error::kNoError;
6635 }
6636 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516637 LOCAL_SET_GL_ERROR(
6638 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296639 return error::kNoError;
6640 }
6641 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316642 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296643 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516644 LOCAL_SET_GL_ERROR(
6645 GL_INVALID_OPERATION,
6646 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316647 return error::kNoError;
6648 }
6649 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516650 LOCAL_SET_GL_ERROR(
6651 GL_INVALID_OPERATION,
6652 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296653 return error::kNoError;
6654 }
[email protected]7cd76fd2013-06-02 21:11:116655 state_.vertex_attrib_manager
6656 ->SetAttribInfo(indx,
6657 state_.bound_array_buffer.get(),
6658 size,
6659 type,
6660 normalized,
6661 stride,
6662 stride != 0 ? stride : component_size * size,
6663 offset);
[email protected]8fbedc02010-11-18 18:43:406664 if (type != GL_FIXED) {
6665 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6666 }
[email protected]f7a64ee2010-02-01 22:24:146667 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326668}
6669
[email protected]43410e92012-04-20 17:06:286670void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6671 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246672 state_.viewport_x = x;
6673 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026674 state_.viewport_width = std::min(width, viewport_max_width_);
6675 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286676 glViewport(x, y, width, height);
6677}
6678
[email protected]c6aef902012-02-14 03:31:426679error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356680 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156681 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516682 LOCAL_SET_GL_ERROR(
6683 GL_INVALID_OPERATION,
6684 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426685 }
6686 GLuint index = c.index;
6687 GLuint divisor = c.divisor;
6688 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516689 LOCAL_SET_GL_ERROR(
6690 GL_INVALID_VALUE,
6691 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426692 return error::kNoError;
6693 }
6694
[email protected]e259eb412012-10-13 05:47:246695 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426696 index,
6697 divisor);
6698 glVertexAttribDivisorANGLE(index, divisor);
6699 return error::kNoError;
6700}
6701
[email protected]f7a64ee2010-02-01 22:24:146702error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:356703 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:446704 if (ShouldDeferReads())
6705 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:316706 GLint x = c.x;
6707 GLint y = c.y;
6708 GLsizei width = c.width;
6709 GLsizei height = c.height;
6710 GLenum format = c.format;
6711 GLenum type = c.type;
[email protected]57f223832010-03-19 01:57:566712 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:516713 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566714 return error::kNoError;
6715 }
[email protected]ed9f9cd2013-02-27 21:12:356716 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186717 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346718 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246719 width, height, format, type, state_.pack_alignment, &pixels_size,
6720 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186721 return error::kOutOfBounds;
6722 }
[email protected]612d2f82009-12-08 20:49:316723 void* pixels = GetSharedMemoryAs<void*>(
6724 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:106725 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:146726 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466727 }
[email protected]de43f082013-04-02 01:16:106728 Result* result = NULL;
6729 if (c.result_shm_id != 0) {
6730 result = GetSharedMemoryAs<Result*>(
6731 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6732 if (!result) {
6733 return error::kOutOfBounds;
6734 }
6735 }
[email protected]a51788e2010-02-24 21:54:256736
[email protected]9438b012010-06-15 22:55:056737 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:516738 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296739 return error::kNoError;
6740 }
[email protected]9438b012010-06-15 22:55:056741 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516742 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:126743 return error::kNoError;
6744 }
[email protected]57f223832010-03-19 01:57:566745 if (width == 0 || height == 0) {
6746 return error::kNoError;
6747 }
6748
[email protected]57f223832010-03-19 01:57:566749 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:306750 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:566751
[email protected]3aad1a32012-09-07 20:54:476752 int32 max_x;
6753 int32 max_y;
6754 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:516755 LOCAL_SET_GL_ERROR(
6756 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:146757 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:316758 }
[email protected]57f223832010-03-19 01:57:566759
[email protected]0d6bfdc2011-11-02 01:32:206760 if (!CheckBoundFramebuffersValid("glReadPixels")) {
6761 return error::kNoError;
6762 }
6763
[email protected]ab09b612013-03-11 22:11:516764 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel");
[email protected]a0b78dc2011-11-11 10:43:106765
6766 ScopedResolvedFrameBufferBinder binder(this, false, true);
6767
[email protected]d37231fa2010-04-09 21:16:026768 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:566769 // The user requested an out of range area. Get the results 1 line
6770 // at a time.
6771 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346772 uint32 unpadded_row_size;
6773 uint32 padded_row_size;
6774 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246775 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346776 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:516777 LOCAL_SET_GL_ERROR(
6778 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566779 return error::kNoError;
6780 }
6781
6782 GLint dest_x_offset = std::max(-x, 0);
6783 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:346784 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246785 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
6786 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:516787 LOCAL_SET_GL_ERROR(
6788 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566789 return error::kNoError;
6790 }
6791
6792 // Copy each row into the larger dest rect.
6793 int8* dst = static_cast<int8*>(pixels);
6794 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:026795 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:566796 GLint read_width = read_end_x - read_x;
6797 for (GLint yy = 0; yy < height; ++yy) {
6798 GLint ry = y + yy;
6799
6800 // Clear the row.
6801 memset(dst, 0, unpadded_row_size);
6802
6803 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:026804 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:566805 glReadPixels(
6806 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6807 }
6808 dst += padded_row_size;
6809 }
6810 } else {
6811 glReadPixels(x, y, width, height, format, type, pixels);
6812 }
[email protected]ab09b612013-03-11 22:11:516813 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:256814 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:106815 if (result != NULL) {
6816 *result = true;
6817 }
[email protected]4848b9f82011-03-10 18:37:566818
6819 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6820 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
[email protected]84eb4252012-06-29 22:56:446821 if ((channels_exist & 0x0008) == 0 &&
[email protected]62e155e2012-10-23 22:43:156822 workarounds().clear_alpha_in_readpixels) {
[email protected]4848b9f82011-03-10 18:37:566823 // Set the alpha to 255 because some drivers are buggy in this regard.
6824 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346825
6826 uint32 unpadded_row_size;
6827 uint32 padded_row_size;
6828 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246829 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346830 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:516831 LOCAL_SET_GL_ERROR(
6832 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]4848b9f82011-03-10 18:37:566833 return error::kNoError;
6834 }
6835 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6836 // of this implementation.
6837 if (type != GL_UNSIGNED_BYTE) {
[email protected]ab09b612013-03-11 22:11:516838 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436839 GL_INVALID_OPERATION, "glReadPixels",
6840 "unsupported readPixel format");
[email protected]4848b9f82011-03-10 18:37:566841 return error::kNoError;
6842 }
6843 switch (format) {
6844 case GL_RGBA:
[email protected]297ca1c2011-06-20 23:08:466845 case GL_BGRA_EXT:
[email protected]4848b9f82011-03-10 18:37:566846 case GL_ALPHA: {
6847 int offset = (format == GL_ALPHA) ? 0 : 3;
6848 int step = (format == GL_ALPHA) ? 1 : 4;
6849 uint8* dst = static_cast<uint8*>(pixels) + offset;
6850 for (GLint yy = 0; yy < height; ++yy) {
6851 uint8* end = dst + unpadded_row_size;
6852 for (uint8* d = dst; d < end; d += step) {
6853 *d = 255;
6854 }
6855 dst += padded_row_size;
6856 }
6857 break;
6858 }
6859 default:
6860 break;
6861 }
6862 }
[email protected]a51788e2010-02-24 21:54:256863 }
[email protected]4848b9f82011-03-10 18:37:566864
[email protected]f7a64ee2010-02-01 22:24:146865 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326866}
6867
[email protected]f7a64ee2010-02-01 22:24:146868error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:356869 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:196870 GLenum pname = c.pname;
6871 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:056872 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:516873 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:126874 return error::kNoError;
6875 }
[email protected]222471d2011-11-30 18:06:396876 switch (pname) {
6877 case GL_PACK_ALIGNMENT:
6878 case GL_UNPACK_ALIGNMENT:
6879 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:516880 LOCAL_SET_GL_ERROR(
6881 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:396882 return error::kNoError;
6883 }
[email protected]164d6d52012-05-05 00:55:036884 break;
[email protected]0a1e9ad2012-05-04 21:13:036885 case GL_UNPACK_FLIP_Y_CHROMIUM:
6886 unpack_flip_y_ = (param != 0);
6887 return error::kNoError;
6888 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
6889 unpack_premultiply_alpha_ = (param != 0);
6890 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:176891 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
6892 unpack_unpremultiply_alpha_ = (param != 0);
6893 return error::kNoError;
[email protected]222471d2011-11-30 18:06:396894 default:
6895 break;
[email protected]b9849abf2009-11-25 19:13:196896 }
6897 glPixelStorei(pname, param);
6898 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:436899 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246900 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436901 break;
6902 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:426903 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:436904 break;
6905 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246906 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436907 break;
6908 default:
6909 // Validation should have prevented us from getting here.
6910 NOTREACHED();
6911 break;
[email protected]b9849abf2009-11-25 19:13:196912 }
[email protected]f7a64ee2010-02-01 22:24:146913 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196914}
6915
[email protected]1c75a3702011-11-11 14:15:286916error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:356917 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:386918 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:456919 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:516920 LOCAL_SET_GL_ERROR(
6921 GL_INVALID_OPERATION,
6922 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:286923 return error::kNoError;
6924 }
[email protected]7794d512012-04-17 20:36:496925 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:286926 return error::kNoError;
[email protected]7794d512012-04-17 20:36:496927 } else {
6928 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:286929 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:496930 }
[email protected]1c75a3702011-11-11 14:15:286931}
6932
[email protected]558847a2010-03-24 07:02:546933error::Error GLES2DecoderImpl::GetAttribLocationHelper(
6934 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6935 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576936 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:516937 LOCAL_SET_GL_ERROR(
6938 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576939 return error::kNoError;
6940 }
[email protected]df37b9932013-03-08 05:21:426941 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586942 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:426943 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:146944 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196945 }
[email protected]df37b9932013-03-08 05:21:426946 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:516947 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436948 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256949 return error::kNoError;
6950 }
[email protected]b9849abf2009-11-25 19:13:196951 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:546952 location_shm_id, location_shm_offset, sizeof(GLint));
6953 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:146954 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196955 }
[email protected]558847a2010-03-24 07:02:546956 // Require the client to init this incase the context is lost and we are no
6957 // longer executing commands.
6958 if (*location != -1) {
6959 return error::kGenericError;
6960 }
[email protected]df37b9932013-03-08 05:21:426961 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:146962 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196963}
6964
[email protected]558847a2010-03-24 07:02:546965error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:356966 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:546967 uint32 name_size = c.data_size;
6968 const char* name = GetSharedMemoryAs<const char*>(
6969 c.name_shm_id, c.name_shm_offset, name_size);
6970 if (!name) {
6971 return error::kOutOfBounds;
6972 }
6973 String name_str(name, name_size);
6974 return GetAttribLocationHelper(
6975 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6976}
6977
[email protected]f7a64ee2010-02-01 22:24:146978error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:356979 uint32 immediate_data_size, const cmds::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:546980 uint32 name_size = c.data_size;
6981 const char* name = GetImmediateDataAs<const char*>(
6982 c, name_size, immediate_data_size);
6983 if (!name) {
6984 return error::kOutOfBounds;
6985 }
6986 String name_str(name, name_size);
6987 return GetAttribLocationHelper(
6988 c.program, c.location_shm_id, c.location_shm_offset, name_str);
6989}
6990
6991error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:356992 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:546993 Bucket* bucket = GetBucket(c.name_bucket_id);
6994 if (!bucket) {
6995 return error::kInvalidArguments;
6996 }
6997 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:186998 if (!bucket->GetAsString(&name_str)) {
6999 return error::kInvalidArguments;
7000 }
[email protected]558847a2010-03-24 07:02:547001 return GetAttribLocationHelper(
7002 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7003}
7004
7005error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7006 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7007 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577008 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517009 LOCAL_SET_GL_ERROR(
7010 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577011 return error::kNoError;
7012 }
[email protected]df37b9932013-03-08 05:21:427013 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587014 client_id, "glUniformLocation");
[email protected]df37b9932013-03-08 05:21:427015 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147016 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197017 }
[email protected]df37b9932013-03-08 05:21:427018 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517019 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437020 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257021 return error::kNoError;
7022 }
[email protected]b9849abf2009-11-25 19:13:197023 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547024 location_shm_id, location_shm_offset, sizeof(GLint));
7025 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147026 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197027 }
[email protected]558847a2010-03-24 07:02:547028 // Require the client to init this incase the context is lost an we are no
7029 // longer executing commands.
7030 if (*location != -1) {
7031 return error::kGenericError;
7032 }
[email protected]df37b9932013-03-08 05:21:427033 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147034 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197035}
7036
[email protected]f7a64ee2010-02-01 22:24:147037error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357038 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197039 uint32 name_size = c.data_size;
7040 const char* name = GetSharedMemoryAs<const char*>(
7041 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547042 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147043 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197044 }
7045 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547046 return GetUniformLocationHelper(
7047 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197048}
7049
[email protected]f7a64ee2010-02-01 22:24:147050error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357051 uint32 immediate_data_size, const cmds::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197052 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:307053 const char* name = GetImmediateDataAs<const char*>(
7054 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:547055 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147056 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197057 }
7058 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547059 return GetUniformLocationHelper(
7060 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7061}
7062
7063error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357064 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547065 Bucket* bucket = GetBucket(c.name_bucket_id);
7066 if (!bucket) {
7067 return error::kInvalidArguments;
7068 }
7069 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187070 if (!bucket->GetAsString(&name_str)) {
7071 return error::kInvalidArguments;
7072 }
[email protected]558847a2010-03-24 07:02:547073 return GetUniformLocationHelper(
7074 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197075}
7076
[email protected]ddd968b82010-03-02 00:44:297077error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357078 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297079 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057080 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517081 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297082 return error::kNoError;
7083 }
[email protected]1958e0e2010-04-22 05:17:157084 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
7085 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:047086 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157087 switch (name) {
7088 case GL_VERSION:
7089 str = "OpenGL ES 2.0 Chromium";
7090 break;
7091 case GL_SHADING_LANGUAGE_VERSION:
7092 str = "OpenGL ES GLSL ES 1.0 Chromium";
7093 break;
[email protected]32939602012-05-09 06:25:167094 case GL_RENDERER:
7095 str = "Chromium";
7096 break;
7097 case GL_VENDOR:
7098 str = "Chromium";
7099 break;
[email protected]1958e0e2010-04-22 05:17:157100 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047101 {
[email protected]70dc60932013-06-04 03:33:497102 // For WebGL contexts, strip out the OES derivatives and
7103 // EXT frag depth extensions if they have not been enabled.
7104 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047105 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497106 if (!derivatives_explicitly_enabled_) {
7107 size_t offset = extensions.find(kOESDerivativeExtension);
7108 if (std::string::npos != offset) {
7109 extensions.replace(offset,
7110 offset + arraysize(kOESDerivativeExtension),
7111 std::string());
7112 }
7113 }
7114 if (!frag_depth_explicitly_enabled_) {
7115 size_t offset = extensions.find(kEXTFragDepthExtension);
7116 if (std::string::npos != offset) {
7117 extensions.replace(offset,
7118 offset + arraysize(kEXTFragDepthExtension),
7119 std::string());
7120 }
[email protected]f0d74742011-10-03 16:31:047121 }
[email protected]aff39ac82013-06-08 04:53:137122 if (!draw_buffers_explicitly_enabled_) {
7123 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7124 if (std::string::npos != offset) {
7125 extensions.replace(offset,
7126 offset + arraysize(kEXTDrawBuffersExtension),
7127 std::string());
7128 }
7129 }
[email protected]f0d74742011-10-03 16:31:047130 } else {
[email protected]6f5fac9d12012-06-26 21:02:457131 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047132 }
[email protected]6f5fac9d12012-06-26 21:02:457133 std::string surface_extensions = surface_->GetExtensions();
7134 if (!surface_extensions.empty())
7135 extensions += " " + surface_extensions;
7136 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047137 }
[email protected]1958e0e2010-04-22 05:17:157138 break;
7139 default:
7140 str = gl_str;
7141 break;
7142 }
[email protected]ddd968b82010-03-02 00:44:297143 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157144 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297145 return error::kNoError;
7146}
7147
[email protected]0c86dbf2010-03-05 08:14:117148void GLES2DecoderImpl::DoBufferData(
[email protected]b9363b22010-06-09 22:06:157149 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
[email protected]9438b012010-06-15 22:55:057150 if (!validators_->buffer_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517151 LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferData", target, "target");
[email protected]8eee29c2010-04-29 03:38:297152 return;
7153 }
[email protected]9438b012010-06-15 22:55:057154 if (!validators_->buffer_usage.IsValid(usage)) {
[email protected]ab09b612013-03-11 22:11:517155 LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferData", usage, "usage");
[email protected]0c86dbf2010-03-05 08:14:117156 return;
[email protected]3b6ec202010-03-05 05:16:237157 }
7158 if (size < 0) {
[email protected]ab09b612013-03-11 22:11:517159 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferData", "size < 0");
[email protected]037896bd2010-04-21 19:07:287160 return;
[email protected]3b6ec202010-03-05 05:16:237161 }
[email protected]17cfbe0e2013-03-07 01:26:087162 Buffer* buffer = GetBufferInfoForTarget(target);
7163 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:517164 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287165 return;
[email protected]3b6ec202010-03-05 05:16:237166 }
[email protected]7989c9e2013-01-23 06:39:267167
7168 if (!EnsureGPUMemoryAvailable(size)) {
[email protected]ab09b612013-03-11 22:11:517169 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glBufferData", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267170 return;
7171 }
7172
[email protected]d3eba342013-04-18 21:11:507173 buffer_manager()->DoBufferData(GetErrorState(), buffer, size, usage, data);
[email protected]0c86dbf2010-03-05 08:14:117174}
7175
7176error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357177 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117178 GLenum target = static_cast<GLenum>(c.target);
7179 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7180 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7181 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7182 GLenum usage = static_cast<GLenum>(c.usage);
7183 const void* data = NULL;
7184 if (data_shm_id != 0 || data_shm_offset != 0) {
7185 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7186 if (!data) {
7187 return error::kOutOfBounds;
7188 }
7189 }
7190 DoBufferData(target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147191 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197192}
7193
[email protected]f7a64ee2010-02-01 22:24:147194error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357195 uint32 immediate_data_size, const cmds::BufferDataImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197196 GLenum target = static_cast<GLenum>(c.target);
7197 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:307198 const void* data = GetImmediateDataAs<const void*>(
7199 c, size, immediate_data_size);
7200 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147201 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:307202 }
[email protected]b9849abf2009-11-25 19:13:197203 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0c86dbf2010-03-05 08:14:117204 DoBufferData(target, size, data, usage);
7205 return error::kNoError;
7206}
7207
7208void GLES2DecoderImpl::DoBufferSubData(
7209 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]17cfbe0e2013-03-07 01:26:087210 Buffer* buffer = GetBufferInfoForTarget(target);
7211 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:517212 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287213 return;
[email protected]a93bb842010-02-16 23:03:477214 }
[email protected]17cfbe0e2013-03-07 01:26:087215
[email protected]d3eba342013-04-18 21:11:507216 buffer_manager()->DoBufferSubData(GetErrorState(), buffer, offset, size,
7217 data);
[email protected]b9849abf2009-11-25 19:13:197218}
7219
[email protected]0d6bfdc2011-11-02 01:32:207220bool GLES2DecoderImpl::ClearLevel(
7221 unsigned service_id,
7222 unsigned bind_target,
7223 unsigned target,
7224 int level,
7225 unsigned format,
7226 unsigned type,
7227 int width,
[email protected]4502e6492011-12-14 19:39:157228 int height,
7229 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007230 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7231 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7232 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7233 // on depth formats.
7234 GLuint fb = 0;
7235 glGenFramebuffersEXT(1, &fb);
7236 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7237
7238 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7239 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7240 GL_DEPTH_ATTACHMENT;
7241
7242 glFramebufferTexture2DEXT(
7243 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7244 // ANGLE promises a depth only attachment ok.
7245 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7246 GL_FRAMEBUFFER_COMPLETE) {
7247 return false;
7248 }
7249 glClearStencil(0);
7250 glStencilMask(-1);
7251 glClearDepth(1.0f);
7252 glDepthMask(true);
7253 glDisable(GL_SCISSOR_TEST);
7254 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7255
7256 RestoreClearState();
7257
7258 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357259 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007260 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7261 GLuint fb_service_id =
7262 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7263 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7264 return true;
7265 }
7266
[email protected]45d15a62012-04-18 14:33:177267 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7268
7269 uint32 size;
7270 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347271 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247272 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177273 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207274 return false;
7275 }
[email protected]45d15a62012-04-18 14:33:177276
[email protected]a5d3dad2012-05-26 04:34:447277 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7278
[email protected]45d15a62012-04-18 14:33:177279 int tile_height;
7280
7281 if (size > kMaxZeroSize) {
7282 if (kMaxZeroSize < padded_row_size) {
7283 // That'd be an awfully large texture.
7284 return false;
7285 }
7286 // We should never have a large total size with a zero row size.
7287 DCHECK_GT(padded_row_size, 0U);
7288 tile_height = kMaxZeroSize / padded_row_size;
7289 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247290 width, tile_height, format, type, state_.unpack_alignment, &size,
7291 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177292 return false;
7293 }
[email protected]4502e6492011-12-14 19:39:157294 } else {
[email protected]45d15a62012-04-18 14:33:177295 tile_height = height;
7296 }
7297
7298 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557299 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177300 memset(zero.get(), 0, size);
7301 glBindTexture(bind_target, service_id);
7302
7303 GLint y = 0;
7304 while (y < height) {
7305 GLint h = y + tile_height > height ? height - y : tile_height;
7306 if (is_texture_immutable || h != height) {
7307 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7308 } else {
[email protected]8f1d2aa2013-05-10 23:45:387309 glTexImage2D(
[email protected]45d15a62012-04-18 14:33:177310 target, level, format, width, h, 0, format, type, zero.get());
7311 }
7312 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157313 }
[email protected]370eaf12013-05-18 09:19:497314 TextureRef* texture = GetTextureInfoForTarget(bind_target);
[email protected]02965c22013-03-09 02:40:077315 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207316 return true;
7317}
7318
[email protected]ad84a3a2012-06-08 21:42:437319namespace {
7320
7321const int kS3TCBlockWidth = 4;
7322const int kS3TCBlockHeight = 4;
7323const int kS3TCDXT1BlockSize = 8;
7324const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077325const int kETC1BlockWidth = 4;
7326const int kETC1BlockHeight = 4;
7327const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437328
7329bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517330 return (size == 1) ||
7331 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437332}
7333
7334} // anonymous namespace.
7335
7336bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7337 const char* function_name,
7338 GLsizei width, GLsizei height, GLenum format, size_t size) {
7339 unsigned int bytes_required = 0;
7340
7341 switch (format) {
7342 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7343 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7344 int num_blocks_across =
7345 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7346 int num_blocks_down =
7347 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7348 int num_blocks = num_blocks_across * num_blocks_down;
7349 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7350 break;
7351 }
7352 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7353 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7354 int num_blocks_across =
7355 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7356 int num_blocks_down =
7357 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7358 int num_blocks = num_blocks_across * num_blocks_down;
7359 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7360 break;
7361 }
[email protected]2d3765b2012-10-03 00:31:077362 case GL_ETC1_RGB8_OES: {
7363 int num_blocks_across =
7364 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7365 int num_blocks_down =
7366 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7367 int num_blocks = num_blocks_across * num_blocks_down;
7368 bytes_required = num_blocks * kETC1BlockSize;
7369 break;
7370 }
[email protected]ad84a3a2012-06-08 21:42:437371 default:
[email protected]ab09b612013-03-11 22:11:517372 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437373 return false;
7374 }
7375
7376 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517377 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437378 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7379 return false;
7380 }
7381
7382 return true;
7383}
7384
7385bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7386 const char* function_name,
7387 GLint level, GLsizei width, GLsizei height, GLenum format) {
7388 switch (format) {
7389 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7390 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7391 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7392 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7393 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517394 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437395 GL_INVALID_OPERATION, function_name,
7396 "width or height invalid for level");
7397 return false;
7398 }
7399 return true;
7400 }
[email protected]2d3765b2012-10-03 00:31:077401 case GL_ETC1_RGB8_OES:
7402 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517403 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077404 GL_INVALID_OPERATION, function_name,
7405 "width or height invalid for level");
7406 return false;
7407 }
7408 return true;
[email protected]ad84a3a2012-06-08 21:42:437409 default:
7410 return false;
7411 }
7412}
7413
7414bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7415 const char* function_name,
7416 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7417 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357418 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437419 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517420 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437421 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7422 return false;
7423 }
7424
7425 switch (format) {
7426 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7427 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7428 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7429 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7430 const int kBlockWidth = 4;
7431 const int kBlockHeight = 4;
7432 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517433 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437434 GL_INVALID_OPERATION, function_name,
7435 "xoffset or yoffset not multiple of 4");
7436 return false;
7437 }
7438 GLsizei tex_width = 0;
7439 GLsizei tex_height = 0;
7440 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7441 width - xoffset > tex_width ||
7442 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517443 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437444 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7445 return false;
7446 }
7447 return ValidateCompressedTexDimensions(
7448 function_name, level, width, height, format);
7449 }
[email protected]2d3765b2012-10-03 00:31:077450 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517451 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077452 GL_INVALID_OPERATION, function_name,
7453 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7454 return false;
7455 }
[email protected]ad84a3a2012-06-08 21:42:437456 default:
7457 return false;
7458 }
7459}
7460
[email protected]a93bb842010-02-16 23:03:477461error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7462 GLenum target,
7463 GLint level,
7464 GLenum internal_format,
7465 GLsizei width,
7466 GLsizei height,
7467 GLint border,
7468 GLsizei image_size,
7469 const void* data) {
[email protected]a93bb842010-02-16 23:03:477470 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057471 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517472 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7473 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297474 return error::kNoError;
7475 }
[email protected]9438b012010-06-15 22:55:057476 if (!validators_->compressed_texture_format.IsValid(
7477 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517478 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537479 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477480 return error::kNoError;
7481 }
[email protected]80eb6b52012-01-19 00:14:417482 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477483 border != 0) {
[email protected]ab09b612013-03-11 22:11:517484 LOCAL_SET_GL_ERROR(
7485 GL_INVALID_VALUE,
7486 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477487 return error::kNoError;
7488 }
[email protected]370eaf12013-05-18 09:19:497489 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7490 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517491 LOCAL_SET_GL_ERROR(
7492 GL_INVALID_VALUE,
7493 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477494 return error::kNoError;
7495 }
[email protected]370eaf12013-05-18 09:19:497496 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077497 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517498 LOCAL_SET_GL_ERROR(
7499 GL_INVALID_OPERATION,
7500 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:437501 return error::kNoError;
7502 }
7503
7504 if (!ValidateCompressedTexDimensions(
7505 "glCompressedTexImage2D", level, width, height, internal_format) ||
7506 !ValidateCompressedTexFuncData(
7507 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177508 return error::kNoError;
7509 }
[email protected]968351b2011-12-20 08:26:517510
[email protected]7989c9e2013-01-23 06:39:267511 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:517512 LOCAL_SET_GL_ERROR(
7513 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267514 return error::kNoError;
7515 }
7516
[email protected]02965c22013-03-09 02:40:077517 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427518 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517519 }
7520
[email protected]40d90a22013-04-09 03:39:557521 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:477522 if (!data) {
7523 zero.reset(new int8[image_size]);
7524 memset(zero.get(), 0, image_size);
7525 data = zero.get();
7526 }
[email protected]ab09b612013-03-11 22:11:517527 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:477528 glCompressedTexImage2D(
7529 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:517530 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437531 if (error == GL_NO_ERROR) {
7532 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497533 texture_ref, target, level, internal_format,
7534 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:437535 }
[email protected]a93bb842010-02-16 23:03:477536 return error::kNoError;
7537}
7538
[email protected]f7a64ee2010-02-01 22:24:147539error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357540 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:197541 GLenum target = static_cast<GLenum>(c.target);
7542 GLint level = static_cast<GLint>(c.level);
7543 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7544 GLsizei width = static_cast<GLsizei>(c.width);
7545 GLsizei height = static_cast<GLsizei>(c.height);
7546 GLint border = static_cast<GLint>(c.border);
7547 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7548 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7549 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7550 const void* data = NULL;
7551 if (data_shm_id != 0 || data_shm_offset != 0) {
7552 data = GetSharedMemoryAs<const void*>(
7553 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467554 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147555 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197556 }
7557 }
[email protected]a93bb842010-02-16 23:03:477558 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197559 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197560}
7561
[email protected]f7a64ee2010-02-01 22:24:147562error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357563 uint32 immediate_data_size, const cmds::CompressedTexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197564 GLenum target = static_cast<GLenum>(c.target);
7565 GLint level = static_cast<GLint>(c.level);
7566 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7567 GLsizei width = static_cast<GLsizei>(c.width);
7568 GLsizei height = static_cast<GLsizei>(c.height);
7569 GLint border = static_cast<GLint>(c.border);
7570 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307571 const void* data = GetImmediateDataAs<const void*>(
7572 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467573 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147574 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467575 }
[email protected]a93bb842010-02-16 23:03:477576 return DoCompressedTexImage2D(
7577 target, level, internal_format, width, height, border, image_size, data);
7578}
7579
[email protected]b6140d02010-05-17 14:47:167580error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:357581 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167582 GLenum target = static_cast<GLenum>(c.target);
7583 GLint level = static_cast<GLint>(c.level);
7584 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7585 GLsizei width = static_cast<GLsizei>(c.width);
7586 GLsizei height = static_cast<GLsizei>(c.height);
7587 GLint border = static_cast<GLint>(c.border);
7588 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287589 if (!bucket) {
7590 return error::kInvalidArguments;
7591 }
7592 uint32 data_size = bucket->size();
7593 GLsizei imageSize = data_size;
7594 const void* data = bucket->GetData(0, data_size);
7595 if (!data) {
7596 return error::kInvalidArguments;
7597 }
[email protected]b6140d02010-05-17 14:47:167598 return DoCompressedTexImage2D(
7599 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287600 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167601}
7602
7603error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7604 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:357605 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167606 GLenum target = static_cast<GLenum>(c.target);
7607 GLint level = static_cast<GLint>(c.level);
7608 GLint xoffset = static_cast<GLint>(c.xoffset);
7609 GLint yoffset = static_cast<GLint>(c.yoffset);
7610 GLsizei width = static_cast<GLsizei>(c.width);
7611 GLsizei height = static_cast<GLsizei>(c.height);
7612 GLenum format = static_cast<GLenum>(c.format);
7613 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287614 if (!bucket) {
7615 return error::kInvalidArguments;
7616 }
[email protected]b6140d02010-05-17 14:47:167617 uint32 data_size = bucket->size();
7618 GLsizei imageSize = data_size;
7619 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287620 if (!data) {
7621 return error::kInvalidArguments;
7622 }
[email protected]9438b012010-06-15 22:55:057623 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517624 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:537625 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167626 return error::kNoError;
7627 }
[email protected]9438b012010-06-15 22:55:057628 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517629 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7630 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057631 return error::kNoError;
7632 }
[email protected]b6140d02010-05-17 14:47:167633 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:517634 LOCAL_SET_GL_ERROR(
7635 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167636 return error::kNoError;
7637 }
7638 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:517639 LOCAL_SET_GL_ERROR(
7640 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167641 return error::kNoError;
7642 }
7643 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:517644 LOCAL_SET_GL_ERROR(
7645 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167646 return error::kNoError;
7647 }
[email protected]cadde4a2010-07-31 17:10:437648 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167649 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7650 return error::kNoError;
7651}
7652
[email protected]81375742012-06-08 00:04:007653bool GLES2DecoderImpl::ValidateTextureParameters(
7654 const char* function_name,
7655 GLenum target, GLenum format, GLenum type, GLint level) {
7656 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517657 LOCAL_SET_GL_ERROR(
7658 GL_INVALID_OPERATION, function_name,
7659 (std::string("invalid type ") +
7660 GLES2Util::GetStringEnum(type) + " for format " +
7661 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007662 return false;
7663 }
7664
7665 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7666 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
[email protected]ab09b612013-03-11 22:11:517667 LOCAL_SET_GL_ERROR(
7668 GL_INVALID_OPERATION, function_name,
7669 (std::string("invalid type ") +
7670 GLES2Util::GetStringEnum(type) + " for format " +
7671 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007672 return false;
7673 }
7674 return true;
7675}
7676
[email protected]f598f422012-12-07 08:30:037677bool GLES2DecoderImpl::ValidateTexImage2D(
7678 const char* function_name,
7679 GLenum target,
7680 GLint level,
7681 GLenum internal_format,
7682 GLsizei width,
7683 GLsizei height,
7684 GLint border,
7685 GLenum format,
7686 GLenum type,
7687 const void* pixels,
7688 uint32 pixels_size) {
[email protected]9438b012010-06-15 22:55:057689 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517690 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:037691 return false;
[email protected]8eee29c2010-04-29 03:38:297692 }
[email protected]9438b012010-06-15 22:55:057693 if (!validators_->texture_format.IsValid(internal_format)) {
[email protected]ab09b612013-03-11 22:11:517694 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7695 function_name, internal_format, "internal_format");
[email protected]f598f422012-12-07 08:30:037696 return false;
[email protected]8eee29c2010-04-29 03:38:297697 }
[email protected]9438b012010-06-15 22:55:057698 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517699 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:037700 return false;
[email protected]8eee29c2010-04-29 03:38:297701 }
[email protected]9438b012010-06-15 22:55:057702 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517703 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:037704 return false;
[email protected]b9849abf2009-11-25 19:13:197705 }
[email protected]7b92c412010-07-20 17:48:257706 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:517707 LOCAL_SET_GL_ERROR(
7708 GL_INVALID_OPERATION, function_name, "format != internalFormat");
[email protected]f598f422012-12-07 08:30:037709 return false;
[email protected]7b92c412010-07-20 17:48:257710 }
[email protected]f598f422012-12-07 08:30:037711 if (!ValidateTextureParameters(function_name, target, format, type, level)) {
7712 return false;
[email protected]81375742012-06-08 00:04:007713 }
[email protected]80eb6b52012-01-19 00:14:417714 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477715 border != 0) {
[email protected]ab09b612013-03-11 22:11:517716 LOCAL_SET_GL_ERROR(
7717 GL_INVALID_VALUE, function_name, "dimensions out of range");
[email protected]f598f422012-12-07 08:30:037718 return false;
[email protected]a93bb842010-02-16 23:03:477719 }
[email protected]81375742012-06-08 00:04:007720 if ((GLES2Util::GetChannelsForFormat(format) &
7721 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
[email protected]ab09b612013-03-11 22:11:517722 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:007723 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037724 function_name, "can not supply data for depth or stencil textures");
7725 return false;
[email protected]81375742012-06-08 00:04:007726 }
[email protected]370eaf12013-05-18 09:19:497727 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7728 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517729 LOCAL_SET_GL_ERROR(
7730 GL_INVALID_OPERATION, function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:037731 return false;
[email protected]a93bb842010-02-16 23:03:477732 }
[email protected]370eaf12013-05-18 09:19:497733 if (texture_ref->texture()->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517734 LOCAL_SET_GL_ERROR(
7735 GL_INVALID_OPERATION, function_name, "texture is immutable");
[email protected]f598f422012-12-07 08:30:037736 return false;
[email protected]97dc7cbe2011-12-06 17:26:177737 }
[email protected]f598f422012-12-07 08:30:037738 return true;
7739}
[email protected]97dc7cbe2011-12-06 17:26:177740
[email protected]f598f422012-12-07 08:30:037741void GLES2DecoderImpl::DoTexImage2D(
7742 GLenum target,
7743 GLint level,
7744 GLenum internal_format,
7745 GLsizei width,
7746 GLsizei height,
7747 GLint border,
7748 GLenum format,
7749 GLenum type,
7750 const void* pixels,
7751 uint32 pixels_size) {
7752 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format,
7753 width, height, border, format, type, pixels, pixels_size)) {
7754 return;
7755 }
[email protected]7989c9e2013-01-23 06:39:267756
7757 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:517758 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267759 return;
7760 }
7761
[email protected]370eaf12013-05-18 09:19:497762 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7763 Texture* texture = texture_ref->texture();
[email protected]0226c112011-07-22 03:25:077764 GLsizei tex_width = 0;
7765 GLsizei tex_height = 0;
7766 GLenum tex_type = 0;
7767 GLenum tex_format = 0;
7768 bool level_is_same =
[email protected]02965c22013-03-09 02:40:077769 texture->GetLevelSize(target, level, &tex_width, &tex_height) &&
7770 texture->GetLevelType(target, level, &tex_type, &tex_format) &&
[email protected]0226c112011-07-22 03:25:077771 width == tex_width && height == tex_height &&
7772 type == tex_type && format == tex_format;
7773
7774 if (level_is_same && !pixels) {
[email protected]02965c22013-03-09 02:40:077775 // Just set the level texture but mark the texture as uncleared.
[email protected]1bed6222011-12-21 11:21:397776 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497777 texture_ref,
[email protected]1bed6222011-12-21 11:21:397778 target, level, internal_format, width, height, 1, border, format, type,
7779 false);
[email protected]ea72ed222011-08-17 18:58:437780 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037781 return;
[email protected]0226c112011-07-22 03:25:077782 }
7783
[email protected]02965c22013-03-09 02:40:077784 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427785 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:467786 }
7787
[email protected]1bed6222011-12-21 11:21:397788 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) {
[email protected]0226c112011-07-22 03:25:077789 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
[email protected]370eaf12013-05-18 09:19:497790 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0226c112011-07-22 03:25:077791 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037792 return;
[email protected]7488d962010-07-16 02:41:587793 }
[email protected]876f6fee2010-08-02 23:10:327794
[email protected]ab09b612013-03-11 22:11:517795 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexImage2D");
[email protected]8f1d2aa2013-05-10 23:45:387796 glTexImage2D(
[email protected]473c01ccb2011-06-07 01:33:307797 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477798 pixels);
[email protected]ab09b612013-03-11 22:11:517799 GLenum error = LOCAL_PEEK_GL_ERROR("glTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437800 if (error == GL_NO_ERROR) {
[email protected]0d6bfdc2011-11-02 01:32:207801 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497802 texture_ref,
[email protected]0d6bfdc2011-11-02 01:32:207803 target, level, internal_format, width, height, 1, border, format, type,
7804 pixels != NULL);
[email protected]b493ee622011-04-13 23:52:007805 tex_image_2d_failed_ = false;
[email protected]cadde4a2010-07-31 17:10:437806 }
[email protected]f598f422012-12-07 08:30:037807 return;
[email protected]b9849abf2009-11-25 19:13:197808}
7809
[email protected]f7a64ee2010-02-01 22:24:147810error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357811 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387812 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]b493ee622011-04-13 23:52:007813 tex_image_2d_failed_ = true;
[email protected]b9849abf2009-11-25 19:13:197814 GLenum target = static_cast<GLenum>(c.target);
7815 GLint level = static_cast<GLint>(c.level);
7816 GLint internal_format = static_cast<GLint>(c.internalformat);
7817 GLsizei width = static_cast<GLsizei>(c.width);
7818 GLsizei height = static_cast<GLsizei>(c.height);
7819 GLint border = static_cast<GLint>(c.border);
7820 GLenum format = static_cast<GLenum>(c.format);
7821 GLenum type = static_cast<GLenum>(c.type);
7822 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7823 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187824 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347825 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247826 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347827 NULL)) {
[email protected]a76b0052010-03-05 00:33:187828 return error::kOutOfBounds;
7829 }
[email protected]b9849abf2009-11-25 19:13:197830 const void* pixels = NULL;
7831 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7832 pixels = GetSharedMemoryAs<const void*>(
7833 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467834 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147835 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197836 }
7837 }
[email protected]f598f422012-12-07 08:30:037838
7839 DoTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197840 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477841 pixels, pixels_size);
[email protected]f598f422012-12-07 08:30:037842 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197843}
7844
[email protected]f7a64ee2010-02-01 22:24:147845error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357846 uint32 immediate_data_size, const cmds::TexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197847 GLenum target = static_cast<GLenum>(c.target);
7848 GLint level = static_cast<GLint>(c.level);
[email protected]ba3176a2009-12-16 18:19:467849 GLint internal_format = static_cast<GLint>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197850 GLsizei width = static_cast<GLsizei>(c.width);
7851 GLsizei height = static_cast<GLsizei>(c.height);
7852 GLint border = static_cast<GLint>(c.border);
7853 GLenum format = static_cast<GLenum>(c.format);
7854 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:187855 uint32 size;
[email protected]3458a64a2012-04-10 17:39:347856 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247857 width, height, format, type, state_.unpack_alignment, &size,
7858 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187859 return error::kOutOfBounds;
7860 }
[email protected]07f54fcc2009-12-22 02:46:307861 const void* pixels = GetImmediateDataAs<const void*>(
7862 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467863 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147864 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467865 }
[email protected]a93bb842010-02-16 23:03:477866 DoTexImage2D(
[email protected]ba3176a2009-12-16 18:19:467867 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477868 pixels, size);
[email protected]f7a64ee2010-02-01 22:24:147869 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327870}
7871
[email protected]cadde4a2010-07-31 17:10:437872void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7873 GLenum target,
7874 GLint level,
7875 GLint xoffset,
7876 GLint yoffset,
7877 GLsizei width,
7878 GLsizei height,
7879 GLenum format,
7880 GLsizei image_size,
7881 const void * data) {
[email protected]370eaf12013-05-18 09:19:497882 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7883 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517884 LOCAL_SET_GL_ERROR(
7885 GL_INVALID_OPERATION,
7886 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437887 return;
7888 }
[email protected]370eaf12013-05-18 09:19:497889 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:437890 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527891 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:077892 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:517893 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527894 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437895 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527896 return;
7897 }
7898 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:517899 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527900 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437901 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527902 return;
7903 }
[email protected]02965c22013-03-09 02:40:077904 if (!texture->ValidForTexture(
[email protected]df6cf1ad2011-01-29 01:20:527905 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:517906 LOCAL_SET_GL_ERROR(
7907 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437908 return;
7909 }
[email protected]ad84a3a2012-06-08 21:42:437910
7911 if (!ValidateCompressedTexFuncData(
7912 "glCompressedTexSubImage2D", width, height, format, image_size) ||
7913 !ValidateCompressedTexSubDimensions(
7914 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:077915 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:437916 return;
7917 }
7918
7919
[email protected]0d6bfdc2011-11-02 01:32:207920 // Note: There is no need to deal with texture cleared tracking here
7921 // because the validation above means you can only get here if the level
7922 // is already a matching compressed format and in that case
7923 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:437924 glCompressedTexSubImage2D(
7925 target, level, xoffset, yoffset, width, height, format, image_size, data);
7926}
7927
[email protected]6e288612010-12-21 20:45:037928static void Clip(
7929 GLint start, GLint range, GLint sourceRange,
7930 GLint* out_start, GLint* out_range) {
7931 DCHECK(out_start);
7932 DCHECK(out_range);
7933 if (start < 0) {
7934 range += start;
7935 start = 0;
7936 }
7937 GLint end = start + range;
7938 if (end > sourceRange) {
7939 range -= end - sourceRange;
7940 }
7941 *out_start = start;
7942 *out_range = range;
7943}
7944
[email protected]cadde4a2010-07-31 17:10:437945void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:447946 GLenum target,
7947 GLint level,
7948 GLenum internal_format,
7949 GLint x,
7950 GLint y,
7951 GLsizei width,
7952 GLsizei height,
7953 GLint border) {
[email protected]09e17272012-11-30 10:30:447954 DCHECK(!ShouldDeferReads());
[email protected]370eaf12013-05-18 09:19:497955 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7956 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517957 LOCAL_SET_GL_ERROR(
7958 GL_INVALID_OPERATION,
7959 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437960 return;
7961 }
[email protected]370eaf12013-05-18 09:19:497962 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077963 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517964 LOCAL_SET_GL_ERROR(
7965 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:177966 }
[email protected]80eb6b52012-01-19 00:14:417967 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:187968 border != 0) {
[email protected]ab09b612013-03-11 22:11:517969 LOCAL_SET_GL_ERROR(
7970 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:187971 return;
7972 }
[email protected]81375742012-06-08 00:04:007973 if (!ValidateTextureParameters(
7974 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
7975 return;
7976 }
[email protected]f5719fb2010-08-04 18:27:187977
[email protected]9edc6b22010-12-23 02:00:267978 // Check we have compatible formats.
7979 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7980 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7981 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
7982
7983 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:517984 LOCAL_SET_GL_ERROR(
7985 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:267986 return;
7987 }
7988
[email protected]81375742012-06-08 00:04:007989 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:517990 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:007991 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:267992 "glCopyTexImage2D", "can not be used with depth or stencil textures");
7993 return;
7994 }
7995
7996 uint32 estimated_size = 0;
7997 if (!GLES2Util::ComputeImageDataSizes(
7998 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
7999 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518000 LOCAL_SET_GL_ERROR(
8001 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268002 return;
8003 }
8004
8005 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518006 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008007 return;
8008 }
8009
[email protected]a0b78dc2011-11-11 10:43:108010 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8011 return;
8012 }
8013
[email protected]ab09b612013-03-11 22:11:518014 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278015 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038016 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268017
[email protected]02965c22013-03-09 02:40:078018 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:428019 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:468020 }
8021
[email protected]9edc6b22010-12-23 02:00:268022 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038023 GLint copyX = 0;
8024 GLint copyY = 0;
8025 GLint copyWidth = 0;
8026 GLint copyHeight = 0;
8027 Clip(x, width, size.width(), &copyX, &copyWidth);
8028 Clip(y, height, size.height(), &copyY, &copyHeight);
8029
8030 if (copyX != x ||
8031 copyY != y ||
8032 copyWidth != width ||
8033 copyHeight != height) {
8034 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208035 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078036 texture->service_id(), texture->target(),
[email protected]4502e6492011-12-14 19:39:158037 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
[email protected]02965c22013-03-09 02:40:078038 texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518039 LOCAL_SET_GL_ERROR(
8040 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038041 return;
8042 }
[email protected]6e288612010-12-21 20:45:038043 if (copyHeight > 0 && copyWidth > 0) {
8044 GLint dx = copyX - x;
8045 GLint dy = copyY - y;
8046 GLint destX = dx;
8047 GLint destY = dy;
8048 glCopyTexSubImage2D(target, level,
8049 destX, destY, copyX, copyY,
8050 copyWidth, copyHeight);
8051 }
8052 } else {
8053 glCopyTexImage2D(target, level, internal_format,
8054 copyX, copyY, copyWidth, copyHeight, border);
8055 }
[email protected]ab09b612013-03-11 22:11:518056 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438057 if (error == GL_NO_ERROR) {
8058 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498059 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208060 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438061 }
8062}
8063
8064void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448065 GLenum target,
8066 GLint level,
8067 GLint xoffset,
8068 GLint yoffset,
8069 GLint x,
8070 GLint y,
8071 GLsizei width,
8072 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448073 DCHECK(!ShouldDeferReads());
[email protected]370eaf12013-05-18 09:19:498074 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8075 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518076 LOCAL_SET_GL_ERROR(
8077 GL_INVALID_OPERATION,
8078 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438079 return;
8080 }
[email protected]370eaf12013-05-18 09:19:498081 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438082 GLenum type = 0;
8083 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078084 if (!texture->GetLevelType(target, level, &type, &format) ||
8085 !texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438086 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518087 LOCAL_SET_GL_ERROR(
8088 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438089 return;
8090 }
[email protected]85a4ac22013-05-31 01:58:478091 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518092 LOCAL_SET_GL_ERROR(
8093 GL_INVALID_OPERATION,
8094 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598095 return;
8096 }
[email protected]9edc6b22010-12-23 02:00:268097
8098 // Check we have compatible formats.
8099 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8100 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8101 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8102
[email protected]2d3765b2012-10-03 00:31:078103 if (!channels_needed ||
8104 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518105 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438106 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268107 return;
8108 }
8109
[email protected]81375742012-06-08 00:04:008110 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518111 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008112 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438113 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008114 return;
8115 }
8116
[email protected]a0b78dc2011-11-11 10:43:108117 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8118 return;
8119 }
8120
[email protected]de26b3c2011-08-03 21:54:278121 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038122 gfx::Size size = GetBoundReadFrameBufferSize();
8123 GLint copyX = 0;
8124 GLint copyY = 0;
8125 GLint copyWidth = 0;
8126 GLint copyHeight = 0;
8127 Clip(x, width, size.width(), &copyX, &copyWidth);
8128 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208129
[email protected]370eaf12013-05-18 09:19:498130 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518131 LOCAL_SET_GL_ERROR(
8132 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208133 return;
8134 }
8135
[email protected]6e288612010-12-21 20:45:038136 if (copyX != x ||
8137 copyY != y ||
8138 copyWidth != width ||
8139 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208140 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038141 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348142 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248143 width, height, format, type, state_.unpack_alignment, &pixels_size,
8144 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518145 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438146 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038147 return;
8148 }
[email protected]40d90a22013-04-09 03:39:558149 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038150 memset(zero.get(), 0, pixels_size);
8151 glTexSubImage2D(
8152 target, level, xoffset, yoffset, width, height,
8153 format, type, zero.get());
8154 }
[email protected]0d6bfdc2011-11-02 01:32:208155
[email protected]6e288612010-12-21 20:45:038156 if (copyHeight > 0 && copyWidth > 0) {
8157 GLint dx = copyX - x;
8158 GLint dy = copyY - y;
8159 GLint destX = xoffset + dx;
8160 GLint destY = yoffset + dy;
8161 glCopyTexSubImage2D(target, level,
8162 destX, destY, copyX, copyY,
8163 copyWidth, copyHeight);
8164 }
[email protected]cadde4a2010-07-31 17:10:438165}
8166
[email protected]f598f422012-12-07 08:30:038167bool GLES2DecoderImpl::ValidateTexSubImage2D(
8168 error::Error* error,
8169 const char* function_name,
8170 GLenum target,
8171 GLint level,
8172 GLint xoffset,
8173 GLint yoffset,
8174 GLsizei width,
8175 GLsizei height,
8176 GLenum format,
8177 GLenum type,
8178 const void * data) {
8179 (*error) = error::kNoError;
8180 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518181 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038182 return false;
8183 }
8184 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518185 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038186 return false;
8187 }
8188 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518189 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038190 return false;
8191 }
8192 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518193 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:038194 return false;
8195 }
8196 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518197 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:038198 return false;
8199 }
[email protected]370eaf12013-05-18 09:19:498200 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8201 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518202 LOCAL_SET_GL_ERROR(
8203 GL_INVALID_OPERATION,
8204 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038205 return false;
[email protected]cadde4a2010-07-31 17:10:438206 }
[email protected]370eaf12013-05-18 09:19:498207 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528208 GLenum current_type = 0;
8209 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078210 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518211 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038212 GL_INVALID_OPERATION, function_name, "level does not exist.");
8213 return false;
[email protected]df6cf1ad2011-01-29 01:20:528214 }
8215 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:518216 LOCAL_SET_GL_ERROR(
8217 GL_INVALID_OPERATION,
8218 function_name, "format does not match internal format.");
[email protected]f598f422012-12-07 08:30:038219 return false;
[email protected]df6cf1ad2011-01-29 01:20:528220 }
8221 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518222 LOCAL_SET_GL_ERROR(
8223 GL_INVALID_OPERATION,
8224 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038225 return false;
[email protected]df6cf1ad2011-01-29 01:20:528226 }
[email protected]85a4ac22013-05-31 01:58:478227 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518228 LOCAL_SET_GL_ERROR(
8229 GL_INVALID_OPERATION,
8230 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598231 return false;
8232 }
[email protected]02965c22013-03-09 02:40:078233 if (!texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438234 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518235 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038236 return false;
[email protected]cadde4a2010-07-31 17:10:438237 }
[email protected]81375742012-06-08 00:04:008238 if ((GLES2Util::GetChannelsForFormat(format) &
8239 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518240 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008241 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038242 function_name, "can not supply data for depth or stencil textures");
8243 return false;
[email protected]81375742012-06-08 00:04:008244 }
[email protected]f598f422012-12-07 08:30:038245 if (data == NULL) {
8246 (*error) = error::kOutOfBounds;
8247 return false;
8248 }
8249 return true;
8250}
[email protected]81375742012-06-08 00:04:008251
[email protected]f598f422012-12-07 08:30:038252error::Error GLES2DecoderImpl::DoTexSubImage2D(
8253 GLenum target,
8254 GLint level,
8255 GLint xoffset,
8256 GLint yoffset,
8257 GLsizei width,
8258 GLsizei height,
8259 GLenum format,
8260 GLenum type,
8261 const void * data) {
8262 error::Error error = error::kNoError;
8263 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8264 xoffset, yoffset, width, height, format, type, data)) {
8265 return error;
8266 }
[email protected]370eaf12013-05-18 09:19:498267 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8268 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158269 GLsizei tex_width = 0;
8270 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078271 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158272 DCHECK(ok);
8273 if (xoffset != 0 || yoffset != 0 ||
8274 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498275 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8276 target, level)) {
[email protected]ab09b612013-03-11 22:11:518277 LOCAL_SET_GL_ERROR(
8278 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038279 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308280 }
[email protected]63b465922012-09-06 02:04:528281 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158282 glTexSubImage2D(
8283 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038284 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208285 }
[email protected]4502e6492011-12-14 19:39:158286
[email protected]02965c22013-03-09 02:40:078287 if (teximage2d_faster_than_texsubimage2d_ && !texture->IsImmutable()) {
[email protected]63b465922012-09-06 02:04:528288 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158289 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8290 // same as internal_foramt. If that changes we'll need to look them up.
[email protected]8f1d2aa2013-05-10 23:45:388291 glTexImage2D(
[email protected]4502e6492011-12-14 19:39:158292 target, level, format, width, height, 0, format, type, data);
8293 } else {
[email protected]63b465922012-09-06 02:04:528294 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158295 glTexSubImage2D(
8296 target, level, xoffset, yoffset, width, height, format, type, data);
8297 }
[email protected]370eaf12013-05-18 09:19:498298 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038299 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438300}
8301
[email protected]b493ee622011-04-13 23:52:008302error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358303 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388304 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008305 GLboolean internal = static_cast<GLboolean>(c.internal);
8306 if (internal == GL_TRUE && tex_image_2d_failed_)
8307 return error::kNoError;
8308
8309 GLenum target = static_cast<GLenum>(c.target);
8310 GLint level = static_cast<GLint>(c.level);
8311 GLint xoffset = static_cast<GLint>(c.xoffset);
8312 GLint yoffset = static_cast<GLint>(c.yoffset);
8313 GLsizei width = static_cast<GLsizei>(c.width);
8314 GLsizei height = static_cast<GLsizei>(c.height);
8315 GLenum format = static_cast<GLenum>(c.format);
8316 GLenum type = static_cast<GLenum>(c.type);
8317 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348318 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248319 width, height, format, type, state_.unpack_alignment, &data_size,
8320 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008321 return error::kOutOfBounds;
8322 }
8323 const void* pixels = GetSharedMemoryAs<const void*>(
8324 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038325 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008326 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008327}
8328
8329error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:358330 uint32 immediate_data_size, const cmds::TexSubImage2DImmediate& c) {
[email protected]b493ee622011-04-13 23:52:008331 GLboolean internal = static_cast<GLboolean>(c.internal);
8332 if (internal == GL_TRUE && tex_image_2d_failed_)
8333 return error::kNoError;
8334
8335 GLenum target = static_cast<GLenum>(c.target);
8336 GLint level = static_cast<GLint>(c.level);
8337 GLint xoffset = static_cast<GLint>(c.xoffset);
8338 GLint yoffset = static_cast<GLint>(c.yoffset);
8339 GLsizei width = static_cast<GLsizei>(c.width);
8340 GLsizei height = static_cast<GLsizei>(c.height);
8341 GLenum format = static_cast<GLenum>(c.format);
8342 GLenum type = static_cast<GLenum>(c.type);
8343 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348344 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248345 width, height, format, type, state_.unpack_alignment, &data_size,
8346 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008347 return error::kOutOfBounds;
8348 }
8349 const void* pixels = GetImmediateDataAs<const void*>(
8350 c, data_size, immediate_data_size);
[email protected]f598f422012-12-07 08:30:038351 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008352 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008353}
8354
[email protected]f7a64ee2010-02-01 22:24:148355error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358356 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368357 GLuint index = static_cast<GLuint>(c.index);
8358 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358359 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258360 Result* result = GetSharedMemoryAs<Result*>(
8361 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368362 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148363 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368364 }
[email protected]07d0cc82010-02-17 04:51:408365 // Check that the client initialized the result.
8366 if (result->size != 0) {
8367 return error::kInvalidArguments;
8368 }
[email protected]9438b012010-06-15 22:55:058369 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518370 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8371 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148372 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368373 }
[email protected]3916c97e2010-02-25 03:20:508374 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518375 LOCAL_SET_GL_ERROR(
8376 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148377 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368378 }
[email protected]0bfd9882010-02-05 23:02:258379 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088380 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358381 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148382 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328383}
8384
[email protected]f7b85372010-02-03 01:11:378385bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428386 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378387 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128388 error::Error* error, GLint* real_location,
8389 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108390 DCHECK(error);
8391 DCHECK(service_id);
8392 DCHECK(result_pointer);
8393 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128394 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378395 *error = error::kNoError;
8396 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258397 SizedResult<GLint>* result;
8398 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8399 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8400 if (!result) {
[email protected]f7b85372010-02-03 01:11:378401 *error = error::kOutOfBounds;
8402 return false;
8403 }
[email protected]0bfd9882010-02-05 23:02:258404 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378405 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258406 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428407 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8408 if (!program) {
[email protected]ae51d192010-04-27 00:48:038409 return false;
8410 }
[email protected]df37b9932013-03-08 05:21:428411 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378412 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518413 LOCAL_SET_GL_ERROR(
8414 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378415 return false;
8416 }
[email protected]df37b9932013-03-08 05:21:428417 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368418 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358419 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428420 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128421 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368422 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378423 // No such location.
[email protected]ab09b612013-03-11 22:11:518424 LOCAL_SET_GL_ERROR(
8425 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378426 return false;
8427 }
[email protected]43c2f1f2011-03-25 18:35:368428 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508429 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378430 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518431 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378432 return false;
8433 }
[email protected]0bfd9882010-02-05 23:02:258434 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8435 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8436 if (!result) {
[email protected]f7b85372010-02-03 01:11:378437 *error = error::kOutOfBounds;
8438 return false;
8439 }
[email protected]0bfd9882010-02-05 23:02:258440 result->size = size;
[email protected]939e7362010-05-13 20:49:108441 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378442 return true;
8443}
8444
[email protected]f7a64ee2010-02-01 22:24:148445error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358446 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378447 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338448 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378449 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108450 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128451 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378452 Error error;
[email protected]0bfd9882010-02-05 23:02:258453 void* result;
[email protected]f7b85372010-02-03 01:11:378454 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128455 program, fake_location, c.params_shm_id, c.params_shm_offset,
8456 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258457 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128458 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358459 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378460 }
8461 return error;
[email protected]96449d2c2009-11-25 00:01:328462}
8463
[email protected]f7a64ee2010-02-01 22:24:148464error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358465 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378466 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338467 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378468 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128469 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378470 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358471 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108472 Result* result;
8473 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378474 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128475 program, fake_location, c.params_shm_id, c.params_shm_offset,
8476 &error, &real_location, &service_id,
8477 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108478 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8479 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8480 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558481 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128482 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108483 GLfloat* dst = result->GetData();
8484 for (GLsizei ii = 0; ii < num_values; ++ii) {
8485 dst[ii] = (temp[ii] != 0);
8486 }
8487 } else {
[email protected]1b0a6752012-02-22 03:44:128488 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108489 }
[email protected]f7b85372010-02-03 01:11:378490 }
8491 return error;
[email protected]96449d2c2009-11-25 00:01:328492}
8493
[email protected]f7a64ee2010-02-01 22:24:148494error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358495 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258496 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8497 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358498 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258499 Result* result = GetSharedMemoryAs<Result*>(
8500 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8501 if (!result) {
8502 return error::kOutOfBounds;
8503 }
[email protected]07d0cc82010-02-17 04:51:408504 // Check that the client initialized the result.
8505 if (result->success != 0) {
8506 return error::kInvalidArguments;
8507 }
[email protected]9438b012010-06-15 22:55:058508 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518509 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538510 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298511 return error::kNoError;
8512 }
[email protected]9438b012010-06-15 22:55:058513 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518514 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538515 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298516 return error::kNoError;
8517 }
8518
8519 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408520
[email protected]46c86752013-05-21 05:08:398521 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:408522 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218523 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408524
8525 result->min_range = range[0];
8526 result->max_range = range[1];
8527 result->precision = precision;
8528
[email protected]f7a64ee2010-02-01 22:24:148529 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328530}
8531
[email protected]f7a64ee2010-02-01 22:24:148532error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358533 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258534 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428535 GLuint program_id = static_cast<GLuint>(c.program);
8536 Program* program = GetProgramInfoNotShader(
8537 program_id, "glGetAttachedShaders");
8538 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258539 return error::kNoError;
8540 }
[email protected]ed9f9cd2013-02-27 21:12:358541 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258542 uint32 max_count = Result::ComputeMaxResults(result_size);
8543 Result* result = GetSharedMemoryAs<Result*>(
8544 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8545 if (!result) {
8546 return error::kOutOfBounds;
8547 }
[email protected]07d0cc82010-02-17 04:51:408548 // Check that the client initialized the result.
8549 if (result->size != 0) {
8550 return error::kInvalidArguments;
8551 }
[email protected]0bfd9882010-02-05 23:02:258552 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038553 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428554 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258555 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038556 if (!shader_manager()->GetClientId(result->GetData()[ii],
8557 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258558 NOTREACHED();
8559 return error::kGenericError;
8560 }
8561 }
8562 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148563 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328564}
8565
[email protected]f7a64ee2010-02-01 22:24:148566error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358567 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428568 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258569 GLuint index = c.index;
8570 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358571 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258572 Result* result = GetSharedMemoryAs<Result*>(
8573 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8574 if (!result) {
8575 return error::kOutOfBounds;
8576 }
[email protected]07d0cc82010-02-17 04:51:408577 // Check that the client initialized the result.
8578 if (result->success != 0) {
8579 return error::kInvalidArguments;
8580 }
[email protected]df37b9932013-03-08 05:21:428581 Program* program = GetProgramInfoNotShader(
8582 program_id, "glGetActiveUniform");
8583 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258584 return error::kNoError;
8585 }
[email protected]ed9f9cd2013-02-27 21:12:358586 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428587 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258588 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518589 LOCAL_SET_GL_ERROR(
8590 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258591 return error::kNoError;
8592 }
8593 result->success = 1; // true.
8594 result->size = uniform_info->size;
8595 result->type = uniform_info->type;
8596 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298597 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148598 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328599}
8600
[email protected]f7a64ee2010-02-01 22:24:148601error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358602 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428603 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258604 GLuint index = c.index;
8605 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358606 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258607 Result* result = GetSharedMemoryAs<Result*>(
8608 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8609 if (!result) {
8610 return error::kOutOfBounds;
8611 }
[email protected]07d0cc82010-02-17 04:51:408612 // Check that the client initialized the result.
8613 if (result->success != 0) {
8614 return error::kInvalidArguments;
8615 }
[email protected]df37b9932013-03-08 05:21:428616 Program* program = GetProgramInfoNotShader(
8617 program_id, "glGetActiveAttrib");
8618 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258619 return error::kNoError;
8620 }
[email protected]ed9f9cd2013-02-27 21:12:358621 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428622 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258623 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518624 LOCAL_SET_GL_ERROR(
8625 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258626 return error::kNoError;
8627 }
8628 result->success = 1; // true.
8629 result->size = attrib_info->size;
8630 result->type = attrib_info->type;
8631 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298632 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148633 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328634}
8635
[email protected]b273e432010-04-12 17:23:588636error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358637 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588638#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518639 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588640 return error::kNoError;
8641#else
8642 GLsizei n = static_cast<GLsizei>(c.n);
8643 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518644 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588645 return error::kNoError;
8646 }
8647 GLsizei length = static_cast<GLsizei>(c.length);
8648 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518649 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588650 return error::kNoError;
8651 }
8652 uint32 data_size;
8653 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8654 return error::kOutOfBounds;
8655 }
8656 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8657 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8658 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8659 const void* binary = GetSharedMemoryAs<const void*>(
8660 c.binary_shm_id, c.binary_shm_offset, length);
8661 if (shaders == NULL || binary == NULL) {
8662 return error::kOutOfBounds;
8663 }
8664 scoped_array<GLuint> service_ids(new GLuint[n]);
8665 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428666 Shader* shader = GetShader(shaders[ii]);
8667 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518668 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588669 return error::kNoError;
8670 }
[email protected]df37b9932013-03-08 05:21:428671 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588672 }
8673 // TODO(gman): call glShaderBinary
8674 return error::kNoError;
8675#endif
8676}
8677
[email protected]6d792ee12013-05-15 00:40:568678void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:498679 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088680
[email protected]64ace852011-05-19 21:49:498681 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428682 // TRACE_EVENT for gpu tests:
8683 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428684 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428685 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8686 "width", (is_offscreen ? offscreen_size_.width() :
8687 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:568688 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:498689 "offscreen", is_offscreen,
8690 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358691 // If offscreen then don't actually SwapBuffers to the display. Just copy
8692 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498693 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318694 TRACE_EVENT2("gpu", "Offscreen",
8695 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538696 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8697 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8698 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8699 // fix this.
[email protected]62e155e2012-10-23 22:43:158700 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538701 offscreen_saved_frame_buffer_->Create();
8702 glFinish();
8703 }
8704
8705 // Allocate the offscreen saved color texture.
8706 DCHECK(offscreen_saved_color_format_);
8707 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098708 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538709
8710 offscreen_saved_frame_buffer_->AttachRenderTexture(
8711 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:058712 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
8713 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8714 GL_FRAMEBUFFER_COMPLETE) {
8715 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8716 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:568717 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
8718 return;
[email protected]f0cfe752013-01-14 01:09:058719 }
[email protected]1fb8c482011-08-31 01:01:538720
[email protected]f0cfe752013-01-14 01:09:058721 // Clear the offscreen color texture.
8722 // TODO(piman): Is this still necessary?
8723 {
8724 ScopedFrameBufferBinder binder(this,
8725 offscreen_saved_frame_buffer_->id());
8726 glClearColor(0, 0, 0, 0);
8727 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8728 glDisable(GL_SCISSOR_TEST);
8729 glClear(GL_COLOR_BUFFER_BIT);
8730 RestoreClearState();
8731 }
[email protected]1fb8c482011-08-31 01:01:538732 }
8733
8734 UpdateParentTextureInfo();
8735 }
8736
[email protected]f0cfe752013-01-14 01:09:058737 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:568738 return;
[email protected]ab09b612013-03-11 22:11:518739 ScopedGLErrorSuppressor suppressor(
[email protected]6d792ee12013-05-15 00:40:568740 "GLES2DecoderImpl::DoSwapBuffers", this);
[email protected]6217d392010-03-25 22:08:358741
[email protected]34ff8b0c2010-10-01 20:06:028742 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138743 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278744 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:488745 } else {
[email protected]069944672012-04-25 20:52:238746 ScopedFrameBufferBinder binder(this,
8747 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138748
[email protected]069944672012-04-25 20:52:238749 if (offscreen_target_buffer_preserved_) {
8750 // Copy the target frame buffer to the saved offscreen texture.
8751 offscreen_saved_color_texture_->Copy(
8752 offscreen_saved_color_texture_->size(),
8753 offscreen_saved_color_format_);
8754 } else {
8755 // Flip the textures in the parent context via the texture manager.
8756 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:498757 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:238758 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568759
[email protected]069944672012-04-25 20:52:238760 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8761 offscreen_target_frame_buffer_->AttachRenderTexture(
8762 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488763 }
[email protected]069944672012-04-25 20:52:238764
8765 // Ensure the side effects of the copy are visible to the parent
8766 // context. There is no need to do this for ANGLE because it uses a
8767 // single D3D device for all contexts.
8768 if (!IsAngle())
8769 glFlush();
[email protected]0c8c9d22010-06-25 17:36:398770 }
[email protected]6217d392010-03-25 22:08:358771 } else {
[email protected]111975c62012-09-06 01:37:318772 TRACE_EVENT2("gpu", "Onscreen",
8773 "width", surface_->GetSize().width(),
8774 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158775 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018776 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:568777 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:018778 }
[email protected]6217d392010-03-25 22:08:358779 }
[email protected]6217d392010-03-25 22:08:358780}
8781
[email protected]d4239852011-08-12 04:51:228782error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358783 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188784 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288785 if (!bucket || bucket->size() == 0) {
8786 return error::kInvalidArguments;
8787 }
[email protected]ed9f9cd2013-02-27 21:12:358788 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188789 Result* result = GetSharedMemoryAs<Result*>(
8790 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8791 if (!result) {
8792 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108793 }
[email protected]b1d2dcb2010-05-17 19:24:188794 // Check that the client initialized the result.
8795 if (*result != 0) {
8796 return error::kInvalidArguments;
8797 }
8798 std::string feature_str;
8799 if (!bucket->GetAsString(&feature_str)) {
8800 return error::kInvalidArguments;
8801 }
8802
8803 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228804 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188805 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228806 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408807 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8808 // TODO(gman): decide how to remove the need for this const_cast.
8809 // I could make validators_ non const but that seems bad as this is the only
8810 // place it is needed. I could make some special friend class of validators
8811 // just to allow this to set them. That seems silly. I could refactor this
8812 // code to use the extension mechanism or the initialization attributes to
8813 // turn this feature on. Given that the only real point of this is to make
8814 // the conformance tests pass and given that there is lots of real work that
8815 // needs to be done it seems like refactoring for one to one of those
8816 // methods is a very low priority.
8817 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048818 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8819 force_webgl_glsl_validation_ = true;
8820 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188821 } else {
8822 return error::kNoError;
8823 }
8824
8825 *result = 1; // true.
8826 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108827}
8828
[email protected]c2f8c8402010-12-06 18:07:248829error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8830 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358831 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248832 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:358833 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:298834 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:248835 bucket->SetFromString(info->extensions().c_str());
8836 return error::kNoError;
8837}
8838
8839error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358840 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248841 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288842 if (!bucket || bucket->size() == 0) {
8843 return error::kInvalidArguments;
8844 }
[email protected]c2f8c8402010-12-06 18:07:248845 std::string feature_str;
8846 if (!bucket->GetAsString(&feature_str)) {
8847 return error::kInvalidArguments;
8848 }
8849
[email protected]4b7eba92013-01-08 02:23:568850 bool desire_webgl_glsl_validation =
8851 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
8852 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:498853 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:138854 bool desire_draw_buffers = false;
[email protected]4b7eba92013-01-08 02:23:568855 if (force_webgl_glsl_validation_) {
8856 desire_standard_derivatives =
8857 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:498858 desire_frag_depth =
8859 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:138860 desire_draw_buffers =
8861 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:048862 }
8863
[email protected]4b7eba92013-01-08 02:23:568864 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:498865 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:138866 desire_frag_depth != frag_depth_explicitly_enabled_ ||
8867 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:498868 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
8869 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
8870 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:138871 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]c2f8c8402010-12-06 18:07:248872 InitializeShaderTranslator();
8873 }
8874
[email protected]302ce6d2011-07-07 23:28:118875 UpdateCapabilities();
8876
[email protected]c2f8c8402010-12-06 18:07:248877 return error::kNoError;
8878}
8879
[email protected]372e0412011-06-28 16:08:568880error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358881 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:568882 GLuint count = c.count;
8883 uint32 pnames_size;
8884 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8885 return error::kOutOfBounds;
8886 }
8887 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8888 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8889 if (pnames == NULL) {
8890 return error::kOutOfBounds;
8891 }
8892
8893 // We have to copy them since we use them twice so the client
8894 // can't change them between the time we validate them and the time we use
8895 // them.
[email protected]40d90a22013-04-09 03:39:558896 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:568897 memcpy(enums.get(), pnames, pnames_size);
8898
8899 // Count up the space needed for the result.
8900 uint32 num_results = 0;
8901 for (GLuint ii = 0; ii < count; ++ii) {
8902 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8903 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:518904 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8905 "glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568906 return error::kNoError;
8907 }
8908 // Num will never be more than 4.
8909 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478910 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568911 return error::kOutOfBounds;
8912 }
8913 }
8914
8915 uint32 result_size = 0;
8916 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8917 return error::kOutOfBounds;
8918 }
8919
8920 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:518921 LOCAL_SET_GL_ERROR(
8922 GL_INVALID_VALUE,
8923 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:568924 return error::kNoError;
8925 }
8926
8927 GLint* results = GetSharedMemoryAs<GLint*>(
8928 c.results_shm_id, c.results_shm_offset, result_size);
8929 if (results == NULL) {
8930 return error::kOutOfBounds;
8931 }
8932
8933 // Check the results have been cleared in case the context was lost.
8934 for (uint32 ii = 0; ii < num_results; ++ii) {
8935 if (results[ii]) {
8936 return error::kInvalidArguments;
8937 }
8938 }
8939
8940 // Get each result.
8941 GLint* start = results;
8942 for (GLuint ii = 0; ii < count; ++ii) {
8943 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:268944 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:538945 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:488946 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:568947 }
8948 results += num_written;
8949 }
8950
8951 // Just to verify. Should this be a DCHECK?
8952 if (static_cast<uint32>(results - start) != num_results) {
8953 return error::kOutOfBounds;
8954 }
8955
8956 return error::kNoError;
8957}
8958
[email protected]2318d342011-07-11 22:27:428959error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358960 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:428961 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:428962 uint32 bucket_id = c.bucket_id;
8963 Bucket* bucket = CreateBucket(bucket_id);
8964 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:428965 Program* program = NULL;
8966 program = GetProgram(program_id);
8967 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:468968 return error::kNoError;
[email protected]2318d342011-07-11 22:27:428969 }
[email protected]df37b9932013-03-08 05:21:428970 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:428971 return error::kNoError;
8972}
8973
[email protected]38d139d2011-07-14 00:38:438974error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
8975 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:438976 case GL_NO_ERROR:
8977 // TODO(kbr): improve the precision of the error code in this case.
8978 // Consider delegating to context for error code if MakeCurrent fails.
8979 return error::kUnknown;
8980 case GL_GUILTY_CONTEXT_RESET_ARB:
8981 return error::kGuilty;
8982 case GL_INNOCENT_CONTEXT_RESET_ARB:
8983 return error::kInnocent;
8984 case GL_UNKNOWN_CONTEXT_RESET_ARB:
8985 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:438986 }
8987
8988 NOTREACHED();
8989 return error::kUnknown;
8990}
8991
8992bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:098993 if (reset_status_ != GL_NO_ERROR) {
8994 return true;
8995 }
[email protected]706b69f2012-07-27 04:59:308996 if (context_->WasAllocatedUsingRobustnessExtension()) {
8997 GLenum status = GL_NO_ERROR;
8998 if (has_robustness_extension_)
8999 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439000 if (status != GL_NO_ERROR) {
9001 // The graphics card was reset. Signal a lost context to the application.
9002 reset_status_ = status;
9003 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099004 << " context lost via ARB/EXT_robustness. Reset status = "
9005 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439006 return true;
9007 }
9008 }
9009 return false;
9010}
9011
[email protected]c4485aad62012-12-17 10:19:099012void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9013 // Only loses the context once.
9014 if (reset_status_ != GL_NO_ERROR) {
9015 return;
9016 }
9017
9018 // Marks this context as lost.
9019 reset_status_ = reset_status;
9020 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099021}
9022
9023error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359024 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099025 GLenum current = static_cast<GLenum>(c.current);
9026 GLenum other = static_cast<GLenum>(c.other);
9027 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519028 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9029 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099030 }
9031 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519032 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099033 }
9034 group_->LoseContexts(other);
9035 reset_status_ = current;
9036 current_decoder_error_ = error::kLostContext;
9037 return error::kLostContext;
9038}
9039
[email protected]b096d032013-03-08 03:08:019040error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9041 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9042 return error::kUnknownCommand;
9043}
9044
[email protected]840a7e462013-02-27 01:29:519045error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359046 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:519047 if (wait_sync_point_callback_.is_null())
9048 return error::kNoError;
9049
9050 return wait_sync_point_callback_.Run(c.sync_point) ?
9051 error::kNoError : error::kDeferCommandUntilLater;
9052}
9053
[email protected]882ba1e22012-03-08 19:02:539054bool GLES2DecoderImpl::GenQueriesEXTHelper(
9055 GLsizei n, const GLuint* client_ids) {
9056 for (GLsizei ii = 0; ii < n; ++ii) {
9057 if (query_manager_->GetQuery(client_ids[ii])) {
9058 return false;
9059 }
9060 }
[email protected]c45f1972012-03-14 07:27:369061 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539062 return true;
9063}
9064
9065void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9066 GLsizei n, const GLuint* client_ids) {
9067 for (GLsizei ii = 0; ii < n; ++ii) {
9068 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9069 if (query && !query->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119070 if (query == state_.current_query.get()) {
[email protected]e259eb412012-10-13 05:47:249071 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539072 }
[email protected]c45f1972012-03-14 07:27:369073 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539074 query_manager_->RemoveQuery(client_ids[ii]);
9075 }
9076 }
9077}
9078
[email protected]22e3f552012-03-13 01:54:199079bool GLES2DecoderImpl::ProcessPendingQueries() {
9080 if (query_manager_.get() == NULL) {
9081 return false;
9082 }
[email protected]c45f1972012-03-14 07:27:369083 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199084 current_decoder_error_ = error::kOutOfBounds;
9085 }
9086 return query_manager_->HavePendingQueries();
9087}
9088
[email protected]2b1767cf2013-03-16 09:25:059089bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]b68b100752013-06-05 08:34:489090 return async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059091}
9092
9093void GLES2DecoderImpl::PerformIdleWork() {
[email protected]b68b100752013-06-05 08:34:489094 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059095 return;
[email protected]b68b100752013-06-05 08:34:489096 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059097 ProcessFinishedAsyncTransfers();
9098}
9099
[email protected]882ba1e22012-03-08 19:02:539100error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359101 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539102 GLenum target = static_cast<GLenum>(c.target);
9103 GLuint client_id = static_cast<GLuint>(c.id);
9104 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9105 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9106
[email protected]c45f1972012-03-14 07:27:369107 switch (target) {
9108 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559109 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]0713f43d2012-12-14 22:41:309110 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009111 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369112 break;
9113 default:
[email protected]62e155e2012-10-23 22:43:159114 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519115 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009116 GL_INVALID_OPERATION, "glBeginQueryEXT",
9117 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369118 return error::kNoError;
9119 }
9120 break;
[email protected]882ba1e22012-03-08 19:02:539121 }
9122
[email protected]7cd76fd2013-06-02 21:11:119123 if (state_.current_query.get()) {
[email protected]ab09b612013-03-11 22:11:519124 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439125 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539126 return error::kNoError;
9127 }
9128
9129 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519130 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539131 return error::kNoError;
9132 }
9133
9134 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9135 if (!query) {
[email protected]c45f1972012-03-14 07:27:369136 // TODO(gman): Decide if we need this check.
9137 //
[email protected]882ba1e22012-03-08 19:02:539138 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369139 //
9140 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9141 // for all Query ids but from the POV of the command buffer service maybe
9142 // you don't.
9143 //
9144 // The client can enforce this. I don't think the service cares.
9145 //
9146 // IdAllocatorInterface* id_allocator =
9147 // group_->GetIdAllocator(id_namespaces::kQueries);
9148 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519149 // LOCAL_SET_GL_ERROR(
9150 // GL_INVALID_OPERATION,
9151 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369152 // return error::kNoError;
9153 // }
9154 query = query_manager_->CreateQuery(
9155 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539156 }
9157
[email protected]c45f1972012-03-14 07:27:369158 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519159 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439160 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539161 return error::kNoError;
9162 } else if (query->shm_id() != sync_shm_id ||
9163 query->shm_offset() != sync_shm_offset) {
9164 DLOG(ERROR) << "Shared memory used by query not the same as before";
9165 return error::kInvalidArguments;
9166 }
9167
[email protected]c45f1972012-03-14 07:27:369168 if (!query_manager_->BeginQuery(query)) {
9169 return error::kOutOfBounds;
9170 }
[email protected]882ba1e22012-03-08 19:02:539171
[email protected]e259eb412012-10-13 05:47:249172 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539173 return error::kNoError;
9174}
9175
9176error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359177 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539178 GLenum target = static_cast<GLenum>(c.target);
9179 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9180
[email protected]7cd76fd2013-06-02 21:11:119181 if (!state_.current_query.get()) {
[email protected]ab09b612013-03-11 22:11:519182 LOCAL_SET_GL_ERROR(
9183 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539184 return error::kNoError;
9185 }
[email protected]e259eb412012-10-13 05:47:249186 if (state_.current_query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519187 LOCAL_SET_GL_ERROR(
9188 GL_INVALID_OPERATION,
9189 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539190 return error::kNoError;
9191 }
[email protected]882ba1e22012-03-08 19:02:539192
[email protected]7cd76fd2013-06-02 21:11:119193 if (!query_manager_->EndQuery(state_.current_query.get(), submit_count)) {
[email protected]c45f1972012-03-14 07:27:369194 return error::kOutOfBounds;
9195 }
9196
[email protected]fe8d73c2013-02-16 22:37:329197 query_manager_->ProcessPendingTransferQueries();
9198
[email protected]e259eb412012-10-13 05:47:249199 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539200 return error::kNoError;
9201}
9202
[email protected]944b62f32012-09-27 02:20:469203bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9204 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469205 for (GLsizei ii = 0; ii < n; ++ii) {
9206 if (GetVertexAttribManager(client_ids[ii])) {
9207 return false;
9208 }
9209 }
[email protected]ab4fd7282012-10-12 16:25:579210
[email protected]62e155e2012-10-23 22:43:159211 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579212 // Emulated VAO
9213 for (GLsizei ii = 0; ii < n; ++ii) {
9214 CreateVertexAttribManager(client_ids[ii], 0);
9215 }
9216 } else {
[email protected]40d90a22013-04-09 03:39:559217 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579218
9219 glGenVertexArraysOES(n, service_ids.get());
9220 for (GLsizei ii = 0; ii < n; ++ii) {
9221 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9222 }
[email protected]944b62f32012-09-27 02:20:469223 }
[email protected]ab4fd7282012-10-12 16:25:579224
[email protected]944b62f32012-09-27 02:20:469225 return true;
9226}
9227
9228void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9229 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469230 for (GLsizei ii = 0; ii < n; ++ii) {
9231 VertexAttribManager* vao =
9232 GetVertexAttribManager(client_ids[ii]);
9233 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119234 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]e259eb412012-10-13 05:47:249235 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469236 }
9237 RemoveVertexAttribManager(client_ids[ii]);
9238 }
9239 }
9240}
9241
9242void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469243 VertexAttribManager* vao = NULL;
9244 GLuint service_id = 0;
9245 if (client_id != 0) {
9246 vao = GetVertexAttribManager(client_id);
9247 if (!vao) {
9248 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9249 // only allows names that have been previously generated. As such, we do
9250 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519251 LOCAL_SET_GL_ERROR(
9252 GL_INVALID_OPERATION,
9253 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469254 current_decoder_error_ = error::kNoError;
9255 return;
9256 } else {
9257 service_id = vao->service_id();
9258 }
[email protected]944b62f32012-09-27 02:20:469259 } else {
[email protected]7cd76fd2013-06-02 21:11:119260 vao = default_vertex_attrib_manager_.get();
[email protected]944b62f32012-09-27 02:20:469261 }
9262
[email protected]ab4fd7282012-10-12 16:25:579263 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:119264 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:249265 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159266 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579267 EmulateVertexArrayState();
9268 } else {
9269 glBindVertexArrayOES(service_id);
9270 }
9271 }
9272}
9273
9274// Used when OES_vertex_array_object isn't natively supported
9275void GLES2DecoderImpl::EmulateVertexArrayState() {
9276 // Setup the Vertex attribute state
9277 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9278 RestoreStateForAttrib(vv);
9279 }
9280
9281 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219282 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249283 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579284 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9285 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469286}
9287
9288bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469289 const VertexAttribManager* vao =
9290 GetVertexAttribManager(client_id);
9291 return vao && vao->IsValid() && !vao->IsDeleted();
9292}
9293
[email protected]b0af4f52011-09-28 22:04:429294error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9295 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359296 const cmds::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159297 if (!features().chromium_stream_texture) {
[email protected]ab09b612013-03-11 22:11:519298 LOCAL_SET_GL_ERROR(
9299 GL_INVALID_OPERATION,
9300 "glOpenStreamTextureCHROMIUM", "not supported.");
[email protected]b0af4f52011-09-28 22:04:429301 return error::kNoError;
9302 }
9303
9304 uint32 client_id = c.client_id;
[email protected]ed9f9cd2013-02-27 21:12:359305 typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
[email protected]b0af4f52011-09-28 22:04:429306 Result* result = GetSharedMemoryAs<Result*>(
9307 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9308
[email protected]e5081262012-01-05 23:09:039309 if (!result)
9310 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429311 *result = GL_ZERO;
[email protected]370eaf12013-05-18 09:19:499312 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
9313 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519314 LOCAL_SET_GL_ERROR(
9315 GL_INVALID_VALUE,
9316 "glCreateStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429317 return error::kNoError;
9318 }
9319
[email protected]370eaf12013-05-18 09:19:499320 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079321 if (texture->IsStreamTexture()) {
[email protected]ab09b612013-03-11 22:11:519322 LOCAL_SET_GL_ERROR(
9323 GL_INVALID_OPERATION,
9324 "glCreateStreamTextureCHROMIUM", "is already a stream texture.");
[email protected]b0af4f52011-09-28 22:04:429325 return error::kNoError;
9326 }
9327
[email protected]02965c22013-03-09 02:40:079328 if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:519329 LOCAL_SET_GL_ERROR(
9330 GL_INVALID_OPERATION,
9331 "glCreateStreamTextureCHROMIUM",
9332 "is already bound to incompatible target.");
[email protected]b0af4f52011-09-28 22:04:429333 return error::kNoError;
9334 }
9335
9336 if (!stream_texture_manager_)
9337 return error::kInvalidArguments;
9338
9339 GLuint object_id = stream_texture_manager_->CreateStreamTexture(
[email protected]02965c22013-03-09 02:40:079340 texture->service_id(), client_id);
[email protected]b0af4f52011-09-28 22:04:429341
9342 if (object_id) {
[email protected]370eaf12013-05-18 09:19:499343 texture_manager()->SetStreamTexture(texture_ref, true);
[email protected]b0af4f52011-09-28 22:04:429344 } else {
[email protected]ab09b612013-03-11 22:11:519345 LOCAL_SET_GL_ERROR(
9346 GL_OUT_OF_MEMORY,
9347 "glCreateStreamTextureCHROMIUM", "failed to create platform texture.");
[email protected]b0af4f52011-09-28 22:04:429348 }
9349
9350 *result = object_id;
9351 return error::kNoError;
9352}
9353
9354error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9355 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359356 const cmds::DestroyStreamTextureCHROMIUM& c) {
[email protected]b0af4f52011-09-28 22:04:429357 GLuint client_id = c.texture;
[email protected]370eaf12013-05-18 09:19:499358 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
9359 if (texture_ref && texture_ref->texture()->IsStreamTexture()) {
[email protected]b0af4f52011-09-28 22:04:429360 if (!stream_texture_manager_)
9361 return error::kInvalidArguments;
9362
[email protected]370eaf12013-05-18 09:19:499363 stream_texture_manager_->DestroyStreamTexture(texture_ref->service_id());
9364 texture_manager()->SetStreamTexture(texture_ref, false);
[email protected]b0af4f52011-09-28 22:04:429365 } else {
[email protected]ab09b612013-03-11 22:11:519366 LOCAL_SET_GL_ERROR(
9367 GL_INVALID_VALUE,
9368 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429369 }
9370
9371 return error::kNoError;
9372}
9373
[email protected]e51bdf32011-11-23 22:21:469374#if defined(OS_MACOSX)
9375void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9376 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9377 texture_id);
9378 if (it != texture_to_io_surface_map_.end()) {
9379 // Found a previous IOSurface bound to this texture; release it.
9380 CFTypeRef surface = it->second;
9381 CFRelease(surface);
9382 texture_to_io_surface_map_.erase(it);
9383 }
9384}
9385#endif
9386
9387void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9388 GLenum target, GLsizei width, GLsizei height,
9389 GLuint io_surface_id, GLuint plane) {
9390#if defined(OS_MACOSX)
9391 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519392 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439393 GL_INVALID_OPERATION,
9394 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469395 return;
9396 }
9397
9398 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9399 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519400 LOCAL_SET_GL_ERROR(
9401 GL_INVALID_OPERATION,
9402 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469403 return;
9404 }
9405
9406 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9407 // This might be supported in the future, and if we could require
9408 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9409 // could delete a lot of code. For now, perform strict validation so we
9410 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519411 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469412 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439413 "glTexImageIOSurface2DCHROMIUM",
9414 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469415 return;
9416 }
9417
[email protected]09d50362012-10-18 20:54:379418 // Default target might be conceptually valid, but disallow it to avoid
9419 // accidents.
[email protected]370eaf12013-05-18 09:19:499420 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
9421 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519422 LOCAL_SET_GL_ERROR(
9423 GL_INVALID_OPERATION,
9424 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469425 return;
9426 }
[email protected]e51bdf32011-11-23 22:21:469427
9428 // Look up the new IOSurface. Note that because of asynchrony
9429 // between processes this might fail; during live resizing the
9430 // plugin process might allocate and release an IOSurface before
9431 // this process gets a chance to look it up. Hold on to any old
9432 // IOSurface in this case.
9433 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9434 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519435 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439436 GL_INVALID_OPERATION,
9437 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469438 return;
9439 }
9440
9441 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499442 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469443
9444 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9445 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499446 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469447
9448 CGLContextObj context =
9449 static_cast<CGLContextObj>(context_->GetHandle());
9450
9451 CGLError err = surface_support->CGLTexImageIOSurface2D(
9452 context,
9453 target,
9454 GL_RGBA,
9455 width,
9456 height,
9457 GL_BGRA,
9458 GL_UNSIGNED_INT_8_8_8_8_REV,
9459 surface,
9460 plane);
9461
9462 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519463 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469464 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439465 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469466 return;
9467 }
9468
9469 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499470 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469471 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9472
9473#else
[email protected]ab09b612013-03-11 22:11:519474 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439475 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469476#endif
9477}
9478
[email protected]97dc7cbe2011-12-06 17:26:179479static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9480 switch (internalformat) {
9481 case GL_RGB565:
9482 return GL_RGB;
9483 case GL_RGBA4:
9484 return GL_RGBA;
9485 case GL_RGB5_A1:
9486 return GL_RGBA;
9487 case GL_RGB8_OES:
9488 return GL_RGB;
9489 case GL_RGBA8_OES:
9490 return GL_RGBA;
9491 case GL_LUMINANCE8_ALPHA8_EXT:
9492 return GL_LUMINANCE_ALPHA;
9493 case GL_LUMINANCE8_EXT:
9494 return GL_LUMINANCE;
9495 case GL_ALPHA8_EXT:
9496 return GL_ALPHA;
9497 case GL_RGBA32F_EXT:
9498 return GL_RGBA;
9499 case GL_RGB32F_EXT:
9500 return GL_RGB;
9501 case GL_ALPHA32F_EXT:
9502 return GL_ALPHA;
9503 case GL_LUMINANCE32F_EXT:
9504 return GL_LUMINANCE;
9505 case GL_LUMINANCE_ALPHA32F_EXT:
9506 return GL_LUMINANCE_ALPHA;
9507 case GL_RGBA16F_EXT:
9508 return GL_RGBA;
9509 case GL_RGB16F_EXT:
9510 return GL_RGB;
9511 case GL_ALPHA16F_EXT:
9512 return GL_ALPHA;
9513 case GL_LUMINANCE16F_EXT:
9514 return GL_LUMINANCE;
9515 case GL_LUMINANCE_ALPHA16F_EXT:
9516 return GL_LUMINANCE_ALPHA;
9517 case GL_BGRA8_EXT:
9518 return GL_BGRA_EXT;
9519 default:
9520 return GL_NONE;
9521 }
9522}
9523
[email protected]43410e92012-04-20 17:06:289524void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039525 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549526 GLenum internal_format, GLenum dest_type) {
[email protected]370eaf12013-05-18 09:19:499527 TextureRef* dest_texture_ref = GetTexture(dest_id);
9528 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289529
[email protected]370eaf12013-05-18 09:19:499530 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519531 LOCAL_SET_GL_ERROR(
9532 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289533 return;
9534 }
9535
9536 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519537 LOCAL_SET_GL_ERROR(
9538 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289539 return;
9540 }
9541
[email protected]370eaf12013-05-18 09:19:499542 Texture* source_texture = source_texture_ref->texture();
9543 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079544 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259545 (source_texture->target() != GL_TEXTURE_2D &&
9546 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]ab09b612013-03-11 22:11:519547 LOCAL_SET_GL_ERROR(
9548 GL_INVALID_VALUE,
9549 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039550 return;
9551 }
9552
[email protected]43410e92012-04-20 17:06:289553 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289554
[email protected]9bc9a2e82013-04-03 03:56:259555 if (source_texture->target() == GL_TEXTURE_2D) {
9556 if (!source_texture->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
9557 &source_height)) {
9558 LOCAL_SET_GL_ERROR(
9559 GL_INVALID_VALUE,
9560 "glCopyTextureChromium", "source texture has no level 0");
9561 return;
9562 }
9563
9564 // Check that this type of texture is allowed.
9565 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
9566 source_height, 1)) {
9567 LOCAL_SET_GL_ERROR(
9568 GL_INVALID_VALUE,
9569 "glCopyTextureCHROMIUM", "Bad dimensions");
9570 return;
9571 }
[email protected]43410e92012-04-20 17:06:289572 }
9573
[email protected]377976552013-05-14 23:32:569574 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9575 DCHECK(stream_texture_manager_);
9576 StreamTexture* stream_tex =
9577 stream_texture_manager_->LookupStreamTexture(
9578 source_texture->service_id());
9579 if (!stream_tex) {
9580 LOCAL_SET_GL_ERROR(
9581 GL_INVALID_VALUE,
9582 "glCopyTextureChromium", "Stream texture lookup failed");
9583 return;
9584 }
9585 gfx::Size size = stream_tex->GetSize();
9586 source_width = size.width();
9587 source_height = size.height();
9588 if (source_width <= 0 || source_height <= 0) {
9589 LOCAL_SET_GL_ERROR(
9590 GL_INVALID_VALUE,
9591 "glCopyTextureChromium", "invalid streamtexture size");
9592 return;
9593 }
9594 }
9595
[email protected]cf6b8f62012-05-25 21:43:379596 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9597 // needed because it takes 10s of milliseconds to initialize.
9598 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519599 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379600 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279601 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379602 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519603 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379604 return;
9605 }
9606
[email protected]a4a6bdd12013-04-19 20:46:549607 GLenum dest_type_previous;
[email protected]0a1e9ad2012-05-04 21:13:039608 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079609 bool dest_level_defined = dest_texture->GetLevelSize(
9610 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289611
[email protected]0a1e9ad2012-05-04 21:13:039612 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:549613 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:079614 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039615 }
9616
9617 // Resize the destination texture to the dimensions of the source texture.
9618 if (!dest_level_defined || dest_width != source_width ||
9619 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:549620 dest_internal_format != internal_format ||
9621 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:289622 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519623 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079624 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:389625 glTexImage2D(
[email protected]43410e92012-04-20 17:06:289626 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039627 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519628 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039629 if (error != GL_NO_ERROR) {
9630 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289631 return;
[email protected]0a1e9ad2012-05-04 21:13:039632 }
[email protected]43410e92012-04-20 17:06:289633
9634 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499635 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039636 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259637 } else {
[email protected]02965c22013-03-09 02:40:079638 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:499639 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289640 }
9641
[email protected]5394a4102013-04-18 05:41:379642 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9643 // before presenting.
9644 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9645 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9646 // instead of using default matrix crbug.com/226218.
9647 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9648 0.0f, 1.0f, 0.0f, 0.0f,
9649 0.0f, 0.0f, 1.0f, 0.0f,
9650 0.0f, 0.0f, 0.0f, 1.0f};
9651 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9652 this,
9653 source_texture->target(),
9654 dest_texture->target(),
9655 source_texture->service_id(),
9656 dest_texture->service_id(), level,
9657 source_width, source_height,
9658 unpack_flip_y_,
9659 unpack_premultiply_alpha_,
9660 unpack_unpremultiply_alpha_,
9661 default_matrix);
9662 } else {
9663 copy_texture_CHROMIUM_->DoCopyTexture(
9664 this,
9665 source_texture->target(),
9666 dest_texture->target(),
9667 source_texture->service_id(),
9668 dest_texture->service_id(), level,
9669 source_width, source_height,
9670 unpack_flip_y_,
9671 unpack_premultiply_alpha_,
9672 unpack_unpremultiply_alpha_);
9673 }
[email protected]43410e92012-04-20 17:06:289674}
9675
[email protected]97dc7cbe2011-12-06 17:26:179676static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9677 switch (internalformat) {
9678 case GL_RGB565:
9679 return GL_UNSIGNED_SHORT_5_6_5;
9680 case GL_RGBA4:
9681 return GL_UNSIGNED_SHORT_4_4_4_4;
9682 case GL_RGB5_A1:
9683 return GL_UNSIGNED_SHORT_5_5_5_1;
9684 case GL_RGB8_OES:
9685 return GL_UNSIGNED_BYTE;
9686 case GL_RGBA8_OES:
9687 return GL_UNSIGNED_BYTE;
9688 case GL_LUMINANCE8_ALPHA8_EXT:
9689 return GL_UNSIGNED_BYTE;
9690 case GL_LUMINANCE8_EXT:
9691 return GL_UNSIGNED_BYTE;
9692 case GL_ALPHA8_EXT:
9693 return GL_UNSIGNED_BYTE;
9694 case GL_RGBA32F_EXT:
9695 return GL_FLOAT;
9696 case GL_RGB32F_EXT:
9697 return GL_FLOAT;
9698 case GL_ALPHA32F_EXT:
9699 return GL_FLOAT;
9700 case GL_LUMINANCE32F_EXT:
9701 return GL_FLOAT;
9702 case GL_LUMINANCE_ALPHA32F_EXT:
9703 return GL_FLOAT;
9704 case GL_RGBA16F_EXT:
9705 return GL_HALF_FLOAT_OES;
9706 case GL_RGB16F_EXT:
9707 return GL_HALF_FLOAT_OES;
9708 case GL_ALPHA16F_EXT:
9709 return GL_HALF_FLOAT_OES;
9710 case GL_LUMINANCE16F_EXT:
9711 return GL_HALF_FLOAT_OES;
9712 case GL_LUMINANCE_ALPHA16F_EXT:
9713 return GL_HALF_FLOAT_OES;
9714 case GL_BGRA8_EXT:
9715 return GL_UNSIGNED_BYTE;
9716 default:
9717 return GL_NONE;
9718 }
9719}
9720
9721void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449722 GLenum target,
9723 GLint levels,
9724 GLenum internal_format,
9725 GLsizei width,
9726 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389727 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419728 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179729 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:519730 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439731 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179732 return;
9733 }
[email protected]370eaf12013-05-18 09:19:499734 TextureRef* texture_ref = GetTextureInfoForTarget(target);
9735 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519736 LOCAL_SET_GL_ERROR(
9737 GL_INVALID_OPERATION,
9738 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179739 return;
9740 }
[email protected]370eaf12013-05-18 09:19:499741 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079742 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:429743 clear_state_dirty_ = true;
[email protected]97dc7cbe2011-12-06 17:26:179744 }
[email protected]02965c22013-03-09 02:40:079745 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519746 LOCAL_SET_GL_ERROR(
9747 GL_INVALID_OPERATION,
9748 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179749 return;
9750 }
[email protected]7989c9e2013-01-23 06:39:269751
9752 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9753 GLenum type = ExtractTypeFromStorageFormat(internal_format);
9754
9755 {
9756 GLsizei level_width = width;
9757 GLsizei level_height = height;
9758 uint32 estimated_size = 0;
9759 for (int ii = 0; ii < levels; ++ii) {
9760 uint32 level_size = 0;
9761 if (!GLES2Util::ComputeImageDataSizes(
9762 level_width, level_height, format, type, state_.unpack_alignment,
9763 &estimated_size, NULL, NULL) ||
9764 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519765 LOCAL_SET_GL_ERROR(
9766 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269767 return;
9768 }
9769 level_width = std::max(1, level_width >> 1);
9770 level_height = std::max(1, level_height >> 1);
9771 }
9772 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519773 LOCAL_SET_GL_ERROR(
9774 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269775 return;
9776 }
9777 }
9778
[email protected]ab09b612013-03-11 22:11:519779 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:389780 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:519781 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:179782 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:159783 GLsizei level_width = width;
9784 GLsizei level_height = height;
9785 for (int ii = 0; ii < levels; ++ii) {
9786 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499787 texture_ref, target, ii, format,
9788 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:159789 level_width = std::max(1, level_width >> 1);
9790 level_height = std::max(1, level_height >> 1);
9791 }
[email protected]02965c22013-03-09 02:40:079792 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:179793 }
[email protected]97dc7cbe2011-12-06 17:26:179794}
[email protected]e51bdf32011-11-23 22:21:469795
[email protected]78b514b2012-05-01 21:50:599796error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359797 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]78b514b2012-05-01 21:50:599798 MailboxName name;
9799 mailbox_manager()->GenerateMailboxName(&name);
9800 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
9801 Bucket* bucket = CreateBucket(bucket_id);
9802
9803 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
9804 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
9805
9806 return error::kNoError;
9807}
9808
9809void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9810 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029811 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329812 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029813 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9814
[email protected]370eaf12013-05-18 09:19:499815 TextureRef* texture_ref = GetTextureInfoForTarget(target);
9816 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519817 LOCAL_SET_GL_ERROR(
9818 GL_INVALID_OPERATION,
9819 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599820 return;
9821 }
9822
[email protected]62e65f02013-05-29 22:28:109823 Texture* produced = texture_manager()->Produce(texture_ref);
9824 if (!produced) {
[email protected]ab09b612013-03-11 22:11:519825 LOCAL_SET_GL_ERROR(
9826 GL_INVALID_OPERATION,
9827 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599828 return;
9829 }
9830
9831 if (!group_->mailbox_manager()->ProduceTexture(
9832 target,
9833 *reinterpret_cast<const MailboxName*>(mailbox),
[email protected]62e65f02013-05-29 22:28:109834 produced)) {
[email protected]ab09b612013-03-11 22:11:519835 LOCAL_SET_GL_ERROR(
9836 GL_INVALID_OPERATION,
9837 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599838 return;
9839 }
[email protected]78b514b2012-05-01 21:50:599840}
9841
9842void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9843 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029844 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329845 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029846 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9847
[email protected]62e65f02013-05-29 22:28:109848 scoped_refptr<TextureRef> texture_ref =
9849 GetTextureInfoForTargetUnlessDefault(target);
[email protected]7cd76fd2013-06-02 21:11:119850 if (!texture_ref.get()) {
9851 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9852 "glConsumeTextureCHROMIUM",
9853 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599854 return;
9855 }
[email protected]62e65f02013-05-29 22:28:109856 GLuint client_id = texture_ref->client_id();
9857 if (!client_id) {
9858 LOCAL_SET_GL_ERROR(
9859 GL_INVALID_OPERATION,
9860 "glConsumeTextureCHROMIUM", "unknown texture for target");
9861 return;
9862 }
9863 Texture* texture =
[email protected]78b514b2012-05-01 21:50:599864 group_->mailbox_manager()->ConsumeTexture(
9865 target,
[email protected]62e65f02013-05-29 22:28:109866 *reinterpret_cast<const MailboxName*>(mailbox));
9867 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519868 LOCAL_SET_GL_ERROR(
9869 GL_INVALID_OPERATION,
9870 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599871 return;
9872 }
[email protected]62e65f02013-05-29 22:28:109873 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:519874 LOCAL_SET_GL_ERROR(
9875 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:109876 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:599877 return;
9878 }
[email protected]62e65f02013-05-29 22:28:109879
9880 DeleteTexturesHelper(1, &client_id);
9881 texture_ref = texture_manager()->Consume(client_id, texture);
9882 glBindTexture(target, texture_ref->service_id());
9883
9884 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
9885 unit.bind_target = target;
9886 switch (target) {
9887 case GL_TEXTURE_2D:
9888 unit.bound_texture_2d = texture_ref;
9889 break;
9890 case GL_TEXTURE_CUBE_MAP:
9891 unit.bound_texture_cube_map = texture_ref;
9892 break;
9893 case GL_TEXTURE_EXTERNAL_OES:
9894 unit.bound_texture_external_oes = texture_ref;
9895 break;
9896 case GL_TEXTURE_RECTANGLE_ARB:
9897 unit.bound_texture_rectangle_arb = texture_ref;
9898 break;
9899 default:
9900 NOTREACHED(); // Validation should prevent us getting here.
9901 break;
9902 }
[email protected]78b514b2012-05-01 21:50:599903}
9904
[email protected]d2a0e1a2012-08-12 02:25:019905void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9906 GLsizei length, const GLchar* marker) {
9907 if (!marker) {
9908 marker = "";
9909 }
9910 debug_marker_manager_.SetMarker(
9911 length ? std::string(marker, length) : std::string(marker));
9912}
9913
9914void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9915 GLsizei length, const GLchar* marker) {
9916 if (!marker) {
9917 marker = "";
9918 }
9919 debug_marker_manager_.PushGroup(
9920 length ? std::string(marker, length) : std::string(marker));
9921}
9922
9923void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9924 debug_marker_manager_.PopGroup();
9925}
9926
[email protected]09d50362012-10-18 20:54:379927void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9928 GLenum target, GLint image_id) {
9929 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9930 if (target != GL_TEXTURE_2D) {
9931 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:519932 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:379933 GL_INVALID_OPERATION,
9934 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9935 return;
9936 }
9937
9938 // Default target might be conceptually valid, but disallow it to avoid
9939 // accidents.
[email protected]370eaf12013-05-18 09:19:499940 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
9941 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519942 LOCAL_SET_GL_ERROR(
9943 GL_INVALID_OPERATION,
9944 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:379945 return;
9946 }
9947
9948 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9949 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:519950 LOCAL_SET_GL_ERROR(
9951 GL_INVALID_OPERATION,
9952 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:379953 return;
9954 }
9955
[email protected]b8160812013-04-09 00:41:049956 {
9957 ScopedGLErrorSuppressor suppressor(
9958 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", this);
9959 if (!gl_image->BindTexImage()) {
9960 LOCAL_SET_GL_ERROR(
9961 GL_INVALID_OPERATION,
9962 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
9963 return;
9964 }
[email protected]09d50362012-10-18 20:54:379965 }
9966
9967 gfx::Size size = gl_image->GetSize();
9968 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499969 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:379970 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:499971 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:379972}
9973
9974void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
9975 GLenum target, GLint image_id) {
9976 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
9977 if (target != GL_TEXTURE_2D) {
9978 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:519979 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:379980 GL_INVALID_OPERATION,
9981 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9982 return;
9983 }
9984
9985 // Default target might be conceptually valid, but disallow it to avoid
9986 // accidents.
[email protected]370eaf12013-05-18 09:19:499987 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
9988 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519989 LOCAL_SET_GL_ERROR(
9990 GL_INVALID_OPERATION,
9991 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:379992 return;
9993 }
9994
9995 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9996 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:519997 LOCAL_SET_GL_ERROR(
9998 GL_INVALID_OPERATION,
9999 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710000 return;
10001 }
10002
10003 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910004 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710005 return;
10006
[email protected]b8160812013-04-09 00:41:0410007 {
10008 ScopedGLErrorSuppressor suppressor(
10009 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", this);
10010 gl_image->ReleaseTexImage();
10011 }
[email protected]09d50362012-10-18 20:54:3710012
10013 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910014 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710015 GL_RGBA, GL_UNSIGNED_BYTE, false);
10016}
[email protected]d2a0e1a2012-08-12 02:25:0110017
[email protected]94307712012-11-16 23:26:1110018error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510019 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110020 Bucket* bucket = GetBucket(c.bucket_id);
10021 if (!bucket || bucket->size() == 0) {
10022 return error::kInvalidArguments;
10023 }
10024 std::string command_name;
10025 if (!bucket->GetAsString(&command_name)) {
10026 return error::kInvalidArguments;
10027 }
[email protected]fb97b662013-02-20 23:02:1410028 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
10029 if (!gpu_tracer_->Begin(command_name)) {
[email protected]ab09b612013-03-11 22:11:5110030 LOCAL_SET_GL_ERROR(
10031 GL_INVALID_OPERATION,
10032 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410033 return error::kNoError;
10034 }
[email protected]94307712012-11-16 23:26:1110035 return error::kNoError;
10036}
10037
10038void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410039 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110040 LOCAL_SET_GL_ERROR(
10041 GL_INVALID_OPERATION,
10042 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110043 return;
10044 }
[email protected]fb97b662013-02-20 23:02:1410045 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
10046 gpu_tracer_->End();
[email protected]94307712012-11-16 23:26:1110047}
10048
[email protected]2f143d482013-03-14 18:04:4910049void GLES2DecoderImpl::DoDrawBuffersEXT(
10050 GLsizei count, const GLenum* bufs) {
10051 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10052 LOCAL_SET_GL_ERROR(
10053 GL_INVALID_VALUE,
10054 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10055 return;
10056 }
10057
10058 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10059 if (framebuffer) {
10060 for (GLsizei i = 0; i < count; ++i) {
10061 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10062 bufs[i] != GL_NONE) {
10063 LOCAL_SET_GL_ERROR(
10064 GL_INVALID_OPERATION,
10065 "glDrawBuffersEXT",
10066 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10067 return;
10068 }
10069 }
10070 glDrawBuffersARB(count, bufs);
10071 framebuffer->SetDrawBuffers(count, bufs);
10072 } else { // backbuffer
10073 if (count > 1 ||
10074 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10075 LOCAL_SET_GL_ERROR(
10076 GL_INVALID_OPERATION,
10077 "glDrawBuffersEXT",
10078 "more than one buffer or bufs not GL_NONE or GL_BACK");
10079 return;
10080 }
10081 GLenum mapped_buf = bufs[0];
10082 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10083 bufs[0] == GL_BACK) {
10084 mapped_buf = GL_COLOR_ATTACHMENT0;
10085 }
10086 glDrawBuffersARB(count, &mapped_buf);
10087 group_->set_draw_buffer(bufs[0]);
10088 }
10089}
10090
[email protected]32145a92012-12-17 09:01:5910091bool GLES2DecoderImpl::ValidateAsyncTransfer(
10092 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710093 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910094 GLenum target,
10095 GLint level,
10096 const void * data) {
10097 // We only support async uploads to 2D textures for now.
10098 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110099 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910100 return false;
10101 }
10102 // We only support uploads to level zero for now.
10103 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110104 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910105 return false;
10106 }
10107 // A transfer buffer must be bound, even for asyncTexImage2D.
10108 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110109 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910110 return false;
10111 }
10112 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710113 if (!texture_ref ||
10114 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110115 LOCAL_SET_GL_ERROR(
10116 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910117 function_name, "transfer already in progress");
10118 return false;
10119 }
10120 return true;
10121}
10122
[email protected]69023942012-11-30 19:57:1610123error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510124 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610125 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610126 GLenum target = static_cast<GLenum>(c.target);
10127 GLint level = static_cast<GLint>(c.level);
10128 GLint internal_format = static_cast<GLint>(c.internalformat);
10129 GLsizei width = static_cast<GLsizei>(c.width);
10130 GLsizei height = static_cast<GLsizei>(c.height);
10131 GLint border = static_cast<GLint>(c.border);
10132 GLenum format = static_cast<GLenum>(c.format);
10133 GLenum type = static_cast<GLenum>(c.type);
10134 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10135 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10136 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910137
10138 // TODO(epenner): Move this and copies of this memory validation
10139 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610140 if (!GLES2Util::ComputeImageDataSizes(
10141 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10142 NULL)) {
10143 return error::kOutOfBounds;
10144 }
10145 const void* pixels = NULL;
10146 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10147 pixels = GetSharedMemoryAs<const void*>(
10148 pixels_shm_id, pixels_shm_offset, pixels_size);
10149 if (!pixels) {
10150 return error::kOutOfBounds;
10151 }
10152 }
10153
[email protected]32145a92012-12-17 09:01:5910154 // All the normal glTexSubImage2D validation.
10155 if (!ValidateTexImage2D(
10156 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
10157 width, height, border, format, type, pixels, pixels_size)) {
10158 return error::kNoError;
10159 }
10160
10161 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910162 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10163 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910164 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710165 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910166 return error::kNoError;
10167
10168 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710169 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110170 LOCAL_SET_GL_ERROR(
10171 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910172 "glAsyncTexImage2DCHROMIUM", "already defined");
10173 return error::kNoError;
10174 }
10175
[email protected]7989c9e2013-01-23 06:39:2610176 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110177 LOCAL_SET_GL_ERROR(
10178 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610179 return error::kNoError;
10180 }
10181
[email protected]32145a92012-12-17 09:01:5910182 // We know the memory/size is safe, so get the real shared memory since
10183 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110184 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910185 base::SharedMemory* shared_memory = buffer.shared_memory;
10186 uint32 shm_size = buffer.size;
10187 uint32 shm_data_offset = c.pixels_shm_offset;
10188 uint32 shm_data_size = pixels_size;
10189
[email protected]5b3a8e02013-03-13 05:36:4410190 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810191 AsyncTexImage2DParams tex_params = {
10192 target, level, static_cast<GLenum>(internal_format),
10193 width, height, border, format, type};
10194 AsyncMemoryParams mem_params = {
10195 shared_memory, shm_size, shm_data_offset, shm_data_size};
[email protected]32145a92012-12-17 09:01:5910196
[email protected]5b3a8e02013-03-13 05:36:4410197 // Set up the async state if needed, and make the texture
10198 // immutable so the async state stays valid. The level info
10199 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1810200 AsyncPixelTransferDelegate* delegate =
10201 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
10202 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4410203 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910204
[email protected]896425e2013-06-12 17:27:1810205 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410206 tex_params,
10207 mem_params,
10208 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910209 // The callback is only invoked if the transfer delegate still
10210 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410211 // ownership that both of these pointers are valid.
10212 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910213 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410214 tex_params));
[email protected]f598f422012-12-07 08:30:0310215 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610216}
10217
10218error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510219 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610220 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610221 GLenum target = static_cast<GLenum>(c.target);
10222 GLint level = static_cast<GLint>(c.level);
10223 GLint xoffset = static_cast<GLint>(c.xoffset);
10224 GLint yoffset = static_cast<GLint>(c.yoffset);
10225 GLsizei width = static_cast<GLsizei>(c.width);
10226 GLsizei height = static_cast<GLsizei>(c.height);
10227 GLenum format = static_cast<GLenum>(c.format);
10228 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910229
10230 // TODO(epenner): Move this and copies of this memory validation
10231 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610232 uint32 data_size;
10233 if (!GLES2Util::ComputeImageDataSizes(
10234 width, height, format, type, state_.unpack_alignment, &data_size,
10235 NULL, NULL)) {
10236 return error::kOutOfBounds;
10237 }
10238 const void* pixels = GetSharedMemoryAs<const void*>(
10239 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910240
10241 // All the normal glTexSubImage2D validation.
10242 error::Error error = error::kNoError;
10243 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10244 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10245 return error;
[email protected]69023942012-11-30 19:57:1610246 }
10247
[email protected]32145a92012-12-17 09:01:5910248 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910249 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10250 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910251 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710252 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910253 return error::kNoError;
10254
10255 // Guarantee async textures are always 'cleared' as follows:
10256 // - AsyncTexImage2D can not redefine an existing texture
10257 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10258 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10259 // - Textures become immutable after an async call.
10260 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710261 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910262 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10263 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110264 LOCAL_SET_GL_ERROR(
10265 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510266 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910267 return error::kNoError;
10268 }
10269 }
10270
10271 // We know the memory/size is safe, so get the real shared memory since
10272 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110273 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910274 base::SharedMemory* shared_memory = buffer.shared_memory;
10275 uint32 shm_size = buffer.size;
10276 uint32 shm_data_offset = c.data_shm_offset;
10277 uint32 shm_data_size = data_size;
10278
[email protected]5b3a8e02013-03-13 05:36:4410279 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310280 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910281 width, height, format, type};
[email protected]2a7568a2013-05-09 23:12:0310282 AsyncMemoryParams mem_params = {shared_memory, shm_size,
[email protected]32145a92012-12-17 09:01:5910283 shm_data_offset, shm_data_size};
[email protected]896425e2013-06-12 17:27:1810284 AsyncPixelTransferDelegate* delegate =
10285 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10286 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4410287 // TODO(epenner): We may want to enforce exclusive use
10288 // of async APIs in which case this should become an error,
10289 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310290 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410291 0, 0, 0, 0, 0, 0};
10292 texture->GetLevelSize(target, level, &define_params.width,
10293 &define_params.height);
10294 texture->GetLevelType(target, level, &define_params.type,
10295 &define_params.internal_format);
10296 // Set up the async state if needed, and make the texture
10297 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1810298 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4710299 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4410300 texture->SetImmutable(true);
10301 }
10302
[email protected]896425e2013-06-12 17:27:1810303 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910304 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610305}
10306
[email protected]a00c1f742013-03-05 17:02:1610307error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10308 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10309 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10310 GLenum target = static_cast<GLenum>(c.target);
10311
10312 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110313 LOCAL_SET_GL_ERROR(
10314 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610315 return error::kNoError;
10316 }
[email protected]370eaf12013-05-18 09:19:4910317 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10318 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110319 LOCAL_SET_GL_ERROR(
10320 GL_INVALID_OPERATION,
10321 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610322 return error::kNoError;
10323 }
[email protected]896425e2013-06-12 17:27:1810324 AsyncPixelTransferDelegate* delegate =
10325 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10326 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4910327 LOCAL_SET_GL_ERROR(
10328 GL_INVALID_OPERATION,
10329 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10330 return error::kNoError;
10331 }
[email protected]896425e2013-06-12 17:27:1810332 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0910333 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610334 return error::kNoError;
10335}
10336
[email protected]96449d2c2009-11-25 00:01:3210337// Include the auto-generated part of this file. We split this because it means
10338// we can easily edit the non-auto generated parts right here in this file
10339// instead of having to edit some template or the code generator.
10340#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10341
10342} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510343} // namespace gpu