blob: 3c49a73b45258d6fbd5b9447aaba6c7748500bd6 [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]423e644f2013-06-19 00:48:2765
[email protected]e51bdf32011-11-23 22:21:4666#if defined(OS_MACOSX)
[email protected]423e644f2013-06-19 00:48:2767#include "ui/gl/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4668#endif
[email protected]de17df392010-04-23 21:09:4169
[email protected]693ca512012-11-13 18:09:1370// TODO(zmo): we can't include "City.h" due to type def conflicts.
71extern uint64 CityHash64(const char*, size_t);
72
[email protected]a7a27ace2009-12-12 00:11:2573namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3274namespace gles2 {
75
[email protected]f0d74742011-10-03 16:31:0476namespace {
[email protected]693ca512012-11-13 18:09:1377
[email protected]f0d74742011-10-03 16:31:0478static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4979static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1380static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]693ca512012-11-13 18:09:1381
[email protected]3d944a82013-02-12 19:09:0282#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]693ca512012-11-13 18:09:1383khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
84 return static_cast<khronos_uint64_t>(
85 CityHash64(name, static_cast<size_t>(len)));
86}
[email protected]3d944a82013-02-12 19:09:0287#endif
[email protected]693ca512012-11-13 18:09:1388
[email protected]448e459e2013-06-12 17:00:4189static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
90 GLint rangeMax,
91 GLint precision) {
92 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
93}
94
[email protected]8dc1bf92013-03-12 03:58:2195static void GetShaderPrecisionFormatImpl(GLenum shader_type,
96 GLenum precision_type,
97 GLint *range, GLint *precision) {
98 switch (precision_type) {
99 case GL_LOW_INT:
100 case GL_MEDIUM_INT:
101 case GL_HIGH_INT:
102 // These values are for a 32-bit twos-complement integer format.
103 range[0] = 31;
104 range[1] = 30;
105 *precision = 0;
106 break;
107 case GL_LOW_FLOAT:
108 case GL_MEDIUM_FLOAT:
109 case GL_HIGH_FLOAT:
110 // These values are for an IEEE single-precision floating-point format.
111 range[0] = 127;
112 range[1] = 127;
113 *precision = 23;
114 break;
115 default:
116 NOTREACHED();
117 break;
118 }
119
[email protected]8af4d5e2013-03-15 23:55:33120 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
121 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21122 // This function is sometimes defined even though it's really just
123 // a stub, so we need to set range and precision as if it weren't
124 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44125 // On Mac OS with some GPUs, calling this generates a
126 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
127 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21128 glGetShaderPrecisionFormat(shader_type, precision_type,
129 range, precision);
[email protected]448e459e2013-06-12 17:00:41130
131 // TODO(brianderson): Make the following official workarounds.
132
133 // Some drivers have bugs where they report the ranges as a negative number.
134 // Taking the absolute value here shouldn't hurt because negative numbers
135 // aren't expected anyway.
136 range[0] = abs(range[0]);
137 range[1] = abs(range[1]);
138
139 // If the driver reports a precision for highp float that isn't actually
140 // highp, don't pretend like it's supported because shader compilation will
141 // fail anyway.
142 if (precision_type == GL_HIGH_FLOAT &&
143 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
144 range[0] = 0;
145 range[1] = 0;
146 *precision = 0;
147 }
[email protected]8dc1bf92013-03-12 03:58:21148 }
149}
150
[email protected]b04e24c2013-01-08 18:35:25151} // namespace
[email protected]f0d74742011-10-03 16:31:04152
[email protected]6217d392010-03-25 22:08:35153class GLES2DecoderImpl;
154
[email protected]ab09b612013-03-11 22:11:51155// Local versions of the SET_GL_ERROR macros
156#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50157 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51158#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50159 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
160 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51161#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50162 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
163 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51164#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50165 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
166 function_name)
[email protected]ab09b612013-03-11 22:11:51167#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50168 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51169#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50170 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51171#define LOCAL_PERFORMANCE_WARNING(msg) \
172 PerformanceWarning(__FILE__, __LINE__, msg)
173#define LOCAL_RENDER_WARNING(msg) \
174 RenderWarning(__FILE__, __LINE__, msg)
175
[email protected]07f54fcc2009-12-22 02:46:30176// Check that certain assumptions the code makes are true. There are places in
177// the code where shared memory is passed direclty to GL. Example, glUniformiv,
178// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
179// a few others) are 32bits. If they are not 32bits the code will have to change
180// to call those GL functions with service side memory and then copy the results
181// to shared memory, converting the sizes.
182COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
183 GLint_not_same_size_as_uint32);
184COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
185 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37186COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
187 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30188
[email protected]43f28f832010-02-03 02:28:48189// TODO(kbr): the use of this anonymous namespace core dumps the
190// linker on Mac OS X 10.6 when the symbol ordering file is used
191// namespace {
[email protected]96449d2c2009-11-25 00:01:32192
193// Returns the address of the first byte after a struct.
194template <typename T>
195const void* AddressAfterStruct(const T& pod) {
196 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
197}
198
[email protected]07f54fcc2009-12-22 02:46:30199// Returns the address of the frst byte after the struct or NULL if size >
200// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32201template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30202RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
203 uint32 size,
204 uint32 immediate_data_size) {
205 return (size <= immediate_data_size) ?
206 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
207 NULL;
[email protected]96449d2c2009-11-25 00:01:32208}
209
[email protected]07f54fcc2009-12-22 02:46:30210// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18211bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32212 GLuint count,
213 size_t size,
[email protected]a76b0052010-03-05 00:33:18214 unsigned int elements_per_unit,
215 uint32* dst) {
216 uint32 value;
217 if (!SafeMultiplyUint32(count, size, &value)) {
218 return false;
219 }
220 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
221 return false;
222 }
223 *dst = value;
224 return true;
[email protected]96449d2c2009-11-25 00:01:32225}
226
227// A struct to hold info about each command.
228struct CommandInfo {
229 int arg_flags; // How to handle the arguments for this command
230 int arg_count; // How many arguments are expected for this command.
231};
232
233// A table of CommandInfo for all the commands.
234const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35235 #define GLES2_CMD_OP(name) { \
236 cmds::name::kArgFlags, \
237 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
[email protected]96449d2c2009-11-25 00:01:32238
239 GLES2_COMMAND_LIST(GLES2_CMD_OP)
240
241 #undef GLES2_CMD_OP
242};
243
[email protected]258a3313f2011-10-18 20:13:57244// Return true if a character belongs to the ASCII subset as defined in
245// GLSL ES 1.0 spec section 3.1.
246static bool CharacterIsValidForGLES(unsigned char c) {
247 // Printing characters are valid except " $ ` @ \ ' DEL.
248 if (c >= 32 && c <= 126 &&
249 c != '"' &&
250 c != '$' &&
251 c != '`' &&
252 c != '@' &&
253 c != '\\' &&
254 c != '\'') {
255 return true;
256 }
257 // Horizontal tab, line feed, vertical tab, form feed, carriage return
258 // are also valid.
259 if (c >= 9 && c <= 13) {
260 return true;
261 }
262
263 return false;
264}
265
266static bool StringIsValidForGLES(const char* str) {
267 for (; *str; ++str) {
268 if (!CharacterIsValidForGLES(*str)) {
269 return false;
270 }
271 }
272 return true;
273}
274
[email protected]297ca1c2011-06-20 23:08:46275// Wrapper for glEnable/glDisable that doesn't suck.
276static void EnableDisable(GLenum pname, bool enable) {
277 if (enable) {
278 glEnable(pname);
279 } else {
280 glDisable(pname);
281 }
282}
283
[email protected]6217d392010-03-25 22:08:35284// This class prevents any GL errors that occur when it is in scope from
285// being reported to the client.
286class ScopedGLErrorSuppressor {
287 public:
[email protected]ab09b612013-03-11 22:11:51288 explicit ScopedGLErrorSuppressor(
289 const char* function_name, GLES2DecoderImpl* decoder);
[email protected]6217d392010-03-25 22:08:35290 ~ScopedGLErrorSuppressor();
291 private:
[email protected]ab09b612013-03-11 22:11:51292 const char* function_name_;
[email protected]6217d392010-03-25 22:08:35293 GLES2DecoderImpl* decoder_;
294 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
295};
296
297// Temporarily changes a decoder's bound 2D texture and restore it when this
298// object goes out of scope. Also temporarily switches to using active texture
299// unit zero in case the client has changed that to something invalid.
300class ScopedTexture2DBinder {
301 public:
302 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
303 ~ScopedTexture2DBinder();
304
305 private:
306 GLES2DecoderImpl* decoder_;
307 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
308};
309
310// Temporarily changes a decoder's bound render buffer and restore it when this
311// object goes out of scope.
312class ScopedRenderBufferBinder {
313 public:
314 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
315 ~ScopedRenderBufferBinder();
316
317 private:
318 GLES2DecoderImpl* decoder_;
319 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
320};
321
322// Temporarily changes a decoder's bound frame buffer and restore it when this
323// object goes out of scope.
324class ScopedFrameBufferBinder {
325 public:
326 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
327 ~ScopedFrameBufferBinder();
328
329 private:
330 GLES2DecoderImpl* decoder_;
331 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
332};
333
[email protected]34ff8b0c2010-10-01 20:06:02334// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52335// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27336// if it is bound or enforce_internal_framebuffer is true. If internal is
337// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02338class ScopedResolvedFrameBufferBinder {
339 public:
[email protected]e7e38032011-07-26 17:25:25340 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27341 bool enforce_internal_framebuffer,
342 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02343 ~ScopedResolvedFrameBufferBinder();
344
345 private:
346 GLES2DecoderImpl* decoder_;
347 bool resolve_and_bind_;
348 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
349};
350
[email protected]63b465922012-09-06 02:04:52351// This class records texture upload time when in scope.
352class ScopedTextureUploadTimer {
353 public:
354 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder);
355 ~ScopedTextureUploadTimer();
356
357 private:
358 GLES2DecoderImpl* decoder_;
359 base::TimeTicks begin_time_;
360 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer);
361};
362
[email protected]6217d392010-03-25 22:08:35363// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35364class BackTexture {
[email protected]6217d392010-03-25 22:08:35365 public:
[email protected]ed9f9cd2013-02-27 21:12:35366 explicit BackTexture(GLES2DecoderImpl* decoder);
367 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35368
369 // Create a new render texture.
370 void Create();
371
372 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09373 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35374
375 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58376 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35377
378 // Destroy the render texture. This must be explicitly called before
379 // destroying this object.
380 void Destroy();
381
[email protected]97872062010-11-03 19:07:05382 // Invalidate the texture. This can be used when a context is lost and it is
383 // not possible to make it current in order to free the resource.
384 void Invalidate();
385
[email protected]6217d392010-03-25 22:08:35386 GLuint id() const {
387 return id_;
388 }
389
[email protected]d37231fa2010-04-09 21:16:02390 gfx::Size size() const {
391 return size_;
392 }
393
[email protected]1078f912011-12-23 13:12:14394 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25395 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14396 }
397
[email protected]6217d392010-03-25 22:08:35398 private:
399 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25400 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48401 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35402 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02403 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35404 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35405};
406
407// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35408class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35409 public:
[email protected]ed9f9cd2013-02-27 21:12:35410 explicit BackRenderbuffer(GLES2DecoderImpl* decoder);
411 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35412
413 // Create a new render buffer.
414 void Create();
415
416 // Set the initial size and format of a render buffer or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02417 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
[email protected]6217d392010-03-25 22:08:35418
419 // Destroy the render buffer. This must be explicitly called before destroying
420 // this object.
421 void Destroy();
422
[email protected]97872062010-11-03 19:07:05423 // Invalidate the render buffer. This can be used when a context is lost and
424 // it is not possible to make it current in order to free the resource.
425 void Invalidate();
426
[email protected]6217d392010-03-25 22:08:35427 GLuint id() const {
428 return id_;
429 }
430
[email protected]1078f912011-12-23 13:12:14431 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25432 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14433 }
434
[email protected]6217d392010-03-25 22:08:35435 private:
436 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25437 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48438 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35439 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35440 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35441};
442
443// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35444class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35445 public:
[email protected]ed9f9cd2013-02-27 21:12:35446 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
447 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35448
449 // Create a new frame buffer.
450 void Create();
451
452 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35453 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35454
[email protected]b9363b22010-06-09 22:06:15455 // Attach a render buffer to a frame buffer. Note that this unbinds any
456 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35457 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35458
[email protected]6217d392010-03-25 22:08:35459 // Destroy the frame buffer. This must be explicitly called before destroying
460 // this object.
461 void Destroy();
462
[email protected]97872062010-11-03 19:07:05463 // Invalidate the frame buffer. This can be used when a context is lost and it
464 // is not possible to make it current in order to free the resource.
465 void Invalidate();
466
[email protected]6217d392010-03-25 22:08:35467 // See glCheckFramebufferStatusEXT.
468 GLenum CheckStatus();
469
470 GLuint id() const {
471 return id_;
472 }
473
474 private:
475 GLES2DecoderImpl* decoder_;
476 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35477 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35478};
[email protected]34ff8b0c2010-10-01 20:06:02479
[email protected]43f28f832010-02-03 02:28:48480// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32481
[email protected]ddb1e5a2010-12-13 20:10:45482bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
483 uint32* service_texture_id) {
484 return false;
485}
486
[email protected]a3ded6d2010-10-19 06:44:39487GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06488 : initialized_(false),
489 debug_(false),
[email protected]1d82e822013-04-10 21:32:32490 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32491}
492
[email protected]3916c97e2010-02-25 03:20:50493GLES2Decoder::~GLES2Decoder() {
494}
495
[email protected]57edfdad2012-02-07 04:57:15496bool GLES2Decoder::testing_force_is_angle_;
497
498void GLES2Decoder::set_testing_force_is_angle(bool force) {
499 testing_force_is_angle_ = force;
500}
501
502bool GLES2Decoder::IsAngle() {
503#if defined(OS_WIN)
504 return testing_force_is_angle_ ||
505 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
506#else
507 return testing_force_is_angle_;
508#endif
509}
510
[email protected]f39f4b3f2010-05-12 17:04:08511// This class implements GLES2Decoder so we don't have to expose all the GLES2
512// cmd stuff to outside this class.
[email protected]ee1e6aa2012-11-29 09:24:10513class GLES2DecoderImpl : public GLES2Decoder {
[email protected]f39f4b3f2010-05-12 17:04:08514 public:
[email protected]476ccb72012-12-06 15:52:52515 // Used by PrepForSetUniformByLocation to validate types.
516 struct BaseUniformInfo {
517 const GLenum* const valid_types;
518 size_t num_valid_types;
519 };
520
[email protected]aa7666122011-09-02 19:45:52521 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00522 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08523
[email protected]96449d2c2009-11-25 00:01:32524 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14525 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50526 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00527 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32528
529 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00530 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32531
532 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38533 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
534 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23535 bool offscreen,
[email protected]6217d392010-03-25 22:08:35536 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29537 const DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39538 const char* allowed_extensions,
[email protected]b8e97b62012-09-30 15:09:00539 const std::vector<int32>& attribs) OVERRIDE;
540 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38541 virtual void SetSurface(
542 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]2ad674132013-06-05 07:48:51543 virtual bool ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00544 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39545 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00546 virtual bool MakeCurrent() OVERRIDE;
547 virtual void ReleaseCurrent() OVERRIDE;
548 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
549 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
550 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]1868a342012-11-07 15:56:02551 virtual void RestoreState() const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06552
553 virtual void RestoreActiveTexture() const OVERRIDE {
554 state_.RestoreActiveTexture();
555 }
[email protected]217004512013-05-10 21:25:55556 virtual void RestoreAllTextureUnitBindings() const OVERRIDE {
557 state_.RestoreAllTextureUnitBindings();
558 }
[email protected]29a4d902013-02-26 20:18:06559 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
560 state_.RestoreAttribute(index);
561 }
562 virtual void RestoreBufferBindings() const OVERRIDE {
563 state_.RestoreBufferBindings();
564 }
565 virtual void RestoreGlobalState() const OVERRIDE {
566 state_.RestoreGlobalState();
567 }
568 virtual void RestoreProgramBindings() const OVERRIDE {
569 state_.RestoreProgramBindings();
570 }
571 virtual void RestoreRenderbufferBindings() const OVERRIDE {
572 state_.RestoreRenderbufferBindings();
573 }
574 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
575 state_.RestoreTextureUnitBindings(unit);
576 }
577 virtual void RestoreFramebufferBindings() const OVERRIDE;
578 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
579
[email protected]b8e97b62012-09-30 15:09:00580 virtual QueryManager* GetQueryManager() OVERRIDE {
581 return query_manager_.get();
582 }
583 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46584 return vertex_array_manager_.get();
585 }
[email protected]b8e97b62012-09-30 15:09:00586 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05587 virtual bool HasMoreIdleWork() OVERRIDE;
588 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48589
[email protected]9d37f062011-11-22 01:24:52590 virtual void SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:07591 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00592
[email protected]1d82e822013-04-10 21:32:32593 virtual Logger* GetLogger() OVERRIDE;
[email protected]d3eba342013-04-18 21:11:50594 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]1d82e822013-04-10 21:32:32595
[email protected]e3932abb2013-03-13 00:01:37596 virtual void SetShaderCacheCallback(
597 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51598 virtual void SetWaitSyncPointCallback(
599 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00600
[email protected]85a4ac22013-05-31 01:58:47601 virtual AsyncPixelTransferManager*
602 GetAsyncPixelTransferManager() OVERRIDE;
603 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]498b5c072013-06-04 19:30:07604 virtual void SetAsyncPixelTransferManagerForTest(
605 AsyncPixelTransferManager* manager) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09606 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59607
[email protected]1318e922010-09-17 22:03:16608 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00609 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48610
[email protected]63b465922012-09-06 02:04:52611 virtual uint32 GetTextureUploadCount() OVERRIDE;
612 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
613 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30614 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52615
[email protected]8e3e0662010-08-23 18:46:30616 // Restores the current state to the user's settings.
617 void RestoreCurrentFramebufferBindings();
618 void RestoreCurrentRenderbufferBindings();
619 void RestoreCurrentTexture2DBindings();
620
[email protected]297ca1c2011-06-20 23:08:46621 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
622 void ApplyDirtyState();
623
624 // These check the state of the currently bound framebuffer or the
625 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54626 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
627 // check with all attached and enabled color attachments.
628 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46629 bool BoundFramebufferHasDepthAttachment();
630 bool BoundFramebufferHasStencilAttachment();
631
[email protected]b8e97b62012-09-30 15:09:00632 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43633
[email protected]96449d2c2009-11-25 00:01:32634 private:
[email protected]70d34263c2013-01-09 00:27:45635 friend class ScopedFrameBufferBinder;
[email protected]6217d392010-03-25 22:08:35636 friend class ScopedGLErrorSuppressor;
[email protected]34ff8b0c2010-10-01 20:06:02637 friend class ScopedResolvedFrameBufferBinder;
[email protected]63b465922012-09-06 02:04:52638 friend class ScopedTextureUploadTimer;
[email protected]ed9f9cd2013-02-27 21:12:35639 friend class BackTexture;
640 friend class BackRenderbuffer;
641 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35642
[email protected]c2f8c8402010-12-06 18:07:24643 // Initialize or re-initialize the shader translator.
644 bool InitializeShaderTranslator();
645
[email protected]302ce6d2011-07-07 23:28:11646 void UpdateCapabilities();
647
[email protected]ae51d192010-04-27 00:48:03648 // Helpers for the glGen and glDelete functions.
649 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
650 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
651 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
652 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
653 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
654 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
655 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
656 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53657 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
658 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46659 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
660 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47661
[email protected]70d34263c2013-01-09 00:27:45662 // Workarounds
663 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51664 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45665
[email protected]3916c97e2010-02-25 03:20:50666 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50667 BufferManager* buffer_manager() {
668 return group_->buffer_manager();
669 }
670
[email protected]a25fa872010-03-25 02:57:58671 RenderbufferManager* renderbuffer_manager() {
672 return group_->renderbuffer_manager();
673 }
674
675 FramebufferManager* framebuffer_manager() {
676 return group_->framebuffer_manager();
677 }
678
[email protected]3916c97e2010-02-25 03:20:50679 ProgramManager* program_manager() {
680 return group_->program_manager();
681 }
682
683 ShaderManager* shader_manager() {
684 return group_->shader_manager();
685 }
686
[email protected]29a4d902013-02-26 20:18:06687 const TextureManager* texture_manager() const {
688 return group_->texture_manager();
689 }
690
[email protected]3916c97e2010-02-25 03:20:50691 TextureManager* texture_manager() {
692 return group_->texture_manager();
693 }
694
[email protected]78b514b2012-05-01 21:50:59695 MailboxManager* mailbox_manager() {
696 return group_->mailbox_manager();
697 }
698
[email protected]09d50362012-10-18 20:54:37699 ImageManager* image_manager() {
700 return group_->image_manager();
701 }
702
[email protected]944b62f32012-09-27 02:20:46703 VertexArrayManager* vertex_array_manager() {
704 return vertex_array_manager_.get();
705 }
706
[email protected]7989c9e2013-01-23 06:39:26707 MemoryTracker* memory_tracker() {
708 return group_->memory_tracker();
709 }
710
[email protected]4f9958142013-07-02 03:58:07711 StreamTextureManager* stream_texture_manager() const {
712 return group_->stream_texture_manager();
713 }
714
[email protected]7989c9e2013-01-23 06:39:26715 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
716 MemoryTracker* tracker = memory_tracker();
717 if (tracker) {
718 return tracker->EnsureGPUMemoryAvailable(estimated_size);
719 }
720 return true;
721 }
722
[email protected]34ff8b0c2010-10-01 20:06:02723 bool IsOffscreenBufferMultisampled() const {
724 return offscreen_target_samples_ > 1;
725 }
726
[email protected]ed9f9cd2013-02-27 21:12:35727 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49728 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03729 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35730 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47731 }
732
733 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49734 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07735 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47736 }
737
738 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35739 void RemoveTexture(GLuint client_id) {
740 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50741 }
[email protected]a93bb842010-02-16 23:03:47742
[email protected]d37231fa2010-04-09 21:16:02743 // Get the size (in pixels) of the currently bound frame buffer (either FBO
744 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30745 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02746
[email protected]9edc6b22010-12-23 02:00:26747 // Get the format of the currently bound frame buffer (either FBO or regular
748 // back buffer)
749 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46750 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26751
[email protected]a93bb842010-02-16 23:03:47752 // Wrapper for CompressedTexImage2D commands.
753 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37754 GLenum target,
755 GLint level,
756 GLenum internal_format,
757 GLsizei width,
758 GLsizei height,
759 GLint border,
760 GLsizei image_size,
761 const void* data);
[email protected]a93bb842010-02-16 23:03:47762
[email protected]cadde4a2010-07-31 17:10:43763 // Wrapper for CompressedTexSubImage2D.
764 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37765 GLenum target,
766 GLint level,
767 GLint xoffset,
768 GLint yoffset,
769 GLsizei width,
770 GLsizei height,
771 GLenum format,
772 GLsizei imageSize,
773 const void * data);
[email protected]cadde4a2010-07-31 17:10:43774
775 // Wrapper for CopyTexImage2D.
776 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37777 GLenum target,
778 GLint level,
779 GLenum internal_format,
780 GLint x,
781 GLint y,
782 GLsizei width,
783 GLsizei height,
784 GLint border);
[email protected]cadde4a2010-07-31 17:10:43785
[email protected]6d792ee12013-05-15 00:40:56786 // Wrapper for SwapBuffers.
787 void DoSwapBuffers();
788
[email protected]cadde4a2010-07-31 17:10:43789 // Wrapper for CopyTexSubImage2D.
790 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37791 GLenum target,
792 GLint level,
793 GLint xoffset,
794 GLint yoffset,
795 GLint x,
796 GLint y,
797 GLsizei width,
798 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43799
[email protected]f598f422012-12-07 08:30:03800 // Validation for TexImage2D commands.
801 bool ValidateTexImage2D(
802 const char* function_name,
[email protected]09d50362012-10-18 20:54:37803 GLenum target,
804 GLint level,
805 GLenum internal_format,
806 GLsizei width,
807 GLsizei height,
808 GLint border,
809 GLenum format,
810 GLenum type,
811 const void* pixels,
812 uint32 pixels_size);
[email protected]a93bb842010-02-16 23:03:47813
[email protected]f598f422012-12-07 08:30:03814 // Wrapper for TexImage2D commands.
815 void DoTexImage2D(
816 GLenum target,
817 GLint level,
818 GLenum internal_format,
819 GLsizei width,
820 GLsizei height,
821 GLint border,
822 GLenum format,
823 GLenum type,
824 const void* pixels,
825 uint32 pixels_size);
826
827 // Validation for TexSubImage2D.
828 bool ValidateTexSubImage2D(
829 error::Error* error,
830 const char* function_name,
831 GLenum target,
832 GLint level,
833 GLint xoffset,
834 GLint yoffset,
835 GLsizei width,
836 GLsizei height,
837 GLenum format,
838 GLenum type,
839 const void * data);
840
[email protected]cadde4a2010-07-31 17:10:43841 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03842 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37843 GLenum target,
844 GLint level,
845 GLint xoffset,
846 GLint yoffset,
847 GLsizei width,
848 GLsizei height,
849 GLenum format,
850 GLenum type,
851 const void * data);
[email protected]cadde4a2010-07-31 17:10:43852
[email protected]32145a92012-12-17 09:01:59853 // Extra validation for async tex(Sub)Image2D.
854 bool ValidateAsyncTransfer(
855 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47856 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59857 GLenum target,
858 GLint level,
859 const void * data);
860
[email protected]e51bdf32011-11-23 22:21:46861 // Wrapper for TexImageIOSurface2DCHROMIUM.
862 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37863 GLenum target,
864 GLsizei width,
865 GLsizei height,
866 GLuint io_surface_id,
867 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46868
[email protected]43410e92012-04-20 17:06:28869 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37870 GLenum target,
871 GLuint source_id,
872 GLuint target_id,
873 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54874 GLenum internal_format,
875 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28876
[email protected]97dc7cbe2011-12-06 17:26:17877 // Wrapper for TexStorage2DEXT.
878 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37879 GLenum target,
880 GLint levels,
881 GLenum internal_format,
882 GLsizei width,
883 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17884
[email protected]78b514b2012-05-01 21:50:59885 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
886 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
887
[email protected]09d50362012-10-18 20:54:37888 void DoBindTexImage2DCHROMIUM(
889 GLenum target,
890 GLint image_id);
891 void DoReleaseTexImage2DCHROMIUM(
892 GLenum target,
893 GLint image_id);
894
[email protected]94307712012-11-16 23:26:11895 void DoTraceEndCHROMIUM(void);
896
[email protected]2f143d482013-03-14 18:04:49897 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
898
[email protected]ed9f9cd2013-02-27 21:12:35899 // Creates a Program for the given program.
900 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57901 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35902 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47903 }
904
[email protected]07f54fcc2009-12-22 02:46:30905 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35906 Program* GetProgram(GLuint client_id) {
907 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46908 }
[email protected]07f54fcc2009-12-22 02:46:30909
[email protected]cae20172012-12-07 00:06:19910#if defined(NDEBUG)
911 void LogClientServiceMapping(
912 const char* /* function_name */,
913 GLuint /* client_id */,
914 GLuint /* service_id */) {
915 }
916 template<typename T>
917 void LogClientServiceForInfo(
918 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
919 }
920#else
921 void LogClientServiceMapping(
922 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26923 if (service_logging_) {
[email protected]1d82e822013-04-10 21:32:32924 DLOG(INFO) << "[" << logger_.GetLogPrefix() << "] " << function_name
[email protected]2a22fe72012-12-07 04:21:26925 << ": client_id = " << client_id
926 << ", service_id = " << service_id;
927 }
[email protected]cae20172012-12-07 00:06:19928 }
929 template<typename T>
930 void LogClientServiceForInfo(
931 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26932 if (info) {
[email protected]cae20172012-12-07 00:06:19933 LogClientServiceMapping(function_name, client_id, info->service_id());
934 }
935 }
936#endif
937
[email protected]6b8cf1a2010-05-06 16:13:58938 // Gets the program info for the given program. If it's not a program
939 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35940 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58941 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42942 Program* program = GetProgram(client_id);
943 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35944 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51945 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43946 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58947 } else {
[email protected]ab09b612013-03-11 22:11:51948 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58949 }
950 }
[email protected]df37b9932013-03-08 05:21:42951 LogClientServiceForInfo(program, client_id, function_name);
952 return program;
[email protected]6b8cf1a2010-05-06 16:13:58953 }
954
955
[email protected]ed9f9cd2013-02-27 21:12:35956 // Creates a Shader for the given shader.
957 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57958 GLuint client_id,
959 GLuint service_id,
960 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:35961 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:57962 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31963 }
964
965 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35966 Shader* GetShader(GLuint client_id) {
967 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:31968 }
969
[email protected]6b8cf1a2010-05-06 16:13:58970 // Gets the shader info for the given shader. If it's not a shader generates a
971 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:35972 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:58973 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42974 Shader* shader = GetShader(client_id);
975 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:35976 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:51977 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43978 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58979 } else {
[email protected]ab09b612013-03-11 22:11:51980 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43981 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58982 }
983 }
[email protected]df37b9932013-03-08 05:21:42984 LogClientServiceForInfo(shader, client_id, function_name);
985 return shader;
[email protected]6b8cf1a2010-05-06 16:13:58986 }
987
[email protected]a93bb842010-02-16 23:03:47988 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:35989 void CreateBuffer(GLuint client_id, GLuint service_id) {
990 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47991 }
992
[email protected]07f54fcc2009-12-22 02:46:30993 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:21994 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:07995 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
996 return buffer;
[email protected]1d32bc82010-01-13 22:06:46997 }
[email protected]07f54fcc2009-12-22 02:46:30998
[email protected]a93bb842010-02-16 23:03:47999 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1000 // on glDeleteBuffers so we can make sure the user does not try to render
1001 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351002 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471003
[email protected]a25fa872010-03-25 02:57:581004 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351005 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1006 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581007 }
1008
1009 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061010 Framebuffer* GetFramebuffer(GLuint client_id) {
1011 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581012 }
1013
1014 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351015 void RemoveFramebuffer(GLuint client_id) {
1016 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581017 }
1018
1019 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351020 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1021 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031022 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581023 }
1024
1025 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271026 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1027 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581028 }
1029
1030 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351031 void RemoveRenderbuffer(GLuint client_id) {
1032 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581033 }
1034
[email protected]944b62f32012-09-27 02:20:461035 // Gets the vertex attrib manager for the given vertex array.
1036 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1037 VertexAttribManager* info =
1038 vertex_array_manager()->GetVertexAttribManager(client_id);
1039 return info;
1040 }
1041
1042 // Removes the vertex attrib manager for the given vertex array.
1043 void RemoveVertexAttribManager(GLuint client_id) {
1044 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1045 }
1046
1047 // Creates a vertex attrib manager for the given vertex array.
1048 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1049 return vertex_array_manager()->CreateVertexAttribManager(
1050 client_id, service_id, group_->max_vertex_attribs());
1051 }
1052
[email protected]258a3313f2011-10-18 20:13:571053 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331054 void DoBindUniformLocationCHROMIUM(
1055 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571056
[email protected]558847a2010-03-24 07:02:541057 error::Error GetAttribLocationHelper(
1058 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1059 const std::string& name_str);
1060
1061 error::Error GetUniformLocationHelper(
1062 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1063 const std::string& name_str);
1064
[email protected]3916c97e2010-02-25 03:20:501065 // Helper for glShaderSource.
1066 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031067 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301068
[email protected]0d6bfdc2011-11-02 01:32:201069 // Clear any textures used by the current program.
1070 bool ClearUnclearedTextures();
1071
1072 // Clear any uncleared level in texture.
1073 // Returns false if there was a generated GL error.
[email protected]02965c22013-03-09 02:40:071074 bool ClearTexture(Texture* texture);
[email protected]0d6bfdc2011-11-02 01:32:201075
1076 // Clears any uncleared attachments attached to the given frame buffer.
1077 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061078 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281079
[email protected]0d6bfdc2011-11-02 01:32:201080 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001081 virtual bool ClearLevel(unsigned service_id,
1082 unsigned bind_target,
1083 unsigned target,
1084 int level,
1085 unsigned format,
1086 unsigned type,
1087 int width,
1088 int height,
1089 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201090
[email protected]c007aa02010-09-02 22:22:401091 // Restore all GL state that affects clearing.
1092 void RestoreClearState();
1093
[email protected]3a2e7c7b2010-08-06 01:12:281094 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461095 // Returns: true if glEnable/glDisable should actually be called.
1096 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281097
[email protected]0d6bfdc2011-11-02 01:32:201098 // Check that the currently bound framebuffers are valid.
1099 // Generates GL error if not.
1100 bool CheckBoundFramebuffersValid(const char* func_name);
1101
1102 // Check if a framebuffer meets our requirements.
1103 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351104 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201105 GLenum target,
1106 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271107
[email protected]939e7362010-05-13 20:49:101108 // Checks if the current program exists and is valid. If not generates the
1109 // appropriate GL error. Returns true if the current program is in a usable
1110 // state.
1111 bool CheckCurrentProgram(const char* function_name);
1112
1113 // Checks if the current program exists and is valid and that location is not
1114 // -1. If the current program is not valid generates the appropriate GL
1115 // error. Returns true if the current program is in a usable state and
1116 // location is not -1.
1117 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1118
1119 // Gets the type of a uniform for a location in the current program. Sets GL
1120 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361121 // program is valid and the location exists. Adjusts count so it
1122 // does not overflow the uniform.
1123 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121124 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521125 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121126 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101127
[email protected]b177ae22011-11-01 03:29:111128 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021129 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111130
[email protected]b273e432010-04-12 17:23:581131 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1132 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1133
[email protected]ac77603c72013-03-08 13:52:061134 // Helper for glGetVertexAttrib
1135 void GetVertexAttribHelper(
1136 const VertexAttrib* attrib, GLenum pname, GLint* param);
1137
[email protected]96449d2c2009-11-25 00:01:321138 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031139 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321140
1141 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031142 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321143
[email protected]3916c97e2010-02-25 03:20:501144 // Wrapper for glActiveTexture
1145 void DoActiveTexture(GLenum texture_unit);
1146
[email protected]ae51d192010-04-27 00:48:031147 // Wrapper for glAttachShader
1148 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1149
[email protected]96449d2c2009-11-25 00:01:321150 // Wrapper for glBindBuffer since we need to track the current targets.
1151 void DoBindBuffer(GLenum target, GLuint buffer);
1152
[email protected]86093972010-03-11 00:13:561153 // Wrapper for glBindFramebuffer since we need to track the current targets.
1154 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1155
1156 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1157 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1158
[email protected]a93bb842010-02-16 23:03:471159 // Wrapper for glBindTexture since we need to track the current targets.
1160 void DoBindTexture(GLenum target, GLuint texture);
1161
[email protected]944b62f32012-09-27 02:20:461162 // Wrapper for glBindVertexArrayOES
1163 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571164 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461165
[email protected]8e3e0662010-08-23 18:46:301166 // Wrapper for glBlitFramebufferEXT.
1167 void DoBlitFramebufferEXT(
1168 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1169 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1170 GLbitfield mask, GLenum filter);
1171
[email protected]36cef8ce2010-03-16 07:34:451172 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111173 void DoBufferSubData(
1174 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1175
[email protected]36cef8ce2010-03-16 07:34:451176 // Wrapper for glCheckFramebufferStatus
1177 GLenum DoCheckFramebufferStatus(GLenum target);
1178
[email protected]3a03a8f2011-03-19 00:51:271179 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081180 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271181
[email protected]88a61bf2012-10-27 13:00:421182 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421183 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251184 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281185
[email protected]45bf5152010-02-12 00:11:311186 // Wrapper for glCompileShader.
1187 void DoCompileShader(GLuint shader);
1188
[email protected]269200b12010-11-18 22:53:061189 // Helper for DeleteSharedIdsCHROMIUM commands.
1190 void DoDeleteSharedIdsCHROMIUM(
1191 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101192
[email protected]ae51d192010-04-27 00:48:031193 // Wrapper for glDetachShader
1194 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1195
[email protected]3a2e7c7b2010-08-06 01:12:281196 // Wrapper for glDisable
1197 void DoDisable(GLenum cap);
1198
[email protected]07f54fcc2009-12-22 02:46:301199 // Wrapper for glDisableVertexAttribArray.
1200 void DoDisableVertexAttribArray(GLuint index);
1201
[email protected]60f22d32012-12-12 00:31:581202 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1203 // attachments.
1204 void DoDiscardFramebufferEXT(GLenum target,
1205 GLsizei numAttachments,
1206 const GLenum* attachments);
1207
[email protected]3a2e7c7b2010-08-06 01:12:281208 // Wrapper for glEnable
1209 void DoEnable(GLenum cap);
1210
[email protected]07f54fcc2009-12-22 02:46:301211 // Wrapper for glEnableVertexAttribArray.
1212 void DoEnableVertexAttribArray(GLuint index);
1213
[email protected]882ba1e22012-03-08 19:02:531214 // Wrapper for glFinish.
1215 void DoFinish();
1216
1217 // Wrapper for glFlush.
1218 void DoFlush();
1219
[email protected]36cef8ce2010-03-16 07:34:451220 // Wrapper for glFramebufferRenderbufffer.
1221 void DoFramebufferRenderbuffer(
1222 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1223 GLuint renderbuffer);
1224
1225 // Wrapper for glFramebufferTexture2D.
1226 void DoFramebufferTexture2D(
1227 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1228 GLint level);
1229
[email protected]7d3c36e2013-07-12 14:13:161230 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1231 void DoFramebufferTexture2DMultisample(
1232 GLenum target, GLenum attachment, GLenum textarget,
1233 GLuint texture, GLint level, GLsizei samples);
1234
1235 // Common implementation for both DoFramebufferTexture2D wrappers.
1236 void DoFramebufferTexture2DCommon(const char* name,
1237 GLenum target, GLenum attachment, GLenum textarget,
1238 GLuint texture, GLint level, GLsizei samples);
1239
[email protected]a93bb842010-02-16 23:03:471240 // Wrapper for glGenerateMipmap
1241 void DoGenerateMipmap(GLenum target);
1242
[email protected]269200b12010-11-18 22:53:061243 // Helper for GenSharedIdsCHROMIUM commands.
1244 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101245 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1246
[email protected]7d3c36e2013-07-12 14:13:161247 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1248 // to account for different pname values defined in different extension
1249 // variants.
1250 GLenum AdjustGetPname(GLenum pname);
1251
[email protected]b273e432010-04-12 17:23:581252 // Wrapper for DoGetBooleanv.
1253 void DoGetBooleanv(GLenum pname, GLboolean* params);
1254
1255 // Wrapper for DoGetFloatv.
1256 void DoGetFloatv(GLenum pname, GLfloat* params);
1257
[email protected]36cef8ce2010-03-16 07:34:451258 // Wrapper for glGetFramebufferAttachmentParameteriv.
1259 void DoGetFramebufferAttachmentParameteriv(
1260 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1261
[email protected]a0c3e972010-04-21 00:49:131262 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581263 void DoGetIntegerv(GLenum pname, GLint* params);
1264
[email protected]29a9eb52010-04-13 09:04:231265 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061266 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231267 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1268
[email protected]17cfbe0e2013-03-07 01:26:081269 // Wrapper for glGetBufferParameteriv.
1270 void DoGetBufferParameteriv(
1271 GLenum target, GLenum pname, GLint* params);
1272
[email protected]a0c3e972010-04-21 00:49:131273 // Wrapper for glGetProgramiv.
1274 void DoGetProgramiv(
1275 GLuint program_id, GLenum pname, GLint* params);
1276
[email protected]36cef8ce2010-03-16 07:34:451277 // Wrapper for glRenderbufferParameteriv.
1278 void DoGetRenderbufferParameteriv(
1279 GLenum target, GLenum pname, GLint* params);
1280
[email protected]ddd968b82010-03-02 00:44:291281 // Wrapper for glGetShaderiv
1282 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1283
[email protected]b1122982010-05-17 23:04:241284 // Wrappers for glGetVertexAttrib.
1285 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1286 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1287
[email protected]1958e0e2010-04-22 05:17:151288 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241289 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151290 bool DoIsBuffer(GLuint client_id);
1291 bool DoIsFramebuffer(GLuint client_id);
1292 bool DoIsProgram(GLuint client_id);
1293 bool DoIsRenderbuffer(GLuint client_id);
1294 bool DoIsShader(GLuint client_id);
1295 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461296 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151297
[email protected]07f54fcc2009-12-22 02:46:301298 // Wrapper for glLinkProgram
1299 void DoLinkProgram(GLuint program);
1300
[email protected]269200b12010-11-18 22:53:061301 // Helper for RegisterSharedIdsCHROMIUM.
1302 void DoRegisterSharedIdsCHROMIUM(
1303 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101304
[email protected]36cef8ce2010-03-16 07:34:451305 // Wrapper for glRenderbufferStorage.
1306 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031307 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451308
[email protected]8e3e0662010-08-23 18:46:301309 // Wrapper for glRenderbufferStorageMultisampleEXT.
1310 void DoRenderbufferStorageMultisample(
1311 GLenum target, GLsizei samples, GLenum internalformat,
1312 GLsizei width, GLsizei height);
1313
[email protected]b273e432010-04-12 17:23:581314 // Wrapper for glReleaseShaderCompiler.
1315 void DoReleaseShaderCompiler() { }
1316
[email protected]3916c97e2010-02-25 03:20:501317 // Wrappers for glTexParameter functions.
1318 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1319 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1320 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1321 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1322
1323 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1324 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121325 void DoUniform1i(GLint fake_location, GLint v0);
1326 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1327 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1328 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1329 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101330
1331 // Wrappers for glUniformfv because some drivers don't correctly accept
1332 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121333 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1334 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1335 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1336 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501337
[email protected]43c2f1f2011-03-25 18:35:361338 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121339 GLint fake_location, GLsizei count, GLboolean transpose,
1340 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361341 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121342 GLint fake_location, GLsizei count, GLboolean transpose,
1343 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361344 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121345 GLint fake_location, GLsizei count, GLboolean transpose,
1346 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361347
[email protected]af6380962012-11-29 23:24:131348 bool SetVertexAttribValue(
1349 const char* function_name, GLuint index, const GLfloat* value);
1350
[email protected]b1122982010-05-17 23:04:241351 // Wrappers for glVertexAttrib??
1352 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1353 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1354 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1355 void DoVertexAttrib4f(
1356 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1357 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1358 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1359 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1360 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1361
[email protected]43410e92012-04-20 17:06:281362 // Wrapper for glViewport
1363 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1364
[email protected]07f54fcc2009-12-22 02:46:301365 // Wrapper for glUseProgram
1366 void DoUseProgram(GLuint program);
1367
[email protected]ae51d192010-04-27 00:48:031368 // Wrapper for glValidateProgram.
1369 void DoValidateProgram(GLuint program_client_id);
1370
[email protected]d2a0e1a2012-08-12 02:25:011371 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1372 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1373 void DoPopGroupMarkerEXT(void);
1374
[email protected]4e8a5b122010-05-08 22:00:101375 // Gets the number of values that will be returned by glGetXXX. Returns
1376 // false if pname is unknown.
1377 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1378
[email protected]07f54fcc2009-12-22 02:46:301379 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431380 bool IsDrawValid(
1381 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301382
[email protected]c13e1da62011-09-09 21:48:301383 // Returns true if successful, simulated will be true if attrib0 was
1384 // simulated.
[email protected]c6aef902012-02-14 03:31:421385 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431386 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281387 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241388
[email protected]ef526492010-06-02 23:12:251389 // Returns true if textures were set.
1390 bool SetBlackTextureForNonRenderableTextures();
[email protected]3916c97e2010-02-25 03:20:501391 void RestoreStateForNonRenderableTextures();
1392
[email protected]8fbedc02010-11-18 18:43:401393 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421394 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431395 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421396 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401397 void RestoreStateForSimulatedFixedAttribs();
1398
[email protected]c6aef902012-02-14 03:31:421399 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1400 // cases (primcount is 0 for non-instanced).
1401 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431402 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421403 bool instanced, GLenum mode, GLint first, GLsizei count,
1404 GLsizei primcount);
1405 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431406 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421407 bool instanced, GLenum mode, GLsizei count, GLenum type,
1408 int32 offset, GLsizei primcount);
1409
[email protected]a93bb842010-02-16 23:03:471410 // Gets the texture id for a given target.
[email protected]370eaf12013-05-18 09:19:491411 TextureRef* GetTextureInfoForTarget(GLenum target) {
[email protected]e259eb412012-10-13 05:47:241412 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]370eaf12013-05-18 09:19:491413 TextureRef* texture = NULL;
[email protected]a93bb842010-02-16 23:03:471414 switch (target) {
1415 case GL_TEXTURE_2D:
[email protected]7cd76fd2013-06-02 21:11:111416 texture = unit.bound_texture_2d.get();
[email protected]3916c97e2010-02-25 03:20:501417 break;
[email protected]a93bb842010-02-16 23:03:471418 case GL_TEXTURE_CUBE_MAP:
1419 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1420 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1421 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1422 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1423 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1424 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
[email protected]7cd76fd2013-06-02 21:11:111425 texture = unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:501426 break;
[email protected]61eeb33f2011-07-26 15:30:311427 case GL_TEXTURE_EXTERNAL_OES:
[email protected]7cd76fd2013-06-02 21:11:111428 texture = unit.bound_texture_external_oes.get();
[email protected]61eeb33f2011-07-26 15:30:311429 break;
[email protected]e51bdf32011-11-23 22:21:461430 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]7cd76fd2013-06-02 21:11:111431 texture = unit.bound_texture_rectangle_arb.get();
[email protected]e51bdf32011-11-23 22:21:461432 break;
[email protected]a93bb842010-02-16 23:03:471433 default:
1434 NOTREACHED();
[email protected]3916c97e2010-02-25 03:20:501435 return NULL;
[email protected]a93bb842010-02-16 23:03:471436 }
[email protected]02965c22013-03-09 02:40:071437 return texture;
[email protected]a93bb842010-02-16 23:03:471438 }
1439
[email protected]370eaf12013-05-18 09:19:491440 TextureRef* GetTextureInfoForTargetUnlessDefault(
[email protected]09d50362012-10-18 20:54:371441 GLenum target) {
[email protected]370eaf12013-05-18 09:19:491442 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:071443 if (!texture)
[email protected]09d50362012-10-18 20:54:371444 return NULL;
[email protected]02965c22013-03-09 02:40:071445 if (texture == texture_manager()->GetDefaultTextureInfo(target))
[email protected]09d50362012-10-18 20:54:371446 return NULL;
[email protected]02965c22013-03-09 02:40:071447 return texture;
[email protected]09d50362012-10-18 20:54:371448 }
1449
[email protected]61eeb33f2011-07-26 15:30:311450 GLenum GetBindTargetForSamplerType(GLenum type) {
1451 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461452 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1453 switch (type) {
1454 case GL_SAMPLER_2D:
1455 return GL_TEXTURE_2D;
1456 case GL_SAMPLER_CUBE:
1457 return GL_TEXTURE_CUBE_MAP;
1458 case GL_SAMPLER_EXTERNAL_OES:
1459 return GL_TEXTURE_EXTERNAL_OES;
1460 case GL_SAMPLER_2D_RECT_ARB:
1461 return GL_TEXTURE_RECTANGLE_ARB;
1462 }
1463
1464 NOTREACHED();
1465 return 0;
[email protected]61eeb33f2011-07-26 15:30:311466 }
1467
[email protected]8e3e0662010-08-23 18:46:301468 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061469 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1470 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301471 switch (target) {
1472 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451473 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]7cd76fd2013-06-02 21:11:111474 framebuffer = state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301475 break;
[email protected]ebfb73c2012-08-15 02:37:451476 case GL_READ_FRAMEBUFFER_EXT:
[email protected]7cd76fd2013-06-02 21:11:111477 framebuffer = state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301478 break;
1479 default:
1480 NOTREACHED();
1481 break;
1482 }
[email protected]4d8f0dd2013-03-09 14:37:061483 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301484 }
1485
[email protected]ed9f9cd2013-02-27 21:12:351486 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201487 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271488 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201489 switch (target) {
1490 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111491 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201492 break;
1493 default:
1494 NOTREACHED();
1495 break;
1496 }
[email protected]ee2a79c32013-03-10 03:50:271497 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201498 }
1499
[email protected]f7b85372010-02-03 01:11:371500 // Validates the program and location for a glGetUniform call and returns
1501 // a SizeResult setup to receive the result. Returns true if glGetUniform
1502 // should be called.
1503 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121504 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371505 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121506 error::Error* error, GLint* real_location, GLuint* service_id,
1507 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371508
[email protected]1078f912011-12-23 13:12:141509 // Computes the estimated memory used for the backbuffer and passes it to
1510 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531511 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141512
[email protected]a10b4a02012-11-26 23:09:501513 virtual bool WasContextLost() OVERRIDE;
[email protected]93a7d98f2013-07-11 00:04:221514 virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091515 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431516
[email protected]e51bdf32011-11-23 22:21:461517#if defined(OS_MACOSX)
1518 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1519#endif
1520
[email protected]81375742012-06-08 00:04:001521 // Validates the combination of texture parameters. For example validates that
1522 // for a given format the specific type, level and targets are valid.
1523 // Synthesizes the correct GL error if invalid. Returns true if valid.
1524 bool ValidateTextureParameters(
1525 const char* function_name,
1526 GLenum target, GLenum format, GLenum type, GLint level);
1527
[email protected]ad84a3a2012-06-08 21:42:431528 bool ValidateCompressedTexDimensions(
1529 const char* function_name,
1530 GLint level, GLsizei width, GLsizei height, GLenum format);
1531 bool ValidateCompressedTexFuncData(
1532 const char* function_name,
1533 GLsizei width, GLsizei height, GLenum format, size_t size);
1534 bool ValidateCompressedTexSubDimensions(
1535 const char* function_name,
1536 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1537 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351538 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431539
[email protected]ab09b612013-03-11 22:11:511540 void RenderWarning(const char* filename, int line, const std::string& msg);
1541 void PerformanceWarning(
1542 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011543
[email protected]62e155e2012-10-23 22:43:151544 const FeatureInfo::FeatureFlags& features() const {
1545 return feature_info_->feature_flags();
1546 }
1547
1548 const FeatureInfo::Workarounds& workarounds() const {
1549 return feature_info_->workarounds();
1550 }
1551
[email protected]a7266a92012-06-28 02:11:081552 bool ShouldDeferDraws() {
1553 return !offscreen_target_frame_buffer_.get() &&
[email protected]7cd76fd2013-06-02 21:11:111554 state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081555 surface_->DeferDraws();
1556 }
1557
[email protected]09e17272012-11-30 10:30:441558 bool ShouldDeferReads() {
1559 return !offscreen_target_frame_buffer_.get() &&
[email protected]7cd76fd2013-06-02 21:11:111560 state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441561 surface_->DeferDraws();
1562 }
1563
[email protected]df37b9932013-03-08 05:21:421564 void ForceCompileShaderIfPending(Shader* shader);
[email protected]c447acd2012-07-23 23:48:411565
[email protected]96449d2c2009-11-25 00:01:321566 // Generate a member function prototype for each command in an automated and
1567 // typesafe way.
1568 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141569 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351570 uint32 immediate_data_size, \
1571 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321572
1573 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1574
1575 #undef GLES2_CMD_OP
1576
[email protected]2f2d7042010-04-14 21:45:581577 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381578 scoped_refptr<gfx::GLSurface> surface_;
1579 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021580
[email protected]a3ded6d2010-10-19 06:44:391581 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351582 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391583
[email protected]1d82e822013-04-10 21:32:321584 DebugMarkerManager debug_marker_manager_;
1585 Logger logger_;
1586
[email protected]e259eb412012-10-13 05:47:241587 // All the state for this context.
1588 ContextState state_;
1589
[email protected]34ff8b0c2010-10-01 20:06:021590 // Current width and height of the offscreen frame buffer.
1591 gfx::Size offscreen_size_;
1592
[email protected]96449d2c2009-11-25 00:01:321593 // Util to help with GL.
1594 GLES2Util util_;
1595
[email protected]43410e92012-04-20 17:06:281596 // unpack flip y as last set by glPixelStorei
1597 bool unpack_flip_y_;
1598
[email protected]6c75c712012-06-19 15:43:171599 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281600 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171601 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281602
[email protected]944b62f32012-09-27 02:20:461603 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351604 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301605
[email protected]b1122982010-05-17 23:04:241606 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1607 GLuint attrib_0_buffer_id_;
1608
1609 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131610 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241611
[email protected]fc753442011-02-04 19:49:491612 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1613 bool attrib_0_buffer_matches_value_;
1614
[email protected]b1122982010-05-17 23:04:241615 // The size of attrib 0.
1616 GLsizei attrib_0_size_;
1617
[email protected]8fbedc02010-11-18 18:43:401618 // The buffer used to simulate GL_FIXED attribs.
1619 GLuint fixed_attrib_buffer_id_;
1620
1621 // The size of fiixed attrib buffer.
1622 GLsizei fixed_attrib_buffer_size_;
1623
[email protected]3a2e7c7b2010-08-06 01:12:281624 // state saved for clearing so we can clear render buffers and then
1625 // restore to these values.
[email protected]88a61bf2012-10-27 13:00:421626 bool clear_state_dirty_;
[email protected]3a2e7c7b2010-08-06 01:12:281627
[email protected]b9363b22010-06-09 22:06:151628 // The offscreen frame buffer that the client renders to. With EGL, the
1629 // depth and stencil buffers are separate. With regular GL there is a single
1630 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1631 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351632 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1633 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1634 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1635 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1636 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021637 GLenum offscreen_target_color_format_;
1638 GLenum offscreen_target_depth_format_;
1639 GLenum offscreen_target_stencil_format_;
1640 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561641 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351642
[email protected]de26b3c2011-08-03 21:54:271643 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351644 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1645 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491646 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351647 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271648
1649 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351650 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1651 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051652 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351653
[email protected]882ba1e22012-03-08 19:02:531654 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531655
[email protected]944b62f32012-09-27 02:20:461656 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1657
[email protected]729c0b42013-05-26 02:05:071658 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001659
[email protected]840a7e462013-02-27 01:29:511660 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481661
[email protected]e3932abb2013-03-13 00:01:371662 ShaderCacheCallback shader_cache_callback_;
1663
[email protected]85a4ac22013-05-31 01:58:471664 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421665
[email protected]32fe9aa2011-01-21 23:47:131666 // The format of the back buffer_
1667 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461668 bool back_buffer_has_depth_;
1669 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131670
[email protected]60f22d32012-12-12 00:31:581671 // Backbuffer attachments that are currently undefined.
1672 uint32 backbuffer_needs_clear_bits_;
1673
[email protected]473c01ccb2011-06-07 01:33:301674 bool teximage2d_faster_than_texsubimage2d_;
[email protected]473c01ccb2011-06-07 01:33:301675
[email protected]a3a93e7b2010-08-28 00:48:561676 // The current decoder error.
1677 error::Error current_decoder_error_;
1678
[email protected]b1d2dcb2010-05-17 19:24:181679 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041680 scoped_refptr<ShaderTranslator> vertex_translator_;
1681 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181682
[email protected]e82fb792011-09-22 00:33:291683 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411684
[email protected]915a59a12010-09-30 21:29:111685 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051686 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351687 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051688
[email protected]b493ee622011-04-13 23:52:001689 // This indicates all the following texSubImage2D calls that are part of the
1690 // failed texImage2D call should be ignored.
1691 bool tex_image_2d_failed_;
1692
[email protected]65225772011-05-12 21:10:241693 int frame_number_;
1694
[email protected]706b69f2012-07-27 04:59:301695 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431696 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221697 bool reset_by_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431698
[email protected]f0d74742011-10-03 16:31:041699 // These flags are used to override the state of the shared feature_info_
1700 // member. Because the same FeatureInfo instance may be shared among many
1701 // contexts, the assumptions on the availablity of extensions in WebGL
1702 // contexts may be broken. These flags override the shared state to preserve
1703 // WebGL semantics.
1704 bool force_webgl_glsl_validation_;
1705 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491706 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131707 bool draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041708
[email protected]062c38b2012-01-18 03:25:101709 bool compile_shader_always_succeeds_;
1710
[email protected]cae20172012-12-07 00:06:191711 // Log extra info.
1712 bool service_logging_;
1713
[email protected]e51bdf32011-11-23 22:21:461714#if defined(OS_MACOSX)
1715 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1716 TextureToIOSurfaceMap texture_to_io_surface_map_;
1717#endif
1718
[email protected]43410e92012-04-20 17:06:281719 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1720
[email protected]1868a342012-11-07 15:56:021721 // Cached values of the currently assigned viewport dimensions.
1722 GLsizei viewport_max_width_;
1723 GLsizei viewport_max_height_;
1724
[email protected]63b465922012-09-06 02:04:521725 // Command buffer stats.
1726 int texture_upload_count_;
1727 base::TimeDelta total_texture_upload_time_;
1728 base::TimeDelta total_processing_commands_time_;
1729
[email protected]fb97b662013-02-20 23:02:141730 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]94307712012-11-16 23:26:111731
[email protected]96449d2c2009-11-25 00:01:321732 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1733};
1734
[email protected]ab09b612013-03-11 22:11:511735ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
1736 const char* function_name, GLES2DecoderImpl* decoder)
1737 : function_name_(function_name),
1738 decoder_(decoder) {
[email protected]d3eba342013-04-18 21:11:501739 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(),
1740 function_name_);
[email protected]6217d392010-03-25 22:08:351741}
1742
1743ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]d3eba342013-04-18 21:11:501744 ERRORSTATE_CLEAR_REAL_GL_ERRORS(decoder_->GetErrorState(), function_name_);
[email protected]6217d392010-03-25 22:08:351745}
1746
1747ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1748 GLuint id)
1749 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511750 ScopedGLErrorSuppressor suppressor(
1751 "ScopedTexture2DBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351752
1753 // TODO(apatrick): Check if there are any other states that need to be reset
1754 // before binding a new texture.
1755 glActiveTexture(GL_TEXTURE0);
1756 glBindTexture(GL_TEXTURE_2D, id);
1757}
1758
1759ScopedTexture2DBinder::~ScopedTexture2DBinder() {
[email protected]ab09b612013-03-11 22:11:511760 ScopedGLErrorSuppressor suppressor(
1761 "ScopedTexture2DBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301762 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351763}
1764
1765ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1766 GLuint id)
1767 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511768 ScopedGLErrorSuppressor suppressor(
1769 "ScopedRenderBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351770 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1771}
1772
1773ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511774 ScopedGLErrorSuppressor suppressor(
1775 "ScopedRenderBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301776 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351777}
1778
1779ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1780 GLuint id)
1781 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511782 ScopedGLErrorSuppressor suppressor(
1783 "ScopedFrameBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351784 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451785 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351786}
1787
1788ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511789 ScopedGLErrorSuppressor suppressor(
1790 "ScopedFrameBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301791 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351792}
1793
[email protected]34ff8b0c2010-10-01 20:06:021794ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271795 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521796 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021797 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1798 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241799 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521800 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021801 if (!resolve_and_bind_)
1802 return;
1803
[email protected]ab09b612013-03-11 22:11:511804 ScopedGLErrorSuppressor suppressor(
1805 "ScopedResolvedFrameBufferBinder::ctor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021806 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1807 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271808 GLuint targetid;
1809 if (internal) {
1810 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1811 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351812 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271813 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351814 decoder_->offscreen_resolved_color_texture_.reset(
1815 new BackTexture(decoder_));
[email protected]de26b3c2011-08-03 21:54:271816 decoder_->offscreen_resolved_color_texture_->Create();
1817
1818 DCHECK(decoder_->offscreen_saved_color_format_);
1819 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091820 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1821 false);
[email protected]de26b3c2011-08-03 21:54:271822 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1823 decoder_->offscreen_resolved_color_texture_.get());
1824 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1825 GL_FRAMEBUFFER_COMPLETE) {
1826 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1827 << "because offscreen resolved FBO was incomplete.";
1828 return;
1829 }
1830 }
1831 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1832 } else {
1833 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1834 }
1835 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021836 const int width = decoder_->offscreen_size_.width();
1837 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181838 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151839 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021840 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1841 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1842 } else {
1843 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1844 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1845 }
[email protected]de26b3c2011-08-03 21:54:271846 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021847}
1848
1849ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1850 if (!resolve_and_bind_)
1851 return;
1852
[email protected]ab09b612013-03-11 22:11:511853 ScopedGLErrorSuppressor suppressor(
1854 "ScopedResolvedFrameBufferBinder::dtor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021855 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221856 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181857 glEnable(GL_SCISSOR_TEST);
1858 }
[email protected]34ff8b0c2010-10-01 20:06:021859}
1860
[email protected]63b465922012-09-06 02:04:521861ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder)
1862 : decoder_(decoder),
1863 begin_time_(base::TimeTicks::HighResNow()) {
1864}
1865
1866ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1867 decoder_->texture_upload_count_++;
1868 decoder_->total_texture_upload_time_ +=
1869 base::TimeTicks::HighResNow() - begin_time_;
1870}
1871
[email protected]ed9f9cd2013-02-27 21:12:351872BackTexture::BackTexture(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351873 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261874 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481875 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251876 id_(0) {
[email protected]6217d392010-03-25 22:08:351877}
1878
[email protected]ed9f9cd2013-02-27 21:12:351879BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351880 // This does not destroy the render texture because that would require that
1881 // the associated GL context was current. Just check that it was explicitly
1882 // destroyed.
1883 DCHECK_EQ(id_, 0u);
1884}
1885
[email protected]ed9f9cd2013-02-27 21:12:351886void BackTexture::Create() {
[email protected]ab09b612013-03-11 22:11:511887 ScopedGLErrorSuppressor suppressor("BackTexture::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351888 Destroy();
1889 glGenTextures(1, &id_);
[email protected]3a4d0c52011-06-29 23:11:581890 ScopedTexture2DBinder binder(decoder_, id_);
1891 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1892 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1893 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1894 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161895
1896 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1897 // never called on an offscreen context, no data will ever be uploaded to the
1898 // saved offscreen color texture (it is deferred until to when SwapBuffers
1899 // is called). My idea is that some nvidia drivers might have a bug where
1900 // deleting a texture that has never been populated might cause a
1901 // crash.
1902 glTexImage2D(
1903 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481904
1905 bytes_allocated_ = 16u * 16u * 4u;
1906 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351907}
1908
[email protected]ed9f9cd2013-02-27 21:12:351909bool BackTexture::AllocateStorage(
1910 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351911 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511912 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351913 ScopedTexture2DBinder binder(decoder_, id_);
[email protected]678a73f2012-12-19 19:22:091914 uint32 image_size = 0;
1915 GLES2Util::ComputeImageDataSizes(
1916 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1917 NULL, NULL);
1918
[email protected]7989c9e2013-01-23 06:39:261919 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
1920 return false;
1921 }
1922
[email protected]40d90a22013-04-09 03:39:551923 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:091924 if (zero) {
1925 zero_data.reset(new char[image_size]);
1926 memset(zero_data.get(), 0, image_size);
1927 }
[email protected]6217d392010-03-25 22:08:351928
[email protected]8f1d2aa2013-05-10 23:45:381929 glTexImage2D(GL_TEXTURE_2D,
1930 0, // mip level
1931 format,
1932 size.width(),
1933 size.height(),
1934 0, // border
1935 format,
1936 GL_UNSIGNED_BYTE,
1937 zero_data.get());
[email protected]6217d392010-03-25 22:08:351938
[email protected]d37231fa2010-04-09 21:16:021939 size_ = size;
1940
[email protected]1078f912011-12-23 13:12:141941 bool success = glGetError() == GL_NO_ERROR;
1942 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481943 memory_tracker_.TrackMemFree(bytes_allocated_);
1944 bytes_allocated_ = image_size;
1945 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141946 }
1947 return success;
[email protected]6217d392010-03-25 22:08:351948}
1949
[email protected]ed9f9cd2013-02-27 21:12:351950void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351951 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511952 ScopedGLErrorSuppressor suppressor("BackTexture::Copy", decoder_);
[email protected]6217d392010-03-25 22:08:351953 ScopedTexture2DBinder binder(decoder_, id_);
1954 glCopyTexImage2D(GL_TEXTURE_2D,
1955 0, // level
[email protected]3a4d0c52011-06-29 23:11:581956 format,
[email protected]6217d392010-03-25 22:08:351957 0, 0,
1958 size.width(),
1959 size.height(),
1960 0); // border
1961}
1962
[email protected]ed9f9cd2013-02-27 21:12:351963void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:351964 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:511965 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:351966 glDeleteTextures(1, &id_);
1967 id_ = 0;
1968 }
[email protected]68e81a4a62012-12-13 01:16:481969 memory_tracker_.TrackMemFree(bytes_allocated_);
1970 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351971}
1972
[email protected]ed9f9cd2013-02-27 21:12:351973void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:051974 id_ = 0;
1975}
1976
[email protected]ed9f9cd2013-02-27 21:12:351977BackRenderbuffer::BackRenderbuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351978 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261979 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481980 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251981 id_(0) {
[email protected]6217d392010-03-25 22:08:351982}
1983
[email protected]ed9f9cd2013-02-27 21:12:351984BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:351985 // This does not destroy the render buffer because that would require that
1986 // the associated GL context was current. Just check that it was explicitly
1987 // destroyed.
1988 DCHECK_EQ(id_, 0u);
1989}
1990
[email protected]ed9f9cd2013-02-27 21:12:351991void BackRenderbuffer::Create() {
[email protected]ab09b612013-03-11 22:11:511992 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351993 Destroy();
1994 glGenRenderbuffersEXT(1, &id_);
1995}
1996
[email protected]ed9f9cd2013-02-27 21:12:351997bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format,
1998 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:511999 ScopedGLErrorSuppressor suppressor(
2000 "BackRenderbuffer::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:352001 ScopedRenderBufferBinder binder(decoder_, id_);
[email protected]7989c9e2013-01-23 06:39:262002
2003 uint32 estimated_size = 0;
2004 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
2005 size.width(), size.height(), samples, format, &estimated_size)) {
2006 return false;
2007 }
2008
2009 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2010 return false;
2011 }
2012
[email protected]34ff8b0c2010-10-01 20:06:022013 if (samples <= 1) {
2014 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2015 format,
2016 size.width(),
2017 size.height());
2018 } else {
[email protected]57edfdad2012-02-07 04:57:152019 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:022020 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
2021 samples,
2022 format,
2023 size.width(),
2024 size.height());
2025 } else {
2026 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
2027 samples,
2028 format,
2029 size.width(),
2030 size.height());
2031 }
2032 }
[email protected]1078f912011-12-23 13:12:142033 bool success = glGetError() == GL_NO_ERROR;
2034 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482035 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262036 bytes_allocated_ = estimated_size;
[email protected]68e81a4a62012-12-13 01:16:482037 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142038 }
2039 return success;
[email protected]6217d392010-03-25 22:08:352040}
2041
[email protected]ed9f9cd2013-02-27 21:12:352042void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352043 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512044 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352045 glDeleteRenderbuffersEXT(1, &id_);
2046 id_ = 0;
2047 }
[email protected]68e81a4a62012-12-13 01:16:482048 memory_tracker_.TrackMemFree(bytes_allocated_);
2049 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352050}
2051
[email protected]ed9f9cd2013-02-27 21:12:352052void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052053 id_ = 0;
2054}
2055
[email protected]ed9f9cd2013-02-27 21:12:352056BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352057 : decoder_(decoder),
2058 id_(0) {
2059}
2060
[email protected]ed9f9cd2013-02-27 21:12:352061BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352062 // This does not destroy the frame buffer because that would require that
2063 // the associated GL context was current. Just check that it was explicitly
2064 // destroyed.
2065 DCHECK_EQ(id_, 0u);
2066}
2067
[email protected]ed9f9cd2013-02-27 21:12:352068void BackFramebuffer::Create() {
[email protected]ab09b612013-03-11 22:11:512069 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:352070 Destroy();
2071 glGenFramebuffersEXT(1, &id_);
2072}
2073
[email protected]ed9f9cd2013-02-27 21:12:352074void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352075 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512076 ScopedGLErrorSuppressor suppressor(
2077 "BackFramebuffer::AttachRenderTexture", decoder_);
[email protected]6217d392010-03-25 22:08:352078 ScopedFrameBufferBinder binder(decoder_, id_);
2079 GLuint attach_id = texture ? texture->id() : 0;
2080 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2081 GL_COLOR_ATTACHMENT0,
2082 GL_TEXTURE_2D,
2083 attach_id,
2084 0);
2085}
2086
[email protected]ed9f9cd2013-02-27 21:12:352087void BackFramebuffer::AttachRenderBuffer(GLenum target,
2088 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352089 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512090 ScopedGLErrorSuppressor suppressor(
2091 "BackFramebuffer::AttachRenderBuffer", decoder_);
[email protected]6217d392010-03-25 22:08:352092 ScopedFrameBufferBinder binder(decoder_, id_);
2093 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2094 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152095 target,
[email protected]6217d392010-03-25 22:08:352096 GL_RENDERBUFFER,
2097 attach_id);
2098}
2099
[email protected]ed9f9cd2013-02-27 21:12:352100void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352101 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512102 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352103 glDeleteFramebuffersEXT(1, &id_);
2104 id_ = 0;
2105 }
2106}
2107
[email protected]ed9f9cd2013-02-27 21:12:352108void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052109 id_ = 0;
2110}
2111
[email protected]ed9f9cd2013-02-27 21:12:352112GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352113 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512114 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", decoder_);
[email protected]6217d392010-03-25 22:08:352115 ScopedFrameBufferBinder binder(decoder_, id_);
2116 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2117}
2118
[email protected]aa7666122011-09-02 19:45:522119GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2120 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322121}
2122
[email protected]aa7666122011-09-02 19:45:522123GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392124 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572125 group_(group),
[email protected]1d82e822013-04-10 21:32:322126 logger_(&debug_marker_manager_),
[email protected]d3eba342013-04-18 21:11:502127 state_(group_->feature_info(), &logger_),
[email protected]43410e92012-04-20 17:06:282128 unpack_flip_y_(false),
2129 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172130 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242131 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492132 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242133 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402134 fixed_attrib_buffer_id_(0),
2135 fixed_attrib_buffer_size_(0),
[email protected]88a61bf2012-10-27 13:00:422136 clear_state_dirty_(true),
[email protected]34ff8b0c2010-10-01 20:06:022137 offscreen_target_color_format_(0),
2138 offscreen_target_depth_format_(0),
2139 offscreen_target_stencil_format_(0),
2140 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562141 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052142 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132143 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462144 back_buffer_has_depth_(false),
2145 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582146 backbuffer_needs_clear_bits_(0),
[email protected]473c01ccb2011-06-07 01:33:302147 teximage2d_faster_than_texsubimage2d_(true),
[email protected]a3a93e7b2010-08-28 00:48:562148 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052149 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112150 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002151 feature_info_(group_->feature_info()),
[email protected]65225772011-05-12 21:10:242152 tex_image_2d_failed_(false),
[email protected]38d139d2011-07-14 00:38:432153 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302154 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512155 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222156 reset_by_robustness_extension_(false),
[email protected]f0d74742011-10-03 16:31:042157 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102158 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492159 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132160 draw_buffers_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282161 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192162 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2163 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022164 viewport_max_width_(0),
2165 viewport_max_height_(0),
[email protected]63b465922012-09-06 02:04:522166 texture_upload_count_(0) {
[email protected]3b1ecc262011-08-03 22:49:572167 DCHECK(group);
2168
[email protected]b1122982010-05-17 23:04:242169 attrib_0_value_.v[0] = 0.0f;
2170 attrib_0_value_.v[1] = 0.0f;
2171 attrib_0_value_.v[2] = 0.0f;
2172 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152173
[email protected]c2f8c8402010-12-06 18:07:242174 // The shader translator is used for WebGL even when running on EGL
2175 // because additional restrictions are needed (like only enabling
2176 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562177 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2178 // the empty string to CompileShader and this is not a valid shader.
2179 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002180 CommandLine::ForCurrentProcess()->HasSwitch(
2181 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152182 use_shader_translator_ = false;
2183 }
[email protected]473c01ccb2011-06-07 01:33:302184
[email protected]a39370652012-09-25 21:52:132185 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:302186 if (IsAngle()) {
2187 teximage2d_faster_than_texsubimage2d_ = false;
[email protected]473c01ccb2011-06-07 01:33:302188 }
[email protected]96449d2c2009-11-25 00:01:322189}
2190
[email protected]80eb6b52012-01-19 00:14:412191GLES2DecoderImpl::~GLES2DecoderImpl() {
2192}
2193
[email protected]c410da802011-03-14 19:17:412194bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382195 const scoped_refptr<gfx::GLSurface>& surface,
2196 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232197 bool offscreen,
[email protected]c410da802011-03-14 19:17:412198 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292199 const DisallowedFeatures& disallowed_features,
[email protected]c410da802011-03-14 19:17:412200 const char* allowed_extensions,
[email protected]3c644d82011-06-20 19:58:242201 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322202 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382203 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302204 DCHECK(!context_.get());
2205
[email protected]55e136f2013-04-03 18:50:062206 set_initialized();
[email protected]fb97b662013-02-20 23:02:142207 gpu_tracer_ = GPUTracer::Create();
2208
[email protected]e844ae22012-01-14 03:36:262209 if (CommandLine::ForCurrentProcess()->HasSwitch(
2210 switches::kEnableGPUDebugging)) {
2211 set_debug(true);
2212 }
2213
[email protected]39ba4f02012-03-26 01:16:002214 if (CommandLine::ForCurrentProcess()->HasSwitch(
2215 switches::kEnableGPUCommandLogging)) {
2216 set_log_commands(true);
2217 }
2218
[email protected]062c38b2012-01-18 03:25:102219 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2220 switches::kCompileShaderAlwaysSucceeds);
2221
[email protected]f62a5ab2011-05-23 20:34:152222
[email protected]63c9b052012-05-17 18:27:382223 // Take ownership of the context and surface. The surface can be replaced with
2224 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382225 context_ = context;
[email protected]63c9b052012-05-17 18:27:382226 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182227
[email protected]c4485aad62012-12-17 10:19:092228 if (!group_->Initialize(this, disallowed_features, allowed_extensions)) {
[email protected]09ddb91f2011-04-14 23:16:222229 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392230 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422231 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382232 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032233 return false;
[email protected]a3ded6d2010-10-19 06:44:392234 }
[email protected]b64c24952012-04-19 03:20:272235 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282236
[email protected]e82fb792011-09-22 00:33:292237 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502238
[email protected]af6380962012-11-29 23:24:132239 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462240 default_vertex_attrib_manager_ = new VertexAttribManager();
2241 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2242
[email protected]ab4fd7282012-10-12 16:25:572243 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2244 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322245
[email protected]7cd76fd2013-06-02 21:11:112246 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]944b62f32012-09-27 02:20:462247 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532248
[email protected]302ce6d2011-07-07 23:28:112249 util_.set_num_compressed_texture_formats(
2250 validators_->compressed_texture_format.GetValues().size());
2251
[email protected]1071e572011-02-09 20:00:122252 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2253 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2254 // OpenGL ES 2.0 does not have this issue.
2255 glEnableVertexAttribArray(0);
2256 }
[email protected]b1122982010-05-17 23:04:242257 glGenBuffersARB(1, &attrib_0_buffer_id_);
2258 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2259 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2260 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402261 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082262
[email protected]1868a342012-11-07 15:56:022263 state_.texture_units.resize(group_->max_texture_units());
2264 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492265 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312266 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492267 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152268 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492269 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072270 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492271 state_.texture_units[tt].bound_texture_external_oes = ref;
2272 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id());
[email protected]61eeb33f2011-07-26 15:30:312273 }
[email protected]62e155e2012-10-23 22:43:152274 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492275 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072276 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492277 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2278 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id());
[email protected]e51bdf32011-11-23 22:21:462279 }
[email protected]370eaf12013-05-18 09:19:492280 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2281 state_.texture_units[tt].bound_texture_cube_map = ref;
2282 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id());
2283 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2284 state_.texture_units[tt].bound_texture_2d = ref;
2285 glBindTexture(GL_TEXTURE_2D, ref->service_id());
[email protected]1958e0e2010-04-22 05:17:152286 }
[email protected]00f893d2010-08-24 18:55:492287 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502288 CHECK_GL_ERROR();
2289
[email protected]297ca1c2011-06-20 23:08:462290 ContextCreationAttribParser attrib_parser;
2291 if (!attrib_parser.Parse(attribs))
2292 return false;
[email protected]41c56362011-06-14 16:47:432293
[email protected]069944672012-04-25 20:52:232294 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022295 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542296 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022297 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432298 // max_sample_count must be initialized to a sane value. If
2299 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2300 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022301 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2302 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2303 max_sample_count);
2304 } else {
2305 offscreen_target_samples_ = 1;
2306 }
[email protected]8a61d872012-01-20 12:43:562307 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022308
2309 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2310 const bool rgb8_supported =
2311 context_->HasExtension("GL_OES_rgb8_rgba8");
2312 // The only available default render buffer formats in GLES2 have very
2313 // little precision. Don't enable multisampling unless 8-bit render
2314 // buffer formats are available--instead fall back to 8-bit textures.
2315 if (rgb8_supported && offscreen_target_samples_ > 1) {
2316 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2317 GL_RGBA8 : GL_RGB8;
2318 } else {
2319 offscreen_target_samples_ = 1;
2320 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2321 GL_RGBA : GL_RGB;
2322 }
2323
2324 // ANGLE only supports packed depth/stencil formats, so use it if it is
2325 // available.
2326 const bool depth24_stencil8_supported =
2327 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272328 VLOG(1) << "GL_OES_packed_depth_stencil "
2329 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002330 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2331 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022332 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2333 offscreen_target_stencil_format_ = 0;
2334 } else {
2335 // It may be the case that this depth/stencil combination is not
2336 // supported, but this will be checked later by CheckFramebufferStatus.
2337 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2338 GL_DEPTH_COMPONENT16 : 0;
2339 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2340 GL_STENCIL_INDEX8 : 0;
2341 }
2342 } else {
2343 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2344 GL_RGBA : GL_RGB;
2345
2346 // If depth is requested at all, use the packed depth stencil format if
2347 // it's available, as some desktop GL drivers don't support any non-packed
2348 // formats for depth attachments.
2349 const bool depth24_stencil8_supported =
2350 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272351 VLOG(1) << "GL_EXT_packed_depth_stencil "
2352 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022353
[email protected]71ee3642010-10-14 18:08:002354 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2355 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022356 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2357 offscreen_target_stencil_format_ = 0;
2358 } else {
2359 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2360 GL_DEPTH_COMPONENT : 0;
2361 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2362 GL_STENCIL_INDEX : 0;
2363 }
2364 }
2365
[email protected]97872062010-11-03 19:07:052366 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2367 GL_RGBA : GL_RGB;
2368
[email protected]6217d392010-03-25 22:08:352369 // Create the target frame buffer. This is the one that the client renders
2370 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352371 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352372 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022373 // Due to GLES2 format limitations, either the color texture (for
2374 // non-multisampling) or the color render buffer (for multisampling) will be
2375 // attached to the offscreen frame buffer. The render buffer has more
2376 // limited formats available to it, but the texture can't do multisampling.
2377 if (IsOffscreenBufferMultisampled()) {
[email protected]ed9f9cd2013-02-27 21:12:352378 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022379 offscreen_target_color_render_buffer_->Create();
2380 } else {
[email protected]ed9f9cd2013-02-27 21:12:352381 offscreen_target_color_texture_.reset(new BackTexture(this));
[email protected]34ff8b0c2010-10-01 20:06:022382 offscreen_target_color_texture_->Create();
2383 }
[email protected]ed9f9cd2013-02-27 21:12:352384 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152385 offscreen_target_depth_render_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352386 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152387 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352388
2389 // Create the saved offscreen texture. The target frame buffer is copied
2390 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352391 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022392 offscreen_saved_frame_buffer_->Create();
2393 //
[email protected]ed9f9cd2013-02-27 21:12:352394 offscreen_saved_color_texture_.reset(new BackTexture(this));
[email protected]6217d392010-03-25 22:08:352395 offscreen_saved_color_texture_->Create();
2396
[email protected]6217d392010-03-25 22:08:352397 // Allocate the render buffers at their initial size and check the status
2398 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592399 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012400 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382401 Destroy(true);
[email protected]6217d392010-03-25 22:08:352402 return false;
2403 }
2404
[email protected]678a73f2012-12-19 19:22:092405 // Allocate the offscreen saved color texture.
2406 DCHECK(offscreen_saved_color_format_);
2407 offscreen_saved_color_texture_->AllocateStorage(
2408 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2409
2410 offscreen_saved_frame_buffer_->AttachRenderTexture(
2411 offscreen_saved_color_texture_.get());
2412 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2413 GL_FRAMEBUFFER_COMPLETE) {
2414 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2415 Destroy(true);
2416 return false;
2417 }
2418
[email protected]6217d392010-03-25 22:08:352419 // Bind to the new default frame buffer (the offscreen target frame buffer).
2420 // This should now be associated with ID zero.
2421 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102422 } else {
2423 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2424 // These are NOT if the back buffer has these proprorties. They are
2425 // if we want the command buffer to enforce them regardless of what
2426 // the real backbuffer is assuming the real back buffer gives us more than
2427 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2428 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2429 // can't do anything about that.
2430
2431 GLint v = 0;
2432 glGetIntegerv(GL_ALPHA_BITS, &v);
2433 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2434 // user requested RGB then RGB. If the user did not specify a preference
2435 // than use whatever we were given. Same for DEPTH and STENCIL.
2436 back_buffer_color_format_ =
2437 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2438 glGetIntegerv(GL_DEPTH_BITS, &v);
2439 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2440 glGetIntegerv(GL_STENCIL_BITS, &v);
2441 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
[email protected]6217d392010-03-25 22:08:352442 }
2443
[email protected]76a0ee102010-04-07 21:03:042444 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2445 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2446 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372447 // mailing list archives. It also implicitly enables the desktop GL
2448 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2449 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152450 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2451 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372452 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152453 }
[email protected]de17df392010-04-23 21:09:412454
[email protected]706b69f2012-07-27 04:59:302455 has_robustness_extension_ =
2456 context->HasExtension("GL_ARB_robustness") ||
2457 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432458
[email protected]c2f8c8402010-12-06 18:07:242459 if (!InitializeShaderTranslator()) {
2460 return false;
[email protected]de17df392010-04-23 21:09:412461 }
[email protected]76a0ee102010-04-07 21:03:042462
[email protected]e259eb412012-10-13 05:47:242463 state_.viewport_width = size.width();
2464 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282465
[email protected]5904806b2012-05-08 18:10:222466 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282467 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022468 viewport_max_width_ = viewport_params[0];
2469 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282470
[email protected]88a61bf2012-10-27 13:00:422471 state_.scissor_width = state_.viewport_width;
2472 state_.scissor_height = state_.viewport_height;
2473
[email protected]11f3e702012-06-19 19:00:012474 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222475 state_.InitCapabilities();
2476 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242477 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012478
2479 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2480 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2481 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2482 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2483
[email protected]88cfd132013-07-11 00:59:002484 bool call_gl_clear = true;
2485#if defined(OS_ANDROID)
2486 // Temporary workaround for Android WebView because this clear ignores the
2487 // clip and corrupts that external UI of the App. Not calling glClear is ok
2488 // because the system already clears the buffer before each draw. Proper
2489 // fix might be setting the scissor clip properly before initialize. See
2490 // crbug.com/259023 for details.
2491 call_gl_clear = surface_->GetHandle();
2492#endif
2493 if (call_gl_clear) {
2494 // Clear the backbuffer.
2495 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2496 }
[email protected]561cc0a62013-05-07 18:34:452497
[email protected]62e155e2012-10-23 22:43:152498 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462499 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2500 }
[email protected]dd289a5d62012-06-30 22:05:462501
[email protected]9b753992013-04-27 02:04:412502 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2503 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242504 }
[email protected]85cb4682013-04-20 00:54:242505
[email protected]97419c02013-04-10 02:52:382506 // Only compositor contexts are known to use only the subset of GL
2507 // that can be safely migrated between the iGPU and the dGPU. Mark
2508 // those contexts as safe to forcibly transition between the GPUs.
2509 // http://crbug.com/180876, http://crbug.com/227228
2510 if (!offscreen)
2511 context_->SetSafeToForceGpuSwitch();
2512
[email protected]85a4ac22013-05-31 01:58:472513 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072514 AsyncPixelTransferManager::Create(context.get()));
2515 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592516
[email protected]246a70452010-03-05 21:53:502517 return true;
[email protected]96449d2c2009-11-25 00:01:322518}
2519
[email protected]302ce6d2011-07-07 23:28:112520void GLES2DecoderImpl::UpdateCapabilities() {
2521 util_.set_num_compressed_texture_formats(
2522 validators_->compressed_texture_format.GetValues().size());
2523 util_.set_num_shader_binary_formats(
2524 validators_->shader_binary_format.GetValues().size());
2525}
2526
[email protected]c2f8c8402010-12-06 18:07:242527bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442528 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2529
[email protected]c2f8c8402010-12-06 18:07:242530 if (!use_shader_translator_) {
2531 return true;
2532 }
2533 ShBuiltInResources resources;
2534 ShInitBuiltInResources(&resources);
2535 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2536 resources.MaxVertexUniformVectors =
2537 group_->max_vertex_uniform_vectors();
2538 resources.MaxVaryingVectors = group_->max_varying_vectors();
2539 resources.MaxVertexTextureImageUnits =
2540 group_->max_vertex_texture_image_units();
2541 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2542 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2543 resources.MaxFragmentUniformVectors =
2544 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492545 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242546 resources.MaxExpressionComplexity = 256;
2547 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042548
[email protected]9e98f61b2013-03-05 02:21:142549#if (ANGLE_SH_VERSION >= 110)
[email protected]46c86752013-05-21 05:08:392550 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212551 GLint precision = 0;
2552 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2553 range, &precision);
[email protected]448e459e2013-06-12 17:00:412554 resources.FragmentPrecisionHigh =
2555 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142556#endif
2557
[email protected]f0d74742011-10-03 16:31:042558 if (force_webgl_glsl_validation_) {
2559 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492560 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132561 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:042562 } else {
2563 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152564 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462565 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152566 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062567 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152568 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492569 resources.EXT_draw_buffers =
2570 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492571 resources.EXT_frag_depth =
2572 features().ext_frag_depth ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042573 }
2574
[email protected]26b61442013-03-17 16:12:012575 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2576 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052577 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022578#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052579 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022580#else
2581 resources.HashFunction = &CityHash64;
2582#endif
[email protected]6aedcdc2013-01-24 01:25:052583 else
2584 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122585 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2586 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2587 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2588 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
[email protected]62e155e2012-10-23 22:43:152589 workarounds().needs_glsl_built_in_function_emulation ?
[email protected]a2a0fe762011-09-20 00:59:122590 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
2591 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
[email protected]87fb6ab2012-06-13 22:28:042592
2593 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2594 vertex_translator_ = cache->GetTranslator(
2595 SH_VERTEX_SHADER, shader_spec, &resources,
2596 implementation_type, function_behavior);
2597 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242598 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382599 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242600 return false;
2601 }
[email protected]87fb6ab2012-06-13 22:28:042602
2603 fragment_translator_ = cache->GetTranslator(
2604 SH_FRAGMENT_SHADER, shader_spec, &resources,
2605 implementation_type, function_behavior);
2606 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242607 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382608 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242609 return false;
2610 }
2611 return true;
2612}
2613
[email protected]ae51d192010-04-27 00:48:032614bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472615 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352616 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032617 return false;
2618 }
2619 }
[email protected]40d90a22013-04-09 03:39:552620 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032621 glGenBuffersARB(n, service_ids.get());
2622 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352623 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032624 }
2625 return true;
2626}
2627
2628bool GLES2DecoderImpl::GenFramebuffersHelper(
2629 GLsizei n, const GLuint* client_ids) {
2630 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352631 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032632 return false;
2633 }
2634 }
[email protected]40d90a22013-04-09 03:39:552635 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032636 glGenFramebuffersEXT(n, service_ids.get());
2637 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352638 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032639 }
2640 return true;
2641}
2642
2643bool GLES2DecoderImpl::GenRenderbuffersHelper(
2644 GLsizei n, const GLuint* client_ids) {
2645 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352646 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032647 return false;
2648 }
2649 }
[email protected]40d90a22013-04-09 03:39:552650 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032651 glGenRenderbuffersEXT(n, service_ids.get());
2652 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352653 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032654 }
2655 return true;
2656}
2657
2658bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2659 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352660 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032661 return false;
2662 }
2663 }
[email protected]40d90a22013-04-09 03:39:552664 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032665 glGenTextures(n, service_ids.get());
2666 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352667 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032668 }
2669 return true;
2670}
2671
2672void GLES2DecoderImpl::DeleteBuffersHelper(
2673 GLsizei n, const GLuint* client_ids) {
2674 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212675 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102676 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242677 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112678 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242679 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102680 }
[email protected]ed9f9cd2013-02-27 21:12:352681 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032682 }
[email protected]a93bb842010-02-16 23:03:472683 }
[email protected]07f54fcc2009-12-22 02:46:302684}
2685
[email protected]ae51d192010-04-27 00:48:032686void GLES2DecoderImpl::DeleteFramebuffersHelper(
2687 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452688 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152689 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112690
[email protected]a25fa872010-03-25 02:57:582691 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352692 Framebuffer* framebuffer =
2693 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102694 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112695 if (framebuffer == state_.bound_draw_framebuffer.get()) {
[email protected]e259eb412012-10-13 05:47:242696 state_.bound_draw_framebuffer = NULL;
[email protected]88a61bf2012-10-27 13:00:422697 clear_state_dirty_ = true;
[email protected]ebfb73c2012-08-15 02:37:452698 GLenum target = supports_separate_framebuffer_binds ?
2699 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112700 glBindFramebufferEXT(target, GetBackbufferServiceId());
2701 }
[email protected]7cd76fd2013-06-02 21:11:112702 if (framebuffer == state_.bound_read_framebuffer.get()) {
[email protected]e259eb412012-10-13 05:47:242703 state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452704 GLenum target = supports_separate_framebuffer_binds ?
2705 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112706 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462707 }
[email protected]70d34263c2013-01-09 00:27:452708 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352709 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032710 }
[email protected]a25fa872010-03-25 02:57:582711 }
[email protected]07f54fcc2009-12-22 02:46:302712}
2713
[email protected]ae51d192010-04-27 00:48:032714void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2715 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452716 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152717 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582718 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352719 Renderbuffer* renderbuffer =
2720 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102721 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112722 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242723 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102724 }
2725 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452726 if (supports_separate_framebuffer_binds) {
[email protected]7cd76fd2013-06-02 21:11:112727 if (state_.bound_read_framebuffer.get()) {
2728 state_.bound_read_framebuffer
2729 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102730 }
[email protected]7cd76fd2013-06-02 21:11:112731 if (state_.bound_draw_framebuffer.get()) {
2732 state_.bound_draw_framebuffer
2733 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102734 }
2735 } else {
[email protected]7cd76fd2013-06-02 21:11:112736 if (state_.bound_draw_framebuffer.get()) {
2737 state_.bound_draw_framebuffer
2738 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102739 }
2740 }
[email protected]88a61bf2012-10-27 13:00:422741 clear_state_dirty_ = true;
[email protected]ed9f9cd2013-02-27 21:12:352742 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032743 }
[email protected]a25fa872010-03-25 02:57:582744 }
[email protected]07f54fcc2009-12-22 02:46:302745}
2746
[email protected]ae51d192010-04-27 00:48:032747void GLES2DecoderImpl::DeleteTexturesHelper(
2748 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452749 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152750 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472751 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492752 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2753 if (texture_ref) {
2754 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102755 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:422756 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462757 }
[email protected]370eaf12013-05-18 09:19:492758 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:022759 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:492760 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102761 }
2762 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452763 if (supports_separate_framebuffer_binds) {
[email protected]7cd76fd2013-06-02 21:11:112764 if (state_.bound_read_framebuffer.get()) {
2765 state_.bound_read_framebuffer
2766 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102767 }
[email protected]7cd76fd2013-06-02 21:11:112768 if (state_.bound_draw_framebuffer.get()) {
2769 state_.bound_draw_framebuffer
2770 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102771 }
2772 } else {
[email protected]7cd76fd2013-06-02 21:11:112773 if (state_.bound_draw_framebuffer.get()) {
2774 state_.bound_draw_framebuffer
2775 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102776 }
2777 }
[email protected]e51bdf32011-11-23 22:21:462778#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:072779 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:462780 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2781 ReleaseIOSurfaceForTexture(service_id);
2782 }
2783#endif
[email protected]ed9f9cd2013-02-27 21:12:352784 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032785 }
[email protected]a93bb842010-02-16 23:03:472786 }
[email protected]07f54fcc2009-12-22 02:46:302787}
2788
[email protected]43f28f832010-02-03 02:28:482789// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322790
[email protected]eb54a562010-01-20 21:55:182791bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382792 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2793 return false;
2794
2795 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432796 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292797
2798 // Some D3D drivers cannot recover from device lost in the GPU process
2799 // sandbox. Allow a new GPU process to launch.
2800 if (workarounds().exit_on_context_lost) {
2801 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2802 << " a D3D device in the Chrome GPU process sandbox.";
2803 exit(0);
2804 }
2805
[email protected]63c9b052012-05-17 18:27:382806 return false;
[email protected]38d139d2011-07-14 00:38:432807 }
2808
[email protected]69a8701e2013-03-07 21:31:092809 ProcessFinishedAsyncTransfers();
2810 if (workarounds().flush_on_context_switch)
2811 glFlush();
2812
[email protected]9b753992013-04-27 02:04:412813 // Rebind the FBO if it was unbound by the context.
2814 if (workarounds().unbind_fbo_on_context_switch)
2815 RestoreFramebufferBindings();
2816
[email protected]370eaf12013-05-18 09:19:492817 clear_state_dirty_ = true;
2818
[email protected]69a8701e2013-03-07 21:31:092819 return true;
2820}
2821
2822void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]fe8d73c2013-02-16 22:37:322823 if (engine() && query_manager_.get())
2824 query_manager_->ProcessPendingTransferQueries();
2825
[email protected]5b3a8e02013-03-13 05:36:442826 // TODO(epenner): Is there a better place to do this?
2827 // This needs to occur before we execute any batch of commands
2828 // from the client, as the client may have recieved an async
2829 // completion while issuing those commands.
2830 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:482831 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:182832}
2833
[email protected]a96a6022011-11-04 00:58:122834void GLES2DecoderImpl::ReleaseCurrent() {
2835 if (context_.get())
2836 context_->ReleaseCurrent(surface_.get());
2837}
2838
[email protected]8e3e0662010-08-23 18:46:302839void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
[email protected]ed9f9cd2013-02-27 21:12:352840 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:202841 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
[email protected]8e3e0662010-08-23 18:46:302842 glBindRenderbufferEXT(
[email protected]0d6bfdc2011-11-02 01:32:202843 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
[email protected]8e3e0662010-08-23 18:46:302844}
2845
2846static void RebindCurrentFramebuffer(
2847 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062848 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242849 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062850 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462851
[email protected]a3783712012-01-20 22:18:242852 if (framebuffer_id == 0) {
2853 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302854 }
[email protected]297ca1c2011-06-20 23:08:462855
[email protected]8e3e0662010-08-23 18:46:302856 glBindFramebufferEXT(target, framebuffer_id);
2857}
2858
2859void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]88a61bf2012-10-27 13:00:422860 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462861
[email protected]62e155e2012-10-23 22:43:152862 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302863 RebindCurrentFramebuffer(
2864 GL_FRAMEBUFFER,
[email protected]e259eb412012-10-13 05:47:242865 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242866 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302867 } else {
2868 RebindCurrentFramebuffer(
2869 GL_READ_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242870 state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242871 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302872 RebindCurrentFramebuffer(
2873 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242874 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242875 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302876 }
[email protected]70d34263c2013-01-09 00:27:452877 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302878}
2879
2880void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
[email protected]e259eb412012-10-13 05:47:242881 TextureUnit& info = state_.texture_units[0];
[email protected]8e3e0662010-08-23 18:46:302882 GLuint last_id;
[email protected]7cd76fd2013-06-02 21:11:112883 if (info.bound_texture_2d.get()) {
[email protected]8e3e0662010-08-23 18:46:302884 last_id = info.bound_texture_2d->service_id();
2885 } else {
2886 last_id = 0;
2887 }
2888
2889 glBindTexture(GL_TEXTURE_2D, last_id);
[email protected]e259eb412012-10-13 05:47:242890 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]8e3e0662010-08-23 18:46:302891}
2892
[email protected]0d6bfdc2011-11-02 01:32:202893bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352894 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202895 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102896 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582897 if (backbuffer_needs_clear_bits_) {
2898 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2899 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2900 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2901 glClearStencil(0);
2902 glStencilMask(-1);
2903 glClearDepth(1.0f);
2904 glDepthMask(true);
2905 glDisable(GL_SCISSOR_TEST);
2906 glClear(backbuffer_needs_clear_bits_);
2907 backbuffer_needs_clear_bits_ = 0;
2908 RestoreClearState();
2909 }
[email protected]0d6bfdc2011-11-02 01:32:202910 return true;
2911 }
2912
[email protected]968351b2011-12-20 08:26:512913 if (framebuffer_manager()->IsComplete(framebuffer)) {
2914 return true;
2915 }
2916
[email protected]0d6bfdc2011-11-02 01:32:202917 GLenum completeness = framebuffer->IsPossiblyComplete();
2918 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512919 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432920 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272921 return false;
2922 }
[email protected]0d6bfdc2011-11-02 01:32:202923
2924 // Are all the attachments cleared?
2925 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2926 texture_manager()->HaveUnclearedMips()) {
2927 if (!framebuffer->IsCleared()) {
2928 // Can we clear them?
[email protected]73276522012-11-09 05:50:202929 if (framebuffer->GetStatus(texture_manager(), target) !=
2930 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512931 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432932 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2933 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202934 return false;
2935 }
2936 ClearUnclearedAttachments(target, framebuffer);
2937 }
2938 }
2939
[email protected]968351b2011-12-20 08:26:512940 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202941 if (framebuffer->GetStatus(texture_manager(), target) !=
2942 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512943 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432944 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2945 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512946 return false;
2947 }
2948 framebuffer_manager()->MarkAsComplete(framebuffer);
2949 }
2950
[email protected]0d6bfdc2011-11-02 01:32:202951 // NOTE: At this point we don't know if the framebuffer is complete but
2952 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272953 return true;
2954}
2955
[email protected]0d6bfdc2011-11-02 01:32:202956bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:152957 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:512958 bool valid = CheckFramebufferValid(
[email protected]7cd76fd2013-06-02 21:11:112959 state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT, func_name);
[email protected]28718a92013-04-04 12:12:512960
2961 if (valid)
2962 OnUseFramebuffer();
2963
2964 return valid;
[email protected]0d6bfdc2011-11-02 01:32:202965 }
[email protected]7cd76fd2013-06-02 21:11:112966 return CheckFramebufferValid(state_.bound_draw_framebuffer.get(),
2967 GL_DRAW_FRAMEBUFFER_EXT,
2968 func_name) &&
2969 CheckFramebufferValid(state_.bound_read_framebuffer.get(),
2970 GL_READ_FRAMEBUFFER_EXT,
2971 func_name);
[email protected]0d6bfdc2011-11-02 01:32:202972}
2973
[email protected]8e3e0662010-08-23 18:46:302974gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:352975 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452976 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202977 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:352978 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:202979 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:262980 if (attachment) {
2981 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:502982 }
[email protected]9edc6b22010-12-23 02:00:262983 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:022984 } else if (offscreen_target_frame_buffer_.get()) {
2985 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:352986 } else {
[email protected]f62a5ab2011-05-23 20:34:152987 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:022988 }
[email protected]246a70452010-03-05 21:53:502989}
2990
[email protected]9edc6b22010-12-23 02:00:262991GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352992 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452993 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202994 if (framebuffer != NULL) {
2995 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:462996 } else if (offscreen_target_frame_buffer_.get()) {
2997 return offscreen_target_color_format_;
2998 } else {
2999 return back_buffer_color_format_;
3000 }
3001}
3002
3003GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353004 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453005 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203006 if (framebuffer != NULL) {
3007 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263008 } else if (offscreen_target_frame_buffer_.get()) {
3009 return offscreen_target_color_format_;
3010 } else {
[email protected]32fe9aa2011-01-21 23:47:133011 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263012 }
3013}
3014
[email protected]9a5afa432011-07-22 18:16:393015void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513016 if (!offscreen_saved_color_texture_info_.get())
3017 return;
3018 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3019 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3020 texture_manager()->SetLevelInfo(
3021 offscreen_saved_color_texture_info_.get(),
3022 GL_TEXTURE_2D,
3023 0, // level
3024 GL_RGBA,
3025 offscreen_size_.width(),
3026 offscreen_size_.height(),
3027 1, // depth
3028 0, // border
3029 GL_RGBA,
3030 GL_UNSIGNED_BYTE,
3031 true);
3032 texture_manager()->SetParameter(
3033 "UpdateParentTextureInfo",
3034 GetErrorState(),
3035 offscreen_saved_color_texture_info_.get(),
3036 GL_TEXTURE_MAG_FILTER,
3037 GL_NEAREST);
3038 texture_manager()->SetParameter(
3039 "UpdateParentTextureInfo",
3040 GetErrorState(),
3041 offscreen_saved_color_texture_info_.get(),
3042 GL_TEXTURE_MIN_FILTER,
3043 GL_NEAREST);
3044 texture_manager()->SetParameter(
3045 "UpdateParentTextureInfo",
3046 GetErrorState(),
3047 offscreen_saved_color_texture_info_.get(),
3048 GL_TEXTURE_WRAP_S,
3049 GL_CLAMP_TO_EDGE);
3050 texture_manager()->SetParameter(
3051 "UpdateParentTextureInfo",
3052 GetErrorState(),
3053 offscreen_saved_color_texture_info_.get(),
3054 GL_TEXTURE_WRAP_T,
3055 GL_CLAMP_TO_EDGE);
3056 TextureRef* texture_ref = GetTextureInfoForTarget(target);
3057 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353058}
3059
[email protected]799b4b22011-08-22 17:09:593060void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073061 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523062 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003063}
3064
[email protected]1d82e822013-04-10 21:32:323065Logger* GLES2DecoderImpl::GetLogger() {
3066 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523067}
3068
[email protected]d3eba342013-04-18 21:11:503069ErrorState* GLES2DecoderImpl::GetErrorState() {
3070 return state_.GetErrorState();
3071}
3072
[email protected]e3932abb2013-03-13 00:01:373073void GLES2DecoderImpl::SetShaderCacheCallback(
3074 const ShaderCacheCallback& callback) {
3075 shader_cache_callback_ = callback;
3076}
3077
[email protected]840a7e462013-02-27 01:29:513078void GLES2DecoderImpl::SetWaitSyncPointCallback(
3079 const WaitSyncPointCallback& callback) {
3080 wait_sync_point_callback_ = callback;
3081}
3082
[email protected]85a4ac22013-05-31 01:58:473083AsyncPixelTransferManager*
3084 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3085 return async_pixel_transfer_manager_.get();
3086}
3087
3088void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3089 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593090}
3091
[email protected]498b5c072013-06-04 19:30:073092void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3093 AsyncPixelTransferManager* manager) {
3094 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3095}
3096
[email protected]1318e922010-09-17 22:03:163097bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3098 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493099 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3100 if (texture_ref) {
3101 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163102 return true;
3103 }
3104 return false;
3105}
3106
[email protected]63b465922012-09-06 02:04:523107uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]b9804322013-01-08 17:54:123108 return texture_upload_count_ +
[email protected]b68b100752013-06-05 08:34:483109 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523110}
3111
3112base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]b9804322013-01-08 17:54:123113 return total_texture_upload_time_ +
[email protected]b68b100752013-06-05 08:34:483114 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523115}
3116
3117base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3118 return total_processing_commands_time_;
3119}
3120
[email protected]dc25dda2012-09-27 21:36:303121void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3122 total_processing_commands_time_ += time;
3123}
3124
[email protected]63c9b052012-05-17 18:27:383125void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063126 if (!initialized())
3127 return;
3128
[email protected]63c9b052012-05-17 18:27:383129 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053130
[email protected]80eb6b52012-01-19 00:14:413131 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243132 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463133 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023134 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243135 state_.bound_array_buffer = NULL;
3136 state_.current_query = NULL;
3137 state_.current_program = NULL;
3138 state_.bound_read_framebuffer = NULL;
3139 state_.bound_draw_framebuffer = NULL;
3140 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413141
[email protected]cadac622013-06-11 16:46:363142 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513143 DCHECK(offscreen_target_color_texture_);
3144 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3145 offscreen_saved_color_texture_->id());
3146 offscreen_saved_color_texture_->Invalidate();
3147 offscreen_saved_color_texture_info_ = NULL;
3148 }
[email protected]eadc96792010-10-27 19:39:393149 if (have_context) {
[email protected]c322e882012-05-23 18:06:183150 if (copy_texture_CHROMIUM_.get()) {
3151 copy_texture_CHROMIUM_->Destroy();
3152 copy_texture_CHROMIUM_.reset();
3153 }
[email protected]43410e92012-04-20 17:06:283154
[email protected]7cd76fd2013-06-02 21:11:113155 if (state_.current_program.get()) {
3156 program_manager()->UnuseProgram(shader_manager(),
3157 state_.current_program.get());
[email protected]e259eb412012-10-13 05:47:243158 state_.current_program = NULL;
[email protected]ca488e12010-12-13 20:06:143159 }
3160
[email protected]b1122982010-05-17 23:04:243161 if (attrib_0_buffer_id_) {
3162 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3163 }
[email protected]8fbedc02010-11-18 18:43:403164 if (fixed_attrib_buffer_id_) {
3165 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3166 }
[email protected]b1122982010-05-17 23:04:243167
[email protected]97872062010-11-03 19:07:053168 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543169 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053170 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543171 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053172 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023173 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053174 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153175 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053176 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153177 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053178 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023179 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053180 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543181 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273182 if (offscreen_resolved_frame_buffer_.get())
3183 offscreen_resolved_frame_buffer_->Destroy();
3184 if (offscreen_resolved_color_texture_.get())
3185 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053186 } else {
3187 if (offscreen_target_frame_buffer_.get())
3188 offscreen_target_frame_buffer_->Invalidate();
3189 if (offscreen_target_color_texture_.get())
3190 offscreen_target_color_texture_->Invalidate();
3191 if (offscreen_target_color_render_buffer_.get())
3192 offscreen_target_color_render_buffer_->Invalidate();
3193 if (offscreen_target_depth_render_buffer_.get())
3194 offscreen_target_depth_render_buffer_->Invalidate();
3195 if (offscreen_target_stencil_render_buffer_.get())
3196 offscreen_target_stencil_render_buffer_->Invalidate();
3197 if (offscreen_saved_frame_buffer_.get())
3198 offscreen_saved_frame_buffer_->Invalidate();
3199 if (offscreen_saved_color_texture_.get())
3200 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273201 if (offscreen_resolved_frame_buffer_.get())
3202 offscreen_resolved_frame_buffer_->Invalidate();
3203 if (offscreen_resolved_color_texture_.get())
3204 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023205 }
[email protected]43410e92012-04-20 17:06:283206 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053207
[email protected]882ba1e22012-03-08 19:02:533208 if (query_manager_.get()) {
3209 query_manager_->Destroy(have_context);
3210 query_manager_.reset();
3211 }
3212
[email protected]944b62f32012-09-27 02:20:463213 if (vertex_array_manager_ .get()) {
3214 vertex_array_manager_->Destroy(have_context);
3215 vertex_array_manager_.reset();
3216 }
3217
[email protected]97872062010-11-03 19:07:053218 offscreen_target_frame_buffer_.reset();
3219 offscreen_target_color_texture_.reset();
3220 offscreen_target_color_render_buffer_.reset();
3221 offscreen_target_depth_render_buffer_.reset();
3222 offscreen_target_stencil_render_buffer_.reset();
3223 offscreen_saved_frame_buffer_.reset();
3224 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273225 offscreen_resolved_frame_buffer_.reset();
3226 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463227
[email protected]85a4ac22013-05-31 01:58:473228 // Should destroy the transfer manager before the texture manager held
3229 // by the context group.
3230 async_pixel_transfer_manager_.reset();
3231
[email protected]7cd76fd2013-06-02 21:11:113232 if (group_.get()) {
[email protected]2d9d3b92013-01-18 01:07:233233 group_->Destroy(this, have_context);
3234 group_ = NULL;
3235 }
3236
3237 if (context_.get()) {
3238 context_->ReleaseCurrent(NULL);
3239 context_ = NULL;
3240 }
3241
[email protected]e51bdf32011-11-23 22:21:463242#if defined(OS_MACOSX)
3243 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3244 it != texture_to_io_surface_map_.end(); ++it) {
3245 CFRelease(it->second);
3246 }
3247 texture_to_io_surface_map_.clear();
3248#endif
[email protected]96449d2c2009-11-25 00:01:323249}
3250
[email protected]63c9b052012-05-17 18:27:383251void GLES2DecoderImpl::SetSurface(
3252 const scoped_refptr<gfx::GLSurface>& surface) {
3253 DCHECK(context_->IsCurrent(NULL));
3254 DCHECK(surface_.get());
3255 surface_ = surface;
3256 RestoreCurrentFramebufferBindings();
3257}
3258
[email protected]2ad674132013-06-05 07:48:513259bool GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
[email protected]9a5afa432011-07-22 18:16:393260 if (!offscreen_saved_color_texture_.get())
3261 return false;
[email protected]2ad674132013-06-05 07:48:513262 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243263 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073264 offscreen_saved_color_texture_info_ = TextureRef::Create(
3265 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513266 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3267 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393268 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243269 }
[email protected]2ad674132013-06-05 07:48:513270 gpu::gles2::MailboxName name;
3271 memcpy(name.key, mailbox.name, sizeof(mailbox.name));
3272 return mailbox_manager()->ProduceTexture(
3273 GL_TEXTURE_2D, name, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243274}
3275
[email protected]260ddc4e2012-06-28 00:01:533276size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143277 size_t total = 0;
3278 if (offscreen_target_frame_buffer_.get()) {
3279 if (offscreen_target_color_texture_.get()) {
3280 total += offscreen_target_color_texture_->estimated_size();
3281 }
3282 if (offscreen_target_color_render_buffer_.get()) {
3283 total += offscreen_target_color_render_buffer_->estimated_size();
3284 }
3285 if (offscreen_target_depth_render_buffer_.get()) {
3286 total += offscreen_target_depth_render_buffer_->estimated_size();
3287 }
3288 if (offscreen_target_stencil_render_buffer_.get()) {
3289 total += offscreen_target_stencil_render_buffer_->estimated_size();
3290 }
3291 if (offscreen_saved_color_texture_.get()) {
3292 total += offscreen_saved_color_texture_->estimated_size();
3293 }
3294 if (offscreen_resolved_color_texture_.get()) {
3295 total += offscreen_resolved_color_texture_->estimated_size();
3296 }
3297 } else {
3298 gfx::Size size = surface_->GetSize();
3299 total += size.width() * size.height() *
3300 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3301 }
[email protected]260ddc4e2012-06-28 00:01:533302 return total;
[email protected]1078f912011-12-23 13:12:143303}
3304
[email protected]799b4b22011-08-22 17:09:593305bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3306 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3307 if (!is_offscreen) {
3308 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3309 << " with an onscreen framebuffer.";
3310 return false;
3311 }
3312
3313 if (offscreen_size_ == size)
3314 return true;
3315
3316 offscreen_size_ = size;
3317 int w = offscreen_size_.width();
3318 int h = offscreen_size_.height();
3319 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3320 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3321 << "to allocate storage due to excessive dimensions.";
3322 return false;
3323 }
3324
3325 // Reallocate the offscreen target buffers.
3326 DCHECK(offscreen_target_color_format_);
3327 if (IsOffscreenBufferMultisampled()) {
3328 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3329 offscreen_size_, offscreen_target_color_format_,
3330 offscreen_target_samples_)) {
3331 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3332 << "to allocate storage for offscreen target color buffer.";
3333 return false;
3334 }
3335 } else {
3336 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093337 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593338 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3339 << "to allocate storage for offscreen target color texture.";
3340 return false;
3341 }
3342 }
3343 if (offscreen_target_depth_format_ &&
3344 !offscreen_target_depth_render_buffer_->AllocateStorage(
3345 offscreen_size_, offscreen_target_depth_format_,
3346 offscreen_target_samples_)) {
3347 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3348 << "to allocate storage for offscreen target depth buffer.";
3349 return false;
3350 }
3351 if (offscreen_target_stencil_format_ &&
3352 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3353 offscreen_size_, offscreen_target_stencil_format_,
3354 offscreen_target_samples_)) {
3355 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3356 << "to allocate storage for offscreen target stencil buffer.";
3357 return false;
3358 }
3359
3360 // Attach the offscreen target buffers to the target frame buffer.
3361 if (IsOffscreenBufferMultisampled()) {
3362 offscreen_target_frame_buffer_->AttachRenderBuffer(
3363 GL_COLOR_ATTACHMENT0,
3364 offscreen_target_color_render_buffer_.get());
3365 } else {
3366 offscreen_target_frame_buffer_->AttachRenderTexture(
3367 offscreen_target_color_texture_.get());
3368 }
3369 if (offscreen_target_depth_format_) {
3370 offscreen_target_frame_buffer_->AttachRenderBuffer(
3371 GL_DEPTH_ATTACHMENT,
3372 offscreen_target_depth_render_buffer_.get());
3373 }
3374 const bool packed_depth_stencil =
3375 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3376 if (packed_depth_stencil) {
3377 offscreen_target_frame_buffer_->AttachRenderBuffer(
3378 GL_STENCIL_ATTACHMENT,
3379 offscreen_target_depth_render_buffer_.get());
3380 } else if (offscreen_target_stencil_format_) {
3381 offscreen_target_frame_buffer_->AttachRenderBuffer(
3382 GL_STENCIL_ATTACHMENT,
3383 offscreen_target_stencil_render_buffer_.get());
3384 }
3385
3386 if (offscreen_target_frame_buffer_->CheckStatus() !=
3387 GL_FRAMEBUFFER_COMPLETE) {
3388 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3389 << "because offscreen FBO was incomplete.";
3390 return false;
3391 }
3392
3393 // Clear the target frame buffer.
3394 {
3395 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3396 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3397 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3398 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3399 glClearStencil(0);
3400 glStencilMaskSeparate(GL_FRONT, -1);
3401 glStencilMaskSeparate(GL_BACK, -1);
3402 glClearDepth(0);
3403 glDepthMask(GL_TRUE);
3404 glDisable(GL_SCISSOR_TEST);
3405 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3406 RestoreClearState();
3407 }
[email protected]d85ef76d2011-09-08 22:21:433408
3409 // Destroy the offscreen resolved framebuffers.
3410 if (offscreen_resolved_frame_buffer_.get())
3411 offscreen_resolved_frame_buffer_->Destroy();
3412 if (offscreen_resolved_color_texture_.get())
3413 offscreen_resolved_color_texture_->Destroy();
3414 offscreen_resolved_color_texture_.reset();
3415 offscreen_resolved_frame_buffer_.reset();
3416
[email protected]799b4b22011-08-22 17:09:593417 return true;
[email protected]6217d392010-03-25 22:08:353418}
3419
[email protected]799b4b22011-08-22 17:09:593420error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353421 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443422 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023423 return error::kDeferCommandUntilLater;
3424
[email protected]799b4b22011-08-22 17:09:593425 GLuint width = static_cast<GLuint>(c.width);
3426 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073427 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593428 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413429
3430 width = std::max(1U, width);
3431 height = std::max(1U, height);
3432
[email protected]a0d989162011-11-22 13:15:073433#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3434 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003435 // Make sure that we are done drawing to the back buffer before resizing.
3436 glFinish();
3437#endif
[email protected]799b4b22011-08-22 17:09:593438 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3439 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493440 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3441 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3442 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593443 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493444 }
[email protected]7ff86b92010-11-25 17:50:003445 }
[email protected]799b4b22011-08-22 17:09:593446
[email protected]9d37f062011-11-22 01:24:523447 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073448 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443449 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493450 if (!context_->IsCurrent(surface_.get())) {
3451 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3452 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053453 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493454 }
[email protected]658f7562011-09-09 05:24:053455 }
[email protected]799b4b22011-08-22 17:09:593456
3457 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393458}
3459
[email protected]96449d2c2009-11-25 00:01:323460const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3461 if (command_id > kStartPoint && command_id < kNumCommands) {
3462 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3463 }
3464 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3465}
3466
3467// Decode command with its arguments, and call the corresponding GL function.
3468// Note: args is a pointer to the command buffer. As such, it could be changed
3469// by a (malicious) client at any time, so if validation has to happen, it
3470// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143471error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323472 unsigned int command,
3473 unsigned int arg_count,
3474 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143475 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263476 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003477 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3478 // LOG(INFO), tried VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323479 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013480 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193481 }
[email protected]96449d2c2009-11-25 00:01:323482 unsigned int command_index = command - kStartPoint - 1;
3483 if (command_index < arraysize(g_command_info)) {
3484 const CommandInfo& info = g_command_info[command_index];
3485 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3486 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3487 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193488 uint32 immediate_data_size =
3489 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323490 switch (command) {
3491 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353492 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193493 result = Handle ## name( \
3494 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353495 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193496 break; \
[email protected]96449d2c2009-11-25 00:01:323497
3498 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323499 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383500 }
3501 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303502 GLenum error;
3503 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323504 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003505 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3506 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513507 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193508 }
[email protected]96449d2c2009-11-25 00:01:323509 }
3510 } else {
[email protected]f7a64ee2010-02-01 22:24:143511 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323512 }
[email protected]b9849abf2009-11-25 19:13:193513 } else {
3514 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323515 }
[email protected]a3a93e7b2010-08-28 00:48:563516 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3517 result = current_decoder_error_;
3518 current_decoder_error_ = error::kNoError;
3519 }
[email protected]b9849abf2009-11-25 19:13:193520 return result;
[email protected]96449d2c2009-11-25 00:01:323521}
3522
[email protected]ed9f9cd2013-02-27 21:12:353523void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3524 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503525}
3526
[email protected]ae51d192010-04-27 00:48:033527bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353528 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033529 return false;
3530 }
[email protected]96449d2c2009-11-25 00:01:323531 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033532 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353533 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323534 }
[email protected]ae51d192010-04-27 00:48:033535 return true;
[email protected]96449d2c2009-11-25 00:01:323536}
3537
[email protected]ae51d192010-04-27 00:48:033538bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353539 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033540 return false;
[email protected]96449d2c2009-11-25 00:01:323541 }
[email protected]ae51d192010-04-27 00:48:033542 GLuint service_id = glCreateShader(type);
3543 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353544 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033545 }
3546 return true;
[email protected]96449d2c2009-11-25 00:01:323547}
3548
[email protected]882ba1e22012-03-08 19:02:533549void GLES2DecoderImpl::DoFinish() {
3550 glFinish();
[email protected]22e3f552012-03-13 01:54:193551 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533552}
3553
3554void GLES2DecoderImpl::DoFlush() {
3555 glFlush();
[email protected]22e3f552012-03-13 01:54:193556 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533557}
3558
[email protected]3916c97e2010-02-25 03:20:503559void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453560 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023561 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513562 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533563 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503564 return;
3565 }
[email protected]e259eb412012-10-13 05:47:243566 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453567 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503568}
3569
[email protected]051b1372010-04-12 02:42:083570void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073571 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083572 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033573 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073574 buffer = GetBuffer(client_id);
3575 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353576 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153577 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3578 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353579 return;
3580 }
3581
[email protected]b10492f2013-03-08 05:24:073582 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033583 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353584 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073585 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573586 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103587 group_->GetIdAllocator(id_namespaces::kBuffers);
3588 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033589 }
[email protected]051b1372010-04-12 02:42:083590 }
[email protected]b10492f2013-03-08 05:24:073591 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3592 if (buffer) {
3593 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513594 LOCAL_SET_GL_ERROR(
3595 GL_INVALID_OPERATION,
3596 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473597 return;
3598 }
[email protected]b10492f2013-03-08 05:24:073599 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473600 }
[email protected]96449d2c2009-11-25 00:01:323601 switch (target) {
3602 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073603 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323604 break;
3605 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073606 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323607 break;
3608 default:
[email protected]a93bb842010-02-16 23:03:473609 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323610 break;
3611 }
[email protected]051b1372010-04-12 02:42:083612 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323613}
3614
[email protected]f3b191b2013-06-19 03:43:543615bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3616 bool all_draw_buffers) {
3617 Framebuffer* framebuffer =
3618 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3619 if (!all_draw_buffers || !framebuffer) {
3620 return (GLES2Util::GetChannelsForFormat(
3621 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3622 }
3623 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463624}
3625
3626bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353627 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453628 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203629 if (framebuffer) {
3630 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463631 }
3632 if (offscreen_target_frame_buffer_.get()) {
3633 return offscreen_target_depth_format_ != 0;
3634 }
3635 return back_buffer_has_depth_;
3636}
3637
3638bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353639 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453640 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203641 if (framebuffer) {
3642 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463643 }
3644 if (offscreen_target_frame_buffer_.get()) {
3645 return offscreen_target_stencil_format_ != 0 ||
3646 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3647 }
3648 return back_buffer_has_stencil_;
3649}
3650
3651void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]88a61bf2012-10-27 13:00:423652 if (clear_state_dirty_) {
[email protected]297ca1c2011-06-20 23:08:463653 glColorMask(
[email protected]e259eb412012-10-13 05:47:243654 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3655 state_.color_mask_alpha &&
[email protected]f3b191b2013-06-19 03:43:543656 BoundFramebufferHasColorAttachmentWithAlpha(true));
[email protected]297ca1c2011-06-20 23:08:463657 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243658 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223659 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463660 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243661 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423662 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243663 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423664 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223665 EnableDisable(
3666 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3667 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3668 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3669 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]88a61bf2012-10-27 13:00:423670 clear_state_dirty_ = false;
[email protected]297ca1c2011-06-20 23:08:463671 }
3672}
3673
[email protected]1868a342012-11-07 15:56:023674GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:113675 return (offscreen_target_frame_buffer_.get())
3676 ? offscreen_target_frame_buffer_->id()
3677 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:023678}
3679
3680void GLES2DecoderImpl::RestoreState() const {
[email protected]962bfbe72013-05-24 11:16:143681 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3682 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:063683 // Restore the Framebuffer first because of bugs in Intel drivers.
3684 // Intel drivers incorrectly clip the viewport settings to
3685 // the size of the current framebuffer object.
3686 RestoreFramebufferBindings();
3687 state_.RestoreState();
3688}
3689
3690void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]7cd76fd2013-06-02 21:11:113691 GLuint service_id = state_.bound_draw_framebuffer.get()
3692 ? state_.bound_draw_framebuffer->service_id()
3693 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063694 if (!features().chromium_framebuffer_multisample) {
3695 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3696 } else {
3697 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]7cd76fd2013-06-02 21:11:113698 service_id = state_.bound_read_framebuffer.get()
3699 ? state_.bound_read_framebuffer->service_id()
3700 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063701 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3702 }
[email protected]70d34263c2013-01-09 00:27:453703 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063704}
3705
3706void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:103707 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3708 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:253709 GLenum target = texture->target();
3710 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063711 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253712 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063713 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253714 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063715 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253716 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063717 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253718 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063719 RestoreTextureUnitBindings(state_.active_texture_unit);
3720 }
[email protected]70d34263c2013-01-09 00:27:453721}
3722
3723void GLES2DecoderImpl::OnFboChanged() const {
3724 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513725 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3726}
3727
3728// Called after the FBO is checked for completeness.
3729void GLES2DecoderImpl::OnUseFramebuffer() const {
3730 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3731 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323732 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513733 glScissor(state_.scissor_x,
3734 state_.scissor_y,
3735 state_.scissor_width,
3736 state_.scissor_height);
3737
3738 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3739 // it's unclear how this bug works.
3740 glFlush();
3741 }
[email protected]b177ae22011-11-01 03:29:113742}
3743
[email protected]051b1372010-04-12 02:42:083744void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063745 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083746 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033747 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063748 framebuffer = GetFramebuffer(client_id);
3749 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353750 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153751 LOG(ERROR)
3752 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3753 current_decoder_error_ = error::kGenericError;
3754 return;
[email protected]bf5a8d132011-08-16 08:39:353755 }
3756
[email protected]4d8f0dd2013-03-09 14:37:063757 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033758 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353759 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063760 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573761 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103762 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3763 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033764 } else {
[email protected]4d8f0dd2013-03-09 14:37:063765 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083766 }
[email protected]4d8f0dd2013-03-09 14:37:063767 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083768 }
[email protected]4d8f0dd2013-03-09 14:37:063769 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303770
3771 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063772 state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303773 }
3774 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063775 state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303776 }
[email protected]6217d392010-03-25 22:08:353777
[email protected]88a61bf2012-10-27 13:00:423778 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:463779
[email protected]b177ae22011-11-01 03:29:113780 // If we are rendering to the backbuffer get the FBO id for any simulated
3781 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063782 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113783 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463784 }
[email protected]6217d392010-03-25 22:08:353785
[email protected]051b1372010-04-12 02:42:083786 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453787 OnFboChanged();
[email protected]86093972010-03-11 00:13:563788}
3789
[email protected]051b1372010-04-12 02:42:083790void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273791 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083792 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033793 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273794 renderbuffer = GetRenderbuffer(client_id);
3795 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353796 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153797 LOG(ERROR)
3798 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3799 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353800 return;
3801 }
3802
[email protected]ee2a79c32013-03-10 03:50:273803 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033804 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353805 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273806 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573807 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103808 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3809 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033810 } else {
[email protected]ee2a79c32013-03-10 03:50:273811 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083812 }
[email protected]ee2a79c32013-03-10 03:50:273813 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083814 }
[email protected]ee2a79c32013-03-10 03:50:273815 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer");
3816 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083817 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563818}
3819
[email protected]051b1372010-04-12 02:42:083820void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:493821 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:083822 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033823 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:493824 texture_ref = GetTexture(client_id);
3825 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:353826 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153827 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3828 current_decoder_error_ = error::kGenericError;
3829 return;
[email protected]bf5a8d132011-08-16 08:39:353830 }
3831
[email protected]02965c22013-03-09 02:40:073832 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033833 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413834 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353835 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:493836 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:573837 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103838 group_->GetIdAllocator(id_namespaces::kTextures);
3839 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033840 }
3841 } else {
[email protected]370eaf12013-05-18 09:19:493842 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083843 }
[email protected]370eaf12013-05-18 09:19:493844 Texture* texture = texture_ref->texture();
[email protected]ae51d192010-04-27 00:48:033845
[email protected]1958e0e2010-04-22 05:17:153846 // Check the texture exists
3847 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073848 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513849 LOCAL_SET_GL_ERROR(
3850 GL_INVALID_OPERATION,
3851 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153852 return;
3853 }
[email protected]02965c22013-03-09 02:40:073854 if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:513855 LOCAL_SET_GL_ERROR(
3856 GL_INVALID_OPERATION,
3857 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423858 return;
3859 }
[email protected]02965c22013-03-09 02:40:073860 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3861 if (texture->target() == 0) {
[email protected]370eaf12013-05-18 09:19:493862 texture_manager()->SetTarget(texture_ref, target);
[email protected]a93bb842010-02-16 23:03:473863 }
[email protected]02965c22013-03-09 02:40:073864 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593865
[email protected]e259eb412012-10-13 05:47:243866 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503867 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473868 switch (target) {
3869 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:493870 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:473871 break;
3872 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:493873 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:473874 break;
[email protected]61eeb33f2011-07-26 15:30:313875 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:493876 unit.bound_texture_external_oes = texture_ref;
[email protected]02965c22013-03-09 02:40:073877 if (texture->IsStreamTexture()) {
[email protected]4f9958142013-07-02 03:58:073878 DCHECK(stream_texture_manager());
[email protected]b0af4f52011-09-28 22:04:423879 StreamTexture* stream_tex =
[email protected]4f9958142013-07-02 03:58:073880 stream_texture_manager()->LookupStreamTexture(
3881 texture->service_id());
[email protected]b0af4f52011-09-28 22:04:423882 if (stream_tex)
3883 stream_tex->Update();
3884 }
[email protected]61eeb33f2011-07-26 15:30:313885 break;
[email protected]e51bdf32011-11-23 22:21:463886 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:493887 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:463888 break;
[email protected]a93bb842010-02-16 23:03:473889 default:
3890 NOTREACHED(); // Validation should prevent us getting here.
3891 break;
3892 }
3893}
3894
[email protected]07f54fcc2009-12-22 02:46:303895void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243896 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123897 if (index != 0 ||
3898 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243899 glDisableVertexAttribArray(index);
3900 }
[email protected]07f54fcc2009-12-22 02:46:303901 } else {
[email protected]ab09b612013-03-11 22:11:513902 LOCAL_SET_GL_ERROR(
3903 GL_INVALID_VALUE,
3904 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303905 }
3906}
3907
[email protected]60f22d32012-12-12 00:31:583908void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3909 GLsizei numAttachments,
3910 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:353911 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:583912 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3913
3914 // Validates the attachments. If one of them fails
3915 // the whole command fails.
3916 for (GLsizei i = 0; i < numAttachments; ++i) {
3917 if ((framebuffer &&
3918 !validators_->attachment.IsValid(attachments[i])) ||
3919 (!framebuffer &&
3920 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:513921 LOCAL_SET_GL_ERROR_INVALID_ENUM(
3922 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:583923 return;
3924 }
3925 }
3926
3927 // Marks each one of them as not cleared
3928 for (GLsizei i = 0; i < numAttachments; ++i) {
3929 if (framebuffer) {
3930 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3931 texture_manager(),
3932 attachments[i],
3933 false);
3934 } else {
3935 switch (attachments[i]) {
3936 case GL_COLOR_EXT:
3937 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3938 break;
3939 case GL_DEPTH_EXT:
3940 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
3941 case GL_STENCIL_EXT:
3942 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
3943 break;
3944 default:
3945 NOTREACHED();
3946 break;
3947 }
3948 }
3949 }
3950
3951 glDiscardFramebufferEXT(target, numAttachments, attachments);
3952}
3953
[email protected]07f54fcc2009-12-22 02:46:303954void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243955 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:303956 glEnableVertexAttribArray(index);
3957 } else {
[email protected]ab09b612013-03-11 22:11:513958 LOCAL_SET_GL_ERROR(
3959 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303960 }
3961}
3962
[email protected]a93bb842010-02-16 23:03:473963void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]370eaf12013-05-18 09:19:493964 TextureRef* texture_ref = GetTextureInfoForTarget(target);
3965 if (!texture_ref ||
3966 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:513967 LOCAL_SET_GL_ERROR(
3968 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:473969 return;
3970 }
[email protected]38c0a972012-05-12 00:48:023971
[email protected]12d95352012-12-14 07:23:543972 if (target == GL_TEXTURE_CUBE_MAP) {
3973 for (int i = 0; i < 6; ++i) {
3974 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:493975 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:513976 LOCAL_SET_GL_ERROR(
3977 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:543978 return;
3979 }
3980 }
3981 } else {
[email protected]370eaf12013-05-18 09:19:493982 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:513983 LOCAL_SET_GL_ERROR(
3984 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:543985 return;
3986 }
[email protected]7687479c2012-05-14 23:54:043987 }
3988
[email protected]ab09b612013-03-11 22:11:513989 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:193990 // Workaround for Mac driver bug. In the large scheme of things setting
3991 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:563992 // hit so there's probably no need to make this conditional. The bug appears
3993 // to be that if the filtering mode is set to something that doesn't require
3994 // mipmaps for rendering, or is never set to something other than the default,
3995 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:153996 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193997 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3998 }
[email protected]a93bb842010-02-16 23:03:473999 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154000 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494001 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4002 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194003 }
[email protected]ab09b612013-03-11 22:11:514004 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024005 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494006 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024007 }
[email protected]a93bb842010-02-16 23:03:474008}
4009
[email protected]b273e432010-04-12 17:23:584010bool GLES2DecoderImpl::GetHelper(
4011 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584012 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154013 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4014 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434015 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4016 *num_written = 1;
4017 if (params) {
4018 *params = GL_RGBA; // We don't support other formats.
4019 }
4020 return true;
4021 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4022 *num_written = 1;
4023 if (params) {
4024 *params = GL_UNSIGNED_BYTE; // We don't support other types.
4025 }
4026 return true;
4027 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4028 *num_written = 1;
4029 if (params) {
4030 *params = group_->max_fragment_uniform_vectors();
4031 }
4032 return true;
4033 case GL_MAX_VARYING_VECTORS:
4034 *num_written = 1;
4035 if (params) {
4036 *params = group_->max_varying_vectors();
4037 }
4038 return true;
4039 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4040 *num_written = 1;
4041 if (params) {
4042 *params = group_->max_vertex_uniform_vectors();
4043 }
4044 return true;
[email protected]4e8a5b122010-05-08 22:00:104045 }
[email protected]5cb735d2011-10-13 01:37:234046 }
4047 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244048 case GL_MAX_VIEWPORT_DIMS:
4049 if (offscreen_target_frame_buffer_.get()) {
4050 *num_written = 2;
4051 if (params) {
4052 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4053 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4054 }
4055 return true;
4056 }
[email protected]5cb735d2011-10-13 01:37:234057 return false;
[email protected]84afefa2011-10-19 21:45:534058 case GL_MAX_SAMPLES:
4059 *num_written = 1;
4060 if (params) {
4061 params[0] = renderbuffer_manager()->max_samples();
4062 }
4063 return true;
4064 case GL_MAX_RENDERBUFFER_SIZE:
4065 *num_written = 1;
4066 if (params) {
4067 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4068 }
4069 return true;
[email protected]5cb735d2011-10-13 01:37:234070 case GL_MAX_TEXTURE_SIZE:
4071 *num_written = 1;
4072 if (params) {
4073 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4074 }
4075 return true;
4076 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4077 *num_written = 1;
4078 if (params) {
4079 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4080 }
4081 return true;
[email protected]2f143d482013-03-14 18:04:494082 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4083 *num_written = 1;
4084 if (params) {
4085 params[0] = group_->max_color_attachments();
4086 }
4087 return true;
4088 case GL_MAX_DRAW_BUFFERS_ARB:
4089 *num_written = 1;
4090 if (params) {
4091 params[0] = group_->max_draw_buffers();
4092 }
4093 return true;
[email protected]297ca1c2011-06-20 23:08:464094 case GL_ALPHA_BITS:
4095 *num_written = 1;
4096 if (params) {
4097 GLint v = 0;
4098 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544099 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464100 }
4101 return true;
4102 case GL_DEPTH_BITS:
4103 *num_written = 1;
4104 if (params) {
4105 GLint v = 0;
4106 glGetIntegerv(GL_DEPTH_BITS, &v);
4107 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4108 }
4109 return true;
4110 case GL_STENCIL_BITS:
4111 *num_written = 1;
4112 if (params) {
4113 GLint v = 0;
4114 glGetIntegerv(GL_STENCIL_BITS, &v);
4115 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4116 }
4117 return true;
[email protected]656dcaad2010-05-07 17:18:374118 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114119 *num_written = validators_->compressed_texture_format.GetValues().size();
4120 if (params) {
4121 for (GLint ii = 0; ii < *num_written; ++ii) {
4122 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4123 }
4124 }
[email protected]656dcaad2010-05-07 17:18:374125 return true;
[email protected]b273e432010-04-12 17:23:584126 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4127 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104128 if (params) {
[email protected]302ce6d2011-07-07 23:28:114129 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104130 }
[email protected]b273e432010-04-12 17:23:584131 return true;
4132 case GL_NUM_SHADER_BINARY_FORMATS:
4133 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104134 if (params) {
[email protected]302ce6d2011-07-07 23:28:114135 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104136 }
[email protected]b273e432010-04-12 17:23:584137 return true;
4138 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114139 *num_written = validators_->shader_binary_format.GetValues().size();
4140 if (params) {
4141 for (GLint ii = 0; ii < *num_written; ++ii) {
4142 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4143 }
4144 }
4145 return true;
[email protected]b273e432010-04-12 17:23:584146 case GL_SHADER_COMPILER:
4147 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104148 if (params) {
4149 *params = GL_TRUE;
4150 }
[email protected]b273e432010-04-12 17:23:584151 return true;
[email protected]6b8cf1a2010-05-06 16:13:584152 case GL_ARRAY_BUFFER_BINDING:
4153 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104154 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114155 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104156 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244157 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104158 &client_id);
4159 *params = client_id;
4160 } else {
4161 *params = 0;
4162 }
[email protected]6b8cf1a2010-05-06 16:13:584163 }
4164 return true;
4165 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4166 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104167 if (params) {
[email protected]e259eb412012-10-13 05:47:244168 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104169 GLuint client_id = 0;
4170 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254171 state_.vertex_attrib_manager->element_array_buffer()->
4172 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104173 *params = client_id;
4174 } else {
4175 *params = 0;
4176 }
[email protected]6b8cf1a2010-05-06 16:13:584177 }
4178 return true;
4179 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304180 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584181 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104182 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354183 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454184 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204185 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104186 GLuint client_id = 0;
4187 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204188 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304189 *params = client_id;
4190 } else {
4191 *params = 0;
4192 }
4193 }
4194 return true;
[email protected]ebfb73c2012-08-15 02:37:454195 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304196 *num_written = 1;
4197 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354198 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454199 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204200 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304201 GLuint client_id = 0;
4202 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204203 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104204 *params = client_id;
4205 } else {
4206 *params = 0;
4207 }
[email protected]6b8cf1a2010-05-06 16:13:584208 }
4209 return true;
4210 case GL_RENDERBUFFER_BINDING:
4211 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104212 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354213 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204214 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4215 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104216 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104217 } else {
4218 *params = 0;
4219 }
[email protected]6b8cf1a2010-05-06 16:13:584220 }
4221 return true;
4222 case GL_CURRENT_PROGRAM:
4223 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104224 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114225 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104226 GLuint client_id = 0;
4227 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244228 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104229 *params = client_id;
4230 } else {
4231 *params = 0;
4232 }
[email protected]6b8cf1a2010-05-06 16:13:584233 }
4234 return true;
[email protected]bf835842012-11-19 15:21:514235 case GL_VERTEX_ARRAY_BINDING_OES:
4236 *num_written = 1;
4237 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114238 if (state_.vertex_attrib_manager.get() !=
4239 default_vertex_attrib_manager_.get()) {
[email protected]bf835842012-11-19 15:21:514240 GLuint client_id = 0;
4241 vertex_array_manager_->GetClientId(
4242 state_.vertex_attrib_manager->service_id(), &client_id);
4243 *params = client_id;
4244 } else {
4245 *params = 0;
4246 }
4247 }
4248 return true;
[email protected]4e8a5b122010-05-08 22:00:104249 case GL_TEXTURE_BINDING_2D:
4250 *num_written = 1;
4251 if (params) {
[email protected]e259eb412012-10-13 05:47:244252 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114253 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104254 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584255 } else {
4256 *params = 0;
4257 }
[email protected]6b8cf1a2010-05-06 16:13:584258 }
[email protected]4e8a5b122010-05-08 22:00:104259 return true;
4260 case GL_TEXTURE_BINDING_CUBE_MAP:
4261 *num_written = 1;
4262 if (params) {
[email protected]e259eb412012-10-13 05:47:244263 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114264 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104265 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584266 } else {
4267 *params = 0;
4268 }
[email protected]6b8cf1a2010-05-06 16:13:584269 }
[email protected]4e8a5b122010-05-08 22:00:104270 return true;
[email protected]61eeb33f2011-07-26 15:30:314271 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4272 *num_written = 1;
4273 if (params) {
[email protected]e259eb412012-10-13 05:47:244274 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114275 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104276 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314277 } else {
4278 *params = 0;
4279 }
4280 }
4281 return true;
[email protected]e51bdf32011-11-23 22:21:464282 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4283 *num_written = 1;
4284 if (params) {
[email protected]e259eb412012-10-13 05:47:244285 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114286 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104287 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464288 } else {
4289 *params = 0;
4290 }
4291 }
4292 return true;
[email protected]6c75c712012-06-19 15:43:174293 case GL_UNPACK_FLIP_Y_CHROMIUM:
4294 *num_written = 1;
4295 if (params) {
4296 params[0] = unpack_flip_y_;
4297 }
4298 return true;
4299 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4300 *num_written = 1;
4301 if (params) {
4302 params[0] = unpack_premultiply_alpha_;
4303 }
4304 return true;
4305 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4306 *num_written = 1;
4307 if (params) {
4308 params[0] = unpack_unpremultiply_alpha_;
4309 }
4310 return true;
[email protected]b273e432010-04-12 17:23:584311 default:
[email protected]2f143d482013-03-14 18:04:494312 if (pname >= GL_DRAW_BUFFER0_ARB &&
4313 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4314 *num_written = 1;
4315 if (params) {
4316 Framebuffer* framebuffer =
4317 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4318 if (framebuffer) {
4319 params[0] = framebuffer->GetDrawBuffer(pname);
4320 } else { // backbuffer
4321 if (pname == GL_DRAW_BUFFER0_ARB)
4322 params[0] = group_->draw_buffer();
4323 else
4324 params[0] = GL_NONE;
4325 }
4326 }
4327 return true;
4328 }
[email protected]4e8a5b122010-05-08 22:00:104329 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534330 return false;
[email protected]b273e432010-04-12 17:23:584331 }
4332}
4333
[email protected]4e8a5b122010-05-08 22:00:104334bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4335 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264336 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534337 return true;
4338 }
[email protected]4e8a5b122010-05-08 22:00:104339 return GetHelper(pname, NULL, num_values);
4340}
4341
[email protected]7d3c36e2013-07-12 14:13:164342GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4343 if (GL_MAX_SAMPLES == pname &&
4344 features().use_img_for_multisampled_render_to_texture) {
4345 return GL_MAX_SAMPLES_IMG;
4346 }
4347 return pname;
4348}
4349
[email protected]b273e432010-04-12 17:23:584350void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4351 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104352 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534353 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554354 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264355 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534356 GetHelper(pname, values.get(), &num_written);
4357 }
[email protected]b273e432010-04-12 17:23:584358 for (GLsizei ii = 0; ii < num_written; ++ii) {
4359 params[ii] = static_cast<GLboolean>(values[ii]);
4360 }
4361 } else {
[email protected]7d3c36e2013-07-12 14:13:164362 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584363 glGetBooleanv(pname, params);
4364 }
4365}
4366
4367void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4368 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104369 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264370 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534371 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554372 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534373 GetHelper(pname, values.get(), &num_written);
4374 for (GLsizei ii = 0; ii < num_written; ++ii) {
4375 params[ii] = static_cast<GLfloat>(values[ii]);
4376 }
4377 } else {
[email protected]7d3c36e2013-07-12 14:13:164378 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534379 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584380 }
[email protected]b273e432010-04-12 17:23:584381 }
4382}
4383
4384void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4385 DCHECK(params);
4386 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264387 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534388 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164389 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584390 glGetIntegerv(pname, params);
4391 }
4392}
4393
[email protected]a0c3e972010-04-21 00:49:134394void GLES2DecoderImpl::DoGetProgramiv(
4395 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424396 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4397 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134398 return;
4399 }
[email protected]df37b9932013-03-08 05:21:424400 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134401}
4402
[email protected]17cfbe0e2013-03-07 01:26:084403void GLES2DecoderImpl::DoGetBufferParameteriv(
4404 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134405 // Just delegate it. Some validation is actually done before this.
4406 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4407 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084408}
4409
[email protected]258a3313f2011-10-18 20:13:574410void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424411 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574412 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514413 LOCAL_SET_GL_ERROR(
4414 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574415 return;
4416 }
[email protected]68dcb1f2012-04-07 00:14:564417 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514418 LOCAL_SET_GL_ERROR(
4419 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564420 return;
4421 }
4422 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514423 LOCAL_SET_GL_ERROR(
4424 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564425 return;
4426 }
[email protected]df37b9932013-03-08 05:21:424427 Program* program = GetProgramInfoNotShader(
4428 program_id, "glBindAttribLocation");
4429 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574430 return;
[email protected]558847a2010-03-24 07:02:544431 }
[email protected]df37b9932013-03-08 05:21:424432 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4433 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574434}
4435
4436error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354437 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574438 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 = GetSharedMemoryAs<const char*>(
4442 c.name_shm_id, c.name_shm_offset, name_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::HandleBindAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:354452 uint32 immediate_data_size, const cmds::BindAttribLocationImmediate& 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 uint32 name_size = c.data_size;
4456 const char* name = GetImmediateDataAs<const char*>(
4457 c, name_size, immediate_data_size);
4458 if (name == NULL) {
4459 return error::kOutOfBounds;
4460 }
4461 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574462 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544463 return error::kNoError;
4464}
4465
4466error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354467 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584468 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544469 GLuint index = static_cast<GLuint>(c.index);
4470 Bucket* bucket = GetBucket(c.name_bucket_id);
4471 if (!bucket || bucket->size() == 0) {
4472 return error::kInvalidArguments;
4473 }
4474 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184475 if (!bucket->GetAsString(&name_str)) {
4476 return error::kInvalidArguments;
4477 }
[email protected]258a3313f2011-10-18 20:13:574478 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544479 return error::kNoError;
4480}
4481
[email protected]2be6abf32012-06-26 00:28:334482void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424483 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334484 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514485 LOCAL_SET_GL_ERROR(
4486 GL_INVALID_VALUE,
4487 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334488 return;
4489 }
4490 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514491 LOCAL_SET_GL_ERROR(
4492 GL_INVALID_OPERATION,
4493 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334494 return;
4495 }
4496 if (location < 0 || static_cast<uint32>(location) >=
4497 (group_->max_fragment_uniform_vectors() +
4498 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514499 LOCAL_SET_GL_ERROR(
4500 GL_INVALID_VALUE,
4501 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334502 return;
4503 }
[email protected]df37b9932013-03-08 05:21:424504 Program* program = GetProgramInfoNotShader(
4505 program_id, "glBindUniformLocationCHROMIUM");
4506 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334507 return;
4508 }
[email protected]df37b9932013-03-08 05:21:424509 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514510 LOCAL_SET_GL_ERROR(
4511 GL_INVALID_VALUE,
4512 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334513 }
4514}
4515
4516error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354517 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334518 GLuint program = static_cast<GLuint>(c.program);
4519 GLint location = static_cast<GLint>(c.location);
4520 uint32 name_size = c.data_size;
4521 const char* name = GetSharedMemoryAs<const char*>(
4522 c.name_shm_id, c.name_shm_offset, name_size);
4523 if (name == NULL) {
4524 return error::kOutOfBounds;
4525 }
4526 String name_str(name, name_size);
4527 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4528 return error::kNoError;
4529}
4530
4531error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4532 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354533 const cmds::BindUniformLocationCHROMIUMImmediate& c) {
[email protected]2be6abf32012-06-26 00:28:334534 GLuint program = static_cast<GLuint>(c.program);
4535 GLint location = static_cast<GLint>(c.location);
4536 uint32 name_size = c.data_size;
4537 const char* name = GetImmediateDataAs<const char*>(
4538 c, name_size, immediate_data_size);
4539 if (name == NULL) {
4540 return error::kOutOfBounds;
4541 }
4542 String name_str(name, name_size);
4543 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4544 return error::kNoError;
4545}
4546
4547error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4548 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354549 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334550 GLuint program = static_cast<GLuint>(c.program);
4551 GLint location = static_cast<GLint>(c.location);
4552 Bucket* bucket = GetBucket(c.name_bucket_id);
4553 if (!bucket || bucket->size() == 0) {
4554 return error::kInvalidArguments;
4555 }
4556 std::string name_str;
4557 if (!bucket->GetAsString(&name_str)) {
4558 return error::kInvalidArguments;
4559 }
4560 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4561 return error::kNoError;
4562}
4563
[email protected]f7a64ee2010-02-01 22:24:144564error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354565 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034566 GLuint client_id = c.shader;
4567 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424568 Shader* shader = GetShader(client_id);
4569 if (shader) {
4570 if (!shader->IsDeleted()) {
4571 glDeleteShader(shader->service_id());
4572 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144573 }
[email protected]ae51d192010-04-27 00:48:034574 } else {
[email protected]ab09b612013-03-11 22:11:514575 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034576 }
[email protected]96449d2c2009-11-25 00:01:324577 }
[email protected]f7a64ee2010-02-01 22:24:144578 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324579}
4580
[email protected]f7a64ee2010-02-01 22:24:144581error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354582 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034583 GLuint client_id = c.program;
4584 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424585 Program* program = GetProgram(client_id);
4586 if (program) {
4587 if (!program->IsDeleted()) {
4588 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144589 }
[email protected]ae51d192010-04-27 00:48:034590 } else {
[email protected]ab09b612013-03-11 22:11:514591 LOCAL_SET_GL_ERROR(
4592 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034593 }
[email protected]96449d2c2009-11-25 00:01:324594 }
[email protected]f7a64ee2010-02-01 22:24:144595 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324596}
4597
[email protected]269200b12010-11-18 22:53:064598void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104599 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574600 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104601 for (GLsizei ii = 0; ii < n; ++ii) {
4602 id_allocator->FreeID(ids[ii]);
4603 }
4604}
4605
[email protected]269200b12010-11-18 22:53:064606error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354607 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104608 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4609 GLsizei n = static_cast<GLsizei>(c.n);
4610 uint32 data_size;
4611 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4612 return error::kOutOfBounds;
4613 }
4614 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4615 c.ids_shm_id, c.ids_shm_offset, data_size);
4616 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514617 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104618 return error::kNoError;
4619 }
4620 if (ids == NULL) {
4621 return error::kOutOfBounds;
4622 }
[email protected]269200b12010-11-18 22:53:064623 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104624 return error::kNoError;
4625}
4626
[email protected]269200b12010-11-18 22:53:064627void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104628 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574629 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104630 if (id_offset == 0) {
4631 for (GLsizei ii = 0; ii < n; ++ii) {
4632 ids[ii] = id_allocator->AllocateID();
4633 }
4634 } else {
4635 for (GLsizei ii = 0; ii < n; ++ii) {
4636 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4637 id_offset = ids[ii] + 1;
4638 }
4639 }
4640}
4641
[email protected]269200b12010-11-18 22:53:064642error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354643 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104644 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4645 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4646 GLsizei n = static_cast<GLsizei>(c.n);
4647 uint32 data_size;
4648 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4649 return error::kOutOfBounds;
4650 }
4651 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4652 c.ids_shm_id, c.ids_shm_offset, data_size);
4653 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514654 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104655 return error::kNoError;
4656 }
4657 if (ids == NULL) {
4658 return error::kOutOfBounds;
4659 }
[email protected]269200b12010-11-18 22:53:064660 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104661 return error::kNoError;
4662}
4663
[email protected]269200b12010-11-18 22:53:064664void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104665 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574666 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104667 for (GLsizei ii = 0; ii < n; ++ii) {
4668 if (!id_allocator->MarkAsUsed(ids[ii])) {
4669 for (GLsizei jj = 0; jj < ii; ++jj) {
4670 id_allocator->FreeID(ids[jj]);
4671 }
[email protected]ab09b612013-03-11 22:11:514672 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434673 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4674 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104675 return;
4676 }
4677 }
4678}
4679
[email protected]269200b12010-11-18 22:53:064680error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354681 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104682 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4683 GLsizei n = static_cast<GLsizei>(c.n);
4684 uint32 data_size;
4685 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4686 return error::kOutOfBounds;
4687 }
4688 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4689 c.ids_shm_id, c.ids_shm_offset, data_size);
4690 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514691 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104692 return error::kNoError;
4693 }
4694 if (ids == NULL) {
4695 return error::kOutOfBounds;
4696 }
[email protected]269200b12010-11-18 22:53:064697 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104698 return error::kNoError;
4699}
4700
[email protected]a7266a92012-06-28 02:11:084701error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444702 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204703 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:464704 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274705 glClear(mask);
4706 }
[email protected]a7266a92012-06-28 02:11:084707 return error::kNoError;
4708}
4709
[email protected]36cef8ce2010-03-16 07:34:454710void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4711 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034712 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064713 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4714 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514715 LOCAL_SET_GL_ERROR(
4716 GL_INVALID_OPERATION,
4717 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454718 return;
4719 }
[email protected]ae51d192010-04-27 00:48:034720 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274721 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034722 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274723 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4724 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514725 LOCAL_SET_GL_ERROR(
4726 GL_INVALID_OPERATION,
4727 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034728 return;
4729 }
[email protected]ee2a79c32013-03-10 03:50:274730 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034731 }
[email protected]ab09b612013-03-11 22:11:514732 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034733 glFramebufferRenderbufferEXT(
4734 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514735 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264736 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274737 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284738 }
[email protected]7cd76fd2013-06-02 21:11:114739 if (framebuffer == state_.bound_draw_framebuffer.get()) {
[email protected]88a61bf2012-10-27 13:00:424740 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464741 }
[email protected]81fc9d02013-03-14 23:53:324742 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284743}
4744
[email protected]3a2e7c7b2010-08-06 01:12:284745void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464746 if (SetCapabilityState(cap, false)) {
4747 glDisable(cap);
4748 }
[email protected]3a2e7c7b2010-08-06 01:12:284749}
4750
4751void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464752 if (SetCapabilityState(cap, true)) {
4753 glEnable(cap);
4754 }
[email protected]3a2e7c7b2010-08-06 01:12:284755}
4756
[email protected]88a61bf2012-10-27 13:00:424757void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4758 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4759 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4760 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284761}
4762
[email protected]b04e24c2013-01-08 18:35:254763void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424764 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4765 state_.sample_coverage_invert = (invert != 0);
4766 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284767}
4768
[email protected]0d6bfdc2011-11-02 01:32:204769// Assumes framebuffer is complete.
4770void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064771 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304772 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204773 // bind this to the DRAW point, clear then bind back to READ
4774 // TODO(gman): I don't think there is any guarantee that an FBO that
4775 // is complete on the READ attachment will be complete as a DRAW
4776 // attachment.
4777 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064778 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304779 }
[email protected]3a2e7c7b2010-08-06 01:12:284780 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064781 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464782 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204783 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464784 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064785 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4786 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284787 glColorMask(true, true, true, true);
4788 clear_bits |= GL_COLOR_BUFFER_BIT;
4789 }
4790
[email protected]4d8f0dd2013-03-09 14:37:064791 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4792 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284793 glClearStencil(0);
4794 glStencilMask(-1);
4795 clear_bits |= GL_STENCIL_BUFFER_BIT;
4796 }
4797
[email protected]4d8f0dd2013-03-09 14:37:064798 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4799 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284800 glClearDepth(1.0f);
4801 glDepthMask(true);
4802 clear_bits |= GL_DEPTH_BUFFER_BIT;
4803 }
4804
4805 glDisable(GL_SCISSOR_TEST);
4806 glClear(clear_bits);
4807
[email protected]968351b2011-12-20 08:26:514808 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064809 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284810
[email protected]c007aa02010-09-02 22:22:404811 RestoreClearState();
4812
4813 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064814 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4815 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484816 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064817 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4818 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484819 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404820 }
4821}
4822
4823void GLES2DecoderImpl::RestoreClearState() {
[email protected]88a61bf2012-10-27 13:00:424824 clear_state_dirty_ = true;
[email protected]e259eb412012-10-13 05:47:244825 glClearColor(
4826 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4827 state_.color_clear_alpha);
4828 glClearStencil(state_.stencil_clear);
4829 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224830 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284831 glEnable(GL_SCISSOR_TEST);
4832 }
[email protected]36cef8ce2010-03-16 07:34:454833}
4834
4835GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354836 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304837 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204838 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454839 return GL_FRAMEBUFFER_COMPLETE;
4840 }
[email protected]0d6bfdc2011-11-02 01:32:204841 GLenum completeness = framebuffer->IsPossiblyComplete();
4842 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4843 return completeness;
4844 }
[email protected]73276522012-11-09 05:50:204845 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454846}
4847
4848void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034849 GLenum target, GLenum attachment, GLenum textarget,
4850 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:164851 DoFramebufferTexture2DCommon(
4852 "glFramebufferTexture2D", target, attachment,
4853 textarget, client_texture_id, level, 0);
4854}
4855
4856void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
4857 GLenum target, GLenum attachment, GLenum textarget,
4858 GLuint client_texture_id, GLint level, GLsizei samples) {
4859 if (!features().multisampled_render_to_texture) {
4860 LOCAL_SET_GL_ERROR(
4861 GL_INVALID_OPERATION,
4862 "glFramebufferTexture2DMultisample", "function not available");
4863 return;
4864 }
4865 DoFramebufferTexture2DCommon(
4866 "glFramebufferTexture2DMultisample", target, attachment,
4867 textarget, client_texture_id, level, samples);
4868}
4869
4870void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
4871 const char* name, GLenum target, GLenum attachment, GLenum textarget,
4872 GLuint client_texture_id, GLint level, GLsizei samples) {
4873 if (samples > renderbuffer_manager()->max_samples()) {
4874 LOCAL_SET_GL_ERROR(
4875 GL_INVALID_VALUE,
4876 "glFramebufferTexture2DMultisample", "samples too large");
4877 return;
4878 }
[email protected]4d8f0dd2013-03-09 14:37:064879 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4880 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514881 LOCAL_SET_GL_ERROR(
4882 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164883 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454884 return;
4885 }
[email protected]ae51d192010-04-27 00:48:034886 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:494887 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:034888 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:494889 texture_ref = GetTexture(client_texture_id);
4890 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:514891 LOCAL_SET_GL_ERROR(
4892 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164893 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:034894 return;
4895 }
[email protected]370eaf12013-05-18 09:19:494896 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:034897 }
[email protected]0d6bfdc2011-11-02 01:32:204898
[email protected]80eb6b52012-01-19 00:14:414899 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:514900 LOCAL_SET_GL_ERROR(
4901 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:164902 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204903 return;
4904 }
4905
[email protected]7d3c36e2013-07-12 14:13:164906 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
4907 if (0 == samples) {
4908 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
4909 } else {
4910 if (features().use_img_for_multisampled_render_to_texture) {
4911 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
4912 service_id, level, samples);
4913 } else {
4914 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
4915 service_id, level, samples);
4916 }
4917 }
4918 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:264919 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:164920 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
4921 samples);
[email protected]3a2e7c7b2010-08-06 01:12:284922 }
[email protected]7cd76fd2013-06-02 21:11:114923 if (framebuffer == state_.bound_draw_framebuffer.get()) {
[email protected]88a61bf2012-10-27 13:00:424924 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464925 }
[email protected]81fc9d02013-03-14 23:53:324926 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:454927}
4928
4929void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4930 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:064931 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4932 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514933 LOCAL_SET_GL_ERROR(
4934 GL_INVALID_OPERATION,
4935 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454936 return;
4937 }
[email protected]74c1ec42010-08-12 01:55:574938 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:104939 const Framebuffer::Attachment* attachment_object =
4940 framebuffer->GetAttachment(attachment);
4941 *params = attachment_object ? attachment_object->object_name() : 0;
4942 } else {
[email protected]7d3c36e2013-07-12 14:13:164943 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
4944 features().use_img_for_multisampled_render_to_texture) {
4945 pname = GL_TEXTURE_SAMPLES_IMG;
4946 }
[email protected]62e65f02013-05-29 22:28:104947 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:574948 }
[email protected]36cef8ce2010-03-16 07:34:454949}
4950
4951void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
4952 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:354953 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204954 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4955 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514956 LOCAL_SET_GL_ERROR(
4957 GL_INVALID_OPERATION,
4958 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454959 return;
4960 }
[email protected]3a03a8f2011-03-19 00:51:274961 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434962 case GL_RENDERBUFFER_INTERNAL_FORMAT:
4963 *params = renderbuffer->internal_format();
4964 break;
4965 case GL_RENDERBUFFER_WIDTH:
4966 *params = renderbuffer->width();
4967 break;
4968 case GL_RENDERBUFFER_HEIGHT:
4969 *params = renderbuffer->height();
4970 break;
[email protected]7d3c36e2013-07-12 14:13:164971 case GL_RENDERBUFFER_SAMPLES_EXT:
4972 if (features().use_img_for_multisampled_render_to_texture) {
4973 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
4974 params);
4975 } else {
4976 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
4977 params);
4978 }
[email protected]ad84a3a2012-06-08 21:42:434979 default:
4980 glGetRenderbufferParameterivEXT(target, pname, params);
4981 break;
[email protected]b71f52c2010-06-18 22:20:204982 }
[email protected]36cef8ce2010-03-16 07:34:454983}
4984
[email protected]8e3e0662010-08-23 18:46:304985void GLES2DecoderImpl::DoBlitFramebufferEXT(
4986 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4987 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4988 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:444989 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:154990 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:514991 LOCAL_SET_GL_ERROR(
4992 GL_INVALID_OPERATION,
4993 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304994 }
[email protected]0c16343f2013-03-08 20:40:164995
4996 if (!CheckBoundFramebuffersValid("glBlitFramebufferEXT")) {
4997 return;
4998 }
4999
[email protected]d058bca2012-11-26 10:27:265000 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:245001 if (IsAngle()) {
5002 glBlitFramebufferANGLE(
5003 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5004 } else {
5005 glBlitFramebufferEXT(
5006 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5007 }
[email protected]d058bca2012-11-26 10:27:265008 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]8e3e0662010-08-23 18:46:305009}
5010
5011void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
5012 GLenum target, GLsizei samples, GLenum internalformat,
5013 GLsizei width, GLsizei height) {
[email protected]7d3c36e2013-07-12 14:13:165014 if (!features().chromium_framebuffer_multisample &&
5015 !features().multisampled_render_to_texture) {
[email protected]ab09b612013-03-11 22:11:515016 LOCAL_SET_GL_ERROR(
5017 GL_INVALID_OPERATION,
5018 "glRenderbufferStorageMultisample", "function not available");
[email protected]8e3e0662010-08-23 18:46:305019 return;
5020 }
[email protected]8e3e0662010-08-23 18:46:305021
[email protected]ed9f9cd2013-02-27 21:12:355022 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205023 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5024 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515025 LOCAL_SET_GL_ERROR(
5026 GL_INVALID_OPERATION,
5027 "glRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:205028 return;
5029 }
5030
[email protected]84afefa2011-10-19 21:45:535031 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515032 LOCAL_SET_GL_ERROR(
5033 GL_INVALID_VALUE,
5034 "glRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:535035 return;
5036 }
5037
5038 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5039 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515040 LOCAL_SET_GL_ERROR(
5041 GL_INVALID_VALUE,
5042 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535043 return;
5044 }
5045
[email protected]7989c9e2013-01-23 06:39:265046 uint32 estimated_size = 0;
5047 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5048 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515049 LOCAL_SET_GL_ERROR(
5050 GL_OUT_OF_MEMORY,
5051 "glRenderbufferStorageMultsample", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265052 return;
[email protected]8e3e0662010-08-23 18:46:305053 }
5054
[email protected]7989c9e2013-01-23 06:39:265055 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515056 LOCAL_SET_GL_ERROR(
5057 GL_OUT_OF_MEMORY,
5058 "glRenderbufferStorageMultsample", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265059 return;
5060 }
5061
5062 GLenum impl_format = RenderbufferManager::
5063 InternalRenderbufferFormatToImplFormat(internalformat);
[email protected]ab09b612013-03-11 22:11:515064 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisample");
[email protected]866b91c52011-03-23 14:38:085065 if (IsAngle()) {
5066 glRenderbufferStorageMultisampleANGLE(
5067 target, samples, impl_format, width, height);
[email protected]7d3c36e2013-07-12 14:13:165068 } else if (features().use_img_for_multisampled_render_to_texture) {
5069 glRenderbufferStorageMultisampleIMG(
5070 target, samples, impl_format, width, height);
[email protected]866b91c52011-03-23 14:38:085071 } else {
5072 glRenderbufferStorageMultisampleEXT(
5073 target, samples, impl_format, width, height);
5074 }
[email protected]ab09b612013-03-11 22:11:515075 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisample");
[email protected]9edc6b22010-12-23 02:00:265076 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515077 // TODO(gman): If renderbuffers tracked which framebuffers they were
5078 // attached to we could just mark those framebuffers as not complete.
5079 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205080 renderbuffer_manager()->SetInfo(
5081 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265082 }
[email protected]8e3e0662010-08-23 18:46:305083}
5084
[email protected]36cef8ce2010-03-16 07:34:455085void GLES2DecoderImpl::DoRenderbufferStorage(
5086 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355087 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205088 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5089 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515090 LOCAL_SET_GL_ERROR(
5091 GL_INVALID_OPERATION,
5092 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455093 return;
5094 }
[email protected]876f6fee2010-08-02 23:10:325095
[email protected]84afefa2011-10-19 21:45:535096 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5097 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515098 LOCAL_SET_GL_ERROR(
5099 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535100 return;
5101 }
5102
[email protected]7989c9e2013-01-23 06:39:265103 uint32 estimated_size = 0;
5104 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5105 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515106 LOCAL_SET_GL_ERROR(
5107 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265108 return;
5109 }
5110
5111 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515112 LOCAL_SET_GL_ERROR(
5113 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265114 return;
[email protected]b71f52c2010-06-18 22:20:205115 }
[email protected]876f6fee2010-08-02 23:10:325116
[email protected]ab09b612013-03-11 22:11:515117 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265118 glRenderbufferStorageEXT(
5119 target, RenderbufferManager::
5120 InternalRenderbufferFormatToImplFormat(internalformat),
5121 width, height);
[email protected]ab09b612013-03-11 22:11:515122 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265123 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515124 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5125 // we could just mark those framebuffers as not complete.
5126 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205127 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265128 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265129 }
[email protected]36cef8ce2010-03-16 07:34:455130}
5131
[email protected]df37b9932013-03-08 05:21:425132void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385133 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425134 Program* program = GetProgramInfoNotShader(
5135 program_id, "glLinkProgram");
5136 if (!program) {
[email protected]a93bb842010-02-16 23:03:475137 return;
5138 }
[email protected]05afda12011-01-20 00:17:345139
[email protected]df37b9932013-03-08 05:21:425140 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395141 ShaderTranslator* vertex_translator = NULL;
5142 ShaderTranslator* fragment_translator = NULL;
5143 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115144 vertex_translator = vertex_translator_.get();
5145 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395146 }
[email protected]df37b9932013-03-08 05:21:425147 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115148 vertex_translator,
5149 fragment_translator,
5150 feature_info_.get(),
5151 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425152 if (program == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:155153 if (workarounds().use_current_program_after_successful_link) {
[email protected]df37b9932013-03-08 05:21:425154 glUseProgram(program->service_id());
[email protected]c2a3caf12012-10-23 19:32:005155 }
[email protected]df37b9932013-03-08 05:21:425156 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545157 }
5158 }
[email protected]07f54fcc2009-12-22 02:46:305159};
5160
[email protected]3916c97e2010-02-25 03:20:505161void GLES2DecoderImpl::DoTexParameterf(
5162 GLenum target, GLenum pname, GLfloat param) {
[email protected]370eaf12013-05-18 09:19:495163 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075164 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515165 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245166 return;
[email protected]07f54fcc2009-12-22 02:46:305167 }
[email protected]cbb22e42011-05-12 23:36:245168
[email protected]02965c22013-03-09 02:40:075169 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505170 "glTexParameterf", GetErrorState(), texture, pname,
5171 static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305172}
5173
[email protected]3916c97e2010-02-25 03:20:505174void GLES2DecoderImpl::DoTexParameteri(
5175 GLenum target, GLenum pname, GLint param) {
[email protected]370eaf12013-05-18 09:19:495176 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075177 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515178 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245179 return;
[email protected]3916c97e2010-02-25 03:20:505180 }
[email protected]cbb22e42011-05-12 23:36:245181
[email protected]02965c22013-03-09 02:40:075182 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505183 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505184}
5185
5186void GLES2DecoderImpl::DoTexParameterfv(
5187 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]370eaf12013-05-18 09:19:495188 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075189 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515190 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245191 return;
[email protected]3916c97e2010-02-25 03:20:505192 }
[email protected]cbb22e42011-05-12 23:36:245193
[email protected]02965c22013-03-09 02:40:075194 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505195 "glTexParameterfv", GetErrorState(), texture, pname,
5196 static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505197}
5198
5199void GLES2DecoderImpl::DoTexParameteriv(
5200 GLenum target, GLenum pname, const GLint* params) {
[email protected]370eaf12013-05-18 09:19:495201 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075202 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515203 LOCAL_SET_GL_ERROR(
5204 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245205 return;
[email protected]3916c97e2010-02-25 03:20:505206 }
[email protected]cbb22e42011-05-12 23:36:245207
[email protected]02965c22013-03-09 02:40:075208 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505209 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505210}
5211
[email protected]939e7362010-05-13 20:49:105212bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115213 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435214 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515215 LOCAL_SET_GL_ERROR(
5216 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435217 return false;
[email protected]939e7362010-05-13 20:49:105218 }
[email protected]e259eb412012-10-13 05:47:245219 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515220 LOCAL_SET_GL_ERROR(
5221 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105222 return false;
5223 }
5224 return true;
5225}
5226
5227bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5228 GLint location, const char* function_name) {
5229 if (!CheckCurrentProgram(function_name)) {
5230 return false;
5231 }
5232 return location != -1;
5233}
5234
[email protected]476ccb72012-12-06 15:52:525235namespace {
5236
5237static const GLenum valid_int_vec1_types_list[] = {
5238 GL_INT,
5239 GL_BOOL,
5240 GL_SAMPLER_2D,
5241 GL_SAMPLER_2D_RECT_ARB,
5242 GL_SAMPLER_CUBE,
5243 GL_SAMPLER_EXTERNAL_OES,
5244};
5245
5246static const GLenum valid_int_vec2_types_list[] = {
5247 GL_INT_VEC2,
5248 GL_BOOL_VEC2,
5249};
5250
5251static const GLenum valid_int_vec3_types_list[] = {
5252 GL_INT_VEC3,
5253 GL_BOOL_VEC3,
5254};
5255
5256static const GLenum valid_int_vec4_types_list[] = {
5257 GL_INT_VEC4,
5258 GL_BOOL_VEC4,
5259};
5260
5261static const GLenum valid_float_vec1_types_list[] = {
5262 GL_FLOAT,
5263 GL_BOOL,
5264};
5265
5266static const GLenum valid_float_vec2_types_list[] = {
5267 GL_FLOAT_VEC2,
5268 GL_BOOL_VEC2,
5269};
5270
5271static const GLenum valid_float_vec3_types_list[] = {
5272 GL_FLOAT_VEC3,
5273 GL_BOOL_VEC3,
5274};
5275
5276static const GLenum valid_float_vec4_types_list[] = {
5277 GL_FLOAT_VEC4,
5278 GL_BOOL_VEC4,
5279};
5280
5281static const GLenum valid_float_mat2_types_list[] = {
5282 GL_FLOAT_MAT2,
5283};
5284
5285static const GLenum valid_float_mat3_types_list[] = {
5286 GL_FLOAT_MAT3,
5287};
5288
5289static const GLenum valid_float_mat4_types_list[] = {
5290 GL_FLOAT_MAT4,
5291};
5292
5293static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5294 valid_int_vec1_types_list,
5295 arraysize(valid_int_vec1_types_list),
5296};
5297
5298static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5299 valid_int_vec2_types_list,
5300 arraysize(valid_int_vec2_types_list),
5301};
5302
5303static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5304 valid_int_vec3_types_list,
5305 arraysize(valid_int_vec3_types_list),
5306};
5307
5308static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5309 valid_int_vec4_types_list,
5310 arraysize(valid_int_vec4_types_list),
5311};
5312
5313static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5314 valid_float_vec1_types_list,
5315 arraysize(valid_float_vec1_types_list),
5316};
5317
5318static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5319 valid_float_vec2_types_list,
5320 arraysize(valid_float_vec2_types_list),
5321};
5322
5323static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5324 valid_float_vec3_types_list,
5325 arraysize(valid_float_vec3_types_list),
5326};
5327
5328static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5329 valid_float_vec4_types_list,
5330 arraysize(valid_float_vec4_types_list),
5331};
5332
5333static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5334 valid_float_mat2_types_list,
5335 arraysize(valid_float_mat2_types_list),
5336};
5337
5338static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5339 valid_float_mat3_types_list,
5340 arraysize(valid_float_mat3_types_list),
5341};
5342
5343static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5344 valid_float_mat4_types_list,
5345 arraysize(valid_float_mat4_types_list),
5346};
5347
5348} // anonymous namespace.
5349
[email protected]43c2f1f2011-03-25 18:35:365350bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125351 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525352 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125353 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365354 DCHECK(type);
5355 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125356 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525357
[email protected]1b0a6752012-02-22 03:44:125358 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105359 return false;
5360 }
[email protected]43c2f1f2011-03-25 18:35:365361 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355362 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245363 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125364 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365365 if (!info) {
[email protected]ab09b612013-03-11 22:11:515366 LOCAL_SET_GL_ERROR(
5367 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105368 return false;
5369 }
[email protected]476ccb72012-12-06 15:52:525370 bool okay = false;
5371 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5372 if (base_info.valid_types[ii] == info->type) {
5373 okay = true;
5374 break;
5375 }
5376 }
5377 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515378 LOCAL_SET_GL_ERROR(
5379 GL_INVALID_OPERATION, function_name,
5380 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525381 return false;
5382 }
[email protected]43c2f1f2011-03-25 18:35:365383 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515384 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435385 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365386 return false;
5387 }
5388 *count = std::min(info->size - array_index, *count);
5389 if (*count <= 0) {
5390 return false;
5391 }
5392 *type = info->type;
[email protected]939e7362010-05-13 20:49:105393 return true;
5394}
5395
[email protected]1b0a6752012-02-22 03:44:125396void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5397 GLenum type = 0;
5398 GLsizei count = 1;
5399 GLint real_location = -1;
5400 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525401 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5402 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505403 return;
5404 }
[email protected]e259eb412012-10-13 05:47:245405 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025406 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515407 LOCAL_SET_GL_ERROR(
5408 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465409 return;
5410 }
[email protected]1b0a6752012-02-22 03:44:125411 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505412}
5413
5414void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125415 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365416 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125417 GLint real_location = -1;
5418 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525419 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5420 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365421 return;
5422 }
[email protected]74727112012-06-13 21:18:085423 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5424 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245425 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025426 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515427 LOCAL_SET_GL_ERROR(
5428 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465429 return;
5430 }
[email protected]43c2f1f2011-03-25 18:35:365431 }
[email protected]1b0a6752012-02-22 03:44:125432 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505433}
5434
[email protected]939e7362010-05-13 20:49:105435void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125436 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365437 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125438 GLint real_location = -1;
5439 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525440 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5441 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105442 return;
5443 }
5444 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555445 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105446 for (GLsizei ii = 0; ii < count; ++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 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105450 } else {
[email protected]1b0a6752012-02-22 03:44:125451 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105452 }
5453}
5454
5455void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125456 GLint fake_location, GLsizei count, const GLfloat* 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, "glUniform2fv", valid_float_vec2_base_info,
5461 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105462 return;
5463 }
5464 if (type == GL_BOOL_VEC2) {
5465 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555466 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105467 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535468 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105469 }
[email protected]1b0a6752012-02-22 03:44:125470 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105471 } else {
[email protected]1b0a6752012-02-22 03:44:125472 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105473 }
5474}
5475
5476void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125477 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365478 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125479 GLint real_location = -1;
5480 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525481 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5482 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105483 return;
5484 }
5485 if (type == GL_BOOL_VEC3) {
5486 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555487 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105488 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535489 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105490 }
[email protected]1b0a6752012-02-22 03:44:125491 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105492 } else {
[email protected]1b0a6752012-02-22 03:44:125493 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105494 }
5495}
5496
5497void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125498 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365499 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125500 GLint real_location = -1;
5501 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525502 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5503 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105504 return;
5505 }
5506 if (type == GL_BOOL_VEC4) {
5507 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555508 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105509 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535510 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105511 }
[email protected]1b0a6752012-02-22 03:44:125512 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105513 } else {
[email protected]1b0a6752012-02-22 03:44:125514 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105515 }
5516}
5517
[email protected]43c2f1f2011-03-25 18:35:365518void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125519 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365520 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125521 GLint real_location = -1;
5522 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525523 fake_location, "glUniform2iv", valid_int_vec2_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 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365528}
5529
5530void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125531 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365532 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125533 GLint real_location = -1;
5534 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525535 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5536 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365537 return;
5538 }
[email protected]1b0a6752012-02-22 03:44:125539 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365540}
5541
5542void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125543 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365544 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125545 GLint real_location = -1;
5546 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525547 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5548 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365549 return;
5550 }
[email protected]1b0a6752012-02-22 03:44:125551 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365552}
5553
5554void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125555 GLint fake_location, GLsizei count, GLboolean transpose,
5556 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365557 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125558 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365559 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525560 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5561 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365562 return;
5563 }
[email protected]1b0a6752012-02-22 03:44:125564 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365565}
5566
5567void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125568 GLint fake_location, GLsizei count, GLboolean transpose,
5569 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365570 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125571 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365572 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525573 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5574 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365575 return;
5576 }
[email protected]1b0a6752012-02-22 03:44:125577 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365578}
5579
5580void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125581 GLint fake_location, GLsizei count, GLboolean transpose,
5582 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365583 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125584 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365585 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525586 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5587 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365588 return;
5589 }
[email protected]1b0a6752012-02-22 03:44:125590 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365591}
5592
[email protected]df37b9932013-03-08 05:21:425593void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035594 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425595 Program* program = NULL;
5596 if (program_id) {
5597 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5598 if (!program) {
[email protected]ae51d192010-04-27 00:48:035599 return;
5600 }
[email protected]df37b9932013-03-08 05:21:425601 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505602 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515603 LOCAL_SET_GL_ERROR(
5604 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505605 return;
5606 }
[email protected]df37b9932013-03-08 05:21:425607 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505608 }
[email protected]7cd76fd2013-06-02 21:11:115609 if (state_.current_program.get()) {
5610 program_manager()->UnuseProgram(shader_manager(),
5611 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145612 }
[email protected]df37b9932013-03-08 05:21:425613 state_.current_program = program;
5614 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545615 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:115616 if (state_.current_program.get()) {
5617 program_manager()->UseProgram(state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145618 }
[email protected]3916c97e2010-02-25 03:20:505619}
5620
[email protected]ab09b612013-03-11 22:11:515621void GLES2DecoderImpl::RenderWarning(
5622 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325623 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015624}
5625
[email protected]ab09b612013-03-11 22:11:515626void GLES2DecoderImpl::PerformanceWarning(
5627 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505628 logger_.LogMessage(filename, line,
5629 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015630}
5631
[email protected]df37b9932013-03-08 05:21:425632void GLES2DecoderImpl::ForceCompileShaderIfPending(Shader* shader) {
5633 if (shader->compilation_status() ==
[email protected]ed9f9cd2013-02-27 21:12:355634 Shader::PENDING_DEFERRED_COMPILE) {
[email protected]c447acd2012-07-23 23:48:415635 ShaderTranslator* translator = NULL;
5636 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:425637 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]c447acd2012-07-23 23:48:415638 vertex_translator_.get() : fragment_translator_.get();
5639 }
5640 // We know there will be no errors, because we only defer compilation on
5641 // shaders that were previously compiled successfully.
[email protected]df37b9932013-03-08 05:21:425642 program_manager()->ForceCompileShader(shader->deferred_compilation_source(),
5643 shader,
[email protected]c447acd2012-07-23 23:48:415644 translator,
[email protected]7cd76fd2013-06-02 21:11:115645 feature_info_.get());
[email protected]c447acd2012-07-23 23:48:415646 }
5647}
5648
[email protected]ef526492010-06-02 23:12:255649bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
[email protected]7cd76fd2013-06-02 21:11:115650 DCHECK(state_.current_program.get());
[email protected]ef526492010-06-02 23:12:255651 // Only check if there are some unrenderable textures.
5652 if (!texture_manager()->HaveUnrenderableTextures()) {
5653 return false;
5654 }
[email protected]e2367b42013-05-31 03:37:215655
[email protected]ef526492010-06-02 23:12:255656 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:355657 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245658 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505659 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355660 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245661 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505662 DCHECK(uniform_info);
5663 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5664 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025665 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245666 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495667 TextureRef* texture =
[email protected]cadac622013-06-11 16:46:365668 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]02965c22013-03-09 02:40:075669 if (!texture || !texture_manager()->CanRender(texture)) {
[email protected]ef526492010-06-02 23:12:255670 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505671 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5672 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315673 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495674 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:515675 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:015676 std::string("texture bound to texture unit ") +
5677 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:295678 " is not renderable. It maybe non-power-of-2 and have"
5679 " incompatible texture filtering or is not"
5680 " 'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505681 }
5682 }
5683 // else: should this be an error?
5684 }
5685 }
[email protected]ef526492010-06-02 23:12:255686 return textures_set;
[email protected]3916c97e2010-02-25 03:20:505687}
5688
5689void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]7cd76fd2013-06-02 21:11:115690 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:355691 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:115692 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505693 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355694 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245695 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505696 DCHECK(uniform_info);
5697 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5698 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025699 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245700 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:115701 TextureRef* texture_ref =
5702 uniform_info->type == GL_SAMPLER_2D
5703 ? texture_unit.bound_texture_2d.get()
5704 : texture_unit.bound_texture_cube_map.get();
[email protected]370eaf12013-05-18 09:19:495705 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:505706 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:495707 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:115708 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
5709 ? texture_unit.bound_texture_2d.get()
5710 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:505711 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:495712 texture_ref ? texture_ref->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505713 }
5714 }
5715 }
5716 }
5717 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245718 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305719}
5720
[email protected]0d6bfdc2011-11-02 01:32:205721bool GLES2DecoderImpl::ClearUnclearedTextures() {
5722 // Only check if there are some uncleared textures.
5723 if (!texture_manager()->HaveUnsafeTextures()) {
5724 return true;
5725 }
5726
5727 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:115728 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:355729 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:115730 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205731 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355732 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245733 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205734 DCHECK(uniform_info);
5735 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5736 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025737 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245738 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495739 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:365740 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:495741 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
5742 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:205743 return false;
5744 }
5745 }
5746 }
5747 }
5748 }
5749 }
5750 return true;
5751}
5752
[email protected]c6aef902012-02-14 03:31:425753bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435754 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035755 // NOTE: We specifically do not check current_program->IsValid() because
5756 // it could never be invalid since glUseProgram would have failed. While
5757 // glLinkProgram could later mark the program as invalid the previous
5758 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:115759 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:505760 // The program does not exist.
5761 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:515762 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505763 return false;
5764 }
[email protected]c6aef902012-02-14 03:31:425765
[email protected]7cd76fd2013-06-02 21:11:115766 return state_.vertex_attrib_manager
5767 ->ValidateBindings(function_name,
5768 this,
5769 feature_info_.get(),
5770 state_.current_program.get(),
5771 max_vertex_accessed,
5772 primcount);
[email protected]b1122982010-05-17 23:04:245773}
5774
[email protected]c13e1da62011-09-09 21:48:305775bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435776 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305777 DCHECK(simulated);
5778 *simulated = false;
5779
[email protected]876f6fee2010-08-02 23:10:325780 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305781 return true;
[email protected]876f6fee2010-08-02 23:10:325782
[email protected]ac77603c72013-03-08 13:52:065783 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:355784 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:245785 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245786 bool attrib_0_used =
5787 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:065788 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305789 return true;
[email protected]b1122982010-05-17 23:04:245790 }
5791
[email protected]b1122982010-05-17 23:04:245792 // Make a buffer with a single repeated vec4 value enough to
5793 // simulate the constant value that is supposed to be here.
5794 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305795 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475796 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305797
5798 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475799 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305800 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515801 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305802 return false;
5803 }
5804
[email protected]ab09b612013-03-11 22:11:515805 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015806 "Attribute 0 is disabled. This has signficant performance penalty");
5807
[email protected]ab09b612013-03-11 22:11:515808 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:305809 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5810
[email protected]8f0b86c2f2012-04-10 05:48:285811 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5812 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495813 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305814 GLenum error = glGetError();
5815 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515816 LOCAL_SET_GL_ERROR(
5817 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305818 return false;
5819 }
[email protected]fc753442011-02-04 19:49:495820 }
[email protected]af6380962012-11-29 23:24:135821
5822 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:285823 if (new_buffer ||
5824 (attrib_0_used &&
5825 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:135826 (value.v[0] != attrib_0_value_.v[0] ||
5827 value.v[1] != attrib_0_value_.v[1] ||
5828 value.v[2] != attrib_0_value_.v[2] ||
5829 value.v[3] != attrib_0_value_.v[3])))) {
5830 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:495831 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
5832 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:135833 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:245834 attrib_0_size_ = size_needed;
5835 }
5836
5837 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
5838
[email protected]ac77603c72013-03-08 13:52:065839 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:425840 glVertexAttribDivisorANGLE(0, 0);
5841
[email protected]c13e1da62011-09-09 21:48:305842 *simulated = true;
[email protected]b1122982010-05-17 23:04:245843 return true;
[email protected]b1122982010-05-17 23:04:245844}
5845
[email protected]ac77603c72013-03-08 13:52:065846void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
5847 const VertexAttrib* attrib =
5848 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
5849 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
5850 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:075851 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:245852 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065853 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
5854 attrib->gl_stride(), ptr);
5855 if (attrib->divisor())
5856 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:245857 glBindBuffer(
5858 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:115859 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
5860 : 0);
[email protected]43410e92012-04-20 17:06:285861
[email protected]265f8992012-07-20 01:03:145862 // Never touch vertex attribute 0's state (in particular, never
5863 // disable it) when running on desktop GL because it will never be
5864 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:065865 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:145866 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:065867 if (attrib->enabled()) {
5868 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145869 } else {
[email protected]ac77603c72013-03-08 13:52:065870 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145871 }
[email protected]43410e92012-04-20 17:06:285872 }
[email protected]b1122982010-05-17 23:04:245873}
[email protected]07f54fcc2009-12-22 02:46:305874
[email protected]8fbedc02010-11-18 18:43:405875bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:435876 const char* function_name,
[email protected]c6aef902012-02-14 03:31:425877 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:405878 DCHECK(simulated);
5879 *simulated = false;
5880 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
5881 return true;
5882
[email protected]e259eb412012-10-13 05:47:245883 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:405884 return true;
5885 }
5886
[email protected]ab09b612013-03-11 22:11:515887 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015888 "GL_FIXED attributes have a signficant performance penalty");
5889
[email protected]8fbedc02010-11-18 18:43:405890 // NOTE: we could be smart and try to check if a buffer is used
5891 // twice in 2 different attribs, find the overlapping parts and therefore
5892 // duplicate the minimum amount of data but this whole code path is not meant
5893 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
5894 // tests so we just add to the buffer attrib used.
5895
[email protected]c13e1da62011-09-09 21:48:305896 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:065897 const VertexAttribManager::VertexAttribList& enabled_attribs =
5898 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
5899 for (VertexAttribManager::VertexAttribList::const_iterator it =
5900 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5901 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355902 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065903 state_.current_program->GetAttribInfoByLocation(attrib->index());
5904 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
5905 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:425906 GLuint num_vertices = max_accessed + 1;
5907 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515908 LOCAL_SET_GL_ERROR(
5909 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425910 return false;
5911 }
[email protected]8fbedc02010-11-18 18:43:405912 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065913 attrib->CanAccess(max_accessed) &&
5914 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:475915 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:065916 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:475917 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:515918 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435919 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405920 return false;
5921 }
5922 }
5923 }
5924
[email protected]3aad1a32012-09-07 20:54:475925 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
5926 uint32 size_needed = 0;
5927 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305928 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515929 LOCAL_SET_GL_ERROR(
5930 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405931 return false;
5932 }
5933
[email protected]ab09b612013-03-11 22:11:515934 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:405935
5936 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:305937 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:405938 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305939 GLenum error = glGetError();
5940 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515941 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435942 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:305943 return false;
5944 }
[email protected]8fbedc02010-11-18 18:43:405945 }
5946
5947 // Copy the elements and convert to float
5948 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:065949 for (VertexAttribManager::VertexAttribList::const_iterator it =
5950 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5951 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355952 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065953 state_.current_program->GetAttribInfoByLocation(attrib->index());
5954 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:425955 max_vertex_accessed);
5956 GLuint num_vertices = max_accessed + 1;
5957 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515958 LOCAL_SET_GL_ERROR(
5959 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425960 return false;
5961 }
[email protected]8fbedc02010-11-18 18:43:405962 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065963 attrib->CanAccess(max_accessed) &&
5964 attrib->type() == GL_FIXED) {
5965 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:405966 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:555967 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:405968 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:065969 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:405970 const int32* end = src + num_elements;
5971 float* dst = data.get();
5972 while (src != end) {
5973 *dst++ = static_cast<float>(*src++) / 65536.0f;
5974 }
5975 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
5976 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065977 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:405978 reinterpret_cast<GLvoid*>(offset));
5979 offset += size;
5980 }
5981 }
5982 *simulated = true;
5983 return true;
5984}
5985
5986void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
5987 // There's no need to call glVertexAttribPointer because we shadow all the
5988 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:245989 glBindBuffer(
5990 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:115991 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
5992 : 0);
[email protected]8fbedc02010-11-18 18:43:405993}
5994
[email protected]ad84a3a2012-06-08 21:42:435995error::Error GLES2DecoderImpl::DoDrawArrays(
5996 const char* function_name,
5997 bool instanced,
5998 GLenum mode,
5999 GLint first,
6000 GLsizei count,
6001 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086002 if (ShouldDeferDraws())
6003 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:436004 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516005 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436006 return error::kNoError;
6007 }
6008 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516009 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436010 return error::kNoError;
6011 }
[email protected]c6aef902012-02-14 03:31:426012 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516013 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426014 return error::kNoError;
6015 }
[email protected]ad84a3a2012-06-08 21:42:436016 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436017 return error::kNoError;
6018 }
6019 // We have to check this here because the prototype for glDrawArrays
6020 // is GLint not GLsizei.
6021 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516022 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436023 return error::kNoError;
6024 }
6025
[email protected]c6aef902012-02-14 03:31:426026 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:516027 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436028 return error::kNoError;
6029 }
6030
6031 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:436032 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206033 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516034 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206035 return error::kNoError;
6036 }
[email protected]c13e1da62011-09-09 21:48:306037 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436038 if (!SimulateAttrib0(
6039 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306040 return error::kNoError;
6041 }
[email protected]38d139d2011-07-14 00:38:436042 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436043 if (SimulateFixedAttribs(
6044 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6045 primcount)) {
[email protected]38d139d2011-07-14 00:38:436046 bool textures_set = SetBlackTextureForNonRenderableTextures();
6047 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:426048 if (!instanced) {
6049 glDrawArrays(mode, first, count);
6050 } else {
6051 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6052 }
[email protected]22e3f552012-03-13 01:54:196053 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:436054 if (textures_set) {
6055 RestoreStateForNonRenderableTextures();
6056 }
6057 if (simulated_fixed_attribs) {
6058 RestoreStateForSimulatedFixedAttribs();
6059 }
6060 }
6061 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286062 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436063 }
[email protected]38d139d2011-07-14 00:38:436064 }
6065 return error::kNoError;
6066}
6067
[email protected]c6aef902012-02-14 03:31:426068error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356069 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436070 return DoDrawArrays("glDrawArrays",
6071 false,
[email protected]c6aef902012-02-14 03:31:426072 static_cast<GLenum>(c.mode),
6073 static_cast<GLint>(c.first),
6074 static_cast<GLsizei>(c.count),
6075 0);
6076}
6077
6078error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356079 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156080 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516081 LOCAL_SET_GL_ERROR(
6082 GL_INVALID_OPERATION,
6083 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426084 return error::kNoError;
6085 }
[email protected]ad84a3a2012-06-08 21:42:436086 return DoDrawArrays("glDrawArraysIntancedANGLE",
6087 true,
[email protected]c6aef902012-02-14 03:31:426088 static_cast<GLenum>(c.mode),
6089 static_cast<GLint>(c.first),
6090 static_cast<GLsizei>(c.count),
6091 static_cast<GLsizei>(c.primcount));
6092}
6093
[email protected]ad84a3a2012-06-08 21:42:436094error::Error GLES2DecoderImpl::DoDrawElements(
6095 const char* function_name,
6096 bool instanced,
6097 GLenum mode,
6098 GLsizei count,
6099 GLenum type,
6100 int32 offset,
6101 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086102 if (ShouldDeferDraws())
6103 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:246104 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516105 LOCAL_SET_GL_ERROR(
6106 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296107 return error::kNoError;
6108 }
6109
[email protected]8eee29c2010-04-29 03:38:296110 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516111 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296112 return error::kNoError;
6113 }
6114 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516115 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296116 return error::kNoError;
6117 }
[email protected]9438b012010-06-15 22:55:056118 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516119 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296120 return error::kNoError;
6121 }
[email protected]9438b012010-06-15 22:55:056122 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516123 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296124 return error::kNoError;
6125 }
[email protected]c6aef902012-02-14 03:31:426126 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516127 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426128 return error::kNoError;
6129 }
[email protected]8eee29c2010-04-29 03:38:296130
[email protected]ad84a3a2012-06-08 21:42:436131 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276132 return error::kNoError;
6133 }
6134
[email protected]c6aef902012-02-14 03:31:426135 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316136 return error::kNoError;
6137 }
6138
[email protected]8eee29c2010-04-29 03:38:296139 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086140 Buffer* element_array_buffer =
6141 state_.vertex_attrib_manager->element_array_buffer();
6142
6143 if (!element_array_buffer->GetMaxValueForRange(
6144 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516145 LOCAL_SET_GL_ERROR(
6146 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296147 return error::kNoError;
6148 }
6149
[email protected]ad84a3a2012-06-08 21:42:436150 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206151 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516152 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206153 return error::kNoError;
6154 }
[email protected]c13e1da62011-09-09 21:48:306155 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436156 if (!SimulateAttrib0(
6157 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306158 return error::kNoError;
6159 }
[email protected]8fbedc02010-11-18 18:43:406160 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436161 if (SimulateFixedAttribs(
6162 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6163 primcount)) {
[email protected]8fbedc02010-11-18 18:43:406164 bool textures_set = SetBlackTextureForNonRenderableTextures();
[email protected]297ca1c2011-06-20 23:08:466165 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086166 // TODO(gman): Refactor to hide these details in BufferManager or
6167 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406168 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086169 bool used_client_side_array = false;
6170 if (element_array_buffer->IsClientSideArray()) {
6171 used_client_side_array = true;
6172 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6173 indices = element_array_buffer->GetRange(offset, 0);
6174 }
6175
[email protected]c6aef902012-02-14 03:31:426176 if (!instanced) {
6177 glDrawElements(mode, count, type, indices);
6178 } else {
6179 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6180 }
[email protected]17cfbe0e2013-03-07 01:26:086181
6182 if (used_client_side_array) {
6183 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6184 element_array_buffer->service_id());
6185 }
6186
[email protected]22e3f552012-03-13 01:54:196187 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406188 if (textures_set) {
6189 RestoreStateForNonRenderableTextures();
6190 }
6191 if (simulated_fixed_attribs) {
6192 RestoreStateForSimulatedFixedAttribs();
6193 }
[email protected]ba3176a2009-12-16 18:19:466194 }
[email protected]b1122982010-05-17 23:04:246195 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286196 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246197 }
[email protected]96449d2c2009-11-25 00:01:326198 }
[email protected]f7a64ee2010-02-01 22:24:146199 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326200}
6201
[email protected]c6aef902012-02-14 03:31:426202error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356203 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436204 return DoDrawElements("glDrawElements",
6205 false,
[email protected]c6aef902012-02-14 03:31:426206 static_cast<GLenum>(c.mode),
6207 static_cast<GLsizei>(c.count),
6208 static_cast<GLenum>(c.type),
6209 static_cast<int32>(c.index_offset),
6210 0);
6211}
6212
6213error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356214 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156215 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516216 LOCAL_SET_GL_ERROR(
6217 GL_INVALID_OPERATION,
6218 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426219 return error::kNoError;
6220 }
[email protected]ad84a3a2012-06-08 21:42:436221 return DoDrawElements("glDrawElementsInstancedANGLE",
6222 true,
[email protected]c6aef902012-02-14 03:31:426223 static_cast<GLenum>(c.mode),
6224 static_cast<GLsizei>(c.count),
6225 static_cast<GLenum>(c.type),
6226 static_cast<int32>(c.index_offset),
6227 static_cast<GLsizei>(c.primcount));
6228}
6229
[email protected]269200b12010-11-18 22:53:066230GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236231 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6232 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076233 Buffer* buffer = GetBuffer(buffer_id);
6234 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036235 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516236 LOCAL_SET_GL_ERROR(
6237 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236238 } else {
[email protected]b10492f2013-03-08 05:24:076239 if (!buffer->GetMaxValueForRange(
6240 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036241 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516242 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066243 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436244 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236245 }
6246 }
6247 return max_vertex_accessed;
6248}
6249
[email protected]96449d2c2009-11-25 00:01:326250// Calls glShaderSource for the various versions of the ShaderSource command.
6251// Assumes that data / data_size points to a piece of memory that is in range
6252// of whatever context it came from (shared memory, immediate memory, bucket
6253// memory.)
[email protected]45bf5152010-02-12 00:11:316254error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036255 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576256 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426257 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6258 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316259 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326260 }
[email protected]45bf5152010-02-12 00:11:316261 // Note: We don't actually call glShaderSource here. We wait until
6262 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426263 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146264 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326265}
6266
[email protected]f7a64ee2010-02-01 22:24:146267error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356268 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326269 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316270 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326271 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466272 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146273 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326274 }
[email protected]ae51d192010-04-27 00:48:036275 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326276}
6277
[email protected]f7a64ee2010-02-01 22:24:146278error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]ed9f9cd2013-02-27 21:12:356279 uint32 immediate_data_size, const cmds::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:326280 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316281 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:306282 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:466283 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146284 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326285 }
[email protected]ae51d192010-04-27 00:48:036286 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:316287}
6288
[email protected]558847a2010-03-24 07:02:546289error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356290 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546291 Bucket* bucket = GetBucket(c.data_bucket_id);
6292 if (!bucket || bucket->size() == 0) {
6293 return error::kInvalidArguments;
6294 }
6295 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036296 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546297 bucket->size() - 1);
6298}
6299
[email protected]ae51d192010-04-27 00:48:036300void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386301 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426302 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6303 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316304 return;
6305 }
[email protected]f57bb282010-11-12 00:51:346306 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186307 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426308 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456309 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416310 }
[email protected]de17df392010-04-23 21:09:416311
[email protected]7cd76fd2013-06-02 21:11:116312 program_manager()->DoCompileShader(shader, translator, feature_info_.get());
[email protected]45bf5152010-02-12 00:11:316313};
6314
[email protected]ddd968b82010-03-02 00:44:296315void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426316 GLuint shader_id, GLenum pname, GLint* params) {
6317 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6318 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296319 return;
6320 }
[email protected]8f1ccdac2010-05-19 21:01:486321 switch (pname) {
6322 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426323 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486324 return;
6325 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426326 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416327 return;
[email protected]8f1ccdac2010-05-19 21:01:486328 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426329 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416330 return;
[email protected]d6a53e42011-10-05 00:09:366331 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426332 ForceCompileShaderIfPending(shader);
6333 *params = shader->translated_source() ?
6334 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366335 return;
[email protected]8f1ccdac2010-05-19 21:01:486336 default:
6337 break;
[email protected]ddd968b82010-03-02 00:44:296338 }
[email protected]df37b9932013-03-08 05:21:426339 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296340}
6341
[email protected]ae51d192010-04-27 00:48:036342error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356343 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426344 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036345 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6346 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426347 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6348 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296349 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296350 return error::kNoError;
6351 }
[email protected]df37b9932013-03-08 05:21:426352 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036353 return error::kNoError;
6354}
6355
[email protected]d6a53e42011-10-05 00:09:366356error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6357 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356358 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426359 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366360 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6361 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426362 Shader* shader = GetShaderInfoNotProgram(
6363 shader_id, "glTranslatedGetShaderSourceANGLE");
6364 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366365 bucket->SetSize(0);
6366 return error::kNoError;
6367 }
[email protected]df37b9932013-03-08 05:21:426368 ForceCompileShaderIfPending(shader);
[email protected]d6a53e42011-10-05 00:09:366369
[email protected]df37b9932013-03-08 05:21:426370 bucket->SetFromString(shader->translated_source() ?
6371 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366372 return error::kNoError;
6373}
6374
[email protected]ae51d192010-04-27 00:48:036375error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356376 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426377 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586378 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6379 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426380 Program* program = GetProgramInfoNotShader(
6381 program_id, "glGetProgramInfoLog");
6382 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466383 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036384 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316385 }
[email protected]df37b9932013-03-08 05:21:426386 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036387 return error::kNoError;
6388}
6389
6390error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356391 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426392 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586393 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6394 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426395 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6396 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466397 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036398 return error::kNoError;
6399 }
[email protected]df37b9932013-03-08 05:21:426400 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036401 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326402}
6403
[email protected]d058bca2012-11-26 10:27:266404bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6405 return state_.GetEnabled(cap);
6406}
6407
[email protected]1958e0e2010-04-22 05:17:156408bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216409 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106410 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156411}
6412
6413bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356414 const Framebuffer* framebuffer =
6415 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106416 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156417}
6418
6419bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366420 // IsProgram is true for programs as soon as they are created, until they are
6421 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356422 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106423 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156424}
6425
6426bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356427 const Renderbuffer* renderbuffer =
6428 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106429 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156430}
6431
6432bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366433 // IsShader is true for shaders as soon as they are created, until they
6434 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356435 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106436 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156437}
6438
6439bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496440 const TextureRef* texture_ref = GetTexture(client_id);
6441 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036442}
6443
6444void GLES2DecoderImpl::DoAttachShader(
6445 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426446 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586447 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426448 if (!program) {
[email protected]ae51d192010-04-27 00:48:036449 return;
[email protected]1958e0e2010-04-22 05:17:156450 }
[email protected]df37b9932013-03-08 05:21:426451 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6452 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036453 return;
6454 }
[email protected]df37b9932013-03-08 05:21:426455 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516456 LOCAL_SET_GL_ERROR(
6457 GL_INVALID_OPERATION,
6458 "glAttachShader",
6459 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316460 return;
6461 }
[email protected]df37b9932013-03-08 05:21:426462 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036463}
6464
6465void GLES2DecoderImpl::DoDetachShader(
6466 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426467 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586468 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426469 if (!program) {
[email protected]ae51d192010-04-27 00:48:036470 return;
6471 }
[email protected]df37b9932013-03-08 05:21:426472 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6473 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036474 return;
6475 }
[email protected]df37b9932013-03-08 05:21:426476 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516477 LOCAL_SET_GL_ERROR(
6478 GL_INVALID_OPERATION,
6479 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226480 return;
6481 }
[email protected]df37b9932013-03-08 05:21:426482 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036483}
6484
6485void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426486 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586487 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426488 if (!program) {
[email protected]ae51d192010-04-27 00:48:036489 return;
6490 }
[email protected]df37b9932013-03-08 05:21:426491 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156492}
6493
[email protected]ac77603c72013-03-08 13:52:066494void GLES2DecoderImpl::GetVertexAttribHelper(
6495 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246496 switch (pname) {
6497 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066498 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246499 if (buffer && !buffer->IsDeleted()) {
6500 GLuint client_id;
6501 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6502 *params = client_id;
6503 }
6504 break;
6505 }
6506 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066507 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246508 break;
6509 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066510 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246511 break;
6512 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066513 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246514 break;
6515 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066516 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246517 break;
6518 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066519 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246520 break;
[email protected]c6aef902012-02-14 03:31:426521 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066522 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426523 break;
[email protected]ac77603c72013-03-08 13:52:066524 default:
6525 NOTREACHED();
6526 break;
6527 }
6528}
6529
6530void GLES2DecoderImpl::DoGetVertexAttribfv(
6531 GLuint index, GLenum pname, GLfloat* params) {
6532 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6533 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516534 LOCAL_SET_GL_ERROR(
6535 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066536 return;
6537 }
6538 switch (pname) {
6539 case GL_CURRENT_VERTEX_ATTRIB: {
6540 const Vec4& value = state_.attrib_values[index];
6541 params[0] = value.v[0];
6542 params[1] = value.v[1];
6543 params[2] = value.v[2];
6544 params[3] = value.v[3];
6545 break;
6546 }
6547 default: {
6548 GLint value = 0;
6549 GetVertexAttribHelper(attrib, pname, &value);
6550 *params = static_cast<GLfloat>(value);
6551 break;
6552 }
6553 }
6554}
6555
6556void GLES2DecoderImpl::DoGetVertexAttribiv(
6557 GLuint index, GLenum pname, GLint* params) {
6558 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6559 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516560 LOCAL_SET_GL_ERROR(
6561 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066562 return;
6563 }
6564 switch (pname) {
[email protected]af6380962012-11-29 23:24:136565 case GL_CURRENT_VERTEX_ATTRIB: {
6566 const Vec4& value = state_.attrib_values[index];
6567 params[0] = static_cast<GLint>(value.v[0]);
6568 params[1] = static_cast<GLint>(value.v[1]);
6569 params[2] = static_cast<GLint>(value.v[2]);
6570 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246571 break;
[email protected]af6380962012-11-29 23:24:136572 }
[email protected]b1122982010-05-17 23:04:246573 default:
[email protected]ac77603c72013-03-08 13:52:066574 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246575 break;
6576 }
6577}
6578
[email protected]af6380962012-11-29 23:24:136579bool GLES2DecoderImpl::SetVertexAttribValue(
6580 const char* function_name, GLuint index, const GLfloat* value) {
6581 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516582 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136583 return false;
[email protected]b1122982010-05-17 23:04:246584 }
[email protected]af6380962012-11-29 23:24:136585 Vec4& v = state_.attrib_values[index];
6586 v.v[0] = value[0];
6587 v.v[1] = value[1];
6588 v.v[2] = value[2];
6589 v.v[3] = value[3];
6590 return true;
6591}
6592
6593void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6594 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6595 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6596 glVertexAttrib1f(index, v0);
6597 }
[email protected]b1122982010-05-17 23:04:246598}
6599
6600void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136601 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6602 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6603 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246604 }
[email protected]b1122982010-05-17 23:04:246605}
6606
6607void GLES2DecoderImpl::DoVertexAttrib3f(
6608 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136609 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6610 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6611 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246612 }
[email protected]b1122982010-05-17 23:04:246613}
6614
6615void GLES2DecoderImpl::DoVertexAttrib4f(
6616 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136617 GLfloat v[4] = { v0, v1, v2, v3, };
6618 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6619 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246620 }
[email protected]b1122982010-05-17 23:04:246621}
6622
6623void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136624 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6625 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6626 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246627 }
[email protected]b1122982010-05-17 23:04:246628}
6629
6630void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136631 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6632 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6633 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246634 }
[email protected]b1122982010-05-17 23:04:246635}
6636
6637void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136638 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6639 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6640 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246641 }
[email protected]b1122982010-05-17 23:04:246642}
6643
6644void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136645 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6646 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246647 }
[email protected]b1122982010-05-17 23:04:246648}
6649
[email protected]f7a64ee2010-02-01 22:24:146650error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:356651 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466652
[email protected]7cd76fd2013-06-02 21:11:116653 if (!state_.bound_array_buffer.get() ||
6654 state_.bound_array_buffer->IsDeleted()) {
6655 if (state_.vertex_attrib_manager.get() ==
6656 default_vertex_attrib_manager_.get()) {
[email protected]ab09b612013-03-11 22:11:516657 LOCAL_SET_GL_ERROR(
6658 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:466659 return error::kNoError;
6660 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:516661 LOCAL_SET_GL_ERROR(
6662 GL_INVALID_VALUE,
6663 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:466664 return error::kNoError;
6665 }
[email protected]96449d2c2009-11-25 00:01:326666 }
[email protected]8eee29c2010-04-29 03:38:296667
6668 GLuint indx = c.indx;
6669 GLint size = c.size;
6670 GLenum type = c.type;
6671 GLboolean normalized = c.normalized;
6672 GLsizei stride = c.stride;
6673 GLsizei offset = c.offset;
6674 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056675 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516676 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296677 return error::kNoError;
6678 }
[email protected]9438b012010-06-15 22:55:056679 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:516680 LOCAL_SET_GL_ERROR(
6681 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296682 return error::kNoError;
6683 }
6684 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516685 LOCAL_SET_GL_ERROR(
6686 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296687 return error::kNoError;
6688 }
6689 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:516690 LOCAL_SET_GL_ERROR(
6691 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296692 return error::kNoError;
6693 }
6694 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:516695 LOCAL_SET_GL_ERROR(
6696 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296697 return error::kNoError;
6698 }
6699 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516700 LOCAL_SET_GL_ERROR(
6701 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296702 return error::kNoError;
6703 }
6704 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316705 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296706 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516707 LOCAL_SET_GL_ERROR(
6708 GL_INVALID_OPERATION,
6709 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316710 return error::kNoError;
6711 }
6712 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516713 LOCAL_SET_GL_ERROR(
6714 GL_INVALID_OPERATION,
6715 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296716 return error::kNoError;
6717 }
[email protected]7cd76fd2013-06-02 21:11:116718 state_.vertex_attrib_manager
6719 ->SetAttribInfo(indx,
6720 state_.bound_array_buffer.get(),
6721 size,
6722 type,
6723 normalized,
6724 stride,
6725 stride != 0 ? stride : component_size * size,
6726 offset);
[email protected]8fbedc02010-11-18 18:43:406727 if (type != GL_FIXED) {
6728 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6729 }
[email protected]f7a64ee2010-02-01 22:24:146730 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326731}
6732
[email protected]43410e92012-04-20 17:06:286733void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6734 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246735 state_.viewport_x = x;
6736 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026737 state_.viewport_width = std::min(width, viewport_max_width_);
6738 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286739 glViewport(x, y, width, height);
6740}
6741
[email protected]c6aef902012-02-14 03:31:426742error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356743 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156744 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516745 LOCAL_SET_GL_ERROR(
6746 GL_INVALID_OPERATION,
6747 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426748 }
6749 GLuint index = c.index;
6750 GLuint divisor = c.divisor;
6751 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516752 LOCAL_SET_GL_ERROR(
6753 GL_INVALID_VALUE,
6754 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426755 return error::kNoError;
6756 }
6757
[email protected]e259eb412012-10-13 05:47:246758 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426759 index,
6760 divisor);
6761 glVertexAttribDivisorANGLE(index, divisor);
6762 return error::kNoError;
6763}
6764
[email protected]f7a64ee2010-02-01 22:24:146765error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:356766 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:446767 if (ShouldDeferReads())
6768 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:316769 GLint x = c.x;
6770 GLint y = c.y;
6771 GLsizei width = c.width;
6772 GLsizei height = c.height;
6773 GLenum format = c.format;
6774 GLenum type = c.type;
[email protected]57f223832010-03-19 01:57:566775 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:516776 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566777 return error::kNoError;
6778 }
[email protected]ed9f9cd2013-02-27 21:12:356779 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186780 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346781 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246782 width, height, format, type, state_.pack_alignment, &pixels_size,
6783 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186784 return error::kOutOfBounds;
6785 }
[email protected]612d2f82009-12-08 20:49:316786 void* pixels = GetSharedMemoryAs<void*>(
6787 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:106788 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:146789 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466790 }
[email protected]de43f082013-04-02 01:16:106791 Result* result = NULL;
6792 if (c.result_shm_id != 0) {
6793 result = GetSharedMemoryAs<Result*>(
6794 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6795 if (!result) {
6796 return error::kOutOfBounds;
6797 }
6798 }
[email protected]a51788e2010-02-24 21:54:256799
[email protected]9438b012010-06-15 22:55:056800 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:516801 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296802 return error::kNoError;
6803 }
[email protected]9438b012010-06-15 22:55:056804 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516805 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:126806 return error::kNoError;
6807 }
[email protected]57f223832010-03-19 01:57:566808 if (width == 0 || height == 0) {
6809 return error::kNoError;
6810 }
6811
[email protected]57f223832010-03-19 01:57:566812 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:306813 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:566814
[email protected]3aad1a32012-09-07 20:54:476815 int32 max_x;
6816 int32 max_y;
6817 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:516818 LOCAL_SET_GL_ERROR(
6819 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:146820 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:316821 }
[email protected]57f223832010-03-19 01:57:566822
[email protected]0d6bfdc2011-11-02 01:32:206823 if (!CheckBoundFramebuffersValid("glReadPixels")) {
6824 return error::kNoError;
6825 }
6826
[email protected]ab09b612013-03-11 22:11:516827 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel");
[email protected]a0b78dc2011-11-11 10:43:106828
6829 ScopedResolvedFrameBufferBinder binder(this, false, true);
6830
[email protected]d37231fa2010-04-09 21:16:026831 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:566832 // The user requested an out of range area. Get the results 1 line
6833 // at a time.
6834 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346835 uint32 unpadded_row_size;
6836 uint32 padded_row_size;
6837 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246838 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346839 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:516840 LOCAL_SET_GL_ERROR(
6841 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566842 return error::kNoError;
6843 }
6844
6845 GLint dest_x_offset = std::max(-x, 0);
6846 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:346847 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246848 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
6849 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:516850 LOCAL_SET_GL_ERROR(
6851 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566852 return error::kNoError;
6853 }
6854
6855 // Copy each row into the larger dest rect.
6856 int8* dst = static_cast<int8*>(pixels);
6857 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:026858 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:566859 GLint read_width = read_end_x - read_x;
6860 for (GLint yy = 0; yy < height; ++yy) {
6861 GLint ry = y + yy;
6862
6863 // Clear the row.
6864 memset(dst, 0, unpadded_row_size);
6865
6866 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:026867 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:566868 glReadPixels(
6869 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6870 }
6871 dst += padded_row_size;
6872 }
6873 } else {
[email protected]57f223832010-03-19 01:57:566874 glReadPixels(x, y, width, height, format, type, pixels);
6875 }
[email protected]ab09b612013-03-11 22:11:516876 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:256877 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:106878 if (result != NULL) {
6879 *result = true;
6880 }
[email protected]744329c2013-07-12 00:54:256881
6882 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6883 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
6884 if ((channels_exist & 0x0008) == 0 &&
6885 workarounds().clear_alpha_in_readpixels) {
6886 // Set the alpha to 255 because some drivers are buggy in this regard.
6887 uint32 temp_size;
6888
6889 uint32 unpadded_row_size;
6890 uint32 padded_row_size;
6891 if (!GLES2Util::ComputeImageDataSizes(
6892 width, 2, format, type, state_.pack_alignment, &temp_size,
6893 &unpadded_row_size, &padded_row_size)) {
6894 LOCAL_SET_GL_ERROR(
6895 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
6896 return error::kNoError;
6897 }
6898 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6899 // of this implementation.
6900 if (type != GL_UNSIGNED_BYTE) {
6901 LOCAL_SET_GL_ERROR(
6902 GL_INVALID_OPERATION, "glReadPixels",
6903 "unsupported readPixel format");
6904 return error::kNoError;
6905 }
6906 switch (format) {
6907 case GL_RGBA:
6908 case GL_BGRA_EXT:
6909 case GL_ALPHA: {
6910 int offset = (format == GL_ALPHA) ? 0 : 3;
6911 int step = (format == GL_ALPHA) ? 1 : 4;
6912 uint8* dst = static_cast<uint8*>(pixels) + offset;
6913 for (GLint yy = 0; yy < height; ++yy) {
6914 uint8* end = dst + unpadded_row_size;
6915 for (uint8* d = dst; d < end; d += step) {
6916 *d = 255;
6917 }
6918 dst += padded_row_size;
6919 }
6920 break;
6921 }
6922 default:
6923 break;
6924 }
6925 }
[email protected]a51788e2010-02-24 21:54:256926 }
[email protected]4848b9f82011-03-10 18:37:566927
[email protected]f7a64ee2010-02-01 22:24:146928 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326929}
6930
[email protected]f7a64ee2010-02-01 22:24:146931error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:356932 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:196933 GLenum pname = c.pname;
6934 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:056935 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:516936 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:126937 return error::kNoError;
6938 }
[email protected]222471d2011-11-30 18:06:396939 switch (pname) {
6940 case GL_PACK_ALIGNMENT:
6941 case GL_UNPACK_ALIGNMENT:
6942 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:516943 LOCAL_SET_GL_ERROR(
6944 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:396945 return error::kNoError;
6946 }
[email protected]164d6d52012-05-05 00:55:036947 break;
[email protected]0a1e9ad2012-05-04 21:13:036948 case GL_UNPACK_FLIP_Y_CHROMIUM:
6949 unpack_flip_y_ = (param != 0);
6950 return error::kNoError;
6951 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
6952 unpack_premultiply_alpha_ = (param != 0);
6953 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:176954 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
6955 unpack_unpremultiply_alpha_ = (param != 0);
6956 return error::kNoError;
[email protected]222471d2011-11-30 18:06:396957 default:
6958 break;
[email protected]b9849abf2009-11-25 19:13:196959 }
6960 glPixelStorei(pname, param);
6961 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:436962 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246963 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436964 break;
6965 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:426966 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:436967 break;
6968 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246969 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436970 break;
6971 default:
6972 // Validation should have prevented us from getting here.
6973 NOTREACHED();
6974 break;
[email protected]b9849abf2009-11-25 19:13:196975 }
[email protected]f7a64ee2010-02-01 22:24:146976 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196977}
6978
[email protected]1c75a3702011-11-11 14:15:286979error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:356980 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:386981 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:456982 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:516983 LOCAL_SET_GL_ERROR(
6984 GL_INVALID_OPERATION,
6985 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:286986 return error::kNoError;
6987 }
[email protected]7794d512012-04-17 20:36:496988 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:286989 return error::kNoError;
[email protected]7794d512012-04-17 20:36:496990 } else {
6991 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:286992 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:496993 }
[email protected]1c75a3702011-11-11 14:15:286994}
6995
[email protected]558847a2010-03-24 07:02:546996error::Error GLES2DecoderImpl::GetAttribLocationHelper(
6997 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6998 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576999 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517000 LOCAL_SET_GL_ERROR(
7001 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577002 return error::kNoError;
7003 }
[email protected]df37b9932013-03-08 05:21:427004 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587005 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427006 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147007 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197008 }
[email protected]df37b9932013-03-08 05:21:427009 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517010 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437011 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257012 return error::kNoError;
7013 }
[email protected]b9849abf2009-11-25 19:13:197014 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547015 location_shm_id, location_shm_offset, sizeof(GLint));
7016 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147017 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197018 }
[email protected]558847a2010-03-24 07:02:547019 // Require the client to init this incase the context is lost and we are no
7020 // longer executing commands.
7021 if (*location != -1) {
7022 return error::kGenericError;
7023 }
[email protected]df37b9932013-03-08 05:21:427024 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147025 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197026}
7027
[email protected]558847a2010-03-24 07:02:547028error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357029 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547030 uint32 name_size = c.data_size;
7031 const char* name = GetSharedMemoryAs<const char*>(
7032 c.name_shm_id, c.name_shm_offset, name_size);
7033 if (!name) {
7034 return error::kOutOfBounds;
7035 }
7036 String name_str(name, name_size);
7037 return GetAttribLocationHelper(
7038 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7039}
7040
[email protected]f7a64ee2010-02-01 22:24:147041error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357042 uint32 immediate_data_size, const cmds::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:547043 uint32 name_size = c.data_size;
7044 const char* name = GetImmediateDataAs<const char*>(
7045 c, name_size, immediate_data_size);
7046 if (!name) {
7047 return error::kOutOfBounds;
7048 }
7049 String name_str(name, name_size);
7050 return GetAttribLocationHelper(
7051 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7052}
7053
7054error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357055 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547056 Bucket* bucket = GetBucket(c.name_bucket_id);
7057 if (!bucket) {
7058 return error::kInvalidArguments;
7059 }
7060 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187061 if (!bucket->GetAsString(&name_str)) {
7062 return error::kInvalidArguments;
7063 }
[email protected]558847a2010-03-24 07:02:547064 return GetAttribLocationHelper(
7065 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7066}
7067
7068error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7069 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7070 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577071 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517072 LOCAL_SET_GL_ERROR(
7073 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577074 return error::kNoError;
7075 }
[email protected]df37b9932013-03-08 05:21:427076 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587077 client_id, "glUniformLocation");
[email protected]df37b9932013-03-08 05:21:427078 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147079 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197080 }
[email protected]df37b9932013-03-08 05:21:427081 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517082 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437083 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257084 return error::kNoError;
7085 }
[email protected]b9849abf2009-11-25 19:13:197086 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547087 location_shm_id, location_shm_offset, sizeof(GLint));
7088 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147089 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197090 }
[email protected]558847a2010-03-24 07:02:547091 // Require the client to init this incase the context is lost an we are no
7092 // longer executing commands.
7093 if (*location != -1) {
7094 return error::kGenericError;
7095 }
[email protected]df37b9932013-03-08 05:21:427096 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147097 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197098}
7099
[email protected]f7a64ee2010-02-01 22:24:147100error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357101 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197102 uint32 name_size = c.data_size;
7103 const char* name = GetSharedMemoryAs<const char*>(
7104 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547105 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147106 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197107 }
7108 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547109 return GetUniformLocationHelper(
7110 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197111}
7112
[email protected]f7a64ee2010-02-01 22:24:147113error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357114 uint32 immediate_data_size, const cmds::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197115 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:307116 const char* name = GetImmediateDataAs<const char*>(
7117 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:547118 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147119 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197120 }
7121 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547122 return GetUniformLocationHelper(
7123 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7124}
7125
7126error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357127 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547128 Bucket* bucket = GetBucket(c.name_bucket_id);
7129 if (!bucket) {
7130 return error::kInvalidArguments;
7131 }
7132 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187133 if (!bucket->GetAsString(&name_str)) {
7134 return error::kInvalidArguments;
7135 }
[email protected]558847a2010-03-24 07:02:547136 return GetUniformLocationHelper(
7137 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197138}
7139
[email protected]ddd968b82010-03-02 00:44:297140error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357141 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297142 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057143 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517144 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297145 return error::kNoError;
7146 }
[email protected]1958e0e2010-04-22 05:17:157147 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
7148 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:047149 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157150 switch (name) {
7151 case GL_VERSION:
7152 str = "OpenGL ES 2.0 Chromium";
7153 break;
7154 case GL_SHADING_LANGUAGE_VERSION:
7155 str = "OpenGL ES GLSL ES 1.0 Chromium";
7156 break;
[email protected]32939602012-05-09 06:25:167157 case GL_RENDERER:
7158 str = "Chromium";
7159 break;
7160 case GL_VENDOR:
7161 str = "Chromium";
7162 break;
[email protected]1958e0e2010-04-22 05:17:157163 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047164 {
[email protected]70dc60932013-06-04 03:33:497165 // For WebGL contexts, strip out the OES derivatives and
7166 // EXT frag depth extensions if they have not been enabled.
7167 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047168 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497169 if (!derivatives_explicitly_enabled_) {
7170 size_t offset = extensions.find(kOESDerivativeExtension);
7171 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097172 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497173 std::string());
7174 }
7175 }
7176 if (!frag_depth_explicitly_enabled_) {
7177 size_t offset = extensions.find(kEXTFragDepthExtension);
7178 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097179 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497180 std::string());
7181 }
[email protected]f0d74742011-10-03 16:31:047182 }
[email protected]aff39ac82013-06-08 04:53:137183 if (!draw_buffers_explicitly_enabled_) {
7184 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7185 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097186 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137187 std::string());
7188 }
7189 }
[email protected]f0d74742011-10-03 16:31:047190 } else {
[email protected]6f5fac9d12012-06-26 21:02:457191 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047192 }
[email protected]6f5fac9d12012-06-26 21:02:457193 std::string surface_extensions = surface_->GetExtensions();
7194 if (!surface_extensions.empty())
7195 extensions += " " + surface_extensions;
7196 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047197 }
[email protected]1958e0e2010-04-22 05:17:157198 break;
7199 default:
7200 str = gl_str;
7201 break;
7202 }
[email protected]ddd968b82010-03-02 00:44:297203 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157204 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297205 return error::kNoError;
7206}
7207
[email protected]0c86dbf2010-03-05 08:14:117208error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357209 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117210 GLenum target = static_cast<GLenum>(c.target);
7211 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7212 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7213 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7214 GLenum usage = static_cast<GLenum>(c.usage);
7215 const void* data = NULL;
7216 if (data_shm_id != 0 || data_shm_offset != 0) {
7217 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7218 if (!data) {
7219 return error::kOutOfBounds;
7220 }
7221 }
[email protected]0fbba3732013-07-17 15:40:137222 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147223 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197224}
7225
[email protected]f7a64ee2010-02-01 22:24:147226error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357227 uint32 immediate_data_size, const cmds::BufferDataImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197228 GLenum target = static_cast<GLenum>(c.target);
7229 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:307230 const void* data = GetImmediateDataAs<const void*>(
7231 c, size, immediate_data_size);
7232 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147233 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:307234 }
[email protected]b9849abf2009-11-25 19:13:197235 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0fbba3732013-07-17 15:40:137236 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]0c86dbf2010-03-05 08:14:117237 return error::kNoError;
7238}
7239
7240void GLES2DecoderImpl::DoBufferSubData(
7241 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137242 // Just delegate it. Some validation is actually done before this.
7243 buffer_manager()->ValidateAndDoBufferSubData(
7244 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197245}
7246
[email protected]0d6bfdc2011-11-02 01:32:207247bool GLES2DecoderImpl::ClearLevel(
7248 unsigned service_id,
7249 unsigned bind_target,
7250 unsigned target,
7251 int level,
7252 unsigned format,
7253 unsigned type,
7254 int width,
[email protected]4502e6492011-12-14 19:39:157255 int height,
7256 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007257 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7258 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7259 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7260 // on depth formats.
7261 GLuint fb = 0;
7262 glGenFramebuffersEXT(1, &fb);
7263 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7264
7265 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7266 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7267 GL_DEPTH_ATTACHMENT;
7268
7269 glFramebufferTexture2DEXT(
7270 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7271 // ANGLE promises a depth only attachment ok.
7272 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7273 GL_FRAMEBUFFER_COMPLETE) {
7274 return false;
7275 }
7276 glClearStencil(0);
7277 glStencilMask(-1);
7278 glClearDepth(1.0f);
7279 glDepthMask(true);
7280 glDisable(GL_SCISSOR_TEST);
7281 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7282
7283 RestoreClearState();
7284
7285 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357286 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007287 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7288 GLuint fb_service_id =
7289 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7290 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7291 return true;
7292 }
7293
[email protected]45d15a62012-04-18 14:33:177294 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7295
7296 uint32 size;
7297 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347298 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247299 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177300 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207301 return false;
7302 }
[email protected]45d15a62012-04-18 14:33:177303
[email protected]a5d3dad2012-05-26 04:34:447304 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7305
[email protected]45d15a62012-04-18 14:33:177306 int tile_height;
7307
7308 if (size > kMaxZeroSize) {
7309 if (kMaxZeroSize < padded_row_size) {
7310 // That'd be an awfully large texture.
7311 return false;
7312 }
7313 // We should never have a large total size with a zero row size.
7314 DCHECK_GT(padded_row_size, 0U);
7315 tile_height = kMaxZeroSize / padded_row_size;
7316 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247317 width, tile_height, format, type, state_.unpack_alignment, &size,
7318 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177319 return false;
7320 }
[email protected]4502e6492011-12-14 19:39:157321 } else {
[email protected]45d15a62012-04-18 14:33:177322 tile_height = height;
7323 }
7324
7325 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557326 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177327 memset(zero.get(), 0, size);
7328 glBindTexture(bind_target, service_id);
7329
7330 GLint y = 0;
7331 while (y < height) {
7332 GLint h = y + tile_height > height ? height - y : tile_height;
7333 if (is_texture_immutable || h != height) {
7334 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7335 } else {
[email protected]8f1d2aa2013-05-10 23:45:387336 glTexImage2D(
[email protected]45d15a62012-04-18 14:33:177337 target, level, format, width, h, 0, format, type, zero.get());
7338 }
7339 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157340 }
[email protected]370eaf12013-05-18 09:19:497341 TextureRef* texture = GetTextureInfoForTarget(bind_target);
[email protected]02965c22013-03-09 02:40:077342 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207343 return true;
7344}
7345
[email protected]ad84a3a2012-06-08 21:42:437346namespace {
7347
7348const int kS3TCBlockWidth = 4;
7349const int kS3TCBlockHeight = 4;
7350const int kS3TCDXT1BlockSize = 8;
7351const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077352const int kETC1BlockWidth = 4;
7353const int kETC1BlockHeight = 4;
7354const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437355
7356bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517357 return (size == 1) ||
7358 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437359}
7360
7361} // anonymous namespace.
7362
7363bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7364 const char* function_name,
7365 GLsizei width, GLsizei height, GLenum format, size_t size) {
7366 unsigned int bytes_required = 0;
7367
7368 switch (format) {
7369 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7370 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7371 int num_blocks_across =
7372 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7373 int num_blocks_down =
7374 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7375 int num_blocks = num_blocks_across * num_blocks_down;
7376 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7377 break;
7378 }
7379 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7380 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7381 int num_blocks_across =
7382 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7383 int num_blocks_down =
7384 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7385 int num_blocks = num_blocks_across * num_blocks_down;
7386 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7387 break;
7388 }
[email protected]2d3765b2012-10-03 00:31:077389 case GL_ETC1_RGB8_OES: {
7390 int num_blocks_across =
7391 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7392 int num_blocks_down =
7393 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7394 int num_blocks = num_blocks_across * num_blocks_down;
7395 bytes_required = num_blocks * kETC1BlockSize;
7396 break;
7397 }
[email protected]ad84a3a2012-06-08 21:42:437398 default:
[email protected]ab09b612013-03-11 22:11:517399 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437400 return false;
7401 }
7402
7403 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517404 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437405 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7406 return false;
7407 }
7408
7409 return true;
7410}
7411
7412bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7413 const char* function_name,
7414 GLint level, GLsizei width, GLsizei height, GLenum format) {
7415 switch (format) {
7416 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7417 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7418 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7419 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7420 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517421 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437422 GL_INVALID_OPERATION, function_name,
7423 "width or height invalid for level");
7424 return false;
7425 }
7426 return true;
7427 }
[email protected]2d3765b2012-10-03 00:31:077428 case GL_ETC1_RGB8_OES:
7429 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517430 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077431 GL_INVALID_OPERATION, function_name,
7432 "width or height invalid for level");
7433 return false;
7434 }
7435 return true;
[email protected]ad84a3a2012-06-08 21:42:437436 default:
7437 return false;
7438 }
7439}
7440
7441bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7442 const char* function_name,
7443 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7444 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357445 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437446 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517447 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437448 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7449 return false;
7450 }
7451
7452 switch (format) {
7453 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7454 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7455 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7456 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7457 const int kBlockWidth = 4;
7458 const int kBlockHeight = 4;
7459 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517460 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437461 GL_INVALID_OPERATION, function_name,
7462 "xoffset or yoffset not multiple of 4");
7463 return false;
7464 }
7465 GLsizei tex_width = 0;
7466 GLsizei tex_height = 0;
7467 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7468 width - xoffset > tex_width ||
7469 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517470 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437471 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7472 return false;
7473 }
7474 return ValidateCompressedTexDimensions(
7475 function_name, level, width, height, format);
7476 }
[email protected]2d3765b2012-10-03 00:31:077477 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517478 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077479 GL_INVALID_OPERATION, function_name,
7480 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7481 return false;
7482 }
[email protected]ad84a3a2012-06-08 21:42:437483 default:
7484 return false;
7485 }
7486}
7487
[email protected]a93bb842010-02-16 23:03:477488error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7489 GLenum target,
7490 GLint level,
7491 GLenum internal_format,
7492 GLsizei width,
7493 GLsizei height,
7494 GLint border,
7495 GLsizei image_size,
7496 const void* data) {
[email protected]a93bb842010-02-16 23:03:477497 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057498 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517499 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7500 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297501 return error::kNoError;
7502 }
[email protected]9438b012010-06-15 22:55:057503 if (!validators_->compressed_texture_format.IsValid(
7504 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517505 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537506 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477507 return error::kNoError;
7508 }
[email protected]80eb6b52012-01-19 00:14:417509 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477510 border != 0) {
[email protected]ab09b612013-03-11 22:11:517511 LOCAL_SET_GL_ERROR(
7512 GL_INVALID_VALUE,
7513 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477514 return error::kNoError;
7515 }
[email protected]370eaf12013-05-18 09:19:497516 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7517 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517518 LOCAL_SET_GL_ERROR(
7519 GL_INVALID_VALUE,
7520 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477521 return error::kNoError;
7522 }
[email protected]370eaf12013-05-18 09:19:497523 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077524 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517525 LOCAL_SET_GL_ERROR(
7526 GL_INVALID_OPERATION,
7527 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:437528 return error::kNoError;
7529 }
7530
7531 if (!ValidateCompressedTexDimensions(
7532 "glCompressedTexImage2D", level, width, height, internal_format) ||
7533 !ValidateCompressedTexFuncData(
7534 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177535 return error::kNoError;
7536 }
[email protected]968351b2011-12-20 08:26:517537
[email protected]7989c9e2013-01-23 06:39:267538 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:517539 LOCAL_SET_GL_ERROR(
7540 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267541 return error::kNoError;
7542 }
7543
[email protected]02965c22013-03-09 02:40:077544 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427545 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517546 }
7547
[email protected]40d90a22013-04-09 03:39:557548 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:477549 if (!data) {
7550 zero.reset(new int8[image_size]);
7551 memset(zero.get(), 0, image_size);
7552 data = zero.get();
7553 }
[email protected]ab09b612013-03-11 22:11:517554 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:477555 glCompressedTexImage2D(
7556 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:517557 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437558 if (error == GL_NO_ERROR) {
7559 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497560 texture_ref, target, level, internal_format,
7561 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:437562 }
[email protected]a93bb842010-02-16 23:03:477563 return error::kNoError;
7564}
7565
[email protected]f7a64ee2010-02-01 22:24:147566error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357567 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:197568 GLenum target = static_cast<GLenum>(c.target);
7569 GLint level = static_cast<GLint>(c.level);
7570 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7571 GLsizei width = static_cast<GLsizei>(c.width);
7572 GLsizei height = static_cast<GLsizei>(c.height);
7573 GLint border = static_cast<GLint>(c.border);
7574 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7575 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7576 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7577 const void* data = NULL;
7578 if (data_shm_id != 0 || data_shm_offset != 0) {
7579 data = GetSharedMemoryAs<const void*>(
7580 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467581 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147582 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197583 }
7584 }
[email protected]a93bb842010-02-16 23:03:477585 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197586 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197587}
7588
[email protected]f7a64ee2010-02-01 22:24:147589error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357590 uint32 immediate_data_size, const cmds::CompressedTexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197591 GLenum target = static_cast<GLenum>(c.target);
7592 GLint level = static_cast<GLint>(c.level);
7593 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7594 GLsizei width = static_cast<GLsizei>(c.width);
7595 GLsizei height = static_cast<GLsizei>(c.height);
7596 GLint border = static_cast<GLint>(c.border);
7597 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307598 const void* data = GetImmediateDataAs<const void*>(
7599 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467600 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147601 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467602 }
[email protected]a93bb842010-02-16 23:03:477603 return DoCompressedTexImage2D(
7604 target, level, internal_format, width, height, border, image_size, data);
7605}
7606
[email protected]b6140d02010-05-17 14:47:167607error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:357608 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167609 GLenum target = static_cast<GLenum>(c.target);
7610 GLint level = static_cast<GLint>(c.level);
7611 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7612 GLsizei width = static_cast<GLsizei>(c.width);
7613 GLsizei height = static_cast<GLsizei>(c.height);
7614 GLint border = static_cast<GLint>(c.border);
7615 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287616 if (!bucket) {
7617 return error::kInvalidArguments;
7618 }
7619 uint32 data_size = bucket->size();
7620 GLsizei imageSize = data_size;
7621 const void* data = bucket->GetData(0, data_size);
7622 if (!data) {
7623 return error::kInvalidArguments;
7624 }
[email protected]b6140d02010-05-17 14:47:167625 return DoCompressedTexImage2D(
7626 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287627 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167628}
7629
7630error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7631 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:357632 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167633 GLenum target = static_cast<GLenum>(c.target);
7634 GLint level = static_cast<GLint>(c.level);
7635 GLint xoffset = static_cast<GLint>(c.xoffset);
7636 GLint yoffset = static_cast<GLint>(c.yoffset);
7637 GLsizei width = static_cast<GLsizei>(c.width);
7638 GLsizei height = static_cast<GLsizei>(c.height);
7639 GLenum format = static_cast<GLenum>(c.format);
7640 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287641 if (!bucket) {
7642 return error::kInvalidArguments;
7643 }
[email protected]b6140d02010-05-17 14:47:167644 uint32 data_size = bucket->size();
7645 GLsizei imageSize = data_size;
7646 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287647 if (!data) {
7648 return error::kInvalidArguments;
7649 }
[email protected]9438b012010-06-15 22:55:057650 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517651 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:537652 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167653 return error::kNoError;
7654 }
[email protected]9438b012010-06-15 22:55:057655 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517656 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7657 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057658 return error::kNoError;
7659 }
[email protected]b6140d02010-05-17 14:47:167660 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:517661 LOCAL_SET_GL_ERROR(
7662 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167663 return error::kNoError;
7664 }
7665 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:517666 LOCAL_SET_GL_ERROR(
7667 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167668 return error::kNoError;
7669 }
7670 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:517671 LOCAL_SET_GL_ERROR(
7672 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167673 return error::kNoError;
7674 }
[email protected]cadde4a2010-07-31 17:10:437675 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167676 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7677 return error::kNoError;
7678}
7679
[email protected]81375742012-06-08 00:04:007680bool GLES2DecoderImpl::ValidateTextureParameters(
7681 const char* function_name,
7682 GLenum target, GLenum format, GLenum type, GLint level) {
7683 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517684 LOCAL_SET_GL_ERROR(
7685 GL_INVALID_OPERATION, function_name,
7686 (std::string("invalid type ") +
7687 GLES2Util::GetStringEnum(type) + " for format " +
7688 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007689 return false;
7690 }
7691
7692 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7693 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
[email protected]ab09b612013-03-11 22:11:517694 LOCAL_SET_GL_ERROR(
7695 GL_INVALID_OPERATION, function_name,
7696 (std::string("invalid type ") +
7697 GLES2Util::GetStringEnum(type) + " for format " +
7698 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007699 return false;
7700 }
7701 return true;
7702}
7703
[email protected]f598f422012-12-07 08:30:037704bool GLES2DecoderImpl::ValidateTexImage2D(
7705 const char* function_name,
7706 GLenum target,
7707 GLint level,
7708 GLenum internal_format,
7709 GLsizei width,
7710 GLsizei height,
7711 GLint border,
7712 GLenum format,
7713 GLenum type,
7714 const void* pixels,
7715 uint32 pixels_size) {
[email protected]9438b012010-06-15 22:55:057716 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517717 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:037718 return false;
[email protected]8eee29c2010-04-29 03:38:297719 }
[email protected]9438b012010-06-15 22:55:057720 if (!validators_->texture_format.IsValid(internal_format)) {
[email protected]ab09b612013-03-11 22:11:517721 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7722 function_name, internal_format, "internal_format");
[email protected]f598f422012-12-07 08:30:037723 return false;
[email protected]8eee29c2010-04-29 03:38:297724 }
[email protected]9438b012010-06-15 22:55:057725 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517726 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:037727 return false;
[email protected]8eee29c2010-04-29 03:38:297728 }
[email protected]9438b012010-06-15 22:55:057729 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517730 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:037731 return false;
[email protected]b9849abf2009-11-25 19:13:197732 }
[email protected]7b92c412010-07-20 17:48:257733 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:517734 LOCAL_SET_GL_ERROR(
7735 GL_INVALID_OPERATION, function_name, "format != internalFormat");
[email protected]f598f422012-12-07 08:30:037736 return false;
[email protected]7b92c412010-07-20 17:48:257737 }
[email protected]f598f422012-12-07 08:30:037738 if (!ValidateTextureParameters(function_name, target, format, type, level)) {
7739 return false;
[email protected]81375742012-06-08 00:04:007740 }
[email protected]80eb6b52012-01-19 00:14:417741 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477742 border != 0) {
[email protected]ab09b612013-03-11 22:11:517743 LOCAL_SET_GL_ERROR(
7744 GL_INVALID_VALUE, function_name, "dimensions out of range");
[email protected]f598f422012-12-07 08:30:037745 return false;
[email protected]a93bb842010-02-16 23:03:477746 }
[email protected]81375742012-06-08 00:04:007747 if ((GLES2Util::GetChannelsForFormat(format) &
7748 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
[email protected]ab09b612013-03-11 22:11:517749 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:007750 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037751 function_name, "can not supply data for depth or stencil textures");
7752 return false;
[email protected]81375742012-06-08 00:04:007753 }
[email protected]370eaf12013-05-18 09:19:497754 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7755 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517756 LOCAL_SET_GL_ERROR(
7757 GL_INVALID_OPERATION, function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:037758 return false;
[email protected]a93bb842010-02-16 23:03:477759 }
[email protected]370eaf12013-05-18 09:19:497760 if (texture_ref->texture()->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517761 LOCAL_SET_GL_ERROR(
7762 GL_INVALID_OPERATION, function_name, "texture is immutable");
[email protected]f598f422012-12-07 08:30:037763 return false;
[email protected]97dc7cbe2011-12-06 17:26:177764 }
[email protected]f598f422012-12-07 08:30:037765 return true;
7766}
[email protected]97dc7cbe2011-12-06 17:26:177767
[email protected]f598f422012-12-07 08:30:037768void GLES2DecoderImpl::DoTexImage2D(
7769 GLenum target,
7770 GLint level,
7771 GLenum internal_format,
7772 GLsizei width,
7773 GLsizei height,
7774 GLint border,
7775 GLenum format,
7776 GLenum type,
7777 const void* pixels,
7778 uint32 pixels_size) {
7779 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format,
7780 width, height, border, format, type, pixels, pixels_size)) {
7781 return;
7782 }
[email protected]7989c9e2013-01-23 06:39:267783
7784 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:517785 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267786 return;
7787 }
7788
[email protected]370eaf12013-05-18 09:19:497789 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7790 Texture* texture = texture_ref->texture();
[email protected]0226c112011-07-22 03:25:077791 GLsizei tex_width = 0;
7792 GLsizei tex_height = 0;
7793 GLenum tex_type = 0;
7794 GLenum tex_format = 0;
7795 bool level_is_same =
[email protected]02965c22013-03-09 02:40:077796 texture->GetLevelSize(target, level, &tex_width, &tex_height) &&
7797 texture->GetLevelType(target, level, &tex_type, &tex_format) &&
[email protected]0226c112011-07-22 03:25:077798 width == tex_width && height == tex_height &&
7799 type == tex_type && format == tex_format;
7800
7801 if (level_is_same && !pixels) {
[email protected]02965c22013-03-09 02:40:077802 // Just set the level texture but mark the texture as uncleared.
[email protected]1bed6222011-12-21 11:21:397803 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497804 texture_ref,
[email protected]1bed6222011-12-21 11:21:397805 target, level, internal_format, width, height, 1, border, format, type,
7806 false);
[email protected]ea72ed222011-08-17 18:58:437807 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037808 return;
[email protected]0226c112011-07-22 03:25:077809 }
7810
[email protected]02965c22013-03-09 02:40:077811 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427812 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:467813 }
7814
[email protected]1bed6222011-12-21 11:21:397815 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) {
[email protected]aa283dc2013-06-14 19:46:037816 {
7817 ScopedTextureUploadTimer timer(this);
7818 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
7819 }
[email protected]370eaf12013-05-18 09:19:497820 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0226c112011-07-22 03:25:077821 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037822 return;
[email protected]7488d962010-07-16 02:41:587823 }
[email protected]876f6fee2010-08-02 23:10:327824
[email protected]ab09b612013-03-11 22:11:517825 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexImage2D");
[email protected]aa283dc2013-06-14 19:46:037826 {
7827 ScopedTextureUploadTimer timer(this);
7828 glTexImage2D(
7829 target, level, internal_format, width, height, border, format, type,
7830 pixels);
7831 }
[email protected]ab09b612013-03-11 22:11:517832 GLenum error = LOCAL_PEEK_GL_ERROR("glTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437833 if (error == GL_NO_ERROR) {
[email protected]0d6bfdc2011-11-02 01:32:207834 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497835 texture_ref,
[email protected]0d6bfdc2011-11-02 01:32:207836 target, level, internal_format, width, height, 1, border, format, type,
7837 pixels != NULL);
[email protected]b493ee622011-04-13 23:52:007838 tex_image_2d_failed_ = false;
[email protected]cadde4a2010-07-31 17:10:437839 }
[email protected]f598f422012-12-07 08:30:037840 return;
[email protected]b9849abf2009-11-25 19:13:197841}
7842
[email protected]f7a64ee2010-02-01 22:24:147843error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357844 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387845 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]b493ee622011-04-13 23:52:007846 tex_image_2d_failed_ = true;
[email protected]b9849abf2009-11-25 19:13:197847 GLenum target = static_cast<GLenum>(c.target);
7848 GLint level = static_cast<GLint>(c.level);
7849 GLint internal_format = static_cast<GLint>(c.internalformat);
7850 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);
7855 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7856 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187857 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347858 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247859 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347860 NULL)) {
[email protected]a76b0052010-03-05 00:33:187861 return error::kOutOfBounds;
7862 }
[email protected]b9849abf2009-11-25 19:13:197863 const void* pixels = NULL;
7864 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7865 pixels = GetSharedMemoryAs<const void*>(
7866 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467867 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147868 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197869 }
7870 }
[email protected]f598f422012-12-07 08:30:037871
7872 DoTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197873 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477874 pixels, pixels_size);
[email protected]f598f422012-12-07 08:30:037875 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197876}
7877
[email protected]f7a64ee2010-02-01 22:24:147878error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357879 uint32 immediate_data_size, const cmds::TexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197880 GLenum target = static_cast<GLenum>(c.target);
7881 GLint level = static_cast<GLint>(c.level);
[email protected]ba3176a2009-12-16 18:19:467882 GLint internal_format = static_cast<GLint>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197883 GLsizei width = static_cast<GLsizei>(c.width);
7884 GLsizei height = static_cast<GLsizei>(c.height);
7885 GLint border = static_cast<GLint>(c.border);
7886 GLenum format = static_cast<GLenum>(c.format);
7887 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:187888 uint32 size;
[email protected]3458a64a2012-04-10 17:39:347889 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247890 width, height, format, type, state_.unpack_alignment, &size,
7891 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187892 return error::kOutOfBounds;
7893 }
[email protected]07f54fcc2009-12-22 02:46:307894 const void* pixels = GetImmediateDataAs<const void*>(
7895 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467896 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147897 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467898 }
[email protected]a93bb842010-02-16 23:03:477899 DoTexImage2D(
[email protected]ba3176a2009-12-16 18:19:467900 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477901 pixels, size);
[email protected]f7a64ee2010-02-01 22:24:147902 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327903}
7904
[email protected]cadde4a2010-07-31 17:10:437905void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7906 GLenum target,
7907 GLint level,
7908 GLint xoffset,
7909 GLint yoffset,
7910 GLsizei width,
7911 GLsizei height,
7912 GLenum format,
7913 GLsizei image_size,
7914 const void * data) {
[email protected]370eaf12013-05-18 09:19:497915 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7916 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517917 LOCAL_SET_GL_ERROR(
7918 GL_INVALID_OPERATION,
7919 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437920 return;
7921 }
[email protected]370eaf12013-05-18 09:19:497922 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:437923 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527924 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:077925 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:517926 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527927 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437928 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527929 return;
7930 }
7931 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:517932 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527933 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437934 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527935 return;
7936 }
[email protected]02965c22013-03-09 02:40:077937 if (!texture->ValidForTexture(
[email protected]df6cf1ad2011-01-29 01:20:527938 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:517939 LOCAL_SET_GL_ERROR(
7940 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437941 return;
7942 }
[email protected]ad84a3a2012-06-08 21:42:437943
7944 if (!ValidateCompressedTexFuncData(
7945 "glCompressedTexSubImage2D", width, height, format, image_size) ||
7946 !ValidateCompressedTexSubDimensions(
7947 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:077948 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:437949 return;
7950 }
7951
7952
[email protected]0d6bfdc2011-11-02 01:32:207953 // Note: There is no need to deal with texture cleared tracking here
7954 // because the validation above means you can only get here if the level
7955 // is already a matching compressed format and in that case
7956 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:437957 glCompressedTexSubImage2D(
7958 target, level, xoffset, yoffset, width, height, format, image_size, data);
7959}
7960
[email protected]6e288612010-12-21 20:45:037961static void Clip(
7962 GLint start, GLint range, GLint sourceRange,
7963 GLint* out_start, GLint* out_range) {
7964 DCHECK(out_start);
7965 DCHECK(out_range);
7966 if (start < 0) {
7967 range += start;
7968 start = 0;
7969 }
7970 GLint end = start + range;
7971 if (end > sourceRange) {
7972 range -= end - sourceRange;
7973 }
7974 *out_start = start;
7975 *out_range = range;
7976}
7977
[email protected]cadde4a2010-07-31 17:10:437978void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:447979 GLenum target,
7980 GLint level,
7981 GLenum internal_format,
7982 GLint x,
7983 GLint y,
7984 GLsizei width,
7985 GLsizei height,
7986 GLint border) {
[email protected]09e17272012-11-30 10:30:447987 DCHECK(!ShouldDeferReads());
[email protected]370eaf12013-05-18 09:19:497988 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7989 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517990 LOCAL_SET_GL_ERROR(
7991 GL_INVALID_OPERATION,
7992 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437993 return;
7994 }
[email protected]370eaf12013-05-18 09:19:497995 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077996 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517997 LOCAL_SET_GL_ERROR(
7998 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:177999 }
[email protected]80eb6b52012-01-19 00:14:418000 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188001 border != 0) {
[email protected]ab09b612013-03-11 22:11:518002 LOCAL_SET_GL_ERROR(
8003 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188004 return;
8005 }
[email protected]81375742012-06-08 00:04:008006 if (!ValidateTextureParameters(
8007 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
8008 return;
8009 }
[email protected]f5719fb2010-08-04 18:27:188010
[email protected]9edc6b22010-12-23 02:00:268011 // Check we have compatible formats.
8012 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8013 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8014 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8015
8016 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518017 LOCAL_SET_GL_ERROR(
8018 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268019 return;
8020 }
8021
[email protected]81375742012-06-08 00:04:008022 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518023 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008024 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268025 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8026 return;
8027 }
8028
8029 uint32 estimated_size = 0;
8030 if (!GLES2Util::ComputeImageDataSizes(
8031 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8032 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518033 LOCAL_SET_GL_ERROR(
8034 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268035 return;
8036 }
8037
8038 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518039 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008040 return;
8041 }
8042
[email protected]a0b78dc2011-11-11 10:43:108043 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8044 return;
8045 }
8046
[email protected]ab09b612013-03-11 22:11:518047 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278048 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038049 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268050
[email protected]02965c22013-03-09 02:40:078051 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:428052 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:468053 }
8054
[email protected]9edc6b22010-12-23 02:00:268055 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038056 GLint copyX = 0;
8057 GLint copyY = 0;
8058 GLint copyWidth = 0;
8059 GLint copyHeight = 0;
8060 Clip(x, width, size.width(), &copyX, &copyWidth);
8061 Clip(y, height, size.height(), &copyY, &copyHeight);
8062
8063 if (copyX != x ||
8064 copyY != y ||
8065 copyWidth != width ||
8066 copyHeight != height) {
8067 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208068 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078069 texture->service_id(), texture->target(),
[email protected]4502e6492011-12-14 19:39:158070 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
[email protected]02965c22013-03-09 02:40:078071 texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518072 LOCAL_SET_GL_ERROR(
8073 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038074 return;
8075 }
[email protected]6e288612010-12-21 20:45:038076 if (copyHeight > 0 && copyWidth > 0) {
8077 GLint dx = copyX - x;
8078 GLint dy = copyY - y;
8079 GLint destX = dx;
8080 GLint destY = dy;
8081 glCopyTexSubImage2D(target, level,
8082 destX, destY, copyX, copyY,
8083 copyWidth, copyHeight);
8084 }
8085 } else {
8086 glCopyTexImage2D(target, level, internal_format,
8087 copyX, copyY, copyWidth, copyHeight, border);
8088 }
[email protected]ab09b612013-03-11 22:11:518089 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438090 if (error == GL_NO_ERROR) {
8091 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498092 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208093 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438094 }
8095}
8096
8097void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448098 GLenum target,
8099 GLint level,
8100 GLint xoffset,
8101 GLint yoffset,
8102 GLint x,
8103 GLint y,
8104 GLsizei width,
8105 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448106 DCHECK(!ShouldDeferReads());
[email protected]370eaf12013-05-18 09:19:498107 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8108 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518109 LOCAL_SET_GL_ERROR(
8110 GL_INVALID_OPERATION,
8111 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438112 return;
8113 }
[email protected]370eaf12013-05-18 09:19:498114 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438115 GLenum type = 0;
8116 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078117 if (!texture->GetLevelType(target, level, &type, &format) ||
8118 !texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438119 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518120 LOCAL_SET_GL_ERROR(
8121 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438122 return;
8123 }
[email protected]85a4ac22013-05-31 01:58:478124 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518125 LOCAL_SET_GL_ERROR(
8126 GL_INVALID_OPERATION,
8127 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598128 return;
8129 }
[email protected]9edc6b22010-12-23 02:00:268130
8131 // Check we have compatible formats.
8132 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8133 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8134 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8135
[email protected]2d3765b2012-10-03 00:31:078136 if (!channels_needed ||
8137 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518138 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438139 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268140 return;
8141 }
8142
[email protected]81375742012-06-08 00:04:008143 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518144 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008145 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438146 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008147 return;
8148 }
8149
[email protected]a0b78dc2011-11-11 10:43:108150 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8151 return;
8152 }
8153
[email protected]de26b3c2011-08-03 21:54:278154 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038155 gfx::Size size = GetBoundReadFrameBufferSize();
8156 GLint copyX = 0;
8157 GLint copyY = 0;
8158 GLint copyWidth = 0;
8159 GLint copyHeight = 0;
8160 Clip(x, width, size.width(), &copyX, &copyWidth);
8161 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208162
[email protected]370eaf12013-05-18 09:19:498163 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518164 LOCAL_SET_GL_ERROR(
8165 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208166 return;
8167 }
8168
[email protected]6e288612010-12-21 20:45:038169 if (copyX != x ||
8170 copyY != y ||
8171 copyWidth != width ||
8172 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208173 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038174 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348175 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248176 width, height, format, type, state_.unpack_alignment, &pixels_size,
8177 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518178 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438179 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038180 return;
8181 }
[email protected]40d90a22013-04-09 03:39:558182 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038183 memset(zero.get(), 0, pixels_size);
8184 glTexSubImage2D(
8185 target, level, xoffset, yoffset, width, height,
8186 format, type, zero.get());
8187 }
[email protected]0d6bfdc2011-11-02 01:32:208188
[email protected]6e288612010-12-21 20:45:038189 if (copyHeight > 0 && copyWidth > 0) {
8190 GLint dx = copyX - x;
8191 GLint dy = copyY - y;
8192 GLint destX = xoffset + dx;
8193 GLint destY = yoffset + dy;
8194 glCopyTexSubImage2D(target, level,
8195 destX, destY, copyX, copyY,
8196 copyWidth, copyHeight);
8197 }
[email protected]cadde4a2010-07-31 17:10:438198}
8199
[email protected]f598f422012-12-07 08:30:038200bool GLES2DecoderImpl::ValidateTexSubImage2D(
8201 error::Error* error,
8202 const char* function_name,
8203 GLenum target,
8204 GLint level,
8205 GLint xoffset,
8206 GLint yoffset,
8207 GLsizei width,
8208 GLsizei height,
8209 GLenum format,
8210 GLenum type,
8211 const void * data) {
8212 (*error) = error::kNoError;
8213 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518214 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038215 return false;
8216 }
8217 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518218 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038219 return false;
8220 }
8221 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518222 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038223 return false;
8224 }
8225 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518226 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:038227 return false;
8228 }
8229 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518230 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:038231 return false;
8232 }
[email protected]370eaf12013-05-18 09:19:498233 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8234 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518235 LOCAL_SET_GL_ERROR(
8236 GL_INVALID_OPERATION,
8237 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038238 return false;
[email protected]cadde4a2010-07-31 17:10:438239 }
[email protected]370eaf12013-05-18 09:19:498240 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528241 GLenum current_type = 0;
8242 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078243 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518244 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038245 GL_INVALID_OPERATION, function_name, "level does not exist.");
8246 return false;
[email protected]df6cf1ad2011-01-29 01:20:528247 }
8248 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:518249 LOCAL_SET_GL_ERROR(
8250 GL_INVALID_OPERATION,
8251 function_name, "format does not match internal format.");
[email protected]f598f422012-12-07 08:30:038252 return false;
[email protected]df6cf1ad2011-01-29 01:20:528253 }
8254 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518255 LOCAL_SET_GL_ERROR(
8256 GL_INVALID_OPERATION,
8257 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038258 return false;
[email protected]df6cf1ad2011-01-29 01:20:528259 }
[email protected]85a4ac22013-05-31 01:58:478260 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518261 LOCAL_SET_GL_ERROR(
8262 GL_INVALID_OPERATION,
8263 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598264 return false;
8265 }
[email protected]02965c22013-03-09 02:40:078266 if (!texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438267 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518268 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038269 return false;
[email protected]cadde4a2010-07-31 17:10:438270 }
[email protected]81375742012-06-08 00:04:008271 if ((GLES2Util::GetChannelsForFormat(format) &
8272 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518273 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008274 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038275 function_name, "can not supply data for depth or stencil textures");
8276 return false;
[email protected]81375742012-06-08 00:04:008277 }
[email protected]f598f422012-12-07 08:30:038278 if (data == NULL) {
8279 (*error) = error::kOutOfBounds;
8280 return false;
8281 }
8282 return true;
8283}
[email protected]81375742012-06-08 00:04:008284
[email protected]f598f422012-12-07 08:30:038285error::Error GLES2DecoderImpl::DoTexSubImage2D(
8286 GLenum target,
8287 GLint level,
8288 GLint xoffset,
8289 GLint yoffset,
8290 GLsizei width,
8291 GLsizei height,
8292 GLenum format,
8293 GLenum type,
8294 const void * data) {
8295 error::Error error = error::kNoError;
8296 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8297 xoffset, yoffset, width, height, format, type, data)) {
8298 return error;
8299 }
[email protected]370eaf12013-05-18 09:19:498300 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8301 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158302 GLsizei tex_width = 0;
8303 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078304 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158305 DCHECK(ok);
8306 if (xoffset != 0 || yoffset != 0 ||
8307 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498308 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8309 target, level)) {
[email protected]ab09b612013-03-11 22:11:518310 LOCAL_SET_GL_ERROR(
8311 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038312 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308313 }
[email protected]63b465922012-09-06 02:04:528314 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158315 glTexSubImage2D(
8316 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038317 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208318 }
[email protected]4502e6492011-12-14 19:39:158319
[email protected]02965c22013-03-09 02:40:078320 if (teximage2d_faster_than_texsubimage2d_ && !texture->IsImmutable()) {
[email protected]63b465922012-09-06 02:04:528321 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158322 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8323 // same as internal_foramt. If that changes we'll need to look them up.
[email protected]8f1d2aa2013-05-10 23:45:388324 glTexImage2D(
[email protected]4502e6492011-12-14 19:39:158325 target, level, format, width, height, 0, format, type, data);
8326 } else {
[email protected]63b465922012-09-06 02:04:528327 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158328 glTexSubImage2D(
8329 target, level, xoffset, yoffset, width, height, format, type, data);
8330 }
[email protected]370eaf12013-05-18 09:19:498331 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038332 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438333}
8334
[email protected]b493ee622011-04-13 23:52:008335error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358336 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388337 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008338 GLboolean internal = static_cast<GLboolean>(c.internal);
8339 if (internal == GL_TRUE && tex_image_2d_failed_)
8340 return error::kNoError;
8341
8342 GLenum target = static_cast<GLenum>(c.target);
8343 GLint level = static_cast<GLint>(c.level);
8344 GLint xoffset = static_cast<GLint>(c.xoffset);
8345 GLint yoffset = static_cast<GLint>(c.yoffset);
8346 GLsizei width = static_cast<GLsizei>(c.width);
8347 GLsizei height = static_cast<GLsizei>(c.height);
8348 GLenum format = static_cast<GLenum>(c.format);
8349 GLenum type = static_cast<GLenum>(c.type);
8350 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348351 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248352 width, height, format, type, state_.unpack_alignment, &data_size,
8353 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008354 return error::kOutOfBounds;
8355 }
8356 const void* pixels = GetSharedMemoryAs<const void*>(
8357 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038358 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008359 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008360}
8361
8362error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:358363 uint32 immediate_data_size, const cmds::TexSubImage2DImmediate& c) {
[email protected]b493ee622011-04-13 23:52:008364 GLboolean internal = static_cast<GLboolean>(c.internal);
8365 if (internal == GL_TRUE && tex_image_2d_failed_)
8366 return error::kNoError;
8367
8368 GLenum target = static_cast<GLenum>(c.target);
8369 GLint level = static_cast<GLint>(c.level);
8370 GLint xoffset = static_cast<GLint>(c.xoffset);
8371 GLint yoffset = static_cast<GLint>(c.yoffset);
8372 GLsizei width = static_cast<GLsizei>(c.width);
8373 GLsizei height = static_cast<GLsizei>(c.height);
8374 GLenum format = static_cast<GLenum>(c.format);
8375 GLenum type = static_cast<GLenum>(c.type);
8376 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348377 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248378 width, height, format, type, state_.unpack_alignment, &data_size,
8379 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008380 return error::kOutOfBounds;
8381 }
8382 const void* pixels = GetImmediateDataAs<const void*>(
8383 c, data_size, immediate_data_size);
[email protected]f598f422012-12-07 08:30:038384 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008385 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008386}
8387
[email protected]f7a64ee2010-02-01 22:24:148388error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358389 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368390 GLuint index = static_cast<GLuint>(c.index);
8391 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358392 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258393 Result* result = GetSharedMemoryAs<Result*>(
8394 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368395 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148396 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368397 }
[email protected]07d0cc82010-02-17 04:51:408398 // Check that the client initialized the result.
8399 if (result->size != 0) {
8400 return error::kInvalidArguments;
8401 }
[email protected]9438b012010-06-15 22:55:058402 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518403 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8404 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148405 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368406 }
[email protected]3916c97e2010-02-25 03:20:508407 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518408 LOCAL_SET_GL_ERROR(
8409 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148410 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368411 }
[email protected]0bfd9882010-02-05 23:02:258412 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088413 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358414 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148415 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328416}
8417
[email protected]f7b85372010-02-03 01:11:378418bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428419 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378420 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128421 error::Error* error, GLint* real_location,
8422 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108423 DCHECK(error);
8424 DCHECK(service_id);
8425 DCHECK(result_pointer);
8426 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128427 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378428 *error = error::kNoError;
8429 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258430 SizedResult<GLint>* result;
8431 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8432 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8433 if (!result) {
[email protected]f7b85372010-02-03 01:11:378434 *error = error::kOutOfBounds;
8435 return false;
8436 }
[email protected]0bfd9882010-02-05 23:02:258437 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378438 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258439 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428440 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8441 if (!program) {
[email protected]ae51d192010-04-27 00:48:038442 return false;
8443 }
[email protected]df37b9932013-03-08 05:21:428444 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378445 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518446 LOCAL_SET_GL_ERROR(
8447 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378448 return false;
8449 }
[email protected]df37b9932013-03-08 05:21:428450 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368451 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358452 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428453 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128454 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368455 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378456 // No such location.
[email protected]ab09b612013-03-11 22:11:518457 LOCAL_SET_GL_ERROR(
8458 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378459 return false;
8460 }
[email protected]43c2f1f2011-03-25 18:35:368461 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508462 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378463 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518464 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378465 return false;
8466 }
[email protected]0bfd9882010-02-05 23:02:258467 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8468 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8469 if (!result) {
[email protected]f7b85372010-02-03 01:11:378470 *error = error::kOutOfBounds;
8471 return false;
8472 }
[email protected]0bfd9882010-02-05 23:02:258473 result->size = size;
[email protected]939e7362010-05-13 20:49:108474 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378475 return true;
8476}
8477
[email protected]f7a64ee2010-02-01 22:24:148478error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358479 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378480 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338481 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378482 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108483 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128484 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378485 Error error;
[email protected]0bfd9882010-02-05 23:02:258486 void* result;
[email protected]f7b85372010-02-03 01:11:378487 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128488 program, fake_location, c.params_shm_id, c.params_shm_offset,
8489 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258490 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128491 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358492 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378493 }
8494 return error;
[email protected]96449d2c2009-11-25 00:01:328495}
8496
[email protected]f7a64ee2010-02-01 22:24:148497error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358498 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378499 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338500 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378501 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128502 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378503 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358504 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108505 Result* result;
8506 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378507 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128508 program, fake_location, c.params_shm_id, c.params_shm_offset,
8509 &error, &real_location, &service_id,
8510 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108511 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8512 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8513 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558514 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128515 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108516 GLfloat* dst = result->GetData();
8517 for (GLsizei ii = 0; ii < num_values; ++ii) {
8518 dst[ii] = (temp[ii] != 0);
8519 }
8520 } else {
[email protected]1b0a6752012-02-22 03:44:128521 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108522 }
[email protected]f7b85372010-02-03 01:11:378523 }
8524 return error;
[email protected]96449d2c2009-11-25 00:01:328525}
8526
[email protected]f7a64ee2010-02-01 22:24:148527error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358528 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258529 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8530 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358531 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258532 Result* result = GetSharedMemoryAs<Result*>(
8533 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8534 if (!result) {
8535 return error::kOutOfBounds;
8536 }
[email protected]07d0cc82010-02-17 04:51:408537 // Check that the client initialized the result.
8538 if (result->success != 0) {
8539 return error::kInvalidArguments;
8540 }
[email protected]9438b012010-06-15 22:55:058541 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518542 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538543 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298544 return error::kNoError;
8545 }
[email protected]9438b012010-06-15 22:55:058546 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518547 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538548 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298549 return error::kNoError;
8550 }
8551
8552 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408553
[email protected]46c86752013-05-21 05:08:398554 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:408555 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218556 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408557
8558 result->min_range = range[0];
8559 result->max_range = range[1];
8560 result->precision = precision;
8561
[email protected]f7a64ee2010-02-01 22:24:148562 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328563}
8564
[email protected]f7a64ee2010-02-01 22:24:148565error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358566 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258567 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428568 GLuint program_id = static_cast<GLuint>(c.program);
8569 Program* program = GetProgramInfoNotShader(
8570 program_id, "glGetAttachedShaders");
8571 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258572 return error::kNoError;
8573 }
[email protected]ed9f9cd2013-02-27 21:12:358574 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258575 uint32 max_count = Result::ComputeMaxResults(result_size);
8576 Result* result = GetSharedMemoryAs<Result*>(
8577 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8578 if (!result) {
8579 return error::kOutOfBounds;
8580 }
[email protected]07d0cc82010-02-17 04:51:408581 // Check that the client initialized the result.
8582 if (result->size != 0) {
8583 return error::kInvalidArguments;
8584 }
[email protected]0bfd9882010-02-05 23:02:258585 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038586 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428587 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258588 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038589 if (!shader_manager()->GetClientId(result->GetData()[ii],
8590 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258591 NOTREACHED();
8592 return error::kGenericError;
8593 }
8594 }
8595 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148596 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328597}
8598
[email protected]f7a64ee2010-02-01 22:24:148599error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358600 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428601 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258602 GLuint index = c.index;
8603 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358604 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258605 Result* result = GetSharedMemoryAs<Result*>(
8606 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8607 if (!result) {
8608 return error::kOutOfBounds;
8609 }
[email protected]07d0cc82010-02-17 04:51:408610 // Check that the client initialized the result.
8611 if (result->success != 0) {
8612 return error::kInvalidArguments;
8613 }
[email protected]df37b9932013-03-08 05:21:428614 Program* program = GetProgramInfoNotShader(
8615 program_id, "glGetActiveUniform");
8616 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258617 return error::kNoError;
8618 }
[email protected]ed9f9cd2013-02-27 21:12:358619 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428620 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258621 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518622 LOCAL_SET_GL_ERROR(
8623 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258624 return error::kNoError;
8625 }
8626 result->success = 1; // true.
8627 result->size = uniform_info->size;
8628 result->type = uniform_info->type;
8629 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298630 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148631 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328632}
8633
[email protected]f7a64ee2010-02-01 22:24:148634error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358635 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428636 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258637 GLuint index = c.index;
8638 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358639 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258640 Result* result = GetSharedMemoryAs<Result*>(
8641 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8642 if (!result) {
8643 return error::kOutOfBounds;
8644 }
[email protected]07d0cc82010-02-17 04:51:408645 // Check that the client initialized the result.
8646 if (result->success != 0) {
8647 return error::kInvalidArguments;
8648 }
[email protected]df37b9932013-03-08 05:21:428649 Program* program = GetProgramInfoNotShader(
8650 program_id, "glGetActiveAttrib");
8651 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258652 return error::kNoError;
8653 }
[email protected]ed9f9cd2013-02-27 21:12:358654 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428655 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258656 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518657 LOCAL_SET_GL_ERROR(
8658 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258659 return error::kNoError;
8660 }
8661 result->success = 1; // true.
8662 result->size = attrib_info->size;
8663 result->type = attrib_info->type;
8664 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298665 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148666 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328667}
8668
[email protected]b273e432010-04-12 17:23:588669error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358670 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588671#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518672 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588673 return error::kNoError;
8674#else
8675 GLsizei n = static_cast<GLsizei>(c.n);
8676 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518677 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588678 return error::kNoError;
8679 }
8680 GLsizei length = static_cast<GLsizei>(c.length);
8681 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518682 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588683 return error::kNoError;
8684 }
8685 uint32 data_size;
8686 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8687 return error::kOutOfBounds;
8688 }
8689 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8690 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8691 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8692 const void* binary = GetSharedMemoryAs<const void*>(
8693 c.binary_shm_id, c.binary_shm_offset, length);
8694 if (shaders == NULL || binary == NULL) {
8695 return error::kOutOfBounds;
8696 }
8697 scoped_array<GLuint> service_ids(new GLuint[n]);
8698 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428699 Shader* shader = GetShader(shaders[ii]);
8700 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518701 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588702 return error::kNoError;
8703 }
[email protected]df37b9932013-03-08 05:21:428704 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588705 }
8706 // TODO(gman): call glShaderBinary
8707 return error::kNoError;
8708#endif
8709}
8710
[email protected]6d792ee12013-05-15 00:40:568711void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:498712 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088713
[email protected]64ace852011-05-19 21:49:498714 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428715 // TRACE_EVENT for gpu tests:
8716 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428717 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428718 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8719 "width", (is_offscreen ? offscreen_size_.width() :
8720 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:568721 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:498722 "offscreen", is_offscreen,
8723 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358724 // If offscreen then don't actually SwapBuffers to the display. Just copy
8725 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498726 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318727 TRACE_EVENT2("gpu", "Offscreen",
8728 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538729 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8730 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8731 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8732 // fix this.
[email protected]62e155e2012-10-23 22:43:158733 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538734 offscreen_saved_frame_buffer_->Create();
8735 glFinish();
8736 }
8737
8738 // Allocate the offscreen saved color texture.
8739 DCHECK(offscreen_saved_color_format_);
8740 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098741 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538742
8743 offscreen_saved_frame_buffer_->AttachRenderTexture(
8744 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:058745 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
8746 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8747 GL_FRAMEBUFFER_COMPLETE) {
8748 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8749 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:568750 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
8751 return;
[email protected]f0cfe752013-01-14 01:09:058752 }
[email protected]1fb8c482011-08-31 01:01:538753
[email protected]f0cfe752013-01-14 01:09:058754 // Clear the offscreen color texture.
8755 // TODO(piman): Is this still necessary?
8756 {
8757 ScopedFrameBufferBinder binder(this,
8758 offscreen_saved_frame_buffer_->id());
8759 glClearColor(0, 0, 0, 0);
8760 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8761 glDisable(GL_SCISSOR_TEST);
8762 glClear(GL_COLOR_BUFFER_BIT);
8763 RestoreClearState();
8764 }
[email protected]1fb8c482011-08-31 01:01:538765 }
8766
8767 UpdateParentTextureInfo();
8768 }
8769
[email protected]f0cfe752013-01-14 01:09:058770 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:568771 return;
[email protected]ab09b612013-03-11 22:11:518772 ScopedGLErrorSuppressor suppressor(
[email protected]6d792ee12013-05-15 00:40:568773 "GLES2DecoderImpl::DoSwapBuffers", this);
[email protected]6217d392010-03-25 22:08:358774
[email protected]34ff8b0c2010-10-01 20:06:028775 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138776 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278777 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:488778 } else {
[email protected]069944672012-04-25 20:52:238779 ScopedFrameBufferBinder binder(this,
8780 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138781
[email protected]069944672012-04-25 20:52:238782 if (offscreen_target_buffer_preserved_) {
8783 // Copy the target frame buffer to the saved offscreen texture.
8784 offscreen_saved_color_texture_->Copy(
8785 offscreen_saved_color_texture_->size(),
8786 offscreen_saved_color_format_);
8787 } else {
8788 // Flip the textures in the parent context via the texture manager.
8789 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:498790 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:238791 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568792
[email protected]069944672012-04-25 20:52:238793 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8794 offscreen_target_frame_buffer_->AttachRenderTexture(
8795 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488796 }
[email protected]069944672012-04-25 20:52:238797
8798 // Ensure the side effects of the copy are visible to the parent
8799 // context. There is no need to do this for ANGLE because it uses a
8800 // single D3D device for all contexts.
8801 if (!IsAngle())
8802 glFlush();
[email protected]0c8c9d22010-06-25 17:36:398803 }
[email protected]6217d392010-03-25 22:08:358804 } else {
[email protected]111975c62012-09-06 01:37:318805 TRACE_EVENT2("gpu", "Onscreen",
8806 "width", surface_->GetSize().width(),
8807 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158808 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018809 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:568810 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:018811 }
[email protected]6217d392010-03-25 22:08:358812 }
[email protected]6217d392010-03-25 22:08:358813}
8814
[email protected]d4239852011-08-12 04:51:228815error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358816 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188817 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288818 if (!bucket || bucket->size() == 0) {
8819 return error::kInvalidArguments;
8820 }
[email protected]ed9f9cd2013-02-27 21:12:358821 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188822 Result* result = GetSharedMemoryAs<Result*>(
8823 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8824 if (!result) {
8825 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108826 }
[email protected]b1d2dcb2010-05-17 19:24:188827 // Check that the client initialized the result.
8828 if (*result != 0) {
8829 return error::kInvalidArguments;
8830 }
8831 std::string feature_str;
8832 if (!bucket->GetAsString(&feature_str)) {
8833 return error::kInvalidArguments;
8834 }
8835
8836 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228837 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188838 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228839 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408840 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8841 // TODO(gman): decide how to remove the need for this const_cast.
8842 // I could make validators_ non const but that seems bad as this is the only
8843 // place it is needed. I could make some special friend class of validators
8844 // just to allow this to set them. That seems silly. I could refactor this
8845 // code to use the extension mechanism or the initialization attributes to
8846 // turn this feature on. Given that the only real point of this is to make
8847 // the conformance tests pass and given that there is lots of real work that
8848 // needs to be done it seems like refactoring for one to one of those
8849 // methods is a very low priority.
8850 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048851 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8852 force_webgl_glsl_validation_ = true;
8853 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188854 } else {
8855 return error::kNoError;
8856 }
8857
8858 *result = 1; // true.
8859 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108860}
8861
[email protected]c2f8c8402010-12-06 18:07:248862error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8863 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358864 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248865 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:358866 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:298867 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:248868 bucket->SetFromString(info->extensions().c_str());
8869 return error::kNoError;
8870}
8871
8872error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358873 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248874 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288875 if (!bucket || bucket->size() == 0) {
8876 return error::kInvalidArguments;
8877 }
[email protected]c2f8c8402010-12-06 18:07:248878 std::string feature_str;
8879 if (!bucket->GetAsString(&feature_str)) {
8880 return error::kInvalidArguments;
8881 }
8882
[email protected]4b7eba92013-01-08 02:23:568883 bool desire_webgl_glsl_validation =
8884 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
8885 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:498886 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:138887 bool desire_draw_buffers = false;
[email protected]4b7eba92013-01-08 02:23:568888 if (force_webgl_glsl_validation_) {
8889 desire_standard_derivatives =
8890 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:498891 desire_frag_depth =
8892 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:138893 desire_draw_buffers =
8894 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:048895 }
8896
[email protected]4b7eba92013-01-08 02:23:568897 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:498898 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:138899 desire_frag_depth != frag_depth_explicitly_enabled_ ||
8900 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:498901 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
8902 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
8903 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:138904 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]c2f8c8402010-12-06 18:07:248905 InitializeShaderTranslator();
8906 }
8907
[email protected]302ce6d2011-07-07 23:28:118908 UpdateCapabilities();
8909
[email protected]c2f8c8402010-12-06 18:07:248910 return error::kNoError;
8911}
8912
[email protected]372e0412011-06-28 16:08:568913error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358914 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:568915 GLuint count = c.count;
8916 uint32 pnames_size;
8917 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8918 return error::kOutOfBounds;
8919 }
8920 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8921 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8922 if (pnames == NULL) {
8923 return error::kOutOfBounds;
8924 }
8925
8926 // We have to copy them since we use them twice so the client
8927 // can't change them between the time we validate them and the time we use
8928 // them.
[email protected]40d90a22013-04-09 03:39:558929 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:568930 memcpy(enums.get(), pnames, pnames_size);
8931
8932 // Count up the space needed for the result.
8933 uint32 num_results = 0;
8934 for (GLuint ii = 0; ii < count; ++ii) {
8935 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8936 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:518937 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8938 "glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568939 return error::kNoError;
8940 }
8941 // Num will never be more than 4.
8942 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478943 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568944 return error::kOutOfBounds;
8945 }
8946 }
8947
8948 uint32 result_size = 0;
8949 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8950 return error::kOutOfBounds;
8951 }
8952
8953 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:518954 LOCAL_SET_GL_ERROR(
8955 GL_INVALID_VALUE,
8956 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:568957 return error::kNoError;
8958 }
8959
8960 GLint* results = GetSharedMemoryAs<GLint*>(
8961 c.results_shm_id, c.results_shm_offset, result_size);
8962 if (results == NULL) {
8963 return error::kOutOfBounds;
8964 }
8965
8966 // Check the results have been cleared in case the context was lost.
8967 for (uint32 ii = 0; ii < num_results; ++ii) {
8968 if (results[ii]) {
8969 return error::kInvalidArguments;
8970 }
8971 }
8972
8973 // Get each result.
8974 GLint* start = results;
8975 for (GLuint ii = 0; ii < count; ++ii) {
8976 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:268977 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:538978 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:488979 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:568980 }
8981 results += num_written;
8982 }
8983
8984 // Just to verify. Should this be a DCHECK?
8985 if (static_cast<uint32>(results - start) != num_results) {
8986 return error::kOutOfBounds;
8987 }
8988
8989 return error::kNoError;
8990}
8991
[email protected]2318d342011-07-11 22:27:428992error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358993 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:428994 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:428995 uint32 bucket_id = c.bucket_id;
8996 Bucket* bucket = CreateBucket(bucket_id);
8997 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:428998 Program* program = NULL;
8999 program = GetProgram(program_id);
9000 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469001 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429002 }
[email protected]df37b9932013-03-08 05:21:429003 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429004 return error::kNoError;
9005}
9006
[email protected]38d139d2011-07-14 00:38:439007error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9008 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439009 case GL_NO_ERROR:
9010 // TODO(kbr): improve the precision of the error code in this case.
9011 // Consider delegating to context for error code if MakeCurrent fails.
9012 return error::kUnknown;
9013 case GL_GUILTY_CONTEXT_RESET_ARB:
9014 return error::kGuilty;
9015 case GL_INNOCENT_CONTEXT_RESET_ARB:
9016 return error::kInnocent;
9017 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9018 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439019 }
9020
9021 NOTREACHED();
9022 return error::kUnknown;
9023}
9024
9025bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099026 if (reset_status_ != GL_NO_ERROR) {
9027 return true;
9028 }
[email protected]706b69f2012-07-27 04:59:309029 if (context_->WasAllocatedUsingRobustnessExtension()) {
9030 GLenum status = GL_NO_ERROR;
9031 if (has_robustness_extension_)
9032 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439033 if (status != GL_NO_ERROR) {
9034 // The graphics card was reset. Signal a lost context to the application.
9035 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229036 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439037 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099038 << " context lost via ARB/EXT_robustness. Reset status = "
9039 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439040 return true;
9041 }
9042 }
9043 return false;
9044}
9045
[email protected]93a7d98f2013-07-11 00:04:229046bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9047 return WasContextLost() && reset_by_robustness_extension_;
9048}
9049
[email protected]c4485aad62012-12-17 10:19:099050void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9051 // Only loses the context once.
9052 if (reset_status_ != GL_NO_ERROR) {
9053 return;
9054 }
9055
9056 // Marks this context as lost.
9057 reset_status_ = reset_status;
9058 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099059}
9060
9061error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359062 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099063 GLenum current = static_cast<GLenum>(c.current);
9064 GLenum other = static_cast<GLenum>(c.other);
9065 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519066 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9067 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099068 }
9069 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519070 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099071 }
9072 group_->LoseContexts(other);
9073 reset_status_ = current;
9074 current_decoder_error_ = error::kLostContext;
9075 return error::kLostContext;
9076}
9077
[email protected]b096d032013-03-08 03:08:019078error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9079 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9080 return error::kUnknownCommand;
9081}
9082
[email protected]840a7e462013-02-27 01:29:519083error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359084 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:519085 if (wait_sync_point_callback_.is_null())
9086 return error::kNoError;
9087
9088 return wait_sync_point_callback_.Run(c.sync_point) ?
9089 error::kNoError : error::kDeferCommandUntilLater;
9090}
9091
[email protected]882ba1e22012-03-08 19:02:539092bool GLES2DecoderImpl::GenQueriesEXTHelper(
9093 GLsizei n, const GLuint* client_ids) {
9094 for (GLsizei ii = 0; ii < n; ++ii) {
9095 if (query_manager_->GetQuery(client_ids[ii])) {
9096 return false;
9097 }
9098 }
[email protected]c45f1972012-03-14 07:27:369099 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539100 return true;
9101}
9102
9103void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9104 GLsizei n, const GLuint* client_ids) {
9105 for (GLsizei ii = 0; ii < n; ++ii) {
9106 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9107 if (query && !query->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119108 if (query == state_.current_query.get()) {
[email protected]e259eb412012-10-13 05:47:249109 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539110 }
[email protected]c45f1972012-03-14 07:27:369111 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539112 query_manager_->RemoveQuery(client_ids[ii]);
9113 }
9114 }
9115}
9116
[email protected]22e3f552012-03-13 01:54:199117bool GLES2DecoderImpl::ProcessPendingQueries() {
9118 if (query_manager_.get() == NULL) {
9119 return false;
9120 }
[email protected]c45f1972012-03-14 07:27:369121 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199122 current_decoder_error_ = error::kOutOfBounds;
9123 }
9124 return query_manager_->HavePendingQueries();
9125}
9126
[email protected]2b1767cf2013-03-16 09:25:059127bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]744329c2013-07-12 00:54:259128 return async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059129}
9130
9131void GLES2DecoderImpl::PerformIdleWork() {
[email protected]b68b100752013-06-05 08:34:489132 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059133 return;
[email protected]b68b100752013-06-05 08:34:489134 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059135 ProcessFinishedAsyncTransfers();
9136}
9137
[email protected]882ba1e22012-03-08 19:02:539138error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359139 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539140 GLenum target = static_cast<GLenum>(c.target);
9141 GLuint client_id = static_cast<GLuint>(c.id);
9142 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9143 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9144
[email protected]c45f1972012-03-14 07:27:369145 switch (target) {
9146 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559147 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]0713f43d2012-12-14 22:41:309148 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009149 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369150 break;
9151 default:
[email protected]62e155e2012-10-23 22:43:159152 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519153 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009154 GL_INVALID_OPERATION, "glBeginQueryEXT",
9155 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369156 return error::kNoError;
9157 }
9158 break;
[email protected]882ba1e22012-03-08 19:02:539159 }
9160
[email protected]7cd76fd2013-06-02 21:11:119161 if (state_.current_query.get()) {
[email protected]ab09b612013-03-11 22:11:519162 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439163 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539164 return error::kNoError;
9165 }
9166
9167 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519168 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539169 return error::kNoError;
9170 }
9171
9172 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9173 if (!query) {
[email protected]c45f1972012-03-14 07:27:369174 // TODO(gman): Decide if we need this check.
9175 //
[email protected]882ba1e22012-03-08 19:02:539176 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369177 //
9178 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9179 // for all Query ids but from the POV of the command buffer service maybe
9180 // you don't.
9181 //
9182 // The client can enforce this. I don't think the service cares.
9183 //
9184 // IdAllocatorInterface* id_allocator =
9185 // group_->GetIdAllocator(id_namespaces::kQueries);
9186 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519187 // LOCAL_SET_GL_ERROR(
9188 // GL_INVALID_OPERATION,
9189 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369190 // return error::kNoError;
9191 // }
9192 query = query_manager_->CreateQuery(
9193 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539194 }
9195
[email protected]c45f1972012-03-14 07:27:369196 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519197 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439198 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539199 return error::kNoError;
9200 } else if (query->shm_id() != sync_shm_id ||
9201 query->shm_offset() != sync_shm_offset) {
9202 DLOG(ERROR) << "Shared memory used by query not the same as before";
9203 return error::kInvalidArguments;
9204 }
9205
[email protected]c45f1972012-03-14 07:27:369206 if (!query_manager_->BeginQuery(query)) {
9207 return error::kOutOfBounds;
9208 }
[email protected]882ba1e22012-03-08 19:02:539209
[email protected]e259eb412012-10-13 05:47:249210 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539211 return error::kNoError;
9212}
9213
9214error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359215 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539216 GLenum target = static_cast<GLenum>(c.target);
9217 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9218
[email protected]7cd76fd2013-06-02 21:11:119219 if (!state_.current_query.get()) {
[email protected]ab09b612013-03-11 22:11:519220 LOCAL_SET_GL_ERROR(
9221 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539222 return error::kNoError;
9223 }
[email protected]e259eb412012-10-13 05:47:249224 if (state_.current_query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519225 LOCAL_SET_GL_ERROR(
9226 GL_INVALID_OPERATION,
9227 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539228 return error::kNoError;
9229 }
[email protected]882ba1e22012-03-08 19:02:539230
[email protected]7cd76fd2013-06-02 21:11:119231 if (!query_manager_->EndQuery(state_.current_query.get(), submit_count)) {
[email protected]c45f1972012-03-14 07:27:369232 return error::kOutOfBounds;
9233 }
9234
[email protected]fe8d73c2013-02-16 22:37:329235 query_manager_->ProcessPendingTransferQueries();
9236
[email protected]e259eb412012-10-13 05:47:249237 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539238 return error::kNoError;
9239}
9240
[email protected]944b62f32012-09-27 02:20:469241bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9242 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469243 for (GLsizei ii = 0; ii < n; ++ii) {
9244 if (GetVertexAttribManager(client_ids[ii])) {
9245 return false;
9246 }
9247 }
[email protected]ab4fd7282012-10-12 16:25:579248
[email protected]62e155e2012-10-23 22:43:159249 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579250 // Emulated VAO
9251 for (GLsizei ii = 0; ii < n; ++ii) {
9252 CreateVertexAttribManager(client_ids[ii], 0);
9253 }
9254 } else {
[email protected]40d90a22013-04-09 03:39:559255 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579256
9257 glGenVertexArraysOES(n, service_ids.get());
9258 for (GLsizei ii = 0; ii < n; ++ii) {
9259 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9260 }
[email protected]944b62f32012-09-27 02:20:469261 }
[email protected]ab4fd7282012-10-12 16:25:579262
[email protected]944b62f32012-09-27 02:20:469263 return true;
9264}
9265
9266void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9267 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469268 for (GLsizei ii = 0; ii < n; ++ii) {
9269 VertexAttribManager* vao =
9270 GetVertexAttribManager(client_ids[ii]);
9271 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119272 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]e259eb412012-10-13 05:47:249273 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469274 }
9275 RemoveVertexAttribManager(client_ids[ii]);
9276 }
9277 }
9278}
9279
9280void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469281 VertexAttribManager* vao = NULL;
9282 GLuint service_id = 0;
9283 if (client_id != 0) {
9284 vao = GetVertexAttribManager(client_id);
9285 if (!vao) {
9286 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9287 // only allows names that have been previously generated. As such, we do
9288 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519289 LOCAL_SET_GL_ERROR(
9290 GL_INVALID_OPERATION,
9291 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469292 current_decoder_error_ = error::kNoError;
9293 return;
9294 } else {
9295 service_id = vao->service_id();
9296 }
[email protected]944b62f32012-09-27 02:20:469297 } else {
[email protected]7cd76fd2013-06-02 21:11:119298 vao = default_vertex_attrib_manager_.get();
[email protected]944b62f32012-09-27 02:20:469299 }
9300
[email protected]ab4fd7282012-10-12 16:25:579301 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:119302 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:249303 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159304 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579305 EmulateVertexArrayState();
9306 } else {
9307 glBindVertexArrayOES(service_id);
9308 }
9309 }
9310}
9311
9312// Used when OES_vertex_array_object isn't natively supported
9313void GLES2DecoderImpl::EmulateVertexArrayState() {
9314 // Setup the Vertex attribute state
9315 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9316 RestoreStateForAttrib(vv);
9317 }
9318
9319 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219320 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249321 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579322 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9323 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469324}
9325
9326bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469327 const VertexAttribManager* vao =
9328 GetVertexAttribManager(client_id);
9329 return vao && vao->IsValid() && !vao->IsDeleted();
9330}
9331
[email protected]b0af4f52011-09-28 22:04:429332error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9333 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359334 const cmds::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159335 if (!features().chromium_stream_texture) {
[email protected]ab09b612013-03-11 22:11:519336 LOCAL_SET_GL_ERROR(
9337 GL_INVALID_OPERATION,
9338 "glOpenStreamTextureCHROMIUM", "not supported.");
[email protected]b0af4f52011-09-28 22:04:429339 return error::kNoError;
9340 }
9341
9342 uint32 client_id = c.client_id;
[email protected]ed9f9cd2013-02-27 21:12:359343 typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
[email protected]b0af4f52011-09-28 22:04:429344 Result* result = GetSharedMemoryAs<Result*>(
9345 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9346
[email protected]e5081262012-01-05 23:09:039347 if (!result)
9348 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429349 *result = GL_ZERO;
[email protected]370eaf12013-05-18 09:19:499350 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
9351 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519352 LOCAL_SET_GL_ERROR(
9353 GL_INVALID_VALUE,
9354 "glCreateStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429355 return error::kNoError;
9356 }
9357
[email protected]370eaf12013-05-18 09:19:499358 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079359 if (texture->IsStreamTexture()) {
[email protected]ab09b612013-03-11 22:11:519360 LOCAL_SET_GL_ERROR(
9361 GL_INVALID_OPERATION,
9362 "glCreateStreamTextureCHROMIUM", "is already a stream texture.");
[email protected]b0af4f52011-09-28 22:04:429363 return error::kNoError;
9364 }
9365
[email protected]02965c22013-03-09 02:40:079366 if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:519367 LOCAL_SET_GL_ERROR(
9368 GL_INVALID_OPERATION,
9369 "glCreateStreamTextureCHROMIUM",
9370 "is already bound to incompatible target.");
[email protected]b0af4f52011-09-28 22:04:429371 return error::kNoError;
9372 }
9373
[email protected]4f9958142013-07-02 03:58:079374 if (!stream_texture_manager())
[email protected]b0af4f52011-09-28 22:04:429375 return error::kInvalidArguments;
9376
[email protected]4f9958142013-07-02 03:58:079377 GLuint object_id = stream_texture_manager()->CreateStreamTexture(
[email protected]02965c22013-03-09 02:40:079378 texture->service_id(), client_id);
[email protected]b0af4f52011-09-28 22:04:429379
9380 if (object_id) {
[email protected]370eaf12013-05-18 09:19:499381 texture_manager()->SetStreamTexture(texture_ref, true);
[email protected]b0af4f52011-09-28 22:04:429382 } else {
[email protected]ab09b612013-03-11 22:11:519383 LOCAL_SET_GL_ERROR(
9384 GL_OUT_OF_MEMORY,
9385 "glCreateStreamTextureCHROMIUM", "failed to create platform texture.");
[email protected]b0af4f52011-09-28 22:04:429386 }
9387
9388 *result = object_id;
9389 return error::kNoError;
9390}
9391
9392error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9393 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359394 const cmds::DestroyStreamTextureCHROMIUM& c) {
[email protected]b0af4f52011-09-28 22:04:429395 GLuint client_id = c.texture;
[email protected]370eaf12013-05-18 09:19:499396 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
[email protected]4f9958142013-07-02 03:58:079397 if (texture_ref && texture_manager()->IsStreamTextureOwner(texture_ref)) {
9398 if (!stream_texture_manager())
[email protected]b0af4f52011-09-28 22:04:429399 return error::kInvalidArguments;
9400
[email protected]4f9958142013-07-02 03:58:079401 stream_texture_manager()->DestroyStreamTexture(texture_ref->service_id());
[email protected]370eaf12013-05-18 09:19:499402 texture_manager()->SetStreamTexture(texture_ref, false);
[email protected]b0af4f52011-09-28 22:04:429403 } else {
[email protected]ab09b612013-03-11 22:11:519404 LOCAL_SET_GL_ERROR(
9405 GL_INVALID_VALUE,
9406 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429407 }
9408
9409 return error::kNoError;
9410}
9411
[email protected]e51bdf32011-11-23 22:21:469412#if defined(OS_MACOSX)
9413void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9414 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9415 texture_id);
9416 if (it != texture_to_io_surface_map_.end()) {
9417 // Found a previous IOSurface bound to this texture; release it.
9418 CFTypeRef surface = it->second;
9419 CFRelease(surface);
9420 texture_to_io_surface_map_.erase(it);
9421 }
9422}
9423#endif
9424
9425void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9426 GLenum target, GLsizei width, GLsizei height,
9427 GLuint io_surface_id, GLuint plane) {
9428#if defined(OS_MACOSX)
9429 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519430 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439431 GL_INVALID_OPERATION,
9432 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469433 return;
9434 }
9435
9436 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9437 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519438 LOCAL_SET_GL_ERROR(
9439 GL_INVALID_OPERATION,
9440 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469441 return;
9442 }
9443
9444 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9445 // This might be supported in the future, and if we could require
9446 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9447 // could delete a lot of code. For now, perform strict validation so we
9448 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519449 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469450 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439451 "glTexImageIOSurface2DCHROMIUM",
9452 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469453 return;
9454 }
9455
[email protected]09d50362012-10-18 20:54:379456 // Default target might be conceptually valid, but disallow it to avoid
9457 // accidents.
[email protected]370eaf12013-05-18 09:19:499458 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
9459 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519460 LOCAL_SET_GL_ERROR(
9461 GL_INVALID_OPERATION,
9462 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469463 return;
9464 }
[email protected]e51bdf32011-11-23 22:21:469465
9466 // Look up the new IOSurface. Note that because of asynchrony
9467 // between processes this might fail; during live resizing the
9468 // plugin process might allocate and release an IOSurface before
9469 // this process gets a chance to look it up. Hold on to any old
9470 // IOSurface in this case.
9471 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9472 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519473 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439474 GL_INVALID_OPERATION,
9475 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469476 return;
9477 }
9478
9479 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499480 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469481
9482 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9483 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499484 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469485
9486 CGLContextObj context =
9487 static_cast<CGLContextObj>(context_->GetHandle());
9488
9489 CGLError err = surface_support->CGLTexImageIOSurface2D(
9490 context,
9491 target,
9492 GL_RGBA,
9493 width,
9494 height,
9495 GL_BGRA,
9496 GL_UNSIGNED_INT_8_8_8_8_REV,
9497 surface,
9498 plane);
9499
9500 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519501 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469502 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439503 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469504 return;
9505 }
9506
9507 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499508 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469509 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9510
9511#else
[email protected]ab09b612013-03-11 22:11:519512 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439513 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469514#endif
9515}
9516
[email protected]97dc7cbe2011-12-06 17:26:179517static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9518 switch (internalformat) {
9519 case GL_RGB565:
9520 return GL_RGB;
9521 case GL_RGBA4:
9522 return GL_RGBA;
9523 case GL_RGB5_A1:
9524 return GL_RGBA;
9525 case GL_RGB8_OES:
9526 return GL_RGB;
9527 case GL_RGBA8_OES:
9528 return GL_RGBA;
9529 case GL_LUMINANCE8_ALPHA8_EXT:
9530 return GL_LUMINANCE_ALPHA;
9531 case GL_LUMINANCE8_EXT:
9532 return GL_LUMINANCE;
9533 case GL_ALPHA8_EXT:
9534 return GL_ALPHA;
9535 case GL_RGBA32F_EXT:
9536 return GL_RGBA;
9537 case GL_RGB32F_EXT:
9538 return GL_RGB;
9539 case GL_ALPHA32F_EXT:
9540 return GL_ALPHA;
9541 case GL_LUMINANCE32F_EXT:
9542 return GL_LUMINANCE;
9543 case GL_LUMINANCE_ALPHA32F_EXT:
9544 return GL_LUMINANCE_ALPHA;
9545 case GL_RGBA16F_EXT:
9546 return GL_RGBA;
9547 case GL_RGB16F_EXT:
9548 return GL_RGB;
9549 case GL_ALPHA16F_EXT:
9550 return GL_ALPHA;
9551 case GL_LUMINANCE16F_EXT:
9552 return GL_LUMINANCE;
9553 case GL_LUMINANCE_ALPHA16F_EXT:
9554 return GL_LUMINANCE_ALPHA;
9555 case GL_BGRA8_EXT:
9556 return GL_BGRA_EXT;
9557 default:
9558 return GL_NONE;
9559 }
9560}
9561
[email protected]43410e92012-04-20 17:06:289562void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039563 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549564 GLenum internal_format, GLenum dest_type) {
[email protected]370eaf12013-05-18 09:19:499565 TextureRef* dest_texture_ref = GetTexture(dest_id);
9566 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289567
[email protected]370eaf12013-05-18 09:19:499568 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519569 LOCAL_SET_GL_ERROR(
9570 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289571 return;
9572 }
9573
9574 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519575 LOCAL_SET_GL_ERROR(
9576 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289577 return;
9578 }
9579
[email protected]370eaf12013-05-18 09:19:499580 Texture* source_texture = source_texture_ref->texture();
9581 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079582 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259583 (source_texture->target() != GL_TEXTURE_2D &&
9584 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]ab09b612013-03-11 22:11:519585 LOCAL_SET_GL_ERROR(
9586 GL_INVALID_VALUE,
9587 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039588 return;
9589 }
9590
[email protected]43410e92012-04-20 17:06:289591 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289592
[email protected]9bc9a2e82013-04-03 03:56:259593 if (source_texture->target() == GL_TEXTURE_2D) {
9594 if (!source_texture->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
9595 &source_height)) {
9596 LOCAL_SET_GL_ERROR(
9597 GL_INVALID_VALUE,
9598 "glCopyTextureChromium", "source texture has no level 0");
9599 return;
9600 }
9601
9602 // Check that this type of texture is allowed.
9603 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
9604 source_height, 1)) {
9605 LOCAL_SET_GL_ERROR(
9606 GL_INVALID_VALUE,
9607 "glCopyTextureCHROMIUM", "Bad dimensions");
9608 return;
9609 }
[email protected]43410e92012-04-20 17:06:289610 }
9611
[email protected]377976552013-05-14 23:32:569612 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
[email protected]4f9958142013-07-02 03:58:079613 DCHECK(stream_texture_manager());
[email protected]377976552013-05-14 23:32:569614 StreamTexture* stream_tex =
[email protected]4f9958142013-07-02 03:58:079615 stream_texture_manager()->LookupStreamTexture(
[email protected]377976552013-05-14 23:32:569616 source_texture->service_id());
9617 if (!stream_tex) {
9618 LOCAL_SET_GL_ERROR(
9619 GL_INVALID_VALUE,
9620 "glCopyTextureChromium", "Stream texture lookup failed");
9621 return;
9622 }
9623 gfx::Size size = stream_tex->GetSize();
9624 source_width = size.width();
9625 source_height = size.height();
9626 if (source_width <= 0 || source_height <= 0) {
9627 LOCAL_SET_GL_ERROR(
9628 GL_INVALID_VALUE,
9629 "glCopyTextureChromium", "invalid streamtexture size");
9630 return;
9631 }
9632 }
9633
[email protected]cf6b8f62012-05-25 21:43:379634 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9635 // needed because it takes 10s of milliseconds to initialize.
9636 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519637 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379638 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279639 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379640 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519641 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379642 return;
9643 }
9644
[email protected]a4a6bdd12013-04-19 20:46:549645 GLenum dest_type_previous;
[email protected]0a1e9ad2012-05-04 21:13:039646 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079647 bool dest_level_defined = dest_texture->GetLevelSize(
9648 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289649
[email protected]0a1e9ad2012-05-04 21:13:039650 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:549651 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:079652 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039653 }
9654
9655 // Resize the destination texture to the dimensions of the source texture.
9656 if (!dest_level_defined || dest_width != source_width ||
9657 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:549658 dest_internal_format != internal_format ||
9659 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:289660 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519661 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079662 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:389663 glTexImage2D(
[email protected]43410e92012-04-20 17:06:289664 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039665 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519666 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039667 if (error != GL_NO_ERROR) {
9668 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289669 return;
[email protected]0a1e9ad2012-05-04 21:13:039670 }
[email protected]43410e92012-04-20 17:06:289671
9672 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499673 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039674 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259675 } else {
[email protected]02965c22013-03-09 02:40:079676 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:499677 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289678 }
9679
[email protected]5394a4102013-04-18 05:41:379680 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9681 // before presenting.
9682 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9683 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9684 // instead of using default matrix crbug.com/226218.
9685 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9686 0.0f, 1.0f, 0.0f, 0.0f,
9687 0.0f, 0.0f, 1.0f, 0.0f,
9688 0.0f, 0.0f, 0.0f, 1.0f};
9689 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9690 this,
9691 source_texture->target(),
9692 dest_texture->target(),
9693 source_texture->service_id(),
9694 dest_texture->service_id(), level,
9695 source_width, source_height,
9696 unpack_flip_y_,
9697 unpack_premultiply_alpha_,
9698 unpack_unpremultiply_alpha_,
9699 default_matrix);
9700 } else {
9701 copy_texture_CHROMIUM_->DoCopyTexture(
9702 this,
9703 source_texture->target(),
9704 dest_texture->target(),
9705 source_texture->service_id(),
9706 dest_texture->service_id(), level,
9707 source_width, source_height,
9708 unpack_flip_y_,
9709 unpack_premultiply_alpha_,
9710 unpack_unpremultiply_alpha_);
9711 }
[email protected]43410e92012-04-20 17:06:289712}
9713
[email protected]97dc7cbe2011-12-06 17:26:179714static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9715 switch (internalformat) {
9716 case GL_RGB565:
9717 return GL_UNSIGNED_SHORT_5_6_5;
9718 case GL_RGBA4:
9719 return GL_UNSIGNED_SHORT_4_4_4_4;
9720 case GL_RGB5_A1:
9721 return GL_UNSIGNED_SHORT_5_5_5_1;
9722 case GL_RGB8_OES:
9723 return GL_UNSIGNED_BYTE;
9724 case GL_RGBA8_OES:
9725 return GL_UNSIGNED_BYTE;
9726 case GL_LUMINANCE8_ALPHA8_EXT:
9727 return GL_UNSIGNED_BYTE;
9728 case GL_LUMINANCE8_EXT:
9729 return GL_UNSIGNED_BYTE;
9730 case GL_ALPHA8_EXT:
9731 return GL_UNSIGNED_BYTE;
9732 case GL_RGBA32F_EXT:
9733 return GL_FLOAT;
9734 case GL_RGB32F_EXT:
9735 return GL_FLOAT;
9736 case GL_ALPHA32F_EXT:
9737 return GL_FLOAT;
9738 case GL_LUMINANCE32F_EXT:
9739 return GL_FLOAT;
9740 case GL_LUMINANCE_ALPHA32F_EXT:
9741 return GL_FLOAT;
9742 case GL_RGBA16F_EXT:
9743 return GL_HALF_FLOAT_OES;
9744 case GL_RGB16F_EXT:
9745 return GL_HALF_FLOAT_OES;
9746 case GL_ALPHA16F_EXT:
9747 return GL_HALF_FLOAT_OES;
9748 case GL_LUMINANCE16F_EXT:
9749 return GL_HALF_FLOAT_OES;
9750 case GL_LUMINANCE_ALPHA16F_EXT:
9751 return GL_HALF_FLOAT_OES;
9752 case GL_BGRA8_EXT:
9753 return GL_UNSIGNED_BYTE;
9754 default:
9755 return GL_NONE;
9756 }
9757}
9758
9759void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449760 GLenum target,
9761 GLint levels,
9762 GLenum internal_format,
9763 GLsizei width,
9764 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389765 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419766 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179767 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:519768 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439769 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179770 return;
9771 }
[email protected]370eaf12013-05-18 09:19:499772 TextureRef* texture_ref = GetTextureInfoForTarget(target);
9773 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519774 LOCAL_SET_GL_ERROR(
9775 GL_INVALID_OPERATION,
9776 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179777 return;
9778 }
[email protected]370eaf12013-05-18 09:19:499779 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079780 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:429781 clear_state_dirty_ = true;
[email protected]97dc7cbe2011-12-06 17:26:179782 }
[email protected]02965c22013-03-09 02:40:079783 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519784 LOCAL_SET_GL_ERROR(
9785 GL_INVALID_OPERATION,
9786 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179787 return;
9788 }
[email protected]7989c9e2013-01-23 06:39:269789
9790 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9791 GLenum type = ExtractTypeFromStorageFormat(internal_format);
9792
9793 {
9794 GLsizei level_width = width;
9795 GLsizei level_height = height;
9796 uint32 estimated_size = 0;
9797 for (int ii = 0; ii < levels; ++ii) {
9798 uint32 level_size = 0;
9799 if (!GLES2Util::ComputeImageDataSizes(
9800 level_width, level_height, format, type, state_.unpack_alignment,
9801 &estimated_size, NULL, NULL) ||
9802 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519803 LOCAL_SET_GL_ERROR(
9804 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269805 return;
9806 }
9807 level_width = std::max(1, level_width >> 1);
9808 level_height = std::max(1, level_height >> 1);
9809 }
9810 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519811 LOCAL_SET_GL_ERROR(
9812 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269813 return;
9814 }
9815 }
9816
[email protected]ab09b612013-03-11 22:11:519817 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:389818 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:519819 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:179820 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:159821 GLsizei level_width = width;
9822 GLsizei level_height = height;
9823 for (int ii = 0; ii < levels; ++ii) {
9824 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499825 texture_ref, target, ii, format,
9826 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:159827 level_width = std::max(1, level_width >> 1);
9828 level_height = std::max(1, level_height >> 1);
9829 }
[email protected]02965c22013-03-09 02:40:079830 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:179831 }
[email protected]97dc7cbe2011-12-06 17:26:179832}
[email protected]e51bdf32011-11-23 22:21:469833
[email protected]78b514b2012-05-01 21:50:599834error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359835 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]78b514b2012-05-01 21:50:599836 MailboxName name;
9837 mailbox_manager()->GenerateMailboxName(&name);
9838 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
9839 Bucket* bucket = CreateBucket(bucket_id);
9840
9841 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
9842 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
9843
9844 return error::kNoError;
9845}
9846
9847void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9848 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029849 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329850 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029851 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9852
[email protected]370eaf12013-05-18 09:19:499853 TextureRef* texture_ref = GetTextureInfoForTarget(target);
9854 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519855 LOCAL_SET_GL_ERROR(
9856 GL_INVALID_OPERATION,
9857 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599858 return;
9859 }
9860
[email protected]62e65f02013-05-29 22:28:109861 Texture* produced = texture_manager()->Produce(texture_ref);
9862 if (!produced) {
[email protected]ab09b612013-03-11 22:11:519863 LOCAL_SET_GL_ERROR(
9864 GL_INVALID_OPERATION,
9865 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599866 return;
9867 }
9868
9869 if (!group_->mailbox_manager()->ProduceTexture(
9870 target,
9871 *reinterpret_cast<const MailboxName*>(mailbox),
[email protected]62e65f02013-05-29 22:28:109872 produced)) {
[email protected]ab09b612013-03-11 22:11:519873 LOCAL_SET_GL_ERROR(
9874 GL_INVALID_OPERATION,
9875 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599876 return;
9877 }
[email protected]78b514b2012-05-01 21:50:599878}
9879
9880void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9881 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029882 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329883 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029884 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9885
[email protected]62e65f02013-05-29 22:28:109886 scoped_refptr<TextureRef> texture_ref =
9887 GetTextureInfoForTargetUnlessDefault(target);
[email protected]7cd76fd2013-06-02 21:11:119888 if (!texture_ref.get()) {
9889 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9890 "glConsumeTextureCHROMIUM",
9891 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599892 return;
9893 }
[email protected]62e65f02013-05-29 22:28:109894 GLuint client_id = texture_ref->client_id();
9895 if (!client_id) {
9896 LOCAL_SET_GL_ERROR(
9897 GL_INVALID_OPERATION,
9898 "glConsumeTextureCHROMIUM", "unknown texture for target");
9899 return;
9900 }
9901 Texture* texture =
[email protected]78b514b2012-05-01 21:50:599902 group_->mailbox_manager()->ConsumeTexture(
9903 target,
[email protected]62e65f02013-05-29 22:28:109904 *reinterpret_cast<const MailboxName*>(mailbox));
9905 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519906 LOCAL_SET_GL_ERROR(
9907 GL_INVALID_OPERATION,
9908 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599909 return;
9910 }
[email protected]62e65f02013-05-29 22:28:109911 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:519912 LOCAL_SET_GL_ERROR(
9913 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:109914 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:599915 return;
9916 }
[email protected]62e65f02013-05-29 22:28:109917
9918 DeleteTexturesHelper(1, &client_id);
9919 texture_ref = texture_manager()->Consume(client_id, texture);
9920 glBindTexture(target, texture_ref->service_id());
9921
9922 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
9923 unit.bind_target = target;
9924 switch (target) {
9925 case GL_TEXTURE_2D:
9926 unit.bound_texture_2d = texture_ref;
9927 break;
9928 case GL_TEXTURE_CUBE_MAP:
9929 unit.bound_texture_cube_map = texture_ref;
9930 break;
9931 case GL_TEXTURE_EXTERNAL_OES:
9932 unit.bound_texture_external_oes = texture_ref;
9933 break;
9934 case GL_TEXTURE_RECTANGLE_ARB:
9935 unit.bound_texture_rectangle_arb = texture_ref;
9936 break;
9937 default:
9938 NOTREACHED(); // Validation should prevent us getting here.
9939 break;
9940 }
[email protected]78b514b2012-05-01 21:50:599941}
9942
[email protected]d2a0e1a2012-08-12 02:25:019943void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9944 GLsizei length, const GLchar* marker) {
9945 if (!marker) {
9946 marker = "";
9947 }
9948 debug_marker_manager_.SetMarker(
9949 length ? std::string(marker, length) : std::string(marker));
9950}
9951
9952void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9953 GLsizei length, const GLchar* marker) {
9954 if (!marker) {
9955 marker = "";
9956 }
9957 debug_marker_manager_.PushGroup(
9958 length ? std::string(marker, length) : std::string(marker));
9959}
9960
9961void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9962 debug_marker_manager_.PopGroup();
9963}
9964
[email protected]09d50362012-10-18 20:54:379965void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9966 GLenum target, GLint image_id) {
9967 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9968 if (target != GL_TEXTURE_2D) {
9969 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:519970 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:379971 GL_INVALID_OPERATION,
9972 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9973 return;
9974 }
9975
9976 // Default target might be conceptually valid, but disallow it to avoid
9977 // accidents.
[email protected]370eaf12013-05-18 09:19:499978 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
9979 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519980 LOCAL_SET_GL_ERROR(
9981 GL_INVALID_OPERATION,
9982 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:379983 return;
9984 }
9985
9986 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9987 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:519988 LOCAL_SET_GL_ERROR(
9989 GL_INVALID_OPERATION,
9990 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:379991 return;
9992 }
9993
[email protected]b8160812013-04-09 00:41:049994 {
9995 ScopedGLErrorSuppressor suppressor(
9996 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", this);
9997 if (!gl_image->BindTexImage()) {
9998 LOCAL_SET_GL_ERROR(
9999 GL_INVALID_OPERATION,
10000 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10001 return;
10002 }
[email protected]09d50362012-10-18 20:54:3710003 }
10004
10005 gfx::Size size = gl_image->GetSize();
10006 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910007 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710008 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910009 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710010}
10011
10012void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10013 GLenum target, GLint image_id) {
10014 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
10015 if (target != GL_TEXTURE_2D) {
10016 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:5110017 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:3710018 GL_INVALID_OPERATION,
10019 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
10020 return;
10021 }
10022
10023 // Default target might be conceptually valid, but disallow it to avoid
10024 // accidents.
[email protected]370eaf12013-05-18 09:19:4910025 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
10026 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110027 LOCAL_SET_GL_ERROR(
10028 GL_INVALID_OPERATION,
10029 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710030 return;
10031 }
10032
10033 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10034 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110035 LOCAL_SET_GL_ERROR(
10036 GL_INVALID_OPERATION,
10037 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710038 return;
10039 }
10040
10041 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910042 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710043 return;
10044
[email protected]b8160812013-04-09 00:41:0410045 {
10046 ScopedGLErrorSuppressor suppressor(
10047 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", this);
10048 gl_image->ReleaseTexImage();
10049 }
[email protected]09d50362012-10-18 20:54:3710050
10051 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910052 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710053 GL_RGBA, GL_UNSIGNED_BYTE, false);
10054}
[email protected]d2a0e1a2012-08-12 02:25:0110055
[email protected]94307712012-11-16 23:26:1110056error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510057 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110058 Bucket* bucket = GetBucket(c.bucket_id);
10059 if (!bucket || bucket->size() == 0) {
10060 return error::kInvalidArguments;
10061 }
10062 std::string command_name;
10063 if (!bucket->GetAsString(&command_name)) {
10064 return error::kInvalidArguments;
10065 }
[email protected]fb97b662013-02-20 23:02:1410066 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
10067 if (!gpu_tracer_->Begin(command_name)) {
[email protected]ab09b612013-03-11 22:11:5110068 LOCAL_SET_GL_ERROR(
10069 GL_INVALID_OPERATION,
10070 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410071 return error::kNoError;
10072 }
[email protected]94307712012-11-16 23:26:1110073 return error::kNoError;
10074}
10075
10076void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410077 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110078 LOCAL_SET_GL_ERROR(
10079 GL_INVALID_OPERATION,
10080 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110081 return;
10082 }
[email protected]fb97b662013-02-20 23:02:1410083 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
10084 gpu_tracer_->End();
[email protected]94307712012-11-16 23:26:1110085}
10086
[email protected]2f143d482013-03-14 18:04:4910087void GLES2DecoderImpl::DoDrawBuffersEXT(
10088 GLsizei count, const GLenum* bufs) {
10089 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10090 LOCAL_SET_GL_ERROR(
10091 GL_INVALID_VALUE,
10092 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10093 return;
10094 }
10095
10096 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10097 if (framebuffer) {
10098 for (GLsizei i = 0; i < count; ++i) {
10099 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10100 bufs[i] != GL_NONE) {
10101 LOCAL_SET_GL_ERROR(
10102 GL_INVALID_OPERATION,
10103 "glDrawBuffersEXT",
10104 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10105 return;
10106 }
10107 }
10108 glDrawBuffersARB(count, bufs);
10109 framebuffer->SetDrawBuffers(count, bufs);
10110 } else { // backbuffer
10111 if (count > 1 ||
10112 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10113 LOCAL_SET_GL_ERROR(
10114 GL_INVALID_OPERATION,
10115 "glDrawBuffersEXT",
10116 "more than one buffer or bufs not GL_NONE or GL_BACK");
10117 return;
10118 }
10119 GLenum mapped_buf = bufs[0];
10120 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10121 bufs[0] == GL_BACK) {
10122 mapped_buf = GL_COLOR_ATTACHMENT0;
10123 }
10124 glDrawBuffersARB(count, &mapped_buf);
10125 group_->set_draw_buffer(bufs[0]);
10126 }
10127}
10128
[email protected]32145a92012-12-17 09:01:5910129bool GLES2DecoderImpl::ValidateAsyncTransfer(
10130 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710131 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910132 GLenum target,
10133 GLint level,
10134 const void * data) {
10135 // We only support async uploads to 2D textures for now.
10136 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110137 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910138 return false;
10139 }
10140 // We only support uploads to level zero for now.
10141 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110142 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910143 return false;
10144 }
10145 // A transfer buffer must be bound, even for asyncTexImage2D.
10146 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110147 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910148 return false;
10149 }
10150 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710151 if (!texture_ref ||
10152 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110153 LOCAL_SET_GL_ERROR(
10154 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910155 function_name, "transfer already in progress");
10156 return false;
10157 }
10158 return true;
10159}
10160
[email protected]69023942012-11-30 19:57:1610161error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510162 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610163 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610164 GLenum target = static_cast<GLenum>(c.target);
10165 GLint level = static_cast<GLint>(c.level);
10166 GLint internal_format = static_cast<GLint>(c.internalformat);
10167 GLsizei width = static_cast<GLsizei>(c.width);
10168 GLsizei height = static_cast<GLsizei>(c.height);
10169 GLint border = static_cast<GLint>(c.border);
10170 GLenum format = static_cast<GLenum>(c.format);
10171 GLenum type = static_cast<GLenum>(c.type);
10172 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10173 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10174 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910175
10176 // TODO(epenner): Move this and copies of this memory validation
10177 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610178 if (!GLES2Util::ComputeImageDataSizes(
10179 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10180 NULL)) {
10181 return error::kOutOfBounds;
10182 }
10183 const void* pixels = NULL;
10184 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10185 pixels = GetSharedMemoryAs<const void*>(
10186 pixels_shm_id, pixels_shm_offset, pixels_size);
10187 if (!pixels) {
10188 return error::kOutOfBounds;
10189 }
10190 }
10191
[email protected]32145a92012-12-17 09:01:5910192 // All the normal glTexSubImage2D validation.
10193 if (!ValidateTexImage2D(
10194 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
10195 width, height, border, format, type, pixels, pixels_size)) {
10196 return error::kNoError;
10197 }
10198
10199 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910200 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10201 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910202 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710203 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910204 return error::kNoError;
10205
10206 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710207 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110208 LOCAL_SET_GL_ERROR(
10209 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910210 "glAsyncTexImage2DCHROMIUM", "already defined");
10211 return error::kNoError;
10212 }
10213
[email protected]7989c9e2013-01-23 06:39:2610214 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110215 LOCAL_SET_GL_ERROR(
10216 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610217 return error::kNoError;
10218 }
10219
[email protected]32145a92012-12-17 09:01:5910220 // We know the memory/size is safe, so get the real shared memory since
10221 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110222 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910223 base::SharedMemory* shared_memory = buffer.shared_memory;
10224 uint32 shm_size = buffer.size;
10225 uint32 shm_data_offset = c.pixels_shm_offset;
10226 uint32 shm_data_size = pixels_size;
10227
[email protected]5b3a8e02013-03-13 05:36:4410228 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810229 AsyncTexImage2DParams tex_params = {
10230 target, level, static_cast<GLenum>(internal_format),
10231 width, height, border, format, type};
10232 AsyncMemoryParams mem_params = {
10233 shared_memory, shm_size, shm_data_offset, shm_data_size};
[email protected]32145a92012-12-17 09:01:5910234
[email protected]5b3a8e02013-03-13 05:36:4410235 // Set up the async state if needed, and make the texture
10236 // immutable so the async state stays valid. The level info
10237 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1810238 AsyncPixelTransferDelegate* delegate =
10239 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
10240 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4410241 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910242
[email protected]896425e2013-06-12 17:27:1810243 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410244 tex_params,
10245 mem_params,
10246 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910247 // The callback is only invoked if the transfer delegate still
10248 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410249 // ownership that both of these pointers are valid.
10250 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910251 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410252 tex_params));
[email protected]f598f422012-12-07 08:30:0310253 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610254}
10255
10256error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510257 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610258 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610259 GLenum target = static_cast<GLenum>(c.target);
10260 GLint level = static_cast<GLint>(c.level);
10261 GLint xoffset = static_cast<GLint>(c.xoffset);
10262 GLint yoffset = static_cast<GLint>(c.yoffset);
10263 GLsizei width = static_cast<GLsizei>(c.width);
10264 GLsizei height = static_cast<GLsizei>(c.height);
10265 GLenum format = static_cast<GLenum>(c.format);
10266 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910267
10268 // TODO(epenner): Move this and copies of this memory validation
10269 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610270 uint32 data_size;
10271 if (!GLES2Util::ComputeImageDataSizes(
10272 width, height, format, type, state_.unpack_alignment, &data_size,
10273 NULL, NULL)) {
10274 return error::kOutOfBounds;
10275 }
10276 const void* pixels = GetSharedMemoryAs<const void*>(
10277 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910278
10279 // All the normal glTexSubImage2D validation.
10280 error::Error error = error::kNoError;
10281 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10282 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10283 return error;
[email protected]69023942012-11-30 19:57:1610284 }
10285
[email protected]32145a92012-12-17 09:01:5910286 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910287 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10288 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910289 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710290 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910291 return error::kNoError;
10292
10293 // Guarantee async textures are always 'cleared' as follows:
10294 // - AsyncTexImage2D can not redefine an existing texture
10295 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10296 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10297 // - Textures become immutable after an async call.
10298 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710299 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910300 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10301 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110302 LOCAL_SET_GL_ERROR(
10303 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510304 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910305 return error::kNoError;
10306 }
10307 }
10308
10309 // We know the memory/size is safe, so get the real shared memory since
10310 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110311 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910312 base::SharedMemory* shared_memory = buffer.shared_memory;
10313 uint32 shm_size = buffer.size;
10314 uint32 shm_data_offset = c.data_shm_offset;
10315 uint32 shm_data_size = data_size;
10316
[email protected]5b3a8e02013-03-13 05:36:4410317 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310318 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910319 width, height, format, type};
[email protected]2a7568a2013-05-09 23:12:0310320 AsyncMemoryParams mem_params = {shared_memory, shm_size,
[email protected]32145a92012-12-17 09:01:5910321 shm_data_offset, shm_data_size};
[email protected]896425e2013-06-12 17:27:1810322 AsyncPixelTransferDelegate* delegate =
10323 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10324 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4410325 // TODO(epenner): We may want to enforce exclusive use
10326 // of async APIs in which case this should become an error,
10327 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310328 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410329 0, 0, 0, 0, 0, 0};
10330 texture->GetLevelSize(target, level, &define_params.width,
10331 &define_params.height);
10332 texture->GetLevelType(target, level, &define_params.type,
10333 &define_params.internal_format);
10334 // Set up the async state if needed, and make the texture
10335 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1810336 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4710337 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4410338 texture->SetImmutable(true);
10339 }
10340
[email protected]896425e2013-06-12 17:27:1810341 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910342 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610343}
10344
[email protected]a00c1f742013-03-05 17:02:1610345error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10346 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10347 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10348 GLenum target = static_cast<GLenum>(c.target);
10349
10350 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110351 LOCAL_SET_GL_ERROR(
10352 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610353 return error::kNoError;
10354 }
[email protected]370eaf12013-05-18 09:19:4910355 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10356 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110357 LOCAL_SET_GL_ERROR(
10358 GL_INVALID_OPERATION,
10359 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610360 return error::kNoError;
10361 }
[email protected]896425e2013-06-12 17:27:1810362 AsyncPixelTransferDelegate* delegate =
10363 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10364 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4910365 LOCAL_SET_GL_ERROR(
10366 GL_INVALID_OPERATION,
10367 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10368 return error::kNoError;
10369 }
[email protected]896425e2013-06-12 17:27:1810370 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0910371 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610372 return error::kNoError;
10373}
10374
[email protected]96449d2c2009-11-25 00:01:3210375// Include the auto-generated part of this file. We split this because it means
10376// we can easily edit the non-auto generated parts right here in this file
10377// instead of having to edit some template or the code generator.
10378#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10379
10380} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510381} // namespace gpu