blob: 44a01345372650ce8780fe20e9337ed68599f9d4 [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]5a36dc132013-07-23 23:17:5562#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3763#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2764#include "ui/gl/gl_implementation.h"
65#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2766
[email protected]e51bdf32011-11-23 22:21:4667#if defined(OS_MACOSX)
[email protected]423e644f2013-06-19 00:48:2768#include "ui/gl/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4669#endif
[email protected]de17df392010-04-23 21:09:4170
[email protected]693ca512012-11-13 18:09:1371// TODO(zmo): we can't include "City.h" due to type def conflicts.
72extern uint64 CityHash64(const char*, size_t);
73
[email protected]a7a27ace2009-12-12 00:11:2574namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3275namespace gles2 {
76
[email protected]f0d74742011-10-03 16:31:0477namespace {
[email protected]693ca512012-11-13 18:09:1378
[email protected]f0d74742011-10-03 16:31:0479static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4980static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1381static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]693ca512012-11-13 18:09:1382
[email protected]3d944a82013-02-12 19:09:0283#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]693ca512012-11-13 18:09:1384khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
85 return static_cast<khronos_uint64_t>(
86 CityHash64(name, static_cast<size_t>(len)));
87}
[email protected]3d944a82013-02-12 19:09:0288#endif
[email protected]693ca512012-11-13 18:09:1389
[email protected]448e459e2013-06-12 17:00:4190static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
91 GLint rangeMax,
92 GLint precision) {
93 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
94}
95
[email protected]8dc1bf92013-03-12 03:58:2196static void GetShaderPrecisionFormatImpl(GLenum shader_type,
97 GLenum precision_type,
98 GLint *range, GLint *precision) {
99 switch (precision_type) {
100 case GL_LOW_INT:
101 case GL_MEDIUM_INT:
102 case GL_HIGH_INT:
103 // These values are for a 32-bit twos-complement integer format.
104 range[0] = 31;
105 range[1] = 30;
106 *precision = 0;
107 break;
108 case GL_LOW_FLOAT:
109 case GL_MEDIUM_FLOAT:
110 case GL_HIGH_FLOAT:
111 // These values are for an IEEE single-precision floating-point format.
112 range[0] = 127;
113 range[1] = 127;
114 *precision = 23;
115 break;
116 default:
117 NOTREACHED();
118 break;
119 }
120
[email protected]8af4d5e2013-03-15 23:55:33121 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
122 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21123 // This function is sometimes defined even though it's really just
124 // a stub, so we need to set range and precision as if it weren't
125 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44126 // On Mac OS with some GPUs, calling this generates a
127 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
128 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21129 glGetShaderPrecisionFormat(shader_type, precision_type,
130 range, precision);
[email protected]448e459e2013-06-12 17:00:41131
132 // TODO(brianderson): Make the following official workarounds.
133
134 // Some drivers have bugs where they report the ranges as a negative number.
135 // Taking the absolute value here shouldn't hurt because negative numbers
136 // aren't expected anyway.
137 range[0] = abs(range[0]);
138 range[1] = abs(range[1]);
139
140 // If the driver reports a precision for highp float that isn't actually
141 // highp, don't pretend like it's supported because shader compilation will
142 // fail anyway.
143 if (precision_type == GL_HIGH_FLOAT &&
144 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
145 range[0] = 0;
146 range[1] = 0;
147 *precision = 0;
148 }
[email protected]8dc1bf92013-03-12 03:58:21149 }
150}
151
[email protected]b04e24c2013-01-08 18:35:25152} // namespace
[email protected]f0d74742011-10-03 16:31:04153
[email protected]6217d392010-03-25 22:08:35154class GLES2DecoderImpl;
155
[email protected]ab09b612013-03-11 22:11:51156// Local versions of the SET_GL_ERROR macros
157#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50158 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51159#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50160 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
161 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51162#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50163 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
164 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51165#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50166 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
167 function_name)
[email protected]ab09b612013-03-11 22:11:51168#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50169 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51170#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50171 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51172#define LOCAL_PERFORMANCE_WARNING(msg) \
173 PerformanceWarning(__FILE__, __LINE__, msg)
174#define LOCAL_RENDER_WARNING(msg) \
175 RenderWarning(__FILE__, __LINE__, msg)
176
[email protected]07f54fcc2009-12-22 02:46:30177// Check that certain assumptions the code makes are true. There are places in
178// the code where shared memory is passed direclty to GL. Example, glUniformiv,
179// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
180// a few others) are 32bits. If they are not 32bits the code will have to change
181// to call those GL functions with service side memory and then copy the results
182// to shared memory, converting the sizes.
183COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
184 GLint_not_same_size_as_uint32);
185COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
186 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37187COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
188 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30189
[email protected]43f28f832010-02-03 02:28:48190// TODO(kbr): the use of this anonymous namespace core dumps the
191// linker on Mac OS X 10.6 when the symbol ordering file is used
192// namespace {
[email protected]96449d2c2009-11-25 00:01:32193
194// Returns the address of the first byte after a struct.
195template <typename T>
196const void* AddressAfterStruct(const T& pod) {
197 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
198}
199
[email protected]07f54fcc2009-12-22 02:46:30200// Returns the address of the frst byte after the struct or NULL if size >
201// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32202template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30203RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
204 uint32 size,
205 uint32 immediate_data_size) {
206 return (size <= immediate_data_size) ?
207 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
208 NULL;
[email protected]96449d2c2009-11-25 00:01:32209}
210
[email protected]07f54fcc2009-12-22 02:46:30211// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18212bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32213 GLuint count,
214 size_t size,
[email protected]a76b0052010-03-05 00:33:18215 unsigned int elements_per_unit,
216 uint32* dst) {
217 uint32 value;
218 if (!SafeMultiplyUint32(count, size, &value)) {
219 return false;
220 }
221 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
222 return false;
223 }
224 *dst = value;
225 return true;
[email protected]96449d2c2009-11-25 00:01:32226}
227
228// A struct to hold info about each command.
229struct CommandInfo {
230 int arg_flags; // How to handle the arguments for this command
231 int arg_count; // How many arguments are expected for this command.
232};
233
234// A table of CommandInfo for all the commands.
235const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35236 #define GLES2_CMD_OP(name) { \
237 cmds::name::kArgFlags, \
238 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
[email protected]96449d2c2009-11-25 00:01:32239
240 GLES2_COMMAND_LIST(GLES2_CMD_OP)
241
242 #undef GLES2_CMD_OP
243};
244
[email protected]258a3313f2011-10-18 20:13:57245// Return true if a character belongs to the ASCII subset as defined in
246// GLSL ES 1.0 spec section 3.1.
247static bool CharacterIsValidForGLES(unsigned char c) {
248 // Printing characters are valid except " $ ` @ \ ' DEL.
249 if (c >= 32 && c <= 126 &&
250 c != '"' &&
251 c != '$' &&
252 c != '`' &&
253 c != '@' &&
254 c != '\\' &&
255 c != '\'') {
256 return true;
257 }
258 // Horizontal tab, line feed, vertical tab, form feed, carriage return
259 // are also valid.
260 if (c >= 9 && c <= 13) {
261 return true;
262 }
263
264 return false;
265}
266
267static bool StringIsValidForGLES(const char* str) {
268 for (; *str; ++str) {
269 if (!CharacterIsValidForGLES(*str)) {
270 return false;
271 }
272 }
273 return true;
274}
275
[email protected]297ca1c2011-06-20 23:08:46276// Wrapper for glEnable/glDisable that doesn't suck.
277static void EnableDisable(GLenum pname, bool enable) {
278 if (enable) {
279 glEnable(pname);
280 } else {
281 glDisable(pname);
282 }
283}
284
[email protected]6217d392010-03-25 22:08:35285// This class prevents any GL errors that occur when it is in scope from
286// being reported to the client.
287class ScopedGLErrorSuppressor {
288 public:
[email protected]ab09b612013-03-11 22:11:51289 explicit ScopedGLErrorSuppressor(
290 const char* function_name, GLES2DecoderImpl* decoder);
[email protected]6217d392010-03-25 22:08:35291 ~ScopedGLErrorSuppressor();
292 private:
[email protected]ab09b612013-03-11 22:11:51293 const char* function_name_;
[email protected]6217d392010-03-25 22:08:35294 GLES2DecoderImpl* decoder_;
295 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
296};
297
298// Temporarily changes a decoder's bound 2D texture and restore it when this
299// object goes out of scope. Also temporarily switches to using active texture
300// unit zero in case the client has changed that to something invalid.
301class ScopedTexture2DBinder {
302 public:
303 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
304 ~ScopedTexture2DBinder();
305
306 private:
307 GLES2DecoderImpl* decoder_;
308 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
309};
310
311// Temporarily changes a decoder's bound render buffer and restore it when this
312// object goes out of scope.
313class ScopedRenderBufferBinder {
314 public:
315 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
316 ~ScopedRenderBufferBinder();
317
318 private:
319 GLES2DecoderImpl* decoder_;
320 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
321};
322
323// Temporarily changes a decoder's bound frame buffer and restore it when this
324// object goes out of scope.
325class ScopedFrameBufferBinder {
326 public:
327 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
328 ~ScopedFrameBufferBinder();
329
330 private:
331 GLES2DecoderImpl* decoder_;
332 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
333};
334
[email protected]34ff8b0c2010-10-01 20:06:02335// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52336// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27337// if it is bound or enforce_internal_framebuffer is true. If internal is
338// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02339class ScopedResolvedFrameBufferBinder {
340 public:
[email protected]e7e38032011-07-26 17:25:25341 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27342 bool enforce_internal_framebuffer,
343 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02344 ~ScopedResolvedFrameBufferBinder();
345
346 private:
347 GLES2DecoderImpl* decoder_;
348 bool resolve_and_bind_;
349 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
350};
351
[email protected]6217d392010-03-25 22:08:35352// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35353class BackTexture {
[email protected]6217d392010-03-25 22:08:35354 public:
[email protected]ed9f9cd2013-02-27 21:12:35355 explicit BackTexture(GLES2DecoderImpl* decoder);
356 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35357
358 // Create a new render texture.
359 void Create();
360
361 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09362 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35363
364 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58365 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35366
367 // Destroy the render texture. This must be explicitly called before
368 // destroying this object.
369 void Destroy();
370
[email protected]97872062010-11-03 19:07:05371 // Invalidate the texture. This can be used when a context is lost and it is
372 // not possible to make it current in order to free the resource.
373 void Invalidate();
374
[email protected]6217d392010-03-25 22:08:35375 GLuint id() const {
376 return id_;
377 }
378
[email protected]d37231fa2010-04-09 21:16:02379 gfx::Size size() const {
380 return size_;
381 }
382
[email protected]1078f912011-12-23 13:12:14383 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25384 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14385 }
386
[email protected]6217d392010-03-25 22:08:35387 private:
388 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25389 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48390 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35391 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02392 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35393 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35394};
395
396// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35397class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35398 public:
[email protected]ed9f9cd2013-02-27 21:12:35399 explicit BackRenderbuffer(GLES2DecoderImpl* decoder);
400 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35401
402 // Create a new render buffer.
403 void Create();
404
405 // Set the initial size and format of a render buffer or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02406 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
[email protected]6217d392010-03-25 22:08:35407
408 // Destroy the render buffer. This must be explicitly called before destroying
409 // this object.
410 void Destroy();
411
[email protected]97872062010-11-03 19:07:05412 // Invalidate the render buffer. This can be used when a context is lost and
413 // it is not possible to make it current in order to free the resource.
414 void Invalidate();
415
[email protected]6217d392010-03-25 22:08:35416 GLuint id() const {
417 return id_;
418 }
419
[email protected]1078f912011-12-23 13:12:14420 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25421 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14422 }
423
[email protected]6217d392010-03-25 22:08:35424 private:
425 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25426 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48427 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35428 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35429 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35430};
431
432// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35433class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35434 public:
[email protected]ed9f9cd2013-02-27 21:12:35435 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
436 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35437
438 // Create a new frame buffer.
439 void Create();
440
441 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35442 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35443
[email protected]b9363b22010-06-09 22:06:15444 // Attach a render buffer to a frame buffer. Note that this unbinds any
445 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35446 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35447
[email protected]6217d392010-03-25 22:08:35448 // Destroy the frame buffer. This must be explicitly called before destroying
449 // this object.
450 void Destroy();
451
[email protected]97872062010-11-03 19:07:05452 // Invalidate the frame buffer. This can be used when a context is lost and it
453 // is not possible to make it current in order to free the resource.
454 void Invalidate();
455
[email protected]6217d392010-03-25 22:08:35456 // See glCheckFramebufferStatusEXT.
457 GLenum CheckStatus();
458
459 GLuint id() const {
460 return id_;
461 }
462
463 private:
464 GLES2DecoderImpl* decoder_;
465 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35466 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35467};
[email protected]34ff8b0c2010-10-01 20:06:02468
[email protected]5a36dc132013-07-23 23:17:55469struct FenceCallback {
470 explicit FenceCallback()
471 : fence(gfx::GLFence::Create()) {
472 DCHECK(fence);
473 }
474 void AddCallback(base::Closure cb) {
475 callbacks.push_back(cb);
476 }
477 std::vector<base::Closure> callbacks;
478 scoped_ptr<gfx::GLFence> fence;
479};
480
481
[email protected]43f28f832010-02-03 02:28:48482// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32483
[email protected]ddb1e5a2010-12-13 20:10:45484bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
485 uint32* service_texture_id) {
486 return false;
487}
488
[email protected]a3ded6d2010-10-19 06:44:39489GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06490 : initialized_(false),
491 debug_(false),
[email protected]1d82e822013-04-10 21:32:32492 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32493}
494
[email protected]3916c97e2010-02-25 03:20:50495GLES2Decoder::~GLES2Decoder() {
496}
497
[email protected]57edfdad2012-02-07 04:57:15498bool GLES2Decoder::testing_force_is_angle_;
499
500void GLES2Decoder::set_testing_force_is_angle(bool force) {
501 testing_force_is_angle_ = force;
502}
503
504bool GLES2Decoder::IsAngle() {
505#if defined(OS_WIN)
506 return testing_force_is_angle_ ||
507 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
508#else
509 return testing_force_is_angle_;
510#endif
511}
512
[email protected]f39f4b3f2010-05-12 17:04:08513// This class implements GLES2Decoder so we don't have to expose all the GLES2
514// cmd stuff to outside this class.
[email protected]ee1e6aa2012-11-29 09:24:10515class GLES2DecoderImpl : public GLES2Decoder {
[email protected]f39f4b3f2010-05-12 17:04:08516 public:
[email protected]476ccb72012-12-06 15:52:52517 // Used by PrepForSetUniformByLocation to validate types.
518 struct BaseUniformInfo {
519 const GLenum* const valid_types;
520 size_t num_valid_types;
521 };
522
[email protected]aa7666122011-09-02 19:45:52523 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00524 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08525
[email protected]96449d2c2009-11-25 00:01:32526 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14527 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50528 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00529 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32530
531 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00532 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32533
534 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38535 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
536 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23537 bool offscreen,
[email protected]6217d392010-03-25 22:08:35538 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29539 const DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39540 const char* allowed_extensions,
[email protected]b8e97b62012-09-30 15:09:00541 const std::vector<int32>& attribs) OVERRIDE;
542 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38543 virtual void SetSurface(
544 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]2ad674132013-06-05 07:48:51545 virtual bool ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00546 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39547 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00548 virtual bool MakeCurrent() OVERRIDE;
549 virtual void ReleaseCurrent() OVERRIDE;
550 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
551 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
552 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]1868a342012-11-07 15:56:02553 virtual void RestoreState() const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06554
555 virtual void RestoreActiveTexture() const OVERRIDE {
556 state_.RestoreActiveTexture();
557 }
[email protected]217004512013-05-10 21:25:55558 virtual void RestoreAllTextureUnitBindings() const OVERRIDE {
559 state_.RestoreAllTextureUnitBindings();
560 }
[email protected]29a4d902013-02-26 20:18:06561 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
562 state_.RestoreAttribute(index);
563 }
564 virtual void RestoreBufferBindings() const OVERRIDE {
565 state_.RestoreBufferBindings();
566 }
567 virtual void RestoreGlobalState() const OVERRIDE {
568 state_.RestoreGlobalState();
569 }
570 virtual void RestoreProgramBindings() const OVERRIDE {
571 state_.RestoreProgramBindings();
572 }
573 virtual void RestoreRenderbufferBindings() const OVERRIDE {
574 state_.RestoreRenderbufferBindings();
575 }
576 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
577 state_.RestoreTextureUnitBindings(unit);
578 }
579 virtual void RestoreFramebufferBindings() const OVERRIDE;
580 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
581
[email protected]b8e97b62012-09-30 15:09:00582 virtual QueryManager* GetQueryManager() OVERRIDE {
583 return query_manager_.get();
584 }
585 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46586 return vertex_array_manager_.get();
587 }
[email protected]b8e97b62012-09-30 15:09:00588 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05589 virtual bool HasMoreIdleWork() OVERRIDE;
590 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48591
[email protected]5a36dc132013-07-23 23:17:55592 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
593
[email protected]9d37f062011-11-22 01:24:52594 virtual void SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:07595 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00596
[email protected]1d82e822013-04-10 21:32:32597 virtual Logger* GetLogger() OVERRIDE;
[email protected]d3eba342013-04-18 21:11:50598 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]1d82e822013-04-10 21:32:32599
[email protected]e3932abb2013-03-13 00:01:37600 virtual void SetShaderCacheCallback(
601 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51602 virtual void SetWaitSyncPointCallback(
603 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00604
[email protected]85a4ac22013-05-31 01:58:47605 virtual AsyncPixelTransferManager*
606 GetAsyncPixelTransferManager() OVERRIDE;
607 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]498b5c072013-06-04 19:30:07608 virtual void SetAsyncPixelTransferManagerForTest(
609 AsyncPixelTransferManager* manager) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09610 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59611
[email protected]1318e922010-09-17 22:03:16612 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00613 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48614
[email protected]63b465922012-09-06 02:04:52615 virtual uint32 GetTextureUploadCount() OVERRIDE;
616 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
617 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30618 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52619
[email protected]8e3e0662010-08-23 18:46:30620 // Restores the current state to the user's settings.
621 void RestoreCurrentFramebufferBindings();
622 void RestoreCurrentRenderbufferBindings();
623 void RestoreCurrentTexture2DBindings();
624
[email protected]297ca1c2011-06-20 23:08:46625 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
626 void ApplyDirtyState();
627
628 // These check the state of the currently bound framebuffer or the
629 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54630 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
631 // check with all attached and enabled color attachments.
632 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46633 bool BoundFramebufferHasDepthAttachment();
634 bool BoundFramebufferHasStencilAttachment();
635
[email protected]b8e97b62012-09-30 15:09:00636 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43637
[email protected]96449d2c2009-11-25 00:01:32638 private:
[email protected]70d34263c2013-01-09 00:27:45639 friend class ScopedFrameBufferBinder;
[email protected]6217d392010-03-25 22:08:35640 friend class ScopedGLErrorSuppressor;
[email protected]34ff8b0c2010-10-01 20:06:02641 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35642 friend class BackTexture;
643 friend class BackRenderbuffer;
644 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35645
[email protected]c2f8c8402010-12-06 18:07:24646 // Initialize or re-initialize the shader translator.
647 bool InitializeShaderTranslator();
648
[email protected]302ce6d2011-07-07 23:28:11649 void UpdateCapabilities();
650
[email protected]ae51d192010-04-27 00:48:03651 // Helpers for the glGen and glDelete functions.
652 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
653 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
654 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
655 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
656 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
657 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
658 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
659 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53660 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
661 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46662 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
663 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47664
[email protected]70d34263c2013-01-09 00:27:45665 // Workarounds
666 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51667 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45668
[email protected]3916c97e2010-02-25 03:20:50669 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50670 BufferManager* buffer_manager() {
671 return group_->buffer_manager();
672 }
673
[email protected]a25fa872010-03-25 02:57:58674 RenderbufferManager* renderbuffer_manager() {
675 return group_->renderbuffer_manager();
676 }
677
678 FramebufferManager* framebuffer_manager() {
679 return group_->framebuffer_manager();
680 }
681
[email protected]3916c97e2010-02-25 03:20:50682 ProgramManager* program_manager() {
683 return group_->program_manager();
684 }
685
686 ShaderManager* shader_manager() {
687 return group_->shader_manager();
688 }
689
[email protected]29a4d902013-02-26 20:18:06690 const TextureManager* texture_manager() const {
691 return group_->texture_manager();
692 }
693
[email protected]3916c97e2010-02-25 03:20:50694 TextureManager* texture_manager() {
695 return group_->texture_manager();
696 }
697
[email protected]78b514b2012-05-01 21:50:59698 MailboxManager* mailbox_manager() {
699 return group_->mailbox_manager();
700 }
701
[email protected]09d50362012-10-18 20:54:37702 ImageManager* image_manager() {
703 return group_->image_manager();
704 }
705
[email protected]944b62f32012-09-27 02:20:46706 VertexArrayManager* vertex_array_manager() {
707 return vertex_array_manager_.get();
708 }
709
[email protected]7989c9e2013-01-23 06:39:26710 MemoryTracker* memory_tracker() {
711 return group_->memory_tracker();
712 }
713
[email protected]4f9958142013-07-02 03:58:07714 StreamTextureManager* stream_texture_manager() const {
715 return group_->stream_texture_manager();
716 }
717
[email protected]7989c9e2013-01-23 06:39:26718 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
719 MemoryTracker* tracker = memory_tracker();
720 if (tracker) {
721 return tracker->EnsureGPUMemoryAvailable(estimated_size);
722 }
723 return true;
724 }
725
[email protected]34ff8b0c2010-10-01 20:06:02726 bool IsOffscreenBufferMultisampled() const {
727 return offscreen_target_samples_ > 1;
728 }
729
[email protected]ed9f9cd2013-02-27 21:12:35730 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49731 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03732 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35733 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47734 }
735
736 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49737 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07738 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47739 }
740
741 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35742 void RemoveTexture(GLuint client_id) {
743 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50744 }
[email protected]a93bb842010-02-16 23:03:47745
[email protected]d37231fa2010-04-09 21:16:02746 // Get the size (in pixels) of the currently bound frame buffer (either FBO
747 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30748 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02749
[email protected]9edc6b22010-12-23 02:00:26750 // Get the format of the currently bound frame buffer (either FBO or regular
751 // back buffer)
752 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46753 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26754
[email protected]a93bb842010-02-16 23:03:47755 // Wrapper for CompressedTexImage2D commands.
756 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37757 GLenum target,
758 GLint level,
759 GLenum internal_format,
760 GLsizei width,
761 GLsizei height,
762 GLint border,
763 GLsizei image_size,
764 const void* data);
[email protected]a93bb842010-02-16 23:03:47765
[email protected]cadde4a2010-07-31 17:10:43766 // Wrapper for CompressedTexSubImage2D.
767 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37768 GLenum target,
769 GLint level,
770 GLint xoffset,
771 GLint yoffset,
772 GLsizei width,
773 GLsizei height,
774 GLenum format,
775 GLsizei imageSize,
776 const void * data);
[email protected]cadde4a2010-07-31 17:10:43777
778 // Wrapper for CopyTexImage2D.
779 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37780 GLenum target,
781 GLint level,
782 GLenum internal_format,
783 GLint x,
784 GLint y,
785 GLsizei width,
786 GLsizei height,
787 GLint border);
[email protected]cadde4a2010-07-31 17:10:43788
[email protected]6d792ee12013-05-15 00:40:56789 // Wrapper for SwapBuffers.
790 void DoSwapBuffers();
791
[email protected]cadde4a2010-07-31 17:10:43792 // Wrapper for CopyTexSubImage2D.
793 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37794 GLenum target,
795 GLint level,
796 GLint xoffset,
797 GLint yoffset,
798 GLint x,
799 GLint y,
800 GLsizei width,
801 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43802
[email protected]f598f422012-12-07 08:30:03803 // Validation for TexSubImage2D.
804 bool ValidateTexSubImage2D(
805 error::Error* error,
806 const char* function_name,
807 GLenum target,
808 GLint level,
809 GLint xoffset,
810 GLint yoffset,
811 GLsizei width,
812 GLsizei height,
813 GLenum format,
814 GLenum type,
815 const void * data);
816
[email protected]cadde4a2010-07-31 17:10:43817 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03818 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37819 GLenum target,
820 GLint level,
821 GLint xoffset,
822 GLint yoffset,
823 GLsizei width,
824 GLsizei height,
825 GLenum format,
826 GLenum type,
827 const void * data);
[email protected]cadde4a2010-07-31 17:10:43828
[email protected]32145a92012-12-17 09:01:59829 // Extra validation for async tex(Sub)Image2D.
830 bool ValidateAsyncTransfer(
831 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47832 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59833 GLenum target,
834 GLint level,
835 const void * data);
836
[email protected]e51bdf32011-11-23 22:21:46837 // Wrapper for TexImageIOSurface2DCHROMIUM.
838 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37839 GLenum target,
840 GLsizei width,
841 GLsizei height,
842 GLuint io_surface_id,
843 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46844
[email protected]43410e92012-04-20 17:06:28845 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37846 GLenum target,
847 GLuint source_id,
848 GLuint target_id,
849 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54850 GLenum internal_format,
851 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28852
[email protected]97dc7cbe2011-12-06 17:26:17853 // Wrapper for TexStorage2DEXT.
854 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37855 GLenum target,
856 GLint levels,
857 GLenum internal_format,
858 GLsizei width,
859 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17860
[email protected]78b514b2012-05-01 21:50:59861 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
862 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
863
[email protected]09d50362012-10-18 20:54:37864 void DoBindTexImage2DCHROMIUM(
865 GLenum target,
866 GLint image_id);
867 void DoReleaseTexImage2DCHROMIUM(
868 GLenum target,
869 GLint image_id);
870
[email protected]94307712012-11-16 23:26:11871 void DoTraceEndCHROMIUM(void);
872
[email protected]2f143d482013-03-14 18:04:49873 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
874
[email protected]ed9f9cd2013-02-27 21:12:35875 // Creates a Program for the given program.
876 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57877 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35878 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47879 }
880
[email protected]07f54fcc2009-12-22 02:46:30881 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35882 Program* GetProgram(GLuint client_id) {
883 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46884 }
[email protected]07f54fcc2009-12-22 02:46:30885
[email protected]cae20172012-12-07 00:06:19886#if defined(NDEBUG)
887 void LogClientServiceMapping(
888 const char* /* function_name */,
889 GLuint /* client_id */,
890 GLuint /* service_id */) {
891 }
892 template<typename T>
893 void LogClientServiceForInfo(
894 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
895 }
896#else
897 void LogClientServiceMapping(
898 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26899 if (service_logging_) {
[email protected]1d82e822013-04-10 21:32:32900 DLOG(INFO) << "[" << logger_.GetLogPrefix() << "] " << function_name
[email protected]2a22fe72012-12-07 04:21:26901 << ": client_id = " << client_id
902 << ", service_id = " << service_id;
903 }
[email protected]cae20172012-12-07 00:06:19904 }
905 template<typename T>
906 void LogClientServiceForInfo(
907 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26908 if (info) {
[email protected]cae20172012-12-07 00:06:19909 LogClientServiceMapping(function_name, client_id, info->service_id());
910 }
911 }
912#endif
913
[email protected]6b8cf1a2010-05-06 16:13:58914 // Gets the program info for the given program. If it's not a program
915 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35916 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58917 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42918 Program* program = GetProgram(client_id);
919 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35920 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51921 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43922 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58923 } else {
[email protected]ab09b612013-03-11 22:11:51924 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58925 }
926 }
[email protected]df37b9932013-03-08 05:21:42927 LogClientServiceForInfo(program, client_id, function_name);
928 return program;
[email protected]6b8cf1a2010-05-06 16:13:58929 }
930
931
[email protected]ed9f9cd2013-02-27 21:12:35932 // Creates a Shader for the given shader.
933 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57934 GLuint client_id,
935 GLuint service_id,
936 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:35937 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:57938 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31939 }
940
941 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35942 Shader* GetShader(GLuint client_id) {
943 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:31944 }
945
[email protected]6b8cf1a2010-05-06 16:13:58946 // Gets the shader info for the given shader. If it's not a shader generates a
947 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:35948 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:58949 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42950 Shader* shader = GetShader(client_id);
951 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:35952 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:51953 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43954 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58955 } else {
[email protected]ab09b612013-03-11 22:11:51956 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43957 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58958 }
959 }
[email protected]df37b9932013-03-08 05:21:42960 LogClientServiceForInfo(shader, client_id, function_name);
961 return shader;
[email protected]6b8cf1a2010-05-06 16:13:58962 }
963
[email protected]a93bb842010-02-16 23:03:47964 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:35965 void CreateBuffer(GLuint client_id, GLuint service_id) {
966 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47967 }
968
[email protected]07f54fcc2009-12-22 02:46:30969 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:21970 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:07971 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
972 return buffer;
[email protected]1d32bc82010-01-13 22:06:46973 }
[email protected]07f54fcc2009-12-22 02:46:30974
[email protected]a93bb842010-02-16 23:03:47975 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
976 // on glDeleteBuffers so we can make sure the user does not try to render
977 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:35978 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:47979
[email protected]a25fa872010-03-25 02:57:58980 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35981 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
982 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58983 }
984
985 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:06986 Framebuffer* GetFramebuffer(GLuint client_id) {
987 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58988 }
989
990 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35991 void RemoveFramebuffer(GLuint client_id) {
992 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58993 }
994
995 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:35996 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
997 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:03998 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58999 }
1000
1001 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271002 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1003 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581004 }
1005
1006 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351007 void RemoveRenderbuffer(GLuint client_id) {
1008 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581009 }
1010
[email protected]944b62f32012-09-27 02:20:461011 // Gets the vertex attrib manager for the given vertex array.
1012 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1013 VertexAttribManager* info =
1014 vertex_array_manager()->GetVertexAttribManager(client_id);
1015 return info;
1016 }
1017
1018 // Removes the vertex attrib manager for the given vertex array.
1019 void RemoveVertexAttribManager(GLuint client_id) {
1020 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1021 }
1022
1023 // Creates a vertex attrib manager for the given vertex array.
1024 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1025 return vertex_array_manager()->CreateVertexAttribManager(
1026 client_id, service_id, group_->max_vertex_attribs());
1027 }
1028
[email protected]258a3313f2011-10-18 20:13:571029 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331030 void DoBindUniformLocationCHROMIUM(
1031 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571032
[email protected]558847a2010-03-24 07:02:541033 error::Error GetAttribLocationHelper(
1034 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1035 const std::string& name_str);
1036
1037 error::Error GetUniformLocationHelper(
1038 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1039 const std::string& name_str);
1040
[email protected]3916c97e2010-02-25 03:20:501041 // Helper for glShaderSource.
1042 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031043 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301044
[email protected]0d6bfdc2011-11-02 01:32:201045 // Clear any textures used by the current program.
1046 bool ClearUnclearedTextures();
1047
1048 // Clear any uncleared level in texture.
1049 // Returns false if there was a generated GL error.
[email protected]02965c22013-03-09 02:40:071050 bool ClearTexture(Texture* texture);
[email protected]0d6bfdc2011-11-02 01:32:201051
1052 // Clears any uncleared attachments attached to the given frame buffer.
1053 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061054 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281055
[email protected]0d6bfdc2011-11-02 01:32:201056 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001057 virtual bool ClearLevel(unsigned service_id,
1058 unsigned bind_target,
1059 unsigned target,
1060 int level,
1061 unsigned format,
1062 unsigned type,
1063 int width,
1064 int height,
1065 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201066
[email protected]c007aa02010-09-02 22:22:401067 // Restore all GL state that affects clearing.
1068 void RestoreClearState();
1069
[email protected]3a2e7c7b2010-08-06 01:12:281070 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461071 // Returns: true if glEnable/glDisable should actually be called.
1072 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281073
[email protected]0d6bfdc2011-11-02 01:32:201074 // Check that the currently bound framebuffers are valid.
1075 // Generates GL error if not.
1076 bool CheckBoundFramebuffersValid(const char* func_name);
1077
1078 // Check if a framebuffer meets our requirements.
1079 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351080 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201081 GLenum target,
1082 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271083
[email protected]939e7362010-05-13 20:49:101084 // Checks if the current program exists and is valid. If not generates the
1085 // appropriate GL error. Returns true if the current program is in a usable
1086 // state.
1087 bool CheckCurrentProgram(const char* function_name);
1088
1089 // Checks if the current program exists and is valid and that location is not
1090 // -1. If the current program is not valid generates the appropriate GL
1091 // error. Returns true if the current program is in a usable state and
1092 // location is not -1.
1093 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1094
1095 // Gets the type of a uniform for a location in the current program. Sets GL
1096 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361097 // program is valid and the location exists. Adjusts count so it
1098 // does not overflow the uniform.
1099 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121100 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521101 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121102 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101103
[email protected]b177ae22011-11-01 03:29:111104 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021105 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111106
[email protected]b273e432010-04-12 17:23:581107 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1108 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1109
[email protected]ac77603c72013-03-08 13:52:061110 // Helper for glGetVertexAttrib
1111 void GetVertexAttribHelper(
1112 const VertexAttrib* attrib, GLenum pname, GLint* param);
1113
[email protected]96449d2c2009-11-25 00:01:321114 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031115 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321116
1117 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031118 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321119
[email protected]3916c97e2010-02-25 03:20:501120 // Wrapper for glActiveTexture
1121 void DoActiveTexture(GLenum texture_unit);
1122
[email protected]ae51d192010-04-27 00:48:031123 // Wrapper for glAttachShader
1124 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1125
[email protected]96449d2c2009-11-25 00:01:321126 // Wrapper for glBindBuffer since we need to track the current targets.
1127 void DoBindBuffer(GLenum target, GLuint buffer);
1128
[email protected]86093972010-03-11 00:13:561129 // Wrapper for glBindFramebuffer since we need to track the current targets.
1130 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1131
1132 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1133 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1134
[email protected]a93bb842010-02-16 23:03:471135 // Wrapper for glBindTexture since we need to track the current targets.
1136 void DoBindTexture(GLenum target, GLuint texture);
1137
[email protected]944b62f32012-09-27 02:20:461138 // Wrapper for glBindVertexArrayOES
1139 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571140 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461141
[email protected]8e3e0662010-08-23 18:46:301142 // Wrapper for glBlitFramebufferEXT.
1143 void DoBlitFramebufferEXT(
1144 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1145 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1146 GLbitfield mask, GLenum filter);
1147
[email protected]36cef8ce2010-03-16 07:34:451148 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111149 void DoBufferSubData(
1150 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1151
[email protected]36cef8ce2010-03-16 07:34:451152 // Wrapper for glCheckFramebufferStatus
1153 GLenum DoCheckFramebufferStatus(GLenum target);
1154
[email protected]3a03a8f2011-03-19 00:51:271155 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081156 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271157
[email protected]88a61bf2012-10-27 13:00:421158 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421159 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251160 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281161
[email protected]45bf5152010-02-12 00:11:311162 // Wrapper for glCompileShader.
1163 void DoCompileShader(GLuint shader);
1164
[email protected]269200b12010-11-18 22:53:061165 // Helper for DeleteSharedIdsCHROMIUM commands.
1166 void DoDeleteSharedIdsCHROMIUM(
1167 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101168
[email protected]ae51d192010-04-27 00:48:031169 // Wrapper for glDetachShader
1170 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1171
[email protected]3a2e7c7b2010-08-06 01:12:281172 // Wrapper for glDisable
1173 void DoDisable(GLenum cap);
1174
[email protected]07f54fcc2009-12-22 02:46:301175 // Wrapper for glDisableVertexAttribArray.
1176 void DoDisableVertexAttribArray(GLuint index);
1177
[email protected]60f22d32012-12-12 00:31:581178 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1179 // attachments.
1180 void DoDiscardFramebufferEXT(GLenum target,
1181 GLsizei numAttachments,
1182 const GLenum* attachments);
1183
[email protected]3a2e7c7b2010-08-06 01:12:281184 // Wrapper for glEnable
1185 void DoEnable(GLenum cap);
1186
[email protected]07f54fcc2009-12-22 02:46:301187 // Wrapper for glEnableVertexAttribArray.
1188 void DoEnableVertexAttribArray(GLuint index);
1189
[email protected]882ba1e22012-03-08 19:02:531190 // Wrapper for glFinish.
1191 void DoFinish();
1192
1193 // Wrapper for glFlush.
1194 void DoFlush();
1195
[email protected]36cef8ce2010-03-16 07:34:451196 // Wrapper for glFramebufferRenderbufffer.
1197 void DoFramebufferRenderbuffer(
1198 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1199 GLuint renderbuffer);
1200
1201 // Wrapper for glFramebufferTexture2D.
1202 void DoFramebufferTexture2D(
1203 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1204 GLint level);
1205
[email protected]7d3c36e2013-07-12 14:13:161206 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1207 void DoFramebufferTexture2DMultisample(
1208 GLenum target, GLenum attachment, GLenum textarget,
1209 GLuint texture, GLint level, GLsizei samples);
1210
1211 // Common implementation for both DoFramebufferTexture2D wrappers.
1212 void DoFramebufferTexture2DCommon(const char* name,
1213 GLenum target, GLenum attachment, GLenum textarget,
1214 GLuint texture, GLint level, GLsizei samples);
1215
[email protected]a93bb842010-02-16 23:03:471216 // Wrapper for glGenerateMipmap
1217 void DoGenerateMipmap(GLenum target);
1218
[email protected]269200b12010-11-18 22:53:061219 // Helper for GenSharedIdsCHROMIUM commands.
1220 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101221 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1222
[email protected]7d3c36e2013-07-12 14:13:161223 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1224 // to account for different pname values defined in different extension
1225 // variants.
1226 GLenum AdjustGetPname(GLenum pname);
1227
[email protected]b273e432010-04-12 17:23:581228 // Wrapper for DoGetBooleanv.
1229 void DoGetBooleanv(GLenum pname, GLboolean* params);
1230
1231 // Wrapper for DoGetFloatv.
1232 void DoGetFloatv(GLenum pname, GLfloat* params);
1233
[email protected]36cef8ce2010-03-16 07:34:451234 // Wrapper for glGetFramebufferAttachmentParameteriv.
1235 void DoGetFramebufferAttachmentParameteriv(
1236 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1237
[email protected]a0c3e972010-04-21 00:49:131238 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581239 void DoGetIntegerv(GLenum pname, GLint* params);
1240
[email protected]29a9eb52010-04-13 09:04:231241 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061242 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231243 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1244
[email protected]17cfbe0e2013-03-07 01:26:081245 // Wrapper for glGetBufferParameteriv.
1246 void DoGetBufferParameteriv(
1247 GLenum target, GLenum pname, GLint* params);
1248
[email protected]a0c3e972010-04-21 00:49:131249 // Wrapper for glGetProgramiv.
1250 void DoGetProgramiv(
1251 GLuint program_id, GLenum pname, GLint* params);
1252
[email protected]36cef8ce2010-03-16 07:34:451253 // Wrapper for glRenderbufferParameteriv.
1254 void DoGetRenderbufferParameteriv(
1255 GLenum target, GLenum pname, GLint* params);
1256
[email protected]ddd968b82010-03-02 00:44:291257 // Wrapper for glGetShaderiv
1258 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1259
[email protected]b1122982010-05-17 23:04:241260 // Wrappers for glGetVertexAttrib.
1261 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1262 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1263
[email protected]1958e0e2010-04-22 05:17:151264 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241265 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151266 bool DoIsBuffer(GLuint client_id);
1267 bool DoIsFramebuffer(GLuint client_id);
1268 bool DoIsProgram(GLuint client_id);
1269 bool DoIsRenderbuffer(GLuint client_id);
1270 bool DoIsShader(GLuint client_id);
1271 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461272 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151273
[email protected]07f54fcc2009-12-22 02:46:301274 // Wrapper for glLinkProgram
1275 void DoLinkProgram(GLuint program);
1276
[email protected]269200b12010-11-18 22:53:061277 // Helper for RegisterSharedIdsCHROMIUM.
1278 void DoRegisterSharedIdsCHROMIUM(
1279 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101280
[email protected]36cef8ce2010-03-16 07:34:451281 // Wrapper for glRenderbufferStorage.
1282 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031283 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451284
[email protected]8e3e0662010-08-23 18:46:301285 // Wrapper for glRenderbufferStorageMultisampleEXT.
1286 void DoRenderbufferStorageMultisample(
1287 GLenum target, GLsizei samples, GLenum internalformat,
1288 GLsizei width, GLsizei height);
1289
[email protected]b273e432010-04-12 17:23:581290 // Wrapper for glReleaseShaderCompiler.
1291 void DoReleaseShaderCompiler() { }
1292
[email protected]3916c97e2010-02-25 03:20:501293 // Wrappers for glTexParameter functions.
1294 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1295 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1296 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1297 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1298
1299 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1300 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121301 void DoUniform1i(GLint fake_location, GLint v0);
1302 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1303 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1304 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1305 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101306
1307 // Wrappers for glUniformfv because some drivers don't correctly accept
1308 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121309 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1310 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1311 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1312 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501313
[email protected]43c2f1f2011-03-25 18:35:361314 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121315 GLint fake_location, GLsizei count, GLboolean transpose,
1316 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361317 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121318 GLint fake_location, GLsizei count, GLboolean transpose,
1319 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361320 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121321 GLint fake_location, GLsizei count, GLboolean transpose,
1322 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361323
[email protected]af6380962012-11-29 23:24:131324 bool SetVertexAttribValue(
1325 const char* function_name, GLuint index, const GLfloat* value);
1326
[email protected]b1122982010-05-17 23:04:241327 // Wrappers for glVertexAttrib??
1328 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1329 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1330 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1331 void DoVertexAttrib4f(
1332 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1333 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1334 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1335 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1336 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1337
[email protected]43410e92012-04-20 17:06:281338 // Wrapper for glViewport
1339 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1340
[email protected]07f54fcc2009-12-22 02:46:301341 // Wrapper for glUseProgram
1342 void DoUseProgram(GLuint program);
1343
[email protected]ae51d192010-04-27 00:48:031344 // Wrapper for glValidateProgram.
1345 void DoValidateProgram(GLuint program_client_id);
1346
[email protected]d2a0e1a2012-08-12 02:25:011347 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1348 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1349 void DoPopGroupMarkerEXT(void);
1350
[email protected]4e8a5b122010-05-08 22:00:101351 // Gets the number of values that will be returned by glGetXXX. Returns
1352 // false if pname is unknown.
1353 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1354
[email protected]07f54fcc2009-12-22 02:46:301355 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431356 bool IsDrawValid(
1357 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301358
[email protected]c13e1da62011-09-09 21:48:301359 // Returns true if successful, simulated will be true if attrib0 was
1360 // simulated.
[email protected]c6aef902012-02-14 03:31:421361 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431362 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281363 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241364
[email protected]e56131d22013-07-28 16:14:111365 // If texture is a stream texture, this will update the stream to the newest
1366 // buffer.
1367 void UpdateStreamTextureIfNeeded(Texture* texture);
1368
1369 // Returns false if unrenderable textures were replaced.
1370 bool PrepareTexturesForRender();
[email protected]3916c97e2010-02-25 03:20:501371 void RestoreStateForNonRenderableTextures();
1372
[email protected]8fbedc02010-11-18 18:43:401373 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421374 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431375 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421376 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401377 void RestoreStateForSimulatedFixedAttribs();
1378
[email protected]c6aef902012-02-14 03:31:421379 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1380 // cases (primcount is 0 for non-instanced).
1381 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431382 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421383 bool instanced, GLenum mode, GLint first, GLsizei count,
1384 GLsizei primcount);
1385 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431386 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421387 bool instanced, GLenum mode, GLsizei count, GLenum type,
1388 int32 offset, GLsizei primcount);
1389
[email protected]61eeb33f2011-07-26 15:30:311390 GLenum GetBindTargetForSamplerType(GLenum type) {
1391 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461392 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1393 switch (type) {
1394 case GL_SAMPLER_2D:
1395 return GL_TEXTURE_2D;
1396 case GL_SAMPLER_CUBE:
1397 return GL_TEXTURE_CUBE_MAP;
1398 case GL_SAMPLER_EXTERNAL_OES:
1399 return GL_TEXTURE_EXTERNAL_OES;
1400 case GL_SAMPLER_2D_RECT_ARB:
1401 return GL_TEXTURE_RECTANGLE_ARB;
1402 }
1403
1404 NOTREACHED();
1405 return 0;
[email protected]61eeb33f2011-07-26 15:30:311406 }
1407
[email protected]8e3e0662010-08-23 18:46:301408 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061409 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1410 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301411 switch (target) {
1412 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451413 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]7cd76fd2013-06-02 21:11:111414 framebuffer = state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301415 break;
[email protected]ebfb73c2012-08-15 02:37:451416 case GL_READ_FRAMEBUFFER_EXT:
[email protected]7cd76fd2013-06-02 21:11:111417 framebuffer = state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301418 break;
1419 default:
1420 NOTREACHED();
1421 break;
1422 }
[email protected]4d8f0dd2013-03-09 14:37:061423 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301424 }
1425
[email protected]ed9f9cd2013-02-27 21:12:351426 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201427 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271428 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201429 switch (target) {
1430 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111431 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201432 break;
1433 default:
1434 NOTREACHED();
1435 break;
1436 }
[email protected]ee2a79c32013-03-10 03:50:271437 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201438 }
1439
[email protected]f7b85372010-02-03 01:11:371440 // Validates the program and location for a glGetUniform call and returns
1441 // a SizeResult setup to receive the result. Returns true if glGetUniform
1442 // should be called.
1443 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121444 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371445 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121446 error::Error* error, GLint* real_location, GLuint* service_id,
1447 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371448
[email protected]1078f912011-12-23 13:12:141449 // Computes the estimated memory used for the backbuffer and passes it to
1450 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531451 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141452
[email protected]a10b4a02012-11-26 23:09:501453 virtual bool WasContextLost() OVERRIDE;
[email protected]93a7d98f2013-07-11 00:04:221454 virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091455 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431456
[email protected]e51bdf32011-11-23 22:21:461457#if defined(OS_MACOSX)
1458 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1459#endif
1460
[email protected]81375742012-06-08 00:04:001461 // Validates the combination of texture parameters. For example validates that
1462 // for a given format the specific type, level and targets are valid.
1463 // Synthesizes the correct GL error if invalid. Returns true if valid.
1464 bool ValidateTextureParameters(
1465 const char* function_name,
1466 GLenum target, GLenum format, GLenum type, GLint level);
1467
[email protected]ad84a3a2012-06-08 21:42:431468 bool ValidateCompressedTexDimensions(
1469 const char* function_name,
1470 GLint level, GLsizei width, GLsizei height, GLenum format);
1471 bool ValidateCompressedTexFuncData(
1472 const char* function_name,
1473 GLsizei width, GLsizei height, GLenum format, size_t size);
1474 bool ValidateCompressedTexSubDimensions(
1475 const char* function_name,
1476 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1477 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351478 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431479
[email protected]ab09b612013-03-11 22:11:511480 void RenderWarning(const char* filename, int line, const std::string& msg);
1481 void PerformanceWarning(
1482 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011483
[email protected]62e155e2012-10-23 22:43:151484 const FeatureInfo::FeatureFlags& features() const {
1485 return feature_info_->feature_flags();
1486 }
1487
1488 const FeatureInfo::Workarounds& workarounds() const {
1489 return feature_info_->workarounds();
1490 }
1491
[email protected]a7266a92012-06-28 02:11:081492 bool ShouldDeferDraws() {
1493 return !offscreen_target_frame_buffer_.get() &&
[email protected]7cd76fd2013-06-02 21:11:111494 state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081495 surface_->DeferDraws();
1496 }
1497
[email protected]09e17272012-11-30 10:30:441498 bool ShouldDeferReads() {
1499 return !offscreen_target_frame_buffer_.get() &&
[email protected]7cd76fd2013-06-02 21:11:111500 state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441501 surface_->DeferDraws();
1502 }
1503
[email protected]5a36dc132013-07-23 23:17:551504 void ProcessPendingReadPixels();
1505 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1506
[email protected]96449d2c2009-11-25 00:01:321507 // Generate a member function prototype for each command in an automated and
1508 // typesafe way.
1509 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141510 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351511 uint32 immediate_data_size, \
1512 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321513
1514 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1515
1516 #undef GLES2_CMD_OP
1517
[email protected]2f2d7042010-04-14 21:45:581518 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381519 scoped_refptr<gfx::GLSurface> surface_;
1520 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021521
[email protected]a3ded6d2010-10-19 06:44:391522 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351523 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391524
[email protected]1d82e822013-04-10 21:32:321525 DebugMarkerManager debug_marker_manager_;
1526 Logger logger_;
1527
[email protected]e259eb412012-10-13 05:47:241528 // All the state for this context.
1529 ContextState state_;
1530
[email protected]34ff8b0c2010-10-01 20:06:021531 // Current width and height of the offscreen frame buffer.
1532 gfx::Size offscreen_size_;
1533
[email protected]96449d2c2009-11-25 00:01:321534 // Util to help with GL.
1535 GLES2Util util_;
1536
[email protected]43410e92012-04-20 17:06:281537 // unpack flip y as last set by glPixelStorei
1538 bool unpack_flip_y_;
1539
[email protected]6c75c712012-06-19 15:43:171540 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281541 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171542 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281543
[email protected]944b62f32012-09-27 02:20:461544 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351545 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301546
[email protected]b1122982010-05-17 23:04:241547 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1548 GLuint attrib_0_buffer_id_;
1549
1550 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131551 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241552
[email protected]fc753442011-02-04 19:49:491553 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1554 bool attrib_0_buffer_matches_value_;
1555
[email protected]b1122982010-05-17 23:04:241556 // The size of attrib 0.
1557 GLsizei attrib_0_size_;
1558
[email protected]8fbedc02010-11-18 18:43:401559 // The buffer used to simulate GL_FIXED attribs.
1560 GLuint fixed_attrib_buffer_id_;
1561
1562 // The size of fiixed attrib buffer.
1563 GLsizei fixed_attrib_buffer_size_;
1564
[email protected]b9363b22010-06-09 22:06:151565 // The offscreen frame buffer that the client renders to. With EGL, the
1566 // depth and stencil buffers are separate. With regular GL there is a single
1567 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1568 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351569 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1570 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1571 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1572 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1573 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021574 GLenum offscreen_target_color_format_;
1575 GLenum offscreen_target_depth_format_;
1576 GLenum offscreen_target_stencil_format_;
1577 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561578 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351579
[email protected]de26b3c2011-08-03 21:54:271580 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351581 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1582 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491583 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351584 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271585
1586 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351587 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1588 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051589 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351590
[email protected]882ba1e22012-03-08 19:02:531591 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531592
[email protected]944b62f32012-09-27 02:20:461593 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1594
[email protected]729c0b42013-05-26 02:05:071595 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001596
[email protected]840a7e462013-02-27 01:29:511597 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481598
[email protected]e3932abb2013-03-13 00:01:371599 ShaderCacheCallback shader_cache_callback_;
1600
[email protected]85a4ac22013-05-31 01:58:471601 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421602
[email protected]32fe9aa2011-01-21 23:47:131603 // The format of the back buffer_
1604 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461605 bool back_buffer_has_depth_;
1606 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131607
[email protected]60f22d32012-12-12 00:31:581608 // Backbuffer attachments that are currently undefined.
1609 uint32 backbuffer_needs_clear_bits_;
1610
[email protected]a3a93e7b2010-08-28 00:48:561611 // The current decoder error.
1612 error::Error current_decoder_error_;
1613
[email protected]b1d2dcb2010-05-17 19:24:181614 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041615 scoped_refptr<ShaderTranslator> vertex_translator_;
1616 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181617
[email protected]e82fb792011-09-22 00:33:291618 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411619
[email protected]915a59a12010-09-30 21:29:111620 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051621 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351622 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051623
[email protected]65225772011-05-12 21:10:241624 int frame_number_;
1625
[email protected]706b69f2012-07-27 04:59:301626 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431627 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221628 bool reset_by_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431629
[email protected]f0d74742011-10-03 16:31:041630 // These flags are used to override the state of the shared feature_info_
1631 // member. Because the same FeatureInfo instance may be shared among many
1632 // contexts, the assumptions on the availablity of extensions in WebGL
1633 // contexts may be broken. These flags override the shared state to preserve
1634 // WebGL semantics.
1635 bool force_webgl_glsl_validation_;
1636 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491637 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131638 bool draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041639
[email protected]062c38b2012-01-18 03:25:101640 bool compile_shader_always_succeeds_;
1641
[email protected]cae20172012-12-07 00:06:191642 // Log extra info.
1643 bool service_logging_;
1644
[email protected]e51bdf32011-11-23 22:21:461645#if defined(OS_MACOSX)
1646 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1647 TextureToIOSurfaceMap texture_to_io_surface_map_;
1648#endif
1649
[email protected]43410e92012-04-20 17:06:281650 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1651
[email protected]1868a342012-11-07 15:56:021652 // Cached values of the currently assigned viewport dimensions.
1653 GLsizei viewport_max_width_;
1654 GLsizei viewport_max_height_;
1655
[email protected]63b465922012-09-06 02:04:521656 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521657 base::TimeDelta total_processing_commands_time_;
1658
[email protected]c986af502013-08-14 01:04:441659 // States related to each manager.
1660 DecoderTextureState texture_state_;
1661 DecoderFramebufferState framebuffer_state_;
1662
[email protected]fb97b662013-02-20 23:02:141663 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]94307712012-11-16 23:26:111664
[email protected]5a36dc132013-07-23 23:17:551665 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1666
[email protected]96449d2c2009-11-25 00:01:321667 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1668};
1669
[email protected]ab09b612013-03-11 22:11:511670ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
1671 const char* function_name, GLES2DecoderImpl* decoder)
1672 : function_name_(function_name),
1673 decoder_(decoder) {
[email protected]d3eba342013-04-18 21:11:501674 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(),
1675 function_name_);
[email protected]6217d392010-03-25 22:08:351676}
1677
1678ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]d3eba342013-04-18 21:11:501679 ERRORSTATE_CLEAR_REAL_GL_ERRORS(decoder_->GetErrorState(), function_name_);
[email protected]6217d392010-03-25 22:08:351680}
1681
1682ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1683 GLuint id)
1684 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511685 ScopedGLErrorSuppressor suppressor(
1686 "ScopedTexture2DBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351687
1688 // TODO(apatrick): Check if there are any other states that need to be reset
1689 // before binding a new texture.
1690 glActiveTexture(GL_TEXTURE0);
1691 glBindTexture(GL_TEXTURE_2D, id);
1692}
1693
1694ScopedTexture2DBinder::~ScopedTexture2DBinder() {
[email protected]ab09b612013-03-11 22:11:511695 ScopedGLErrorSuppressor suppressor(
1696 "ScopedTexture2DBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301697 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351698}
1699
1700ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1701 GLuint id)
1702 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511703 ScopedGLErrorSuppressor suppressor(
1704 "ScopedRenderBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351705 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1706}
1707
1708ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511709 ScopedGLErrorSuppressor suppressor(
1710 "ScopedRenderBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301711 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351712}
1713
1714ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1715 GLuint id)
1716 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511717 ScopedGLErrorSuppressor suppressor(
1718 "ScopedFrameBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351719 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451720 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351721}
1722
1723ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511724 ScopedGLErrorSuppressor suppressor(
1725 "ScopedFrameBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301726 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351727}
1728
[email protected]34ff8b0c2010-10-01 20:06:021729ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271730 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521731 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021732 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1733 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241734 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521735 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021736 if (!resolve_and_bind_)
1737 return;
1738
[email protected]ab09b612013-03-11 22:11:511739 ScopedGLErrorSuppressor suppressor(
1740 "ScopedResolvedFrameBufferBinder::ctor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021741 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1742 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271743 GLuint targetid;
1744 if (internal) {
1745 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1746 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351747 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271748 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351749 decoder_->offscreen_resolved_color_texture_.reset(
1750 new BackTexture(decoder_));
[email protected]de26b3c2011-08-03 21:54:271751 decoder_->offscreen_resolved_color_texture_->Create();
1752
1753 DCHECK(decoder_->offscreen_saved_color_format_);
1754 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091755 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1756 false);
[email protected]de26b3c2011-08-03 21:54:271757 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1758 decoder_->offscreen_resolved_color_texture_.get());
1759 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1760 GL_FRAMEBUFFER_COMPLETE) {
1761 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1762 << "because offscreen resolved FBO was incomplete.";
1763 return;
1764 }
1765 }
1766 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1767 } else {
1768 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1769 }
1770 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021771 const int width = decoder_->offscreen_size_.width();
1772 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181773 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151774 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021775 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1776 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1777 } else {
1778 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1779 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1780 }
[email protected]de26b3c2011-08-03 21:54:271781 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021782}
1783
1784ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1785 if (!resolve_and_bind_)
1786 return;
1787
[email protected]ab09b612013-03-11 22:11:511788 ScopedGLErrorSuppressor suppressor(
1789 "ScopedResolvedFrameBufferBinder::dtor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021790 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221791 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181792 glEnable(GL_SCISSOR_TEST);
1793 }
[email protected]34ff8b0c2010-10-01 20:06:021794}
1795
[email protected]ed9f9cd2013-02-27 21:12:351796BackTexture::BackTexture(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351797 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261798 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481799 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251800 id_(0) {
[email protected]6217d392010-03-25 22:08:351801}
1802
[email protected]ed9f9cd2013-02-27 21:12:351803BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351804 // This does not destroy the render texture because that would require that
1805 // the associated GL context was current. Just check that it was explicitly
1806 // destroyed.
1807 DCHECK_EQ(id_, 0u);
1808}
1809
[email protected]ed9f9cd2013-02-27 21:12:351810void BackTexture::Create() {
[email protected]ab09b612013-03-11 22:11:511811 ScopedGLErrorSuppressor suppressor("BackTexture::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351812 Destroy();
1813 glGenTextures(1, &id_);
[email protected]3a4d0c52011-06-29 23:11:581814 ScopedTexture2DBinder binder(decoder_, id_);
1815 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1816 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1817 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1818 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161819
1820 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1821 // never called on an offscreen context, no data will ever be uploaded to the
1822 // saved offscreen color texture (it is deferred until to when SwapBuffers
1823 // is called). My idea is that some nvidia drivers might have a bug where
1824 // deleting a texture that has never been populated might cause a
1825 // crash.
1826 glTexImage2D(
1827 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481828
1829 bytes_allocated_ = 16u * 16u * 4u;
1830 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351831}
1832
[email protected]ed9f9cd2013-02-27 21:12:351833bool BackTexture::AllocateStorage(
1834 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351835 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511836 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351837 ScopedTexture2DBinder binder(decoder_, id_);
[email protected]678a73f2012-12-19 19:22:091838 uint32 image_size = 0;
1839 GLES2Util::ComputeImageDataSizes(
1840 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1841 NULL, NULL);
1842
[email protected]7989c9e2013-01-23 06:39:261843 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
1844 return false;
1845 }
1846
[email protected]40d90a22013-04-09 03:39:551847 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:091848 if (zero) {
1849 zero_data.reset(new char[image_size]);
1850 memset(zero_data.get(), 0, image_size);
1851 }
[email protected]6217d392010-03-25 22:08:351852
[email protected]8f1d2aa2013-05-10 23:45:381853 glTexImage2D(GL_TEXTURE_2D,
1854 0, // mip level
1855 format,
1856 size.width(),
1857 size.height(),
1858 0, // border
1859 format,
1860 GL_UNSIGNED_BYTE,
1861 zero_data.get());
[email protected]6217d392010-03-25 22:08:351862
[email protected]d37231fa2010-04-09 21:16:021863 size_ = size;
1864
[email protected]1078f912011-12-23 13:12:141865 bool success = glGetError() == GL_NO_ERROR;
1866 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481867 memory_tracker_.TrackMemFree(bytes_allocated_);
1868 bytes_allocated_ = image_size;
1869 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141870 }
1871 return success;
[email protected]6217d392010-03-25 22:08:351872}
1873
[email protected]ed9f9cd2013-02-27 21:12:351874void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351875 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511876 ScopedGLErrorSuppressor suppressor("BackTexture::Copy", decoder_);
[email protected]6217d392010-03-25 22:08:351877 ScopedTexture2DBinder binder(decoder_, id_);
1878 glCopyTexImage2D(GL_TEXTURE_2D,
1879 0, // level
[email protected]3a4d0c52011-06-29 23:11:581880 format,
[email protected]6217d392010-03-25 22:08:351881 0, 0,
1882 size.width(),
1883 size.height(),
1884 0); // border
1885}
1886
[email protected]ed9f9cd2013-02-27 21:12:351887void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:351888 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:511889 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:351890 glDeleteTextures(1, &id_);
1891 id_ = 0;
1892 }
[email protected]68e81a4a62012-12-13 01:16:481893 memory_tracker_.TrackMemFree(bytes_allocated_);
1894 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351895}
1896
[email protected]ed9f9cd2013-02-27 21:12:351897void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:051898 id_ = 0;
1899}
1900
[email protected]ed9f9cd2013-02-27 21:12:351901BackRenderbuffer::BackRenderbuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351902 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261903 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481904 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251905 id_(0) {
[email protected]6217d392010-03-25 22:08:351906}
1907
[email protected]ed9f9cd2013-02-27 21:12:351908BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:351909 // This does not destroy the render buffer because that would require that
1910 // the associated GL context was current. Just check that it was explicitly
1911 // destroyed.
1912 DCHECK_EQ(id_, 0u);
1913}
1914
[email protected]ed9f9cd2013-02-27 21:12:351915void BackRenderbuffer::Create() {
[email protected]ab09b612013-03-11 22:11:511916 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351917 Destroy();
1918 glGenRenderbuffersEXT(1, &id_);
1919}
1920
[email protected]ed9f9cd2013-02-27 21:12:351921bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format,
1922 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:511923 ScopedGLErrorSuppressor suppressor(
1924 "BackRenderbuffer::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351925 ScopedRenderBufferBinder binder(decoder_, id_);
[email protected]7989c9e2013-01-23 06:39:261926
1927 uint32 estimated_size = 0;
1928 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
1929 size.width(), size.height(), samples, format, &estimated_size)) {
1930 return false;
1931 }
1932
1933 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
1934 return false;
1935 }
1936
[email protected]34ff8b0c2010-10-01 20:06:021937 if (samples <= 1) {
1938 glRenderbufferStorageEXT(GL_RENDERBUFFER,
1939 format,
1940 size.width(),
1941 size.height());
1942 } else {
[email protected]57edfdad2012-02-07 04:57:151943 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021944 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
1945 samples,
1946 format,
1947 size.width(),
1948 size.height());
1949 } else {
1950 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
1951 samples,
1952 format,
1953 size.width(),
1954 size.height());
1955 }
1956 }
[email protected]1078f912011-12-23 13:12:141957 bool success = glGetError() == GL_NO_ERROR;
1958 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481959 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:261960 bytes_allocated_ = estimated_size;
[email protected]68e81a4a62012-12-13 01:16:481961 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141962 }
1963 return success;
[email protected]6217d392010-03-25 22:08:351964}
1965
[email protected]ed9f9cd2013-02-27 21:12:351966void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:351967 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:511968 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:351969 glDeleteRenderbuffersEXT(1, &id_);
1970 id_ = 0;
1971 }
[email protected]68e81a4a62012-12-13 01:16:481972 memory_tracker_.TrackMemFree(bytes_allocated_);
1973 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351974}
1975
[email protected]ed9f9cd2013-02-27 21:12:351976void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:051977 id_ = 0;
1978}
1979
[email protected]ed9f9cd2013-02-27 21:12:351980BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351981 : decoder_(decoder),
1982 id_(0) {
1983}
1984
[email protected]ed9f9cd2013-02-27 21:12:351985BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:351986 // This does not destroy the frame buffer because that would require that
1987 // the associated GL context was current. Just check that it was explicitly
1988 // destroyed.
1989 DCHECK_EQ(id_, 0u);
1990}
1991
[email protected]ed9f9cd2013-02-27 21:12:351992void BackFramebuffer::Create() {
[email protected]ab09b612013-03-11 22:11:511993 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351994 Destroy();
1995 glGenFramebuffersEXT(1, &id_);
1996}
1997
[email protected]ed9f9cd2013-02-27 21:12:351998void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:351999 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512000 ScopedGLErrorSuppressor suppressor(
2001 "BackFramebuffer::AttachRenderTexture", decoder_);
[email protected]6217d392010-03-25 22:08:352002 ScopedFrameBufferBinder binder(decoder_, id_);
2003 GLuint attach_id = texture ? texture->id() : 0;
2004 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2005 GL_COLOR_ATTACHMENT0,
2006 GL_TEXTURE_2D,
2007 attach_id,
2008 0);
2009}
2010
[email protected]ed9f9cd2013-02-27 21:12:352011void BackFramebuffer::AttachRenderBuffer(GLenum target,
2012 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352013 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512014 ScopedGLErrorSuppressor suppressor(
2015 "BackFramebuffer::AttachRenderBuffer", decoder_);
[email protected]6217d392010-03-25 22:08:352016 ScopedFrameBufferBinder binder(decoder_, id_);
2017 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2018 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152019 target,
[email protected]6217d392010-03-25 22:08:352020 GL_RENDERBUFFER,
2021 attach_id);
2022}
2023
[email protected]ed9f9cd2013-02-27 21:12:352024void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352025 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512026 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352027 glDeleteFramebuffersEXT(1, &id_);
2028 id_ = 0;
2029 }
2030}
2031
[email protected]ed9f9cd2013-02-27 21:12:352032void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052033 id_ = 0;
2034}
2035
[email protected]ed9f9cd2013-02-27 21:12:352036GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352037 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512038 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", decoder_);
[email protected]6217d392010-03-25 22:08:352039 ScopedFrameBufferBinder binder(decoder_, id_);
2040 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2041}
2042
[email protected]aa7666122011-09-02 19:45:522043GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2044 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322045}
2046
[email protected]aa7666122011-09-02 19:45:522047GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392048 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572049 group_(group),
[email protected]1d82e822013-04-10 21:32:322050 logger_(&debug_marker_manager_),
[email protected]d3eba342013-04-18 21:11:502051 state_(group_->feature_info(), &logger_),
[email protected]43410e92012-04-20 17:06:282052 unpack_flip_y_(false),
2053 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172054 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242055 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492056 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242057 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402058 fixed_attrib_buffer_id_(0),
2059 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022060 offscreen_target_color_format_(0),
2061 offscreen_target_depth_format_(0),
2062 offscreen_target_stencil_format_(0),
2063 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562064 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052065 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132066 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462067 back_buffer_has_depth_(false),
2068 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582069 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562070 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052071 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112072 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002073 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432074 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302075 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512076 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222077 reset_by_robustness_extension_(false),
[email protected]f0d74742011-10-03 16:31:042078 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102079 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492080 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132081 draw_buffers_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282082 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192083 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2084 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022085 viewport_max_width_(0),
[email protected]c986af502013-08-14 01:04:442086 viewport_max_height_(0) {
[email protected]3b1ecc262011-08-03 22:49:572087 DCHECK(group);
2088
[email protected]b1122982010-05-17 23:04:242089 attrib_0_value_.v[0] = 0.0f;
2090 attrib_0_value_.v[1] = 0.0f;
2091 attrib_0_value_.v[2] = 0.0f;
2092 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152093
[email protected]c2f8c8402010-12-06 18:07:242094 // The shader translator is used for WebGL even when running on EGL
2095 // because additional restrictions are needed (like only enabling
2096 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562097 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2098 // the empty string to CompileShader and this is not a valid shader.
2099 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002100 CommandLine::ForCurrentProcess()->HasSwitch(
2101 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152102 use_shader_translator_ = false;
2103 }
[email protected]473c01ccb2011-06-07 01:33:302104
[email protected]a39370652012-09-25 21:52:132105 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:302106 if (IsAngle()) {
[email protected]c986af502013-08-14 01:04:442107 texture_state_.teximage2d_faster_than_texsubimage2d = false;
[email protected]473c01ccb2011-06-07 01:33:302108 }
[email protected]96449d2c2009-11-25 00:01:322109}
2110
[email protected]80eb6b52012-01-19 00:14:412111GLES2DecoderImpl::~GLES2DecoderImpl() {
2112}
2113
[email protected]c410da802011-03-14 19:17:412114bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382115 const scoped_refptr<gfx::GLSurface>& surface,
2116 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232117 bool offscreen,
[email protected]c410da802011-03-14 19:17:412118 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292119 const DisallowedFeatures& disallowed_features,
[email protected]c410da802011-03-14 19:17:412120 const char* allowed_extensions,
[email protected]3c644d82011-06-20 19:58:242121 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322122 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382123 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302124 DCHECK(!context_.get());
2125
[email protected]55e136f2013-04-03 18:50:062126 set_initialized();
[email protected]fb97b662013-02-20 23:02:142127 gpu_tracer_ = GPUTracer::Create();
2128
[email protected]e844ae22012-01-14 03:36:262129 if (CommandLine::ForCurrentProcess()->HasSwitch(
2130 switches::kEnableGPUDebugging)) {
2131 set_debug(true);
2132 }
2133
[email protected]39ba4f02012-03-26 01:16:002134 if (CommandLine::ForCurrentProcess()->HasSwitch(
2135 switches::kEnableGPUCommandLogging)) {
2136 set_log_commands(true);
2137 }
2138
[email protected]062c38b2012-01-18 03:25:102139 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2140 switches::kCompileShaderAlwaysSucceeds);
2141
[email protected]f62a5ab2011-05-23 20:34:152142
[email protected]63c9b052012-05-17 18:27:382143 // Take ownership of the context and surface. The surface can be replaced with
2144 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382145 context_ = context;
[email protected]63c9b052012-05-17 18:27:382146 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182147
[email protected]c4485aad62012-12-17 10:19:092148 if (!group_->Initialize(this, disallowed_features, allowed_extensions)) {
[email protected]09ddb91f2011-04-14 23:16:222149 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392150 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422151 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382152 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032153 return false;
[email protected]a3ded6d2010-10-19 06:44:392154 }
[email protected]b64c24952012-04-19 03:20:272155 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282156
[email protected]e82fb792011-09-22 00:33:292157 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502158
[email protected]af6380962012-11-29 23:24:132159 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462160 default_vertex_attrib_manager_ = new VertexAttribManager();
2161 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2162
[email protected]ab4fd7282012-10-12 16:25:572163 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2164 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322165
[email protected]7cd76fd2013-06-02 21:11:112166 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]944b62f32012-09-27 02:20:462167 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532168
[email protected]302ce6d2011-07-07 23:28:112169 util_.set_num_compressed_texture_formats(
2170 validators_->compressed_texture_format.GetValues().size());
2171
[email protected]1071e572011-02-09 20:00:122172 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2173 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2174 // OpenGL ES 2.0 does not have this issue.
2175 glEnableVertexAttribArray(0);
2176 }
[email protected]b1122982010-05-17 23:04:242177 glGenBuffersARB(1, &attrib_0_buffer_id_);
2178 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2179 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2180 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402181 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082182
[email protected]1868a342012-11-07 15:56:022183 state_.texture_units.resize(group_->max_texture_units());
2184 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492185 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312186 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492187 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152188 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492189 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072190 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492191 state_.texture_units[tt].bound_texture_external_oes = ref;
2192 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id());
[email protected]61eeb33f2011-07-26 15:30:312193 }
[email protected]62e155e2012-10-23 22:43:152194 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492195 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072196 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492197 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2198 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id());
[email protected]e51bdf32011-11-23 22:21:462199 }
[email protected]370eaf12013-05-18 09:19:492200 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2201 state_.texture_units[tt].bound_texture_cube_map = ref;
2202 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id());
2203 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2204 state_.texture_units[tt].bound_texture_2d = ref;
2205 glBindTexture(GL_TEXTURE_2D, ref->service_id());
[email protected]1958e0e2010-04-22 05:17:152206 }
[email protected]00f893d2010-08-24 18:55:492207 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502208 CHECK_GL_ERROR();
2209
[email protected]297ca1c2011-06-20 23:08:462210 ContextCreationAttribParser attrib_parser;
2211 if (!attrib_parser.Parse(attribs))
2212 return false;
[email protected]41c56362011-06-14 16:47:432213
[email protected]069944672012-04-25 20:52:232214 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022215 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542216 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022217 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432218 // max_sample_count must be initialized to a sane value. If
2219 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2220 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022221 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2222 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2223 max_sample_count);
2224 } else {
2225 offscreen_target_samples_ = 1;
2226 }
[email protected]8a61d872012-01-20 12:43:562227 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022228
2229 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2230 const bool rgb8_supported =
2231 context_->HasExtension("GL_OES_rgb8_rgba8");
2232 // The only available default render buffer formats in GLES2 have very
2233 // little precision. Don't enable multisampling unless 8-bit render
2234 // buffer formats are available--instead fall back to 8-bit textures.
2235 if (rgb8_supported && offscreen_target_samples_ > 1) {
2236 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2237 GL_RGBA8 : GL_RGB8;
2238 } else {
2239 offscreen_target_samples_ = 1;
2240 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2241 GL_RGBA : GL_RGB;
2242 }
2243
2244 // ANGLE only supports packed depth/stencil formats, so use it if it is
2245 // available.
2246 const bool depth24_stencil8_supported =
2247 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272248 VLOG(1) << "GL_OES_packed_depth_stencil "
2249 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002250 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2251 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022252 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2253 offscreen_target_stencil_format_ = 0;
2254 } else {
2255 // It may be the case that this depth/stencil combination is not
2256 // supported, but this will be checked later by CheckFramebufferStatus.
2257 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2258 GL_DEPTH_COMPONENT16 : 0;
2259 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2260 GL_STENCIL_INDEX8 : 0;
2261 }
2262 } else {
2263 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2264 GL_RGBA : GL_RGB;
2265
2266 // If depth is requested at all, use the packed depth stencil format if
2267 // it's available, as some desktop GL drivers don't support any non-packed
2268 // formats for depth attachments.
2269 const bool depth24_stencil8_supported =
2270 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272271 VLOG(1) << "GL_EXT_packed_depth_stencil "
2272 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022273
[email protected]71ee3642010-10-14 18:08:002274 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2275 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022276 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2277 offscreen_target_stencil_format_ = 0;
2278 } else {
2279 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2280 GL_DEPTH_COMPONENT : 0;
2281 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2282 GL_STENCIL_INDEX : 0;
2283 }
2284 }
2285
[email protected]97872062010-11-03 19:07:052286 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2287 GL_RGBA : GL_RGB;
2288
[email protected]6217d392010-03-25 22:08:352289 // Create the target frame buffer. This is the one that the client renders
2290 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352291 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352292 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022293 // Due to GLES2 format limitations, either the color texture (for
2294 // non-multisampling) or the color render buffer (for multisampling) will be
2295 // attached to the offscreen frame buffer. The render buffer has more
2296 // limited formats available to it, but the texture can't do multisampling.
2297 if (IsOffscreenBufferMultisampled()) {
[email protected]ed9f9cd2013-02-27 21:12:352298 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022299 offscreen_target_color_render_buffer_->Create();
2300 } else {
[email protected]ed9f9cd2013-02-27 21:12:352301 offscreen_target_color_texture_.reset(new BackTexture(this));
[email protected]34ff8b0c2010-10-01 20:06:022302 offscreen_target_color_texture_->Create();
2303 }
[email protected]ed9f9cd2013-02-27 21:12:352304 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152305 offscreen_target_depth_render_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352306 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152307 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352308
2309 // Create the saved offscreen texture. The target frame buffer is copied
2310 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352311 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022312 offscreen_saved_frame_buffer_->Create();
2313 //
[email protected]ed9f9cd2013-02-27 21:12:352314 offscreen_saved_color_texture_.reset(new BackTexture(this));
[email protected]6217d392010-03-25 22:08:352315 offscreen_saved_color_texture_->Create();
2316
[email protected]6217d392010-03-25 22:08:352317 // Allocate the render buffers at their initial size and check the status
2318 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592319 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012320 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382321 Destroy(true);
[email protected]6217d392010-03-25 22:08:352322 return false;
2323 }
2324
[email protected]678a73f2012-12-19 19:22:092325 // Allocate the offscreen saved color texture.
2326 DCHECK(offscreen_saved_color_format_);
2327 offscreen_saved_color_texture_->AllocateStorage(
2328 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2329
2330 offscreen_saved_frame_buffer_->AttachRenderTexture(
2331 offscreen_saved_color_texture_.get());
2332 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2333 GL_FRAMEBUFFER_COMPLETE) {
2334 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2335 Destroy(true);
2336 return false;
2337 }
2338
[email protected]6217d392010-03-25 22:08:352339 // Bind to the new default frame buffer (the offscreen target frame buffer).
2340 // This should now be associated with ID zero.
2341 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102342 } else {
2343 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2344 // These are NOT if the back buffer has these proprorties. They are
2345 // if we want the command buffer to enforce them regardless of what
2346 // the real backbuffer is assuming the real back buffer gives us more than
2347 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2348 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2349 // can't do anything about that.
2350
2351 GLint v = 0;
2352 glGetIntegerv(GL_ALPHA_BITS, &v);
2353 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2354 // user requested RGB then RGB. If the user did not specify a preference
2355 // than use whatever we were given. Same for DEPTH and STENCIL.
2356 back_buffer_color_format_ =
2357 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2358 glGetIntegerv(GL_DEPTH_BITS, &v);
2359 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2360 glGetIntegerv(GL_STENCIL_BITS, &v);
2361 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
[email protected]6217d392010-03-25 22:08:352362 }
2363
[email protected]76a0ee102010-04-07 21:03:042364 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2365 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2366 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372367 // mailing list archives. It also implicitly enables the desktop GL
2368 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2369 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152370 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2371 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372372 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152373 }
[email protected]de17df392010-04-23 21:09:412374
[email protected]706b69f2012-07-27 04:59:302375 has_robustness_extension_ =
2376 context->HasExtension("GL_ARB_robustness") ||
2377 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432378
[email protected]c2f8c8402010-12-06 18:07:242379 if (!InitializeShaderTranslator()) {
2380 return false;
[email protected]de17df392010-04-23 21:09:412381 }
[email protected]76a0ee102010-04-07 21:03:042382
[email protected]e259eb412012-10-13 05:47:242383 state_.viewport_width = size.width();
2384 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282385
[email protected]5904806b2012-05-08 18:10:222386 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282387 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022388 viewport_max_width_ = viewport_params[0];
2389 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282390
[email protected]88a61bf2012-10-27 13:00:422391 state_.scissor_width = state_.viewport_width;
2392 state_.scissor_height = state_.viewport_height;
2393
[email protected]11f3e702012-06-19 19:00:012394 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222395 state_.InitCapabilities();
2396 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242397 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012398
2399 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2400 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2401 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2402 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2403
[email protected]88cfd132013-07-11 00:59:002404 bool call_gl_clear = true;
2405#if defined(OS_ANDROID)
2406 // Temporary workaround for Android WebView because this clear ignores the
2407 // clip and corrupts that external UI of the App. Not calling glClear is ok
2408 // because the system already clears the buffer before each draw. Proper
2409 // fix might be setting the scissor clip properly before initialize. See
2410 // crbug.com/259023 for details.
2411 call_gl_clear = surface_->GetHandle();
2412#endif
2413 if (call_gl_clear) {
2414 // Clear the backbuffer.
2415 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2416 }
[email protected]561cc0a62013-05-07 18:34:452417
[email protected]62e155e2012-10-23 22:43:152418 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462419 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2420 }
[email protected]dd289a5d62012-06-30 22:05:462421
[email protected]9b753992013-04-27 02:04:412422 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2423 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242424 }
[email protected]85cb4682013-04-20 00:54:242425
[email protected]97419c02013-04-10 02:52:382426 // Only compositor contexts are known to use only the subset of GL
2427 // that can be safely migrated between the iGPU and the dGPU. Mark
2428 // those contexts as safe to forcibly transition between the GPUs.
2429 // http://crbug.com/180876, http://crbug.com/227228
2430 if (!offscreen)
2431 context_->SetSafeToForceGpuSwitch();
2432
[email protected]85a4ac22013-05-31 01:58:472433 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072434 AsyncPixelTransferManager::Create(context.get()));
2435 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592436
[email protected]246a70452010-03-05 21:53:502437 return true;
[email protected]96449d2c2009-11-25 00:01:322438}
2439
[email protected]302ce6d2011-07-07 23:28:112440void GLES2DecoderImpl::UpdateCapabilities() {
2441 util_.set_num_compressed_texture_formats(
2442 validators_->compressed_texture_format.GetValues().size());
2443 util_.set_num_shader_binary_formats(
2444 validators_->shader_binary_format.GetValues().size());
2445}
2446
[email protected]c2f8c8402010-12-06 18:07:242447bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442448 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2449
[email protected]c2f8c8402010-12-06 18:07:242450 if (!use_shader_translator_) {
2451 return true;
2452 }
2453 ShBuiltInResources resources;
2454 ShInitBuiltInResources(&resources);
2455 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2456 resources.MaxVertexUniformVectors =
2457 group_->max_vertex_uniform_vectors();
2458 resources.MaxVaryingVectors = group_->max_varying_vectors();
2459 resources.MaxVertexTextureImageUnits =
2460 group_->max_vertex_texture_image_units();
2461 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2462 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2463 resources.MaxFragmentUniformVectors =
2464 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492465 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242466 resources.MaxExpressionComplexity = 256;
2467 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042468
[email protected]9e98f61b2013-03-05 02:21:142469#if (ANGLE_SH_VERSION >= 110)
[email protected]46c86752013-05-21 05:08:392470 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212471 GLint precision = 0;
2472 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2473 range, &precision);
[email protected]448e459e2013-06-12 17:00:412474 resources.FragmentPrecisionHigh =
2475 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142476#endif
2477
[email protected]f0d74742011-10-03 16:31:042478 if (force_webgl_glsl_validation_) {
2479 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492480 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132481 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:042482 } else {
2483 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152484 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462485 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152486 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062487 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152488 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492489 resources.EXT_draw_buffers =
2490 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492491 resources.EXT_frag_depth =
2492 features().ext_frag_depth ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042493 }
2494
[email protected]26b61442013-03-17 16:12:012495 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2496 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052497 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022498#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052499 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022500#else
2501 resources.HashFunction = &CityHash64;
2502#endif
[email protected]6aedcdc2013-01-24 01:25:052503 else
2504 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122505 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2506 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2507 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2508 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
[email protected]62e155e2012-10-23 22:43:152509 workarounds().needs_glsl_built_in_function_emulation ?
[email protected]a2a0fe762011-09-20 00:59:122510 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
2511 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
[email protected]87fb6ab2012-06-13 22:28:042512
2513 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2514 vertex_translator_ = cache->GetTranslator(
2515 SH_VERTEX_SHADER, shader_spec, &resources,
2516 implementation_type, function_behavior);
2517 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242518 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382519 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242520 return false;
2521 }
[email protected]87fb6ab2012-06-13 22:28:042522
2523 fragment_translator_ = cache->GetTranslator(
2524 SH_FRAGMENT_SHADER, shader_spec, &resources,
2525 implementation_type, function_behavior);
2526 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242527 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382528 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242529 return false;
2530 }
2531 return true;
2532}
2533
[email protected]ae51d192010-04-27 00:48:032534bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472535 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352536 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032537 return false;
2538 }
2539 }
[email protected]40d90a22013-04-09 03:39:552540 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032541 glGenBuffersARB(n, service_ids.get());
2542 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352543 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032544 }
2545 return true;
2546}
2547
2548bool GLES2DecoderImpl::GenFramebuffersHelper(
2549 GLsizei n, const GLuint* client_ids) {
2550 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352551 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032552 return false;
2553 }
2554 }
[email protected]40d90a22013-04-09 03:39:552555 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032556 glGenFramebuffersEXT(n, service_ids.get());
2557 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352558 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032559 }
2560 return true;
2561}
2562
2563bool GLES2DecoderImpl::GenRenderbuffersHelper(
2564 GLsizei n, const GLuint* client_ids) {
2565 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352566 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032567 return false;
2568 }
2569 }
[email protected]40d90a22013-04-09 03:39:552570 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032571 glGenRenderbuffersEXT(n, service_ids.get());
2572 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352573 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032574 }
2575 return true;
2576}
2577
2578bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2579 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352580 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032581 return false;
2582 }
2583 }
[email protected]40d90a22013-04-09 03:39:552584 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032585 glGenTextures(n, service_ids.get());
2586 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352587 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032588 }
2589 return true;
2590}
2591
2592void GLES2DecoderImpl::DeleteBuffersHelper(
2593 GLsizei n, const GLuint* client_ids) {
2594 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212595 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102596 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242597 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112598 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242599 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102600 }
[email protected]ed9f9cd2013-02-27 21:12:352601 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032602 }
[email protected]a93bb842010-02-16 23:03:472603 }
[email protected]07f54fcc2009-12-22 02:46:302604}
2605
[email protected]ae51d192010-04-27 00:48:032606void GLES2DecoderImpl::DeleteFramebuffersHelper(
2607 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452608 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152609 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112610
[email protected]a25fa872010-03-25 02:57:582611 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352612 Framebuffer* framebuffer =
2613 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102614 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112615 if (framebuffer == state_.bound_draw_framebuffer.get()) {
[email protected]e259eb412012-10-13 05:47:242616 state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442617 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452618 GLenum target = supports_separate_framebuffer_binds ?
2619 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112620 glBindFramebufferEXT(target, GetBackbufferServiceId());
2621 }
[email protected]7cd76fd2013-06-02 21:11:112622 if (framebuffer == state_.bound_read_framebuffer.get()) {
[email protected]e259eb412012-10-13 05:47:242623 state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452624 GLenum target = supports_separate_framebuffer_binds ?
2625 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112626 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462627 }
[email protected]70d34263c2013-01-09 00:27:452628 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352629 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032630 }
[email protected]a25fa872010-03-25 02:57:582631 }
[email protected]07f54fcc2009-12-22 02:46:302632}
2633
[email protected]ae51d192010-04-27 00:48:032634void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2635 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452636 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152637 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582638 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352639 Renderbuffer* renderbuffer =
2640 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102641 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112642 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242643 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102644 }
2645 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452646 if (supports_separate_framebuffer_binds) {
[email protected]7cd76fd2013-06-02 21:11:112647 if (state_.bound_read_framebuffer.get()) {
2648 state_.bound_read_framebuffer
2649 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102650 }
[email protected]7cd76fd2013-06-02 21:11:112651 if (state_.bound_draw_framebuffer.get()) {
2652 state_.bound_draw_framebuffer
2653 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102654 }
2655 } else {
[email protected]7cd76fd2013-06-02 21:11:112656 if (state_.bound_draw_framebuffer.get()) {
2657 state_.bound_draw_framebuffer
2658 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102659 }
2660 }
[email protected]c986af502013-08-14 01:04:442661 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:352662 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032663 }
[email protected]a25fa872010-03-25 02:57:582664 }
[email protected]07f54fcc2009-12-22 02:46:302665}
2666
[email protected]ae51d192010-04-27 00:48:032667void GLES2DecoderImpl::DeleteTexturesHelper(
2668 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452669 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152670 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472671 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492672 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2673 if (texture_ref) {
2674 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102675 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:442676 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462677 }
[email protected]370eaf12013-05-18 09:19:492678 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:022679 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:492680 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102681 }
2682 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452683 if (supports_separate_framebuffer_binds) {
[email protected]7cd76fd2013-06-02 21:11:112684 if (state_.bound_read_framebuffer.get()) {
2685 state_.bound_read_framebuffer
2686 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102687 }
[email protected]7cd76fd2013-06-02 21:11:112688 if (state_.bound_draw_framebuffer.get()) {
2689 state_.bound_draw_framebuffer
2690 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102691 }
2692 } else {
[email protected]7cd76fd2013-06-02 21:11:112693 if (state_.bound_draw_framebuffer.get()) {
2694 state_.bound_draw_framebuffer
2695 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102696 }
2697 }
[email protected]e51bdf32011-11-23 22:21:462698#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:072699 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:462700 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2701 ReleaseIOSurfaceForTexture(service_id);
2702 }
2703#endif
[email protected]ed9f9cd2013-02-27 21:12:352704 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032705 }
[email protected]a93bb842010-02-16 23:03:472706 }
[email protected]07f54fcc2009-12-22 02:46:302707}
2708
[email protected]43f28f832010-02-03 02:28:482709// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322710
[email protected]eb54a562010-01-20 21:55:182711bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382712 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2713 return false;
2714
2715 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432716 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292717
2718 // Some D3D drivers cannot recover from device lost in the GPU process
2719 // sandbox. Allow a new GPU process to launch.
2720 if (workarounds().exit_on_context_lost) {
2721 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2722 << " a D3D device in the Chrome GPU process sandbox.";
2723 exit(0);
2724 }
2725
[email protected]63c9b052012-05-17 18:27:382726 return false;
[email protected]38d139d2011-07-14 00:38:432727 }
2728
[email protected]69a8701e2013-03-07 21:31:092729 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:092730
[email protected]9b753992013-04-27 02:04:412731 // Rebind the FBO if it was unbound by the context.
2732 if (workarounds().unbind_fbo_on_context_switch)
2733 RestoreFramebufferBindings();
2734
[email protected]c986af502013-08-14 01:04:442735 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:492736
[email protected]69a8701e2013-03-07 21:31:092737 return true;
2738}
2739
2740void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:552741 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:322742 if (engine() && query_manager_.get())
2743 query_manager_->ProcessPendingTransferQueries();
2744
[email protected]5b3a8e02013-03-13 05:36:442745 // TODO(epenner): Is there a better place to do this?
2746 // This needs to occur before we execute any batch of commands
2747 // from the client, as the client may have recieved an async
2748 // completion while issuing those commands.
2749 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:482750 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:182751}
2752
[email protected]a96a6022011-11-04 00:58:122753void GLES2DecoderImpl::ReleaseCurrent() {
2754 if (context_.get())
2755 context_->ReleaseCurrent(surface_.get());
2756}
2757
[email protected]8e3e0662010-08-23 18:46:302758void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
[email protected]ed9f9cd2013-02-27 21:12:352759 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:202760 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
[email protected]8e3e0662010-08-23 18:46:302761 glBindRenderbufferEXT(
[email protected]0d6bfdc2011-11-02 01:32:202762 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
[email protected]8e3e0662010-08-23 18:46:302763}
2764
2765static void RebindCurrentFramebuffer(
2766 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062767 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242768 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062769 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462770
[email protected]a3783712012-01-20 22:18:242771 if (framebuffer_id == 0) {
2772 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302773 }
[email protected]297ca1c2011-06-20 23:08:462774
[email protected]8e3e0662010-08-23 18:46:302775 glBindFramebufferEXT(target, framebuffer_id);
2776}
2777
2778void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:442779 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462780
[email protected]62e155e2012-10-23 22:43:152781 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302782 RebindCurrentFramebuffer(
2783 GL_FRAMEBUFFER,
[email protected]e259eb412012-10-13 05:47:242784 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242785 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302786 } else {
2787 RebindCurrentFramebuffer(
2788 GL_READ_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242789 state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242790 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302791 RebindCurrentFramebuffer(
2792 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242793 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242794 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302795 }
[email protected]70d34263c2013-01-09 00:27:452796 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302797}
2798
2799void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
[email protected]e259eb412012-10-13 05:47:242800 TextureUnit& info = state_.texture_units[0];
[email protected]8e3e0662010-08-23 18:46:302801 GLuint last_id;
[email protected]7cd76fd2013-06-02 21:11:112802 if (info.bound_texture_2d.get()) {
[email protected]8e3e0662010-08-23 18:46:302803 last_id = info.bound_texture_2d->service_id();
2804 } else {
2805 last_id = 0;
2806 }
2807
2808 glBindTexture(GL_TEXTURE_2D, last_id);
[email protected]e259eb412012-10-13 05:47:242809 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]8e3e0662010-08-23 18:46:302810}
2811
[email protected]0d6bfdc2011-11-02 01:32:202812bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352813 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202814 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102815 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582816 if (backbuffer_needs_clear_bits_) {
2817 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2818 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2819 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2820 glClearStencil(0);
2821 glStencilMask(-1);
2822 glClearDepth(1.0f);
2823 glDepthMask(true);
2824 glDisable(GL_SCISSOR_TEST);
2825 glClear(backbuffer_needs_clear_bits_);
2826 backbuffer_needs_clear_bits_ = 0;
2827 RestoreClearState();
2828 }
[email protected]0d6bfdc2011-11-02 01:32:202829 return true;
2830 }
2831
[email protected]968351b2011-12-20 08:26:512832 if (framebuffer_manager()->IsComplete(framebuffer)) {
2833 return true;
2834 }
2835
[email protected]0d6bfdc2011-11-02 01:32:202836 GLenum completeness = framebuffer->IsPossiblyComplete();
2837 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512838 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432839 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272840 return false;
2841 }
[email protected]0d6bfdc2011-11-02 01:32:202842
2843 // Are all the attachments cleared?
2844 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2845 texture_manager()->HaveUnclearedMips()) {
2846 if (!framebuffer->IsCleared()) {
2847 // Can we clear them?
[email protected]73276522012-11-09 05:50:202848 if (framebuffer->GetStatus(texture_manager(), target) !=
2849 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512850 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432851 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2852 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202853 return false;
2854 }
2855 ClearUnclearedAttachments(target, framebuffer);
2856 }
2857 }
2858
[email protected]968351b2011-12-20 08:26:512859 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202860 if (framebuffer->GetStatus(texture_manager(), target) !=
2861 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512862 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432863 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2864 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512865 return false;
2866 }
2867 framebuffer_manager()->MarkAsComplete(framebuffer);
2868 }
2869
[email protected]0d6bfdc2011-11-02 01:32:202870 // NOTE: At this point we don't know if the framebuffer is complete but
2871 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272872 return true;
2873}
2874
[email protected]0d6bfdc2011-11-02 01:32:202875bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:152876 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:512877 bool valid = CheckFramebufferValid(
[email protected]7cd76fd2013-06-02 21:11:112878 state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT, func_name);
[email protected]28718a92013-04-04 12:12:512879
2880 if (valid)
2881 OnUseFramebuffer();
2882
2883 return valid;
[email protected]0d6bfdc2011-11-02 01:32:202884 }
[email protected]7cd76fd2013-06-02 21:11:112885 return CheckFramebufferValid(state_.bound_draw_framebuffer.get(),
2886 GL_DRAW_FRAMEBUFFER_EXT,
2887 func_name) &&
2888 CheckFramebufferValid(state_.bound_read_framebuffer.get(),
2889 GL_READ_FRAMEBUFFER_EXT,
2890 func_name);
[email protected]0d6bfdc2011-11-02 01:32:202891}
2892
[email protected]8e3e0662010-08-23 18:46:302893gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:352894 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452895 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202896 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:352897 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:202898 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:262899 if (attachment) {
2900 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:502901 }
[email protected]9edc6b22010-12-23 02:00:262902 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:022903 } else if (offscreen_target_frame_buffer_.get()) {
2904 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:352905 } else {
[email protected]f62a5ab2011-05-23 20:34:152906 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:022907 }
[email protected]246a70452010-03-05 21:53:502908}
2909
[email protected]9edc6b22010-12-23 02:00:262910GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352911 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452912 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202913 if (framebuffer != NULL) {
2914 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:462915 } else if (offscreen_target_frame_buffer_.get()) {
2916 return offscreen_target_color_format_;
2917 } else {
2918 return back_buffer_color_format_;
2919 }
2920}
2921
2922GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352923 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452924 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202925 if (framebuffer != NULL) {
2926 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:262927 } else if (offscreen_target_frame_buffer_.get()) {
2928 return offscreen_target_color_format_;
2929 } else {
[email protected]32fe9aa2011-01-21 23:47:132930 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:262931 }
2932}
2933
[email protected]9a5afa432011-07-22 18:16:392934void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:512935 if (!offscreen_saved_color_texture_info_.get())
2936 return;
2937 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
2938 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
2939 texture_manager()->SetLevelInfo(
2940 offscreen_saved_color_texture_info_.get(),
2941 GL_TEXTURE_2D,
2942 0, // level
2943 GL_RGBA,
2944 offscreen_size_.width(),
2945 offscreen_size_.height(),
2946 1, // depth
2947 0, // border
2948 GL_RGBA,
2949 GL_UNSIGNED_BYTE,
2950 true);
2951 texture_manager()->SetParameter(
2952 "UpdateParentTextureInfo",
2953 GetErrorState(),
2954 offscreen_saved_color_texture_info_.get(),
2955 GL_TEXTURE_MAG_FILTER,
2956 GL_NEAREST);
2957 texture_manager()->SetParameter(
2958 "UpdateParentTextureInfo",
2959 GetErrorState(),
2960 offscreen_saved_color_texture_info_.get(),
2961 GL_TEXTURE_MIN_FILTER,
2962 GL_NEAREST);
2963 texture_manager()->SetParameter(
2964 "UpdateParentTextureInfo",
2965 GetErrorState(),
2966 offscreen_saved_color_texture_info_.get(),
2967 GL_TEXTURE_WRAP_S,
2968 GL_CLAMP_TO_EDGE);
2969 texture_manager()->SetParameter(
2970 "UpdateParentTextureInfo",
2971 GetErrorState(),
2972 offscreen_saved_color_texture_info_.get(),
2973 GL_TEXTURE_WRAP_T,
2974 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:442975 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
2976 &state_, target);
[email protected]2ad674132013-06-05 07:48:512977 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:352978}
2979
[email protected]799b4b22011-08-22 17:09:592980void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:072981 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:522982 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:002983}
2984
[email protected]1d82e822013-04-10 21:32:322985Logger* GLES2DecoderImpl::GetLogger() {
2986 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:522987}
2988
[email protected]d3eba342013-04-18 21:11:502989ErrorState* GLES2DecoderImpl::GetErrorState() {
2990 return state_.GetErrorState();
2991}
2992
[email protected]e3932abb2013-03-13 00:01:372993void GLES2DecoderImpl::SetShaderCacheCallback(
2994 const ShaderCacheCallback& callback) {
2995 shader_cache_callback_ = callback;
2996}
2997
[email protected]840a7e462013-02-27 01:29:512998void GLES2DecoderImpl::SetWaitSyncPointCallback(
2999 const WaitSyncPointCallback& callback) {
3000 wait_sync_point_callback_ = callback;
3001}
3002
[email protected]85a4ac22013-05-31 01:58:473003AsyncPixelTransferManager*
3004 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3005 return async_pixel_transfer_manager_.get();
3006}
3007
3008void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3009 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593010}
3011
[email protected]498b5c072013-06-04 19:30:073012void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3013 AsyncPixelTransferManager* manager) {
3014 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3015}
3016
[email protected]1318e922010-09-17 22:03:163017bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3018 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493019 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3020 if (texture_ref) {
3021 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163022 return true;
3023 }
3024 return false;
3025}
3026
[email protected]63b465922012-09-06 02:04:523027uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443028 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483029 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523030}
3031
3032base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443033 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483034 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523035}
3036
3037base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3038 return total_processing_commands_time_;
3039}
3040
[email protected]dc25dda2012-09-27 21:36:303041void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3042 total_processing_commands_time_ += time;
3043}
3044
[email protected]63c9b052012-05-17 18:27:383045void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063046 if (!initialized())
3047 return;
3048
[email protected]63c9b052012-05-17 18:27:383049 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053050
[email protected]80eb6b52012-01-19 00:14:413051 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243052 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463053 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023054 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243055 state_.bound_array_buffer = NULL;
3056 state_.current_query = NULL;
[email protected]e259eb412012-10-13 05:47:243057 state_.bound_read_framebuffer = NULL;
3058 state_.bound_draw_framebuffer = NULL;
3059 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413060
[email protected]cadac622013-06-11 16:46:363061 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513062 DCHECK(offscreen_target_color_texture_);
3063 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3064 offscreen_saved_color_texture_->id());
3065 offscreen_saved_color_texture_->Invalidate();
3066 offscreen_saved_color_texture_info_ = NULL;
3067 }
[email protected]eadc96792010-10-27 19:39:393068 if (have_context) {
[email protected]c322e882012-05-23 18:06:183069 if (copy_texture_CHROMIUM_.get()) {
3070 copy_texture_CHROMIUM_->Destroy();
3071 copy_texture_CHROMIUM_.reset();
3072 }
[email protected]43410e92012-04-20 17:06:283073
[email protected]7cd76fd2013-06-02 21:11:113074 if (state_.current_program.get()) {
3075 program_manager()->UnuseProgram(shader_manager(),
3076 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143077 }
3078
[email protected]b1122982010-05-17 23:04:243079 if (attrib_0_buffer_id_) {
3080 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3081 }
[email protected]8fbedc02010-11-18 18:43:403082 if (fixed_attrib_buffer_id_) {
3083 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3084 }
[email protected]b1122982010-05-17 23:04:243085
[email protected]97872062010-11-03 19:07:053086 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543087 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053088 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543089 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053090 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023091 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053092 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153093 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053094 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153095 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053096 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023097 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053098 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543099 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273100 if (offscreen_resolved_frame_buffer_.get())
3101 offscreen_resolved_frame_buffer_->Destroy();
3102 if (offscreen_resolved_color_texture_.get())
3103 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053104 } else {
3105 if (offscreen_target_frame_buffer_.get())
3106 offscreen_target_frame_buffer_->Invalidate();
3107 if (offscreen_target_color_texture_.get())
3108 offscreen_target_color_texture_->Invalidate();
3109 if (offscreen_target_color_render_buffer_.get())
3110 offscreen_target_color_render_buffer_->Invalidate();
3111 if (offscreen_target_depth_render_buffer_.get())
3112 offscreen_target_depth_render_buffer_->Invalidate();
3113 if (offscreen_target_stencil_render_buffer_.get())
3114 offscreen_target_stencil_render_buffer_->Invalidate();
3115 if (offscreen_saved_frame_buffer_.get())
3116 offscreen_saved_frame_buffer_->Invalidate();
3117 if (offscreen_saved_color_texture_.get())
3118 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273119 if (offscreen_resolved_frame_buffer_.get())
3120 offscreen_resolved_frame_buffer_->Invalidate();
3121 if (offscreen_resolved_color_texture_.get())
3122 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023123 }
[email protected]83a52d032013-07-24 10:30:373124
3125 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3126 // Otherwise, we can leak objects. http://crbug.com/258772.
3127 // state_.current_program must be reset before group_ is reset because
3128 // the later deletes the ProgramManager object that referred by
3129 // state_.current_program object.
3130 state_.current_program = NULL;
3131
[email protected]43410e92012-04-20 17:06:283132 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053133
[email protected]882ba1e22012-03-08 19:02:533134 if (query_manager_.get()) {
3135 query_manager_->Destroy(have_context);
3136 query_manager_.reset();
3137 }
3138
[email protected]944b62f32012-09-27 02:20:463139 if (vertex_array_manager_ .get()) {
3140 vertex_array_manager_->Destroy(have_context);
3141 vertex_array_manager_.reset();
3142 }
3143
[email protected]97872062010-11-03 19:07:053144 offscreen_target_frame_buffer_.reset();
3145 offscreen_target_color_texture_.reset();
3146 offscreen_target_color_render_buffer_.reset();
3147 offscreen_target_depth_render_buffer_.reset();
3148 offscreen_target_stencil_render_buffer_.reset();
3149 offscreen_saved_frame_buffer_.reset();
3150 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273151 offscreen_resolved_frame_buffer_.reset();
3152 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463153
[email protected]85a4ac22013-05-31 01:58:473154 // Should destroy the transfer manager before the texture manager held
3155 // by the context group.
3156 async_pixel_transfer_manager_.reset();
3157
[email protected]7cd76fd2013-06-02 21:11:113158 if (group_.get()) {
[email protected]2d9d3b92013-01-18 01:07:233159 group_->Destroy(this, have_context);
3160 group_ = NULL;
3161 }
3162
3163 if (context_.get()) {
3164 context_->ReleaseCurrent(NULL);
3165 context_ = NULL;
3166 }
3167
[email protected]e51bdf32011-11-23 22:21:463168#if defined(OS_MACOSX)
3169 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3170 it != texture_to_io_surface_map_.end(); ++it) {
3171 CFRelease(it->second);
3172 }
3173 texture_to_io_surface_map_.clear();
3174#endif
[email protected]96449d2c2009-11-25 00:01:323175}
3176
[email protected]63c9b052012-05-17 18:27:383177void GLES2DecoderImpl::SetSurface(
3178 const scoped_refptr<gfx::GLSurface>& surface) {
3179 DCHECK(context_->IsCurrent(NULL));
3180 DCHECK(surface_.get());
3181 surface_ = surface;
3182 RestoreCurrentFramebufferBindings();
3183}
3184
[email protected]2ad674132013-06-05 07:48:513185bool GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
[email protected]9a5afa432011-07-22 18:16:393186 if (!offscreen_saved_color_texture_.get())
3187 return false;
[email protected]2ad674132013-06-05 07:48:513188 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243189 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073190 offscreen_saved_color_texture_info_ = TextureRef::Create(
3191 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513192 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3193 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393194 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243195 }
[email protected]2ad674132013-06-05 07:48:513196 gpu::gles2::MailboxName name;
3197 memcpy(name.key, mailbox.name, sizeof(mailbox.name));
3198 return mailbox_manager()->ProduceTexture(
3199 GL_TEXTURE_2D, name, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243200}
3201
[email protected]260ddc4e2012-06-28 00:01:533202size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143203 size_t total = 0;
3204 if (offscreen_target_frame_buffer_.get()) {
3205 if (offscreen_target_color_texture_.get()) {
3206 total += offscreen_target_color_texture_->estimated_size();
3207 }
3208 if (offscreen_target_color_render_buffer_.get()) {
3209 total += offscreen_target_color_render_buffer_->estimated_size();
3210 }
3211 if (offscreen_target_depth_render_buffer_.get()) {
3212 total += offscreen_target_depth_render_buffer_->estimated_size();
3213 }
3214 if (offscreen_target_stencil_render_buffer_.get()) {
3215 total += offscreen_target_stencil_render_buffer_->estimated_size();
3216 }
3217 if (offscreen_saved_color_texture_.get()) {
3218 total += offscreen_saved_color_texture_->estimated_size();
3219 }
3220 if (offscreen_resolved_color_texture_.get()) {
3221 total += offscreen_resolved_color_texture_->estimated_size();
3222 }
3223 } else {
3224 gfx::Size size = surface_->GetSize();
3225 total += size.width() * size.height() *
3226 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3227 }
[email protected]260ddc4e2012-06-28 00:01:533228 return total;
[email protected]1078f912011-12-23 13:12:143229}
3230
[email protected]799b4b22011-08-22 17:09:593231bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3232 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3233 if (!is_offscreen) {
3234 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3235 << " with an onscreen framebuffer.";
3236 return false;
3237 }
3238
3239 if (offscreen_size_ == size)
3240 return true;
3241
3242 offscreen_size_ = size;
3243 int w = offscreen_size_.width();
3244 int h = offscreen_size_.height();
3245 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3246 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3247 << "to allocate storage due to excessive dimensions.";
3248 return false;
3249 }
3250
3251 // Reallocate the offscreen target buffers.
3252 DCHECK(offscreen_target_color_format_);
3253 if (IsOffscreenBufferMultisampled()) {
3254 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3255 offscreen_size_, offscreen_target_color_format_,
3256 offscreen_target_samples_)) {
3257 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3258 << "to allocate storage for offscreen target color buffer.";
3259 return false;
3260 }
3261 } else {
3262 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093263 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593264 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3265 << "to allocate storage for offscreen target color texture.";
3266 return false;
3267 }
3268 }
3269 if (offscreen_target_depth_format_ &&
3270 !offscreen_target_depth_render_buffer_->AllocateStorage(
3271 offscreen_size_, offscreen_target_depth_format_,
3272 offscreen_target_samples_)) {
3273 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3274 << "to allocate storage for offscreen target depth buffer.";
3275 return false;
3276 }
3277 if (offscreen_target_stencil_format_ &&
3278 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3279 offscreen_size_, offscreen_target_stencil_format_,
3280 offscreen_target_samples_)) {
3281 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3282 << "to allocate storage for offscreen target stencil buffer.";
3283 return false;
3284 }
3285
3286 // Attach the offscreen target buffers to the target frame buffer.
3287 if (IsOffscreenBufferMultisampled()) {
3288 offscreen_target_frame_buffer_->AttachRenderBuffer(
3289 GL_COLOR_ATTACHMENT0,
3290 offscreen_target_color_render_buffer_.get());
3291 } else {
3292 offscreen_target_frame_buffer_->AttachRenderTexture(
3293 offscreen_target_color_texture_.get());
3294 }
3295 if (offscreen_target_depth_format_) {
3296 offscreen_target_frame_buffer_->AttachRenderBuffer(
3297 GL_DEPTH_ATTACHMENT,
3298 offscreen_target_depth_render_buffer_.get());
3299 }
3300 const bool packed_depth_stencil =
3301 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3302 if (packed_depth_stencil) {
3303 offscreen_target_frame_buffer_->AttachRenderBuffer(
3304 GL_STENCIL_ATTACHMENT,
3305 offscreen_target_depth_render_buffer_.get());
3306 } else if (offscreen_target_stencil_format_) {
3307 offscreen_target_frame_buffer_->AttachRenderBuffer(
3308 GL_STENCIL_ATTACHMENT,
3309 offscreen_target_stencil_render_buffer_.get());
3310 }
3311
3312 if (offscreen_target_frame_buffer_->CheckStatus() !=
3313 GL_FRAMEBUFFER_COMPLETE) {
3314 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3315 << "because offscreen FBO was incomplete.";
3316 return false;
3317 }
3318
3319 // Clear the target frame buffer.
3320 {
3321 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3322 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3323 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3324 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3325 glClearStencil(0);
3326 glStencilMaskSeparate(GL_FRONT, -1);
3327 glStencilMaskSeparate(GL_BACK, -1);
3328 glClearDepth(0);
3329 glDepthMask(GL_TRUE);
3330 glDisable(GL_SCISSOR_TEST);
3331 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3332 RestoreClearState();
3333 }
[email protected]d85ef76d2011-09-08 22:21:433334
3335 // Destroy the offscreen resolved framebuffers.
3336 if (offscreen_resolved_frame_buffer_.get())
3337 offscreen_resolved_frame_buffer_->Destroy();
3338 if (offscreen_resolved_color_texture_.get())
3339 offscreen_resolved_color_texture_->Destroy();
3340 offscreen_resolved_color_texture_.reset();
3341 offscreen_resolved_frame_buffer_.reset();
3342
[email protected]799b4b22011-08-22 17:09:593343 return true;
[email protected]6217d392010-03-25 22:08:353344}
3345
[email protected]799b4b22011-08-22 17:09:593346error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353347 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443348 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023349 return error::kDeferCommandUntilLater;
3350
[email protected]799b4b22011-08-22 17:09:593351 GLuint width = static_cast<GLuint>(c.width);
3352 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073353 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593354 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413355
3356 width = std::max(1U, width);
3357 height = std::max(1U, height);
3358
[email protected]a0d989162011-11-22 13:15:073359#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3360 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003361 // Make sure that we are done drawing to the back buffer before resizing.
3362 glFinish();
3363#endif
[email protected]799b4b22011-08-22 17:09:593364 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3365 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493366 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3367 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3368 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593369 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493370 }
[email protected]7ff86b92010-11-25 17:50:003371 }
[email protected]799b4b22011-08-22 17:09:593372
[email protected]9d37f062011-11-22 01:24:523373 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073374 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443375 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493376 if (!context_->IsCurrent(surface_.get())) {
3377 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3378 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053379 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493380 }
[email protected]658f7562011-09-09 05:24:053381 }
[email protected]799b4b22011-08-22 17:09:593382
3383 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393384}
3385
[email protected]96449d2c2009-11-25 00:01:323386const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3387 if (command_id > kStartPoint && command_id < kNumCommands) {
3388 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3389 }
3390 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3391}
3392
3393// Decode command with its arguments, and call the corresponding GL function.
3394// Note: args is a pointer to the command buffer. As such, it could be changed
3395// by a (malicious) client at any time, so if validation has to happen, it
3396// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143397error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323398 unsigned int command,
3399 unsigned int arg_count,
3400 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143401 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263402 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003403 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3404 // LOG(INFO), tried VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323405 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013406 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193407 }
[email protected]96449d2c2009-11-25 00:01:323408 unsigned int command_index = command - kStartPoint - 1;
3409 if (command_index < arraysize(g_command_info)) {
3410 const CommandInfo& info = g_command_info[command_index];
3411 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3412 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3413 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193414 uint32 immediate_data_size =
3415 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323416 switch (command) {
3417 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353418 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193419 result = Handle ## name( \
3420 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353421 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193422 break; \
[email protected]96449d2c2009-11-25 00:01:323423
3424 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323425 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383426 }
3427 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303428 GLenum error;
3429 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323430 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003431 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3432 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513433 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193434 }
[email protected]96449d2c2009-11-25 00:01:323435 }
3436 } else {
[email protected]f7a64ee2010-02-01 22:24:143437 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323438 }
[email protected]b9849abf2009-11-25 19:13:193439 } else {
3440 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323441 }
[email protected]a3a93e7b2010-08-28 00:48:563442 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3443 result = current_decoder_error_;
3444 current_decoder_error_ = error::kNoError;
3445 }
[email protected]b9849abf2009-11-25 19:13:193446 return result;
[email protected]96449d2c2009-11-25 00:01:323447}
3448
[email protected]ed9f9cd2013-02-27 21:12:353449void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3450 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503451}
3452
[email protected]ae51d192010-04-27 00:48:033453bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353454 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033455 return false;
3456 }
[email protected]96449d2c2009-11-25 00:01:323457 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033458 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353459 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323460 }
[email protected]ae51d192010-04-27 00:48:033461 return true;
[email protected]96449d2c2009-11-25 00:01:323462}
3463
[email protected]ae51d192010-04-27 00:48:033464bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353465 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033466 return false;
[email protected]96449d2c2009-11-25 00:01:323467 }
[email protected]ae51d192010-04-27 00:48:033468 GLuint service_id = glCreateShader(type);
3469 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353470 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033471 }
3472 return true;
[email protected]96449d2c2009-11-25 00:01:323473}
3474
[email protected]882ba1e22012-03-08 19:02:533475void GLES2DecoderImpl::DoFinish() {
3476 glFinish();
[email protected]5a36dc132013-07-23 23:17:553477 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193478 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533479}
3480
3481void GLES2DecoderImpl::DoFlush() {
3482 glFlush();
[email protected]22e3f552012-03-13 01:54:193483 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533484}
3485
[email protected]3916c97e2010-02-25 03:20:503486void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453487 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023488 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513489 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533490 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503491 return;
3492 }
[email protected]e259eb412012-10-13 05:47:243493 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453494 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503495}
3496
[email protected]051b1372010-04-12 02:42:083497void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073498 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083499 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033500 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073501 buffer = GetBuffer(client_id);
3502 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353503 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153504 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3505 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353506 return;
3507 }
3508
[email protected]b10492f2013-03-08 05:24:073509 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033510 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353511 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073512 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573513 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103514 group_->GetIdAllocator(id_namespaces::kBuffers);
3515 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033516 }
[email protected]051b1372010-04-12 02:42:083517 }
[email protected]b10492f2013-03-08 05:24:073518 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3519 if (buffer) {
3520 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513521 LOCAL_SET_GL_ERROR(
3522 GL_INVALID_OPERATION,
3523 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473524 return;
3525 }
[email protected]b10492f2013-03-08 05:24:073526 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473527 }
[email protected]96449d2c2009-11-25 00:01:323528 switch (target) {
3529 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073530 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323531 break;
3532 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073533 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323534 break;
3535 default:
[email protected]a93bb842010-02-16 23:03:473536 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323537 break;
3538 }
[email protected]051b1372010-04-12 02:42:083539 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323540}
3541
[email protected]f3b191b2013-06-19 03:43:543542bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3543 bool all_draw_buffers) {
3544 Framebuffer* framebuffer =
3545 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3546 if (!all_draw_buffers || !framebuffer) {
3547 return (GLES2Util::GetChannelsForFormat(
3548 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3549 }
3550 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463551}
3552
3553bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353554 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453555 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203556 if (framebuffer) {
3557 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463558 }
3559 if (offscreen_target_frame_buffer_.get()) {
3560 return offscreen_target_depth_format_ != 0;
3561 }
3562 return back_buffer_has_depth_;
3563}
3564
3565bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353566 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453567 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203568 if (framebuffer) {
3569 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463570 }
3571 if (offscreen_target_frame_buffer_.get()) {
3572 return offscreen_target_stencil_format_ != 0 ||
3573 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3574 }
3575 return back_buffer_has_stencil_;
3576}
3577
3578void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:443579 if (framebuffer_state_.clear_state_dirty) {
[email protected]297ca1c2011-06-20 23:08:463580 glColorMask(
[email protected]e259eb412012-10-13 05:47:243581 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3582 state_.color_mask_alpha &&
[email protected]f3b191b2013-06-19 03:43:543583 BoundFramebufferHasColorAttachmentWithAlpha(true));
[email protected]297ca1c2011-06-20 23:08:463584 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243585 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223586 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463587 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243588 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423589 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243590 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423591 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223592 EnableDisable(
3593 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3594 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3595 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3596 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]c986af502013-08-14 01:04:443597 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:463598 }
3599}
3600
[email protected]1868a342012-11-07 15:56:023601GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:113602 return (offscreen_target_frame_buffer_.get())
3603 ? offscreen_target_frame_buffer_->id()
3604 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:023605}
3606
3607void GLES2DecoderImpl::RestoreState() const {
[email protected]962bfbe72013-05-24 11:16:143608 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3609 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:063610 // Restore the Framebuffer first because of bugs in Intel drivers.
3611 // Intel drivers incorrectly clip the viewport settings to
3612 // the size of the current framebuffer object.
3613 RestoreFramebufferBindings();
3614 state_.RestoreState();
3615}
3616
3617void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]7cd76fd2013-06-02 21:11:113618 GLuint service_id = state_.bound_draw_framebuffer.get()
3619 ? state_.bound_draw_framebuffer->service_id()
3620 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063621 if (!features().chromium_framebuffer_multisample) {
3622 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3623 } else {
3624 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]7cd76fd2013-06-02 21:11:113625 service_id = state_.bound_read_framebuffer.get()
3626 ? state_.bound_read_framebuffer->service_id()
3627 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063628 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3629 }
[email protected]70d34263c2013-01-09 00:27:453630 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063631}
3632
3633void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:103634 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3635 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:253636 GLenum target = texture->target();
3637 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063638 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253639 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063640 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253641 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063642 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253643 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063644 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253645 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063646 RestoreTextureUnitBindings(state_.active_texture_unit);
3647 }
[email protected]70d34263c2013-01-09 00:27:453648}
3649
3650void GLES2DecoderImpl::OnFboChanged() const {
3651 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513652 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3653}
3654
3655// Called after the FBO is checked for completeness.
3656void GLES2DecoderImpl::OnUseFramebuffer() const {
3657 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3658 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323659 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513660 glScissor(state_.scissor_x,
3661 state_.scissor_y,
3662 state_.scissor_width,
3663 state_.scissor_height);
3664
3665 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3666 // it's unclear how this bug works.
3667 glFlush();
3668 }
[email protected]b177ae22011-11-01 03:29:113669}
3670
[email protected]051b1372010-04-12 02:42:083671void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063672 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083673 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033674 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063675 framebuffer = GetFramebuffer(client_id);
3676 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353677 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153678 LOG(ERROR)
3679 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3680 current_decoder_error_ = error::kGenericError;
3681 return;
[email protected]bf5a8d132011-08-16 08:39:353682 }
3683
[email protected]4d8f0dd2013-03-09 14:37:063684 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033685 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353686 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063687 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573688 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103689 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3690 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033691 } else {
[email protected]4d8f0dd2013-03-09 14:37:063692 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083693 }
[email protected]4d8f0dd2013-03-09 14:37:063694 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083695 }
[email protected]4d8f0dd2013-03-09 14:37:063696 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303697
3698 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063699 state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303700 }
3701 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063702 state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303703 }
[email protected]6217d392010-03-25 22:08:353704
[email protected]c986af502013-08-14 01:04:443705 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463706
[email protected]b177ae22011-11-01 03:29:113707 // If we are rendering to the backbuffer get the FBO id for any simulated
3708 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063709 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113710 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463711 }
[email protected]6217d392010-03-25 22:08:353712
[email protected]051b1372010-04-12 02:42:083713 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453714 OnFboChanged();
[email protected]86093972010-03-11 00:13:563715}
3716
[email protected]051b1372010-04-12 02:42:083717void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273718 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083719 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033720 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273721 renderbuffer = GetRenderbuffer(client_id);
3722 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353723 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153724 LOG(ERROR)
3725 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3726 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353727 return;
3728 }
3729
[email protected]ee2a79c32013-03-10 03:50:273730 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033731 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353732 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273733 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573734 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103735 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3736 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033737 } else {
[email protected]ee2a79c32013-03-10 03:50:273738 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083739 }
[email protected]ee2a79c32013-03-10 03:50:273740 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083741 }
[email protected]ee2a79c32013-03-10 03:50:273742 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer");
3743 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083744 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563745}
3746
[email protected]051b1372010-04-12 02:42:083747void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:493748 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:083749 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033750 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:493751 texture_ref = GetTexture(client_id);
3752 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:353753 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153754 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3755 current_decoder_error_ = error::kGenericError;
3756 return;
[email protected]bf5a8d132011-08-16 08:39:353757 }
3758
[email protected]02965c22013-03-09 02:40:073759 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033760 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413761 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353762 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:493763 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:573764 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103765 group_->GetIdAllocator(id_namespaces::kTextures);
3766 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033767 }
3768 } else {
[email protected]370eaf12013-05-18 09:19:493769 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083770 }
[email protected]370eaf12013-05-18 09:19:493771 Texture* texture = texture_ref->texture();
[email protected]ae51d192010-04-27 00:48:033772
[email protected]1958e0e2010-04-22 05:17:153773 // Check the texture exists
3774 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073775 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513776 LOCAL_SET_GL_ERROR(
3777 GL_INVALID_OPERATION,
3778 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153779 return;
3780 }
[email protected]02965c22013-03-09 02:40:073781 if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:513782 LOCAL_SET_GL_ERROR(
3783 GL_INVALID_OPERATION,
3784 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423785 return;
3786 }
[email protected]02965c22013-03-09 02:40:073787 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3788 if (texture->target() == 0) {
[email protected]370eaf12013-05-18 09:19:493789 texture_manager()->SetTarget(texture_ref, target);
[email protected]a93bb842010-02-16 23:03:473790 }
[email protected]02965c22013-03-09 02:40:073791 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593792
[email protected]e259eb412012-10-13 05:47:243793 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503794 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473795 switch (target) {
3796 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:493797 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:473798 break;
3799 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:493800 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:473801 break;
[email protected]61eeb33f2011-07-26 15:30:313802 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:493803 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:313804 break;
[email protected]e51bdf32011-11-23 22:21:463805 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:493806 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:463807 break;
[email protected]a93bb842010-02-16 23:03:473808 default:
3809 NOTREACHED(); // Validation should prevent us getting here.
3810 break;
3811 }
3812}
3813
[email protected]07f54fcc2009-12-22 02:46:303814void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243815 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123816 if (index != 0 ||
3817 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243818 glDisableVertexAttribArray(index);
3819 }
[email protected]07f54fcc2009-12-22 02:46:303820 } else {
[email protected]ab09b612013-03-11 22:11:513821 LOCAL_SET_GL_ERROR(
3822 GL_INVALID_VALUE,
3823 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303824 }
3825}
3826
[email protected]60f22d32012-12-12 00:31:583827void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3828 GLsizei numAttachments,
3829 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:353830 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:583831 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3832
3833 // Validates the attachments. If one of them fails
3834 // the whole command fails.
3835 for (GLsizei i = 0; i < numAttachments; ++i) {
3836 if ((framebuffer &&
3837 !validators_->attachment.IsValid(attachments[i])) ||
3838 (!framebuffer &&
3839 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:513840 LOCAL_SET_GL_ERROR_INVALID_ENUM(
3841 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:583842 return;
3843 }
3844 }
3845
3846 // Marks each one of them as not cleared
3847 for (GLsizei i = 0; i < numAttachments; ++i) {
3848 if (framebuffer) {
3849 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3850 texture_manager(),
3851 attachments[i],
3852 false);
3853 } else {
3854 switch (attachments[i]) {
3855 case GL_COLOR_EXT:
3856 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3857 break;
3858 case GL_DEPTH_EXT:
3859 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
3860 case GL_STENCIL_EXT:
3861 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
3862 break;
3863 default:
3864 NOTREACHED();
3865 break;
3866 }
3867 }
3868 }
3869
3870 glDiscardFramebufferEXT(target, numAttachments, attachments);
3871}
3872
[email protected]07f54fcc2009-12-22 02:46:303873void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243874 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:303875 glEnableVertexAttribArray(index);
3876 } else {
[email protected]ab09b612013-03-11 22:11:513877 LOCAL_SET_GL_ERROR(
3878 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303879 }
3880}
3881
[email protected]a93bb842010-02-16 23:03:473882void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:443883 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3884 &state_, target);
[email protected]370eaf12013-05-18 09:19:493885 if (!texture_ref ||
3886 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:513887 LOCAL_SET_GL_ERROR(
3888 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:473889 return;
3890 }
[email protected]38c0a972012-05-12 00:48:023891
[email protected]12d95352012-12-14 07:23:543892 if (target == GL_TEXTURE_CUBE_MAP) {
3893 for (int i = 0; i < 6; ++i) {
3894 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:493895 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:513896 LOCAL_SET_GL_ERROR(
3897 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:543898 return;
3899 }
3900 }
3901 } else {
[email protected]370eaf12013-05-18 09:19:493902 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:513903 LOCAL_SET_GL_ERROR(
3904 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:543905 return;
3906 }
[email protected]7687479c2012-05-14 23:54:043907 }
3908
[email protected]ab09b612013-03-11 22:11:513909 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:193910 // Workaround for Mac driver bug. In the large scheme of things setting
3911 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:563912 // hit so there's probably no need to make this conditional. The bug appears
3913 // to be that if the filtering mode is set to something that doesn't require
3914 // mipmaps for rendering, or is never set to something other than the default,
3915 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:153916 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193917 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3918 }
[email protected]a93bb842010-02-16 23:03:473919 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:153920 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:493921 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
3922 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:193923 }
[email protected]ab09b612013-03-11 22:11:513924 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:023925 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:493926 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:023927 }
[email protected]a93bb842010-02-16 23:03:473928}
3929
[email protected]b273e432010-04-12 17:23:583930bool GLES2DecoderImpl::GetHelper(
3931 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:583932 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:153933 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
3934 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:433935 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3936 *num_written = 1;
3937 if (params) {
3938 *params = GL_RGBA; // We don't support other formats.
3939 }
3940 return true;
3941 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3942 *num_written = 1;
3943 if (params) {
3944 *params = GL_UNSIGNED_BYTE; // We don't support other types.
3945 }
3946 return true;
3947 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
3948 *num_written = 1;
3949 if (params) {
3950 *params = group_->max_fragment_uniform_vectors();
3951 }
3952 return true;
3953 case GL_MAX_VARYING_VECTORS:
3954 *num_written = 1;
3955 if (params) {
3956 *params = group_->max_varying_vectors();
3957 }
3958 return true;
3959 case GL_MAX_VERTEX_UNIFORM_VECTORS:
3960 *num_written = 1;
3961 if (params) {
3962 *params = group_->max_vertex_uniform_vectors();
3963 }
3964 return true;
[email protected]4e8a5b122010-05-08 22:00:103965 }
[email protected]5cb735d2011-10-13 01:37:233966 }
3967 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:243968 case GL_MAX_VIEWPORT_DIMS:
3969 if (offscreen_target_frame_buffer_.get()) {
3970 *num_written = 2;
3971 if (params) {
3972 params[0] = renderbuffer_manager()->max_renderbuffer_size();
3973 params[1] = renderbuffer_manager()->max_renderbuffer_size();
3974 }
3975 return true;
3976 }
[email protected]5cb735d2011-10-13 01:37:233977 return false;
[email protected]84afefa2011-10-19 21:45:533978 case GL_MAX_SAMPLES:
3979 *num_written = 1;
3980 if (params) {
3981 params[0] = renderbuffer_manager()->max_samples();
3982 }
3983 return true;
3984 case GL_MAX_RENDERBUFFER_SIZE:
3985 *num_written = 1;
3986 if (params) {
3987 params[0] = renderbuffer_manager()->max_renderbuffer_size();
3988 }
3989 return true;
[email protected]5cb735d2011-10-13 01:37:233990 case GL_MAX_TEXTURE_SIZE:
3991 *num_written = 1;
3992 if (params) {
3993 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
3994 }
3995 return true;
3996 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
3997 *num_written = 1;
3998 if (params) {
3999 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4000 }
4001 return true;
[email protected]2f143d482013-03-14 18:04:494002 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4003 *num_written = 1;
4004 if (params) {
4005 params[0] = group_->max_color_attachments();
4006 }
4007 return true;
4008 case GL_MAX_DRAW_BUFFERS_ARB:
4009 *num_written = 1;
4010 if (params) {
4011 params[0] = group_->max_draw_buffers();
4012 }
4013 return true;
[email protected]297ca1c2011-06-20 23:08:464014 case GL_ALPHA_BITS:
4015 *num_written = 1;
4016 if (params) {
4017 GLint v = 0;
4018 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544019 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464020 }
4021 return true;
4022 case GL_DEPTH_BITS:
4023 *num_written = 1;
4024 if (params) {
4025 GLint v = 0;
4026 glGetIntegerv(GL_DEPTH_BITS, &v);
4027 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4028 }
4029 return true;
4030 case GL_STENCIL_BITS:
4031 *num_written = 1;
4032 if (params) {
4033 GLint v = 0;
4034 glGetIntegerv(GL_STENCIL_BITS, &v);
4035 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4036 }
4037 return true;
[email protected]656dcaad2010-05-07 17:18:374038 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114039 *num_written = validators_->compressed_texture_format.GetValues().size();
4040 if (params) {
4041 for (GLint ii = 0; ii < *num_written; ++ii) {
4042 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4043 }
4044 }
[email protected]656dcaad2010-05-07 17:18:374045 return true;
[email protected]b273e432010-04-12 17:23:584046 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4047 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104048 if (params) {
[email protected]302ce6d2011-07-07 23:28:114049 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104050 }
[email protected]b273e432010-04-12 17:23:584051 return true;
4052 case GL_NUM_SHADER_BINARY_FORMATS:
4053 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104054 if (params) {
[email protected]302ce6d2011-07-07 23:28:114055 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104056 }
[email protected]b273e432010-04-12 17:23:584057 return true;
4058 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114059 *num_written = validators_->shader_binary_format.GetValues().size();
4060 if (params) {
4061 for (GLint ii = 0; ii < *num_written; ++ii) {
4062 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4063 }
4064 }
4065 return true;
[email protected]b273e432010-04-12 17:23:584066 case GL_SHADER_COMPILER:
4067 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104068 if (params) {
4069 *params = GL_TRUE;
4070 }
[email protected]b273e432010-04-12 17:23:584071 return true;
[email protected]6b8cf1a2010-05-06 16:13:584072 case GL_ARRAY_BUFFER_BINDING:
4073 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104074 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114075 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104076 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244077 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104078 &client_id);
4079 *params = client_id;
4080 } else {
4081 *params = 0;
4082 }
[email protected]6b8cf1a2010-05-06 16:13:584083 }
4084 return true;
4085 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4086 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104087 if (params) {
[email protected]e259eb412012-10-13 05:47:244088 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104089 GLuint client_id = 0;
4090 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254091 state_.vertex_attrib_manager->element_array_buffer()->
4092 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104093 *params = client_id;
4094 } else {
4095 *params = 0;
4096 }
[email protected]6b8cf1a2010-05-06 16:13:584097 }
4098 return true;
4099 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304100 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584101 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104102 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354103 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454104 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204105 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104106 GLuint client_id = 0;
4107 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204108 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304109 *params = client_id;
4110 } else {
4111 *params = 0;
4112 }
4113 }
4114 return true;
[email protected]ebfb73c2012-08-15 02:37:454115 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304116 *num_written = 1;
4117 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354118 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454119 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204120 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304121 GLuint client_id = 0;
4122 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204123 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104124 *params = client_id;
4125 } else {
4126 *params = 0;
4127 }
[email protected]6b8cf1a2010-05-06 16:13:584128 }
4129 return true;
4130 case GL_RENDERBUFFER_BINDING:
4131 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104132 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354133 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204134 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4135 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104136 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104137 } else {
4138 *params = 0;
4139 }
[email protected]6b8cf1a2010-05-06 16:13:584140 }
4141 return true;
4142 case GL_CURRENT_PROGRAM:
4143 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104144 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114145 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104146 GLuint client_id = 0;
4147 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244148 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104149 *params = client_id;
4150 } else {
4151 *params = 0;
4152 }
[email protected]6b8cf1a2010-05-06 16:13:584153 }
4154 return true;
[email protected]bf835842012-11-19 15:21:514155 case GL_VERTEX_ARRAY_BINDING_OES:
4156 *num_written = 1;
4157 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114158 if (state_.vertex_attrib_manager.get() !=
4159 default_vertex_attrib_manager_.get()) {
[email protected]bf835842012-11-19 15:21:514160 GLuint client_id = 0;
4161 vertex_array_manager_->GetClientId(
4162 state_.vertex_attrib_manager->service_id(), &client_id);
4163 *params = client_id;
4164 } else {
4165 *params = 0;
4166 }
4167 }
4168 return true;
[email protected]4e8a5b122010-05-08 22:00:104169 case GL_TEXTURE_BINDING_2D:
4170 *num_written = 1;
4171 if (params) {
[email protected]e259eb412012-10-13 05:47:244172 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114173 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104174 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584175 } else {
4176 *params = 0;
4177 }
[email protected]6b8cf1a2010-05-06 16:13:584178 }
[email protected]4e8a5b122010-05-08 22:00:104179 return true;
4180 case GL_TEXTURE_BINDING_CUBE_MAP:
4181 *num_written = 1;
4182 if (params) {
[email protected]e259eb412012-10-13 05:47:244183 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114184 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104185 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584186 } else {
4187 *params = 0;
4188 }
[email protected]6b8cf1a2010-05-06 16:13:584189 }
[email protected]4e8a5b122010-05-08 22:00:104190 return true;
[email protected]61eeb33f2011-07-26 15:30:314191 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4192 *num_written = 1;
4193 if (params) {
[email protected]e259eb412012-10-13 05:47:244194 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114195 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104196 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314197 } else {
4198 *params = 0;
4199 }
4200 }
4201 return true;
[email protected]e51bdf32011-11-23 22:21:464202 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4203 *num_written = 1;
4204 if (params) {
[email protected]e259eb412012-10-13 05:47:244205 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114206 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104207 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464208 } else {
4209 *params = 0;
4210 }
4211 }
4212 return true;
[email protected]6c75c712012-06-19 15:43:174213 case GL_UNPACK_FLIP_Y_CHROMIUM:
4214 *num_written = 1;
4215 if (params) {
4216 params[0] = unpack_flip_y_;
4217 }
4218 return true;
4219 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4220 *num_written = 1;
4221 if (params) {
4222 params[0] = unpack_premultiply_alpha_;
4223 }
4224 return true;
4225 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4226 *num_written = 1;
4227 if (params) {
4228 params[0] = unpack_unpremultiply_alpha_;
4229 }
4230 return true;
[email protected]b273e432010-04-12 17:23:584231 default:
[email protected]2f143d482013-03-14 18:04:494232 if (pname >= GL_DRAW_BUFFER0_ARB &&
4233 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4234 *num_written = 1;
4235 if (params) {
4236 Framebuffer* framebuffer =
4237 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4238 if (framebuffer) {
4239 params[0] = framebuffer->GetDrawBuffer(pname);
4240 } else { // backbuffer
4241 if (pname == GL_DRAW_BUFFER0_ARB)
4242 params[0] = group_->draw_buffer();
4243 else
4244 params[0] = GL_NONE;
4245 }
4246 }
4247 return true;
4248 }
[email protected]4e8a5b122010-05-08 22:00:104249 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534250 return false;
[email protected]b273e432010-04-12 17:23:584251 }
4252}
4253
[email protected]4e8a5b122010-05-08 22:00:104254bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4255 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264256 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534257 return true;
4258 }
[email protected]4e8a5b122010-05-08 22:00:104259 return GetHelper(pname, NULL, num_values);
4260}
4261
[email protected]7d3c36e2013-07-12 14:13:164262GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4263 if (GL_MAX_SAMPLES == pname &&
4264 features().use_img_for_multisampled_render_to_texture) {
4265 return GL_MAX_SAMPLES_IMG;
4266 }
4267 return pname;
4268}
4269
[email protected]b273e432010-04-12 17:23:584270void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4271 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104272 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534273 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554274 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264275 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534276 GetHelper(pname, values.get(), &num_written);
4277 }
[email protected]b273e432010-04-12 17:23:584278 for (GLsizei ii = 0; ii < num_written; ++ii) {
4279 params[ii] = static_cast<GLboolean>(values[ii]);
4280 }
4281 } else {
[email protected]7d3c36e2013-07-12 14:13:164282 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584283 glGetBooleanv(pname, params);
4284 }
4285}
4286
4287void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4288 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104289 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264290 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534291 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554292 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534293 GetHelper(pname, values.get(), &num_written);
4294 for (GLsizei ii = 0; ii < num_written; ++ii) {
4295 params[ii] = static_cast<GLfloat>(values[ii]);
4296 }
4297 } else {
[email protected]7d3c36e2013-07-12 14:13:164298 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534299 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584300 }
[email protected]b273e432010-04-12 17:23:584301 }
4302}
4303
4304void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4305 DCHECK(params);
4306 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264307 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534308 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164309 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584310 glGetIntegerv(pname, params);
4311 }
4312}
4313
[email protected]a0c3e972010-04-21 00:49:134314void GLES2DecoderImpl::DoGetProgramiv(
4315 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424316 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4317 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134318 return;
4319 }
[email protected]df37b9932013-03-08 05:21:424320 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134321}
4322
[email protected]17cfbe0e2013-03-07 01:26:084323void GLES2DecoderImpl::DoGetBufferParameteriv(
4324 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134325 // Just delegate it. Some validation is actually done before this.
4326 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4327 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084328}
4329
[email protected]258a3313f2011-10-18 20:13:574330void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424331 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574332 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514333 LOCAL_SET_GL_ERROR(
4334 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574335 return;
4336 }
[email protected]68dcb1f2012-04-07 00:14:564337 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514338 LOCAL_SET_GL_ERROR(
4339 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564340 return;
4341 }
4342 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514343 LOCAL_SET_GL_ERROR(
4344 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564345 return;
4346 }
[email protected]df37b9932013-03-08 05:21:424347 Program* program = GetProgramInfoNotShader(
4348 program_id, "glBindAttribLocation");
4349 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574350 return;
[email protected]558847a2010-03-24 07:02:544351 }
[email protected]df37b9932013-03-08 05:21:424352 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4353 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574354}
4355
4356error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354357 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574358 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544359 GLuint index = static_cast<GLuint>(c.index);
4360 uint32 name_size = c.data_size;
4361 const char* name = GetSharedMemoryAs<const char*>(
4362 c.name_shm_id, c.name_shm_offset, name_size);
4363 if (name == NULL) {
4364 return error::kOutOfBounds;
4365 }
4366 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574367 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544368 return error::kNoError;
4369}
4370
4371error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:354372 uint32 immediate_data_size, const cmds::BindAttribLocationImmediate& c) {
[email protected]6b8cf1a2010-05-06 16:13:584373 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544374 GLuint index = static_cast<GLuint>(c.index);
4375 uint32 name_size = c.data_size;
4376 const char* name = GetImmediateDataAs<const char*>(
4377 c, name_size, immediate_data_size);
4378 if (name == NULL) {
4379 return error::kOutOfBounds;
4380 }
4381 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574382 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544383 return error::kNoError;
4384}
4385
4386error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354387 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584388 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544389 GLuint index = static_cast<GLuint>(c.index);
4390 Bucket* bucket = GetBucket(c.name_bucket_id);
4391 if (!bucket || bucket->size() == 0) {
4392 return error::kInvalidArguments;
4393 }
4394 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184395 if (!bucket->GetAsString(&name_str)) {
4396 return error::kInvalidArguments;
4397 }
[email protected]258a3313f2011-10-18 20:13:574398 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544399 return error::kNoError;
4400}
4401
[email protected]2be6abf32012-06-26 00:28:334402void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424403 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334404 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514405 LOCAL_SET_GL_ERROR(
4406 GL_INVALID_VALUE,
4407 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334408 return;
4409 }
4410 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514411 LOCAL_SET_GL_ERROR(
4412 GL_INVALID_OPERATION,
4413 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334414 return;
4415 }
4416 if (location < 0 || static_cast<uint32>(location) >=
4417 (group_->max_fragment_uniform_vectors() +
4418 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514419 LOCAL_SET_GL_ERROR(
4420 GL_INVALID_VALUE,
4421 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334422 return;
4423 }
[email protected]df37b9932013-03-08 05:21:424424 Program* program = GetProgramInfoNotShader(
4425 program_id, "glBindUniformLocationCHROMIUM");
4426 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334427 return;
4428 }
[email protected]df37b9932013-03-08 05:21:424429 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514430 LOCAL_SET_GL_ERROR(
4431 GL_INVALID_VALUE,
4432 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334433 }
4434}
4435
4436error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354437 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334438 GLuint program = static_cast<GLuint>(c.program);
4439 GLint location = static_cast<GLint>(c.location);
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);
4447 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4448 return error::kNoError;
4449}
4450
4451error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4452 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354453 const cmds::BindUniformLocationCHROMIUMImmediate& c) {
[email protected]2be6abf32012-06-26 00:28:334454 GLuint program = static_cast<GLuint>(c.program);
4455 GLint location = static_cast<GLint>(c.location);
4456 uint32 name_size = c.data_size;
4457 const char* name = GetImmediateDataAs<const char*>(
4458 c, name_size, immediate_data_size);
4459 if (name == NULL) {
4460 return error::kOutOfBounds;
4461 }
4462 String name_str(name, name_size);
4463 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4464 return error::kNoError;
4465}
4466
4467error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4468 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354469 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334470 GLuint program = static_cast<GLuint>(c.program);
4471 GLint location = static_cast<GLint>(c.location);
4472 Bucket* bucket = GetBucket(c.name_bucket_id);
4473 if (!bucket || bucket->size() == 0) {
4474 return error::kInvalidArguments;
4475 }
4476 std::string name_str;
4477 if (!bucket->GetAsString(&name_str)) {
4478 return error::kInvalidArguments;
4479 }
4480 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4481 return error::kNoError;
4482}
4483
[email protected]f7a64ee2010-02-01 22:24:144484error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354485 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034486 GLuint client_id = c.shader;
4487 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424488 Shader* shader = GetShader(client_id);
4489 if (shader) {
4490 if (!shader->IsDeleted()) {
4491 glDeleteShader(shader->service_id());
4492 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144493 }
[email protected]ae51d192010-04-27 00:48:034494 } else {
[email protected]ab09b612013-03-11 22:11:514495 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034496 }
[email protected]96449d2c2009-11-25 00:01:324497 }
[email protected]f7a64ee2010-02-01 22:24:144498 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324499}
4500
[email protected]f7a64ee2010-02-01 22:24:144501error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354502 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034503 GLuint client_id = c.program;
4504 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424505 Program* program = GetProgram(client_id);
4506 if (program) {
4507 if (!program->IsDeleted()) {
4508 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144509 }
[email protected]ae51d192010-04-27 00:48:034510 } else {
[email protected]ab09b612013-03-11 22:11:514511 LOCAL_SET_GL_ERROR(
4512 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034513 }
[email protected]96449d2c2009-11-25 00:01:324514 }
[email protected]f7a64ee2010-02-01 22:24:144515 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324516}
4517
[email protected]269200b12010-11-18 22:53:064518void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104519 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574520 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104521 for (GLsizei ii = 0; ii < n; ++ii) {
4522 id_allocator->FreeID(ids[ii]);
4523 }
4524}
4525
[email protected]269200b12010-11-18 22:53:064526error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354527 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104528 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4529 GLsizei n = static_cast<GLsizei>(c.n);
4530 uint32 data_size;
4531 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4532 return error::kOutOfBounds;
4533 }
4534 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4535 c.ids_shm_id, c.ids_shm_offset, data_size);
4536 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514537 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104538 return error::kNoError;
4539 }
4540 if (ids == NULL) {
4541 return error::kOutOfBounds;
4542 }
[email protected]269200b12010-11-18 22:53:064543 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104544 return error::kNoError;
4545}
4546
[email protected]269200b12010-11-18 22:53:064547void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104548 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574549 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104550 if (id_offset == 0) {
4551 for (GLsizei ii = 0; ii < n; ++ii) {
4552 ids[ii] = id_allocator->AllocateID();
4553 }
4554 } else {
4555 for (GLsizei ii = 0; ii < n; ++ii) {
4556 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4557 id_offset = ids[ii] + 1;
4558 }
4559 }
4560}
4561
[email protected]269200b12010-11-18 22:53:064562error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354563 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104564 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4565 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4566 GLsizei n = static_cast<GLsizei>(c.n);
4567 uint32 data_size;
4568 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4569 return error::kOutOfBounds;
4570 }
4571 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4572 c.ids_shm_id, c.ids_shm_offset, data_size);
4573 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514574 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104575 return error::kNoError;
4576 }
4577 if (ids == NULL) {
4578 return error::kOutOfBounds;
4579 }
[email protected]269200b12010-11-18 22:53:064580 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104581 return error::kNoError;
4582}
4583
[email protected]269200b12010-11-18 22:53:064584void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104585 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574586 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104587 for (GLsizei ii = 0; ii < n; ++ii) {
4588 if (!id_allocator->MarkAsUsed(ids[ii])) {
4589 for (GLsizei jj = 0; jj < ii; ++jj) {
4590 id_allocator->FreeID(ids[jj]);
4591 }
[email protected]ab09b612013-03-11 22:11:514592 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434593 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4594 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104595 return;
4596 }
4597 }
4598}
4599
[email protected]269200b12010-11-18 22:53:064600error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354601 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104602 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4603 GLsizei n = static_cast<GLsizei>(c.n);
4604 uint32 data_size;
4605 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4606 return error::kOutOfBounds;
4607 }
4608 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4609 c.ids_shm_id, c.ids_shm_offset, data_size);
4610 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514611 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104612 return error::kNoError;
4613 }
4614 if (ids == NULL) {
4615 return error::kOutOfBounds;
4616 }
[email protected]269200b12010-11-18 22:53:064617 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104618 return error::kNoError;
4619}
4620
[email protected]a7266a92012-06-28 02:11:084621error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444622 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204623 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:464624 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274625 glClear(mask);
4626 }
[email protected]a7266a92012-06-28 02:11:084627 return error::kNoError;
4628}
4629
[email protected]36cef8ce2010-03-16 07:34:454630void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4631 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034632 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064633 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4634 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514635 LOCAL_SET_GL_ERROR(
4636 GL_INVALID_OPERATION,
4637 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454638 return;
4639 }
[email protected]ae51d192010-04-27 00:48:034640 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274641 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034642 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274643 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4644 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514645 LOCAL_SET_GL_ERROR(
4646 GL_INVALID_OPERATION,
4647 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034648 return;
4649 }
[email protected]ee2a79c32013-03-10 03:50:274650 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034651 }
[email protected]ab09b612013-03-11 22:11:514652 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034653 glFramebufferRenderbufferEXT(
4654 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514655 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264656 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274657 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284658 }
[email protected]7cd76fd2013-06-02 21:11:114659 if (framebuffer == state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:444660 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464661 }
[email protected]81fc9d02013-03-14 23:53:324662 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284663}
4664
[email protected]3a2e7c7b2010-08-06 01:12:284665void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464666 if (SetCapabilityState(cap, false)) {
4667 glDisable(cap);
4668 }
[email protected]3a2e7c7b2010-08-06 01:12:284669}
4670
4671void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464672 if (SetCapabilityState(cap, true)) {
4673 glEnable(cap);
4674 }
[email protected]3a2e7c7b2010-08-06 01:12:284675}
4676
[email protected]88a61bf2012-10-27 13:00:424677void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4678 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4679 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4680 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284681}
4682
[email protected]b04e24c2013-01-08 18:35:254683void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424684 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4685 state_.sample_coverage_invert = (invert != 0);
4686 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284687}
4688
[email protected]0d6bfdc2011-11-02 01:32:204689// Assumes framebuffer is complete.
4690void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064691 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304692 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204693 // bind this to the DRAW point, clear then bind back to READ
4694 // TODO(gman): I don't think there is any guarantee that an FBO that
4695 // is complete on the READ attachment will be complete as a DRAW
4696 // attachment.
4697 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064698 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304699 }
[email protected]3a2e7c7b2010-08-06 01:12:284700 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064701 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464702 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204703 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464704 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064705 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4706 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284707 glColorMask(true, true, true, true);
4708 clear_bits |= GL_COLOR_BUFFER_BIT;
4709 }
4710
[email protected]4d8f0dd2013-03-09 14:37:064711 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4712 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284713 glClearStencil(0);
4714 glStencilMask(-1);
4715 clear_bits |= GL_STENCIL_BUFFER_BIT;
4716 }
4717
[email protected]4d8f0dd2013-03-09 14:37:064718 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4719 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284720 glClearDepth(1.0f);
4721 glDepthMask(true);
4722 clear_bits |= GL_DEPTH_BUFFER_BIT;
4723 }
4724
4725 glDisable(GL_SCISSOR_TEST);
4726 glClear(clear_bits);
4727
[email protected]968351b2011-12-20 08:26:514728 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064729 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284730
[email protected]c007aa02010-09-02 22:22:404731 RestoreClearState();
4732
4733 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064734 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4735 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484736 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064737 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4738 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484739 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404740 }
4741}
4742
4743void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:444744 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:244745 glClearColor(
4746 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4747 state_.color_clear_alpha);
4748 glClearStencil(state_.stencil_clear);
4749 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224750 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284751 glEnable(GL_SCISSOR_TEST);
4752 }
[email protected]36cef8ce2010-03-16 07:34:454753}
4754
4755GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354756 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304757 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204758 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454759 return GL_FRAMEBUFFER_COMPLETE;
4760 }
[email protected]0d6bfdc2011-11-02 01:32:204761 GLenum completeness = framebuffer->IsPossiblyComplete();
4762 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4763 return completeness;
4764 }
[email protected]73276522012-11-09 05:50:204765 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454766}
4767
4768void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034769 GLenum target, GLenum attachment, GLenum textarget,
4770 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:164771 DoFramebufferTexture2DCommon(
4772 "glFramebufferTexture2D", target, attachment,
4773 textarget, client_texture_id, level, 0);
4774}
4775
4776void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
4777 GLenum target, GLenum attachment, GLenum textarget,
4778 GLuint client_texture_id, GLint level, GLsizei samples) {
4779 if (!features().multisampled_render_to_texture) {
4780 LOCAL_SET_GL_ERROR(
4781 GL_INVALID_OPERATION,
4782 "glFramebufferTexture2DMultisample", "function not available");
4783 return;
4784 }
4785 DoFramebufferTexture2DCommon(
4786 "glFramebufferTexture2DMultisample", target, attachment,
4787 textarget, client_texture_id, level, samples);
4788}
4789
4790void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
4791 const char* name, GLenum target, GLenum attachment, GLenum textarget,
4792 GLuint client_texture_id, GLint level, GLsizei samples) {
4793 if (samples > renderbuffer_manager()->max_samples()) {
4794 LOCAL_SET_GL_ERROR(
4795 GL_INVALID_VALUE,
4796 "glFramebufferTexture2DMultisample", "samples too large");
4797 return;
4798 }
[email protected]4d8f0dd2013-03-09 14:37:064799 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4800 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514801 LOCAL_SET_GL_ERROR(
4802 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164803 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454804 return;
4805 }
[email protected]ae51d192010-04-27 00:48:034806 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:494807 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:034808 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:494809 texture_ref = GetTexture(client_texture_id);
4810 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:514811 LOCAL_SET_GL_ERROR(
4812 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164813 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:034814 return;
4815 }
[email protected]370eaf12013-05-18 09:19:494816 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:034817 }
[email protected]0d6bfdc2011-11-02 01:32:204818
[email protected]80eb6b52012-01-19 00:14:414819 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:514820 LOCAL_SET_GL_ERROR(
4821 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:164822 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204823 return;
4824 }
4825
[email protected]7d3c36e2013-07-12 14:13:164826 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
4827 if (0 == samples) {
4828 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
4829 } else {
4830 if (features().use_img_for_multisampled_render_to_texture) {
4831 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
4832 service_id, level, samples);
4833 } else {
4834 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
4835 service_id, level, samples);
4836 }
4837 }
4838 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:264839 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:164840 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
4841 samples);
[email protected]3a2e7c7b2010-08-06 01:12:284842 }
[email protected]7cd76fd2013-06-02 21:11:114843 if (framebuffer == state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:444844 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464845 }
[email protected]81fc9d02013-03-14 23:53:324846 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:454847}
4848
4849void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4850 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:064851 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4852 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514853 LOCAL_SET_GL_ERROR(
4854 GL_INVALID_OPERATION,
4855 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454856 return;
4857 }
[email protected]74c1ec42010-08-12 01:55:574858 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:104859 const Framebuffer::Attachment* attachment_object =
4860 framebuffer->GetAttachment(attachment);
4861 *params = attachment_object ? attachment_object->object_name() : 0;
4862 } else {
[email protected]7d3c36e2013-07-12 14:13:164863 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
4864 features().use_img_for_multisampled_render_to_texture) {
4865 pname = GL_TEXTURE_SAMPLES_IMG;
4866 }
[email protected]62e65f02013-05-29 22:28:104867 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:574868 }
[email protected]36cef8ce2010-03-16 07:34:454869}
4870
4871void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
4872 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:354873 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204874 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4875 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514876 LOCAL_SET_GL_ERROR(
4877 GL_INVALID_OPERATION,
4878 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454879 return;
4880 }
[email protected]3a03a8f2011-03-19 00:51:274881 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434882 case GL_RENDERBUFFER_INTERNAL_FORMAT:
4883 *params = renderbuffer->internal_format();
4884 break;
4885 case GL_RENDERBUFFER_WIDTH:
4886 *params = renderbuffer->width();
4887 break;
4888 case GL_RENDERBUFFER_HEIGHT:
4889 *params = renderbuffer->height();
4890 break;
[email protected]7d3c36e2013-07-12 14:13:164891 case GL_RENDERBUFFER_SAMPLES_EXT:
4892 if (features().use_img_for_multisampled_render_to_texture) {
4893 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
4894 params);
4895 } else {
4896 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
4897 params);
4898 }
[email protected]ad84a3a2012-06-08 21:42:434899 default:
4900 glGetRenderbufferParameterivEXT(target, pname, params);
4901 break;
[email protected]b71f52c2010-06-18 22:20:204902 }
[email protected]36cef8ce2010-03-16 07:34:454903}
4904
[email protected]8e3e0662010-08-23 18:46:304905void GLES2DecoderImpl::DoBlitFramebufferEXT(
4906 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4907 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4908 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:444909 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:154910 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:514911 LOCAL_SET_GL_ERROR(
4912 GL_INVALID_OPERATION,
4913 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304914 }
[email protected]0c16343f2013-03-08 20:40:164915
4916 if (!CheckBoundFramebuffersValid("glBlitFramebufferEXT")) {
4917 return;
4918 }
4919
[email protected]d058bca2012-11-26 10:27:264920 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:244921 if (IsAngle()) {
4922 glBlitFramebufferANGLE(
4923 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4924 } else {
4925 glBlitFramebufferEXT(
4926 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4927 }
[email protected]d058bca2012-11-26 10:27:264928 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]8e3e0662010-08-23 18:46:304929}
4930
4931void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
4932 GLenum target, GLsizei samples, GLenum internalformat,
4933 GLsizei width, GLsizei height) {
[email protected]7d3c36e2013-07-12 14:13:164934 if (!features().chromium_framebuffer_multisample &&
4935 !features().multisampled_render_to_texture) {
[email protected]ab09b612013-03-11 22:11:514936 LOCAL_SET_GL_ERROR(
4937 GL_INVALID_OPERATION,
4938 "glRenderbufferStorageMultisample", "function not available");
[email protected]8e3e0662010-08-23 18:46:304939 return;
4940 }
[email protected]8e3e0662010-08-23 18:46:304941
[email protected]ed9f9cd2013-02-27 21:12:354942 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204943 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4944 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514945 LOCAL_SET_GL_ERROR(
4946 GL_INVALID_OPERATION,
4947 "glRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:204948 return;
4949 }
4950
[email protected]84afefa2011-10-19 21:45:534951 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:514952 LOCAL_SET_GL_ERROR(
4953 GL_INVALID_VALUE,
4954 "glRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:534955 return;
4956 }
4957
4958 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
4959 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:514960 LOCAL_SET_GL_ERROR(
4961 GL_INVALID_VALUE,
4962 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:534963 return;
4964 }
4965
[email protected]7989c9e2013-01-23 06:39:264966 uint32 estimated_size = 0;
4967 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
4968 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:514969 LOCAL_SET_GL_ERROR(
4970 GL_OUT_OF_MEMORY,
4971 "glRenderbufferStorageMultsample", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:264972 return;
[email protected]8e3e0662010-08-23 18:46:304973 }
4974
[email protected]7989c9e2013-01-23 06:39:264975 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:514976 LOCAL_SET_GL_ERROR(
4977 GL_OUT_OF_MEMORY,
4978 "glRenderbufferStorageMultsample", "out of memory");
[email protected]7989c9e2013-01-23 06:39:264979 return;
4980 }
4981
4982 GLenum impl_format = RenderbufferManager::
4983 InternalRenderbufferFormatToImplFormat(internalformat);
[email protected]ab09b612013-03-11 22:11:514984 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisample");
[email protected]866b91c52011-03-23 14:38:084985 if (IsAngle()) {
4986 glRenderbufferStorageMultisampleANGLE(
4987 target, samples, impl_format, width, height);
[email protected]7d3c36e2013-07-12 14:13:164988 } else if (features().use_img_for_multisampled_render_to_texture) {
4989 glRenderbufferStorageMultisampleIMG(
4990 target, samples, impl_format, width, height);
[email protected]866b91c52011-03-23 14:38:084991 } else {
4992 glRenderbufferStorageMultisampleEXT(
4993 target, samples, impl_format, width, height);
4994 }
[email protected]ab09b612013-03-11 22:11:514995 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisample");
[email protected]9edc6b22010-12-23 02:00:264996 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:514997 // TODO(gman): If renderbuffers tracked which framebuffers they were
4998 // attached to we could just mark those framebuffers as not complete.
4999 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205000 renderbuffer_manager()->SetInfo(
5001 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265002 }
[email protected]8e3e0662010-08-23 18:46:305003}
5004
[email protected]36cef8ce2010-03-16 07:34:455005void GLES2DecoderImpl::DoRenderbufferStorage(
5006 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355007 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205008 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5009 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515010 LOCAL_SET_GL_ERROR(
5011 GL_INVALID_OPERATION,
5012 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455013 return;
5014 }
[email protected]876f6fee2010-08-02 23:10:325015
[email protected]84afefa2011-10-19 21:45:535016 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5017 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515018 LOCAL_SET_GL_ERROR(
5019 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535020 return;
5021 }
5022
[email protected]7989c9e2013-01-23 06:39:265023 uint32 estimated_size = 0;
5024 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5025 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515026 LOCAL_SET_GL_ERROR(
5027 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265028 return;
5029 }
5030
5031 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515032 LOCAL_SET_GL_ERROR(
5033 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265034 return;
[email protected]b71f52c2010-06-18 22:20:205035 }
[email protected]876f6fee2010-08-02 23:10:325036
[email protected]ab09b612013-03-11 22:11:515037 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265038 glRenderbufferStorageEXT(
5039 target, RenderbufferManager::
5040 InternalRenderbufferFormatToImplFormat(internalformat),
5041 width, height);
[email protected]ab09b612013-03-11 22:11:515042 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265043 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515044 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5045 // we could just mark those framebuffers as not complete.
5046 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205047 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265048 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265049 }
[email protected]36cef8ce2010-03-16 07:34:455050}
5051
[email protected]df37b9932013-03-08 05:21:425052void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385053 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425054 Program* program = GetProgramInfoNotShader(
5055 program_id, "glLinkProgram");
5056 if (!program) {
[email protected]a93bb842010-02-16 23:03:475057 return;
5058 }
[email protected]05afda12011-01-20 00:17:345059
[email protected]df37b9932013-03-08 05:21:425060 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395061 ShaderTranslator* vertex_translator = NULL;
5062 ShaderTranslator* fragment_translator = NULL;
5063 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115064 vertex_translator = vertex_translator_.get();
5065 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395066 }
[email protected]df37b9932013-03-08 05:21:425067 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115068 vertex_translator,
5069 fragment_translator,
5070 feature_info_.get(),
5071 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425072 if (program == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:155073 if (workarounds().use_current_program_after_successful_link) {
[email protected]df37b9932013-03-08 05:21:425074 glUseProgram(program->service_id());
[email protected]c2a3caf12012-10-23 19:32:005075 }
[email protected]df37b9932013-03-08 05:21:425076 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545077 }
5078 }
[email protected]07f54fcc2009-12-22 02:46:305079};
5080
[email protected]3916c97e2010-02-25 03:20:505081void GLES2DecoderImpl::DoTexParameterf(
5082 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445083 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5084 &state_, target);
[email protected]02965c22013-03-09 02:40:075085 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515086 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245087 return;
[email protected]07f54fcc2009-12-22 02:46:305088 }
[email protected]cbb22e42011-05-12 23:36:245089
[email protected]02965c22013-03-09 02:40:075090 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505091 "glTexParameterf", GetErrorState(), texture, pname,
5092 static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305093}
5094
[email protected]3916c97e2010-02-25 03:20:505095void GLES2DecoderImpl::DoTexParameteri(
5096 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445097 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5098 &state_, target);
[email protected]02965c22013-03-09 02:40:075099 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515100 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245101 return;
[email protected]3916c97e2010-02-25 03:20:505102 }
[email protected]cbb22e42011-05-12 23:36:245103
[email protected]02965c22013-03-09 02:40:075104 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505105 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505106}
5107
5108void GLES2DecoderImpl::DoTexParameterfv(
5109 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445110 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5111 &state_, target);
[email protected]02965c22013-03-09 02:40:075112 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515113 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245114 return;
[email protected]3916c97e2010-02-25 03:20:505115 }
[email protected]cbb22e42011-05-12 23:36:245116
[email protected]02965c22013-03-09 02:40:075117 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505118 "glTexParameterfv", GetErrorState(), texture, pname,
5119 static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505120}
5121
5122void GLES2DecoderImpl::DoTexParameteriv(
5123 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445124 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5125 &state_, target);
[email protected]02965c22013-03-09 02:40:075126 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515127 LOCAL_SET_GL_ERROR(
5128 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245129 return;
[email protected]3916c97e2010-02-25 03:20:505130 }
[email protected]cbb22e42011-05-12 23:36:245131
[email protected]02965c22013-03-09 02:40:075132 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505133 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505134}
5135
[email protected]939e7362010-05-13 20:49:105136bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115137 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435138 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515139 LOCAL_SET_GL_ERROR(
5140 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435141 return false;
[email protected]939e7362010-05-13 20:49:105142 }
[email protected]e259eb412012-10-13 05:47:245143 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515144 LOCAL_SET_GL_ERROR(
5145 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105146 return false;
5147 }
5148 return true;
5149}
5150
5151bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5152 GLint location, const char* function_name) {
5153 if (!CheckCurrentProgram(function_name)) {
5154 return false;
5155 }
5156 return location != -1;
5157}
5158
[email protected]476ccb72012-12-06 15:52:525159namespace {
5160
5161static const GLenum valid_int_vec1_types_list[] = {
5162 GL_INT,
5163 GL_BOOL,
5164 GL_SAMPLER_2D,
5165 GL_SAMPLER_2D_RECT_ARB,
5166 GL_SAMPLER_CUBE,
5167 GL_SAMPLER_EXTERNAL_OES,
5168};
5169
5170static const GLenum valid_int_vec2_types_list[] = {
5171 GL_INT_VEC2,
5172 GL_BOOL_VEC2,
5173};
5174
5175static const GLenum valid_int_vec3_types_list[] = {
5176 GL_INT_VEC3,
5177 GL_BOOL_VEC3,
5178};
5179
5180static const GLenum valid_int_vec4_types_list[] = {
5181 GL_INT_VEC4,
5182 GL_BOOL_VEC4,
5183};
5184
5185static const GLenum valid_float_vec1_types_list[] = {
5186 GL_FLOAT,
5187 GL_BOOL,
5188};
5189
5190static const GLenum valid_float_vec2_types_list[] = {
5191 GL_FLOAT_VEC2,
5192 GL_BOOL_VEC2,
5193};
5194
5195static const GLenum valid_float_vec3_types_list[] = {
5196 GL_FLOAT_VEC3,
5197 GL_BOOL_VEC3,
5198};
5199
5200static const GLenum valid_float_vec4_types_list[] = {
5201 GL_FLOAT_VEC4,
5202 GL_BOOL_VEC4,
5203};
5204
5205static const GLenum valid_float_mat2_types_list[] = {
5206 GL_FLOAT_MAT2,
5207};
5208
5209static const GLenum valid_float_mat3_types_list[] = {
5210 GL_FLOAT_MAT3,
5211};
5212
5213static const GLenum valid_float_mat4_types_list[] = {
5214 GL_FLOAT_MAT4,
5215};
5216
5217static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5218 valid_int_vec1_types_list,
5219 arraysize(valid_int_vec1_types_list),
5220};
5221
5222static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5223 valid_int_vec2_types_list,
5224 arraysize(valid_int_vec2_types_list),
5225};
5226
5227static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5228 valid_int_vec3_types_list,
5229 arraysize(valid_int_vec3_types_list),
5230};
5231
5232static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5233 valid_int_vec4_types_list,
5234 arraysize(valid_int_vec4_types_list),
5235};
5236
5237static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5238 valid_float_vec1_types_list,
5239 arraysize(valid_float_vec1_types_list),
5240};
5241
5242static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5243 valid_float_vec2_types_list,
5244 arraysize(valid_float_vec2_types_list),
5245};
5246
5247static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5248 valid_float_vec3_types_list,
5249 arraysize(valid_float_vec3_types_list),
5250};
5251
5252static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5253 valid_float_vec4_types_list,
5254 arraysize(valid_float_vec4_types_list),
5255};
5256
5257static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5258 valid_float_mat2_types_list,
5259 arraysize(valid_float_mat2_types_list),
5260};
5261
5262static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5263 valid_float_mat3_types_list,
5264 arraysize(valid_float_mat3_types_list),
5265};
5266
5267static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5268 valid_float_mat4_types_list,
5269 arraysize(valid_float_mat4_types_list),
5270};
5271
5272} // anonymous namespace.
5273
[email protected]43c2f1f2011-03-25 18:35:365274bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125275 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525276 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125277 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365278 DCHECK(type);
5279 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125280 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525281
[email protected]1b0a6752012-02-22 03:44:125282 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105283 return false;
5284 }
[email protected]43c2f1f2011-03-25 18:35:365285 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355286 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245287 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125288 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365289 if (!info) {
[email protected]ab09b612013-03-11 22:11:515290 LOCAL_SET_GL_ERROR(
5291 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105292 return false;
5293 }
[email protected]476ccb72012-12-06 15:52:525294 bool okay = false;
5295 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5296 if (base_info.valid_types[ii] == info->type) {
5297 okay = true;
5298 break;
5299 }
5300 }
5301 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515302 LOCAL_SET_GL_ERROR(
5303 GL_INVALID_OPERATION, function_name,
5304 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525305 return false;
5306 }
[email protected]43c2f1f2011-03-25 18:35:365307 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515308 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435309 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365310 return false;
5311 }
5312 *count = std::min(info->size - array_index, *count);
5313 if (*count <= 0) {
5314 return false;
5315 }
5316 *type = info->type;
[email protected]939e7362010-05-13 20:49:105317 return true;
5318}
5319
[email protected]1b0a6752012-02-22 03:44:125320void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5321 GLenum type = 0;
5322 GLsizei count = 1;
5323 GLint real_location = -1;
5324 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525325 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5326 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505327 return;
5328 }
[email protected]e259eb412012-10-13 05:47:245329 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025330 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515331 LOCAL_SET_GL_ERROR(
5332 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465333 return;
5334 }
[email protected]1b0a6752012-02-22 03:44:125335 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505336}
5337
5338void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125339 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365340 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125341 GLint real_location = -1;
5342 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525343 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5344 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365345 return;
5346 }
[email protected]74727112012-06-13 21:18:085347 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5348 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245349 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025350 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515351 LOCAL_SET_GL_ERROR(
5352 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465353 return;
5354 }
[email protected]43c2f1f2011-03-25 18:35:365355 }
[email protected]1b0a6752012-02-22 03:44:125356 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505357}
5358
[email protected]939e7362010-05-13 20:49:105359void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125360 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365361 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125362 GLint real_location = -1;
5363 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525364 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5365 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105366 return;
5367 }
5368 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555369 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105370 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535371 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105372 }
[email protected]1b0a6752012-02-22 03:44:125373 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105374 } else {
[email protected]1b0a6752012-02-22 03:44:125375 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105376 }
5377}
5378
5379void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125380 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365381 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125382 GLint real_location = -1;
5383 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525384 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5385 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105386 return;
5387 }
5388 if (type == GL_BOOL_VEC2) {
5389 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555390 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105391 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535392 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105393 }
[email protected]1b0a6752012-02-22 03:44:125394 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105395 } else {
[email protected]1b0a6752012-02-22 03:44:125396 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105397 }
5398}
5399
5400void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125401 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365402 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125403 GLint real_location = -1;
5404 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525405 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5406 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105407 return;
5408 }
5409 if (type == GL_BOOL_VEC3) {
5410 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555411 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105412 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535413 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105414 }
[email protected]1b0a6752012-02-22 03:44:125415 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105416 } else {
[email protected]1b0a6752012-02-22 03:44:125417 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105418 }
5419}
5420
5421void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125422 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365423 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125424 GLint real_location = -1;
5425 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525426 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5427 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105428 return;
5429 }
5430 if (type == GL_BOOL_VEC4) {
5431 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555432 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105433 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535434 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105435 }
[email protected]1b0a6752012-02-22 03:44:125436 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105437 } else {
[email protected]1b0a6752012-02-22 03:44:125438 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105439 }
5440}
5441
[email protected]43c2f1f2011-03-25 18:35:365442void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125443 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365444 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125445 GLint real_location = -1;
5446 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525447 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5448 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365449 return;
5450 }
[email protected]1b0a6752012-02-22 03:44:125451 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365452}
5453
5454void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125455 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365456 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125457 GLint real_location = -1;
5458 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525459 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5460 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365461 return;
5462 }
[email protected]1b0a6752012-02-22 03:44:125463 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365464}
5465
5466void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125467 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365468 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125469 GLint real_location = -1;
5470 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525471 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5472 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365473 return;
5474 }
[email protected]1b0a6752012-02-22 03:44:125475 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365476}
5477
5478void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125479 GLint fake_location, GLsizei count, GLboolean transpose,
5480 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365481 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125482 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365483 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525484 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5485 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365486 return;
5487 }
[email protected]1b0a6752012-02-22 03:44:125488 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365489}
5490
5491void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125492 GLint fake_location, GLsizei count, GLboolean transpose,
5493 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365494 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125495 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365496 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525497 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5498 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365499 return;
5500 }
[email protected]1b0a6752012-02-22 03:44:125501 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365502}
5503
5504void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125505 GLint fake_location, GLsizei count, GLboolean transpose,
5506 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365507 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125508 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365509 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525510 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5511 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365512 return;
5513 }
[email protected]1b0a6752012-02-22 03:44:125514 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365515}
5516
[email protected]df37b9932013-03-08 05:21:425517void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035518 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425519 Program* program = NULL;
5520 if (program_id) {
5521 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5522 if (!program) {
[email protected]ae51d192010-04-27 00:48:035523 return;
5524 }
[email protected]df37b9932013-03-08 05:21:425525 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505526 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515527 LOCAL_SET_GL_ERROR(
5528 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505529 return;
5530 }
[email protected]df37b9932013-03-08 05:21:425531 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505532 }
[email protected]7cd76fd2013-06-02 21:11:115533 if (state_.current_program.get()) {
5534 program_manager()->UnuseProgram(shader_manager(),
5535 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145536 }
[email protected]df37b9932013-03-08 05:21:425537 state_.current_program = program;
5538 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545539 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:115540 if (state_.current_program.get()) {
5541 program_manager()->UseProgram(state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145542 }
[email protected]3916c97e2010-02-25 03:20:505543}
5544
[email protected]ab09b612013-03-11 22:11:515545void GLES2DecoderImpl::RenderWarning(
5546 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325547 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015548}
5549
[email protected]ab09b612013-03-11 22:11:515550void GLES2DecoderImpl::PerformanceWarning(
5551 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505552 logger_.LogMessage(filename, line,
5553 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015554}
5555
[email protected]e56131d22013-07-28 16:14:115556void GLES2DecoderImpl::UpdateStreamTextureIfNeeded(Texture* texture) {
5557 if (texture && texture->IsStreamTexture()) {
5558 DCHECK(stream_texture_manager());
5559 StreamTexture* stream_tex =
5560 stream_texture_manager()->LookupStreamTexture(texture->service_id());
5561 if (stream_tex)
5562 stream_tex->Update();
5563 }
5564}
5565
5566bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:115567 DCHECK(state_.current_program.get());
[email protected]e56131d22013-07-28 16:14:115568 bool have_unrenderable_textures =
5569 texture_manager()->HaveUnrenderableTextures();
5570 if (!have_unrenderable_textures && !features().oes_egl_image_external) {
5571 return true;
[email protected]ef526492010-06-02 23:12:255572 }
[email protected]e2367b42013-05-31 03:37:215573
[email protected]ef526492010-06-02 23:12:255574 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:355575 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245576 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505577 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355578 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245579 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505580 DCHECK(uniform_info);
5581 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5582 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025583 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245584 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495585 TextureRef* texture =
[email protected]cadac622013-06-11 16:46:365586 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]79dc5b32013-07-30 20:08:295587 if (texture)
5588 UpdateStreamTextureIfNeeded(texture->texture());
[email protected]e56131d22013-07-28 16:14:115589 if (have_unrenderable_textures &&
5590 (!texture || !texture_manager()->CanRender(texture))) {
[email protected]ef526492010-06-02 23:12:255591 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505592 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5593 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315594 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495595 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:515596 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:015597 std::string("texture bound to texture unit ") +
5598 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:295599 " is not renderable. It maybe non-power-of-2 and have"
5600 " incompatible texture filtering or is not"
5601 " 'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505602 }
5603 }
5604 // else: should this be an error?
5605 }
5606 }
[email protected]e56131d22013-07-28 16:14:115607 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:505608}
5609
5610void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]7cd76fd2013-06-02 21:11:115611 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:355612 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:115613 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505614 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355615 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245616 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505617 DCHECK(uniform_info);
5618 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5619 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025620 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245621 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:115622 TextureRef* texture_ref =
5623 uniform_info->type == GL_SAMPLER_2D
5624 ? texture_unit.bound_texture_2d.get()
5625 : texture_unit.bound_texture_cube_map.get();
[email protected]370eaf12013-05-18 09:19:495626 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:505627 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:495628 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:115629 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
5630 ? texture_unit.bound_texture_2d.get()
5631 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:505632 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:495633 texture_ref ? texture_ref->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505634 }
5635 }
5636 }
5637 }
5638 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245639 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305640}
5641
[email protected]0d6bfdc2011-11-02 01:32:205642bool GLES2DecoderImpl::ClearUnclearedTextures() {
5643 // Only check if there are some uncleared textures.
5644 if (!texture_manager()->HaveUnsafeTextures()) {
5645 return true;
5646 }
5647
5648 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:115649 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:355650 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:115651 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205652 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355653 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245654 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205655 DCHECK(uniform_info);
5656 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5657 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025658 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245659 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495660 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:365661 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:495662 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
5663 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:205664 return false;
5665 }
5666 }
5667 }
5668 }
5669 }
5670 }
5671 return true;
5672}
5673
[email protected]c6aef902012-02-14 03:31:425674bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435675 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035676 // NOTE: We specifically do not check current_program->IsValid() because
5677 // it could never be invalid since glUseProgram would have failed. While
5678 // glLinkProgram could later mark the program as invalid the previous
5679 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:115680 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:505681 // The program does not exist.
5682 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:515683 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505684 return false;
5685 }
[email protected]c6aef902012-02-14 03:31:425686
[email protected]7cd76fd2013-06-02 21:11:115687 return state_.vertex_attrib_manager
5688 ->ValidateBindings(function_name,
5689 this,
5690 feature_info_.get(),
5691 state_.current_program.get(),
5692 max_vertex_accessed,
5693 primcount);
[email protected]b1122982010-05-17 23:04:245694}
5695
[email protected]c13e1da62011-09-09 21:48:305696bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435697 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305698 DCHECK(simulated);
5699 *simulated = false;
5700
[email protected]876f6fee2010-08-02 23:10:325701 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305702 return true;
[email protected]876f6fee2010-08-02 23:10:325703
[email protected]ac77603c72013-03-08 13:52:065704 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:355705 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:245706 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245707 bool attrib_0_used =
5708 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:065709 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305710 return true;
[email protected]b1122982010-05-17 23:04:245711 }
5712
[email protected]b1122982010-05-17 23:04:245713 // Make a buffer with a single repeated vec4 value enough to
5714 // simulate the constant value that is supposed to be here.
5715 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305716 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475717 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305718
5719 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475720 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305721 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515722 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305723 return false;
5724 }
5725
[email protected]ab09b612013-03-11 22:11:515726 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015727 "Attribute 0 is disabled. This has signficant performance penalty");
5728
[email protected]ab09b612013-03-11 22:11:515729 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:305730 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5731
[email protected]8f0b86c2f2012-04-10 05:48:285732 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5733 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495734 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305735 GLenum error = glGetError();
5736 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515737 LOCAL_SET_GL_ERROR(
5738 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305739 return false;
5740 }
[email protected]fc753442011-02-04 19:49:495741 }
[email protected]af6380962012-11-29 23:24:135742
5743 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:285744 if (new_buffer ||
5745 (attrib_0_used &&
5746 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:135747 (value.v[0] != attrib_0_value_.v[0] ||
5748 value.v[1] != attrib_0_value_.v[1] ||
5749 value.v[2] != attrib_0_value_.v[2] ||
5750 value.v[3] != attrib_0_value_.v[3])))) {
5751 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:495752 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
5753 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:135754 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:245755 attrib_0_size_ = size_needed;
5756 }
5757
5758 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
5759
[email protected]ac77603c72013-03-08 13:52:065760 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:425761 glVertexAttribDivisorANGLE(0, 0);
5762
[email protected]c13e1da62011-09-09 21:48:305763 *simulated = true;
[email protected]b1122982010-05-17 23:04:245764 return true;
[email protected]b1122982010-05-17 23:04:245765}
5766
[email protected]ac77603c72013-03-08 13:52:065767void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
5768 const VertexAttrib* attrib =
5769 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
5770 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
5771 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:075772 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:245773 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065774 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
5775 attrib->gl_stride(), ptr);
5776 if (attrib->divisor())
5777 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:245778 glBindBuffer(
5779 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:115780 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
5781 : 0);
[email protected]43410e92012-04-20 17:06:285782
[email protected]265f8992012-07-20 01:03:145783 // Never touch vertex attribute 0's state (in particular, never
5784 // disable it) when running on desktop GL because it will never be
5785 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:065786 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:145787 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:065788 if (attrib->enabled()) {
5789 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145790 } else {
[email protected]ac77603c72013-03-08 13:52:065791 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145792 }
[email protected]43410e92012-04-20 17:06:285793 }
[email protected]b1122982010-05-17 23:04:245794}
[email protected]07f54fcc2009-12-22 02:46:305795
[email protected]8fbedc02010-11-18 18:43:405796bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:435797 const char* function_name,
[email protected]c6aef902012-02-14 03:31:425798 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:405799 DCHECK(simulated);
5800 *simulated = false;
5801 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
5802 return true;
5803
[email protected]e259eb412012-10-13 05:47:245804 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:405805 return true;
5806 }
5807
[email protected]ab09b612013-03-11 22:11:515808 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015809 "GL_FIXED attributes have a signficant performance penalty");
5810
[email protected]8fbedc02010-11-18 18:43:405811 // NOTE: we could be smart and try to check if a buffer is used
5812 // twice in 2 different attribs, find the overlapping parts and therefore
5813 // duplicate the minimum amount of data but this whole code path is not meant
5814 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
5815 // tests so we just add to the buffer attrib used.
5816
[email protected]c13e1da62011-09-09 21:48:305817 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:065818 const VertexAttribManager::VertexAttribList& enabled_attribs =
5819 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
5820 for (VertexAttribManager::VertexAttribList::const_iterator it =
5821 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5822 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355823 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065824 state_.current_program->GetAttribInfoByLocation(attrib->index());
5825 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
5826 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:425827 GLuint num_vertices = max_accessed + 1;
5828 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515829 LOCAL_SET_GL_ERROR(
5830 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425831 return false;
5832 }
[email protected]8fbedc02010-11-18 18:43:405833 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065834 attrib->CanAccess(max_accessed) &&
5835 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:475836 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:065837 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:475838 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:515839 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435840 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405841 return false;
5842 }
5843 }
5844 }
5845
[email protected]3aad1a32012-09-07 20:54:475846 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
5847 uint32 size_needed = 0;
5848 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305849 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515850 LOCAL_SET_GL_ERROR(
5851 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405852 return false;
5853 }
5854
[email protected]ab09b612013-03-11 22:11:515855 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:405856
5857 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:305858 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:405859 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305860 GLenum error = glGetError();
5861 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515862 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435863 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:305864 return false;
5865 }
[email protected]8fbedc02010-11-18 18:43:405866 }
5867
5868 // Copy the elements and convert to float
5869 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:065870 for (VertexAttribManager::VertexAttribList::const_iterator it =
5871 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5872 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355873 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065874 state_.current_program->GetAttribInfoByLocation(attrib->index());
5875 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:425876 max_vertex_accessed);
5877 GLuint num_vertices = max_accessed + 1;
5878 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515879 LOCAL_SET_GL_ERROR(
5880 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425881 return false;
5882 }
[email protected]8fbedc02010-11-18 18:43:405883 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065884 attrib->CanAccess(max_accessed) &&
5885 attrib->type() == GL_FIXED) {
5886 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:405887 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:555888 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:405889 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:065890 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:405891 const int32* end = src + num_elements;
5892 float* dst = data.get();
5893 while (src != end) {
5894 *dst++ = static_cast<float>(*src++) / 65536.0f;
5895 }
5896 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
5897 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065898 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:405899 reinterpret_cast<GLvoid*>(offset));
5900 offset += size;
5901 }
5902 }
5903 *simulated = true;
5904 return true;
5905}
5906
5907void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
5908 // There's no need to call glVertexAttribPointer because we shadow all the
5909 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:245910 glBindBuffer(
5911 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:115912 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
5913 : 0);
[email protected]8fbedc02010-11-18 18:43:405914}
5915
[email protected]ad84a3a2012-06-08 21:42:435916error::Error GLES2DecoderImpl::DoDrawArrays(
5917 const char* function_name,
5918 bool instanced,
5919 GLenum mode,
5920 GLint first,
5921 GLsizei count,
5922 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:085923 if (ShouldDeferDraws())
5924 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:435925 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:515926 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:435927 return error::kNoError;
5928 }
5929 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:515930 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:435931 return error::kNoError;
5932 }
[email protected]c6aef902012-02-14 03:31:425933 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:515934 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:425935 return error::kNoError;
5936 }
[email protected]ad84a3a2012-06-08 21:42:435937 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:435938 return error::kNoError;
5939 }
5940 // We have to check this here because the prototype for glDrawArrays
5941 // is GLint not GLsizei.
5942 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:515943 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:435944 return error::kNoError;
5945 }
5946
[email protected]c6aef902012-02-14 03:31:425947 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:515948 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:435949 return error::kNoError;
5950 }
5951
5952 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:435953 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:205954 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:515955 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:205956 return error::kNoError;
5957 }
[email protected]c13e1da62011-09-09 21:48:305958 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:435959 if (!SimulateAttrib0(
5960 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:305961 return error::kNoError;
5962 }
[email protected]38d139d2011-07-14 00:38:435963 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:435964 if (SimulateFixedAttribs(
5965 function_name, max_vertex_accessed, &simulated_fixed_attribs,
5966 primcount)) {
[email protected]e56131d22013-07-28 16:14:115967 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:435968 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:425969 if (!instanced) {
5970 glDrawArrays(mode, first, count);
5971 } else {
5972 glDrawArraysInstancedANGLE(mode, first, count, primcount);
5973 }
[email protected]22e3f552012-03-13 01:54:195974 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:435975 if (textures_set) {
5976 RestoreStateForNonRenderableTextures();
5977 }
5978 if (simulated_fixed_attribs) {
5979 RestoreStateForSimulatedFixedAttribs();
5980 }
5981 }
5982 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:285983 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:435984 }
[email protected]38d139d2011-07-14 00:38:435985 }
5986 return error::kNoError;
5987}
5988
[email protected]c6aef902012-02-14 03:31:425989error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:355990 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:435991 return DoDrawArrays("glDrawArrays",
5992 false,
[email protected]c6aef902012-02-14 03:31:425993 static_cast<GLenum>(c.mode),
5994 static_cast<GLint>(c.first),
5995 static_cast<GLsizei>(c.count),
5996 0);
5997}
5998
5999error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356000 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156001 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516002 LOCAL_SET_GL_ERROR(
6003 GL_INVALID_OPERATION,
6004 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426005 return error::kNoError;
6006 }
[email protected]ad84a3a2012-06-08 21:42:436007 return DoDrawArrays("glDrawArraysIntancedANGLE",
6008 true,
[email protected]c6aef902012-02-14 03:31:426009 static_cast<GLenum>(c.mode),
6010 static_cast<GLint>(c.first),
6011 static_cast<GLsizei>(c.count),
6012 static_cast<GLsizei>(c.primcount));
6013}
6014
[email protected]ad84a3a2012-06-08 21:42:436015error::Error GLES2DecoderImpl::DoDrawElements(
6016 const char* function_name,
6017 bool instanced,
6018 GLenum mode,
6019 GLsizei count,
6020 GLenum type,
6021 int32 offset,
6022 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086023 if (ShouldDeferDraws())
6024 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:246025 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516026 LOCAL_SET_GL_ERROR(
6027 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296028 return error::kNoError;
6029 }
6030
[email protected]8eee29c2010-04-29 03:38:296031 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516032 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296033 return error::kNoError;
6034 }
6035 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516036 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296037 return error::kNoError;
6038 }
[email protected]9438b012010-06-15 22:55:056039 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516040 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296041 return error::kNoError;
6042 }
[email protected]9438b012010-06-15 22:55:056043 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516044 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296045 return error::kNoError;
6046 }
[email protected]c6aef902012-02-14 03:31:426047 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516048 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426049 return error::kNoError;
6050 }
[email protected]8eee29c2010-04-29 03:38:296051
[email protected]ad84a3a2012-06-08 21:42:436052 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276053 return error::kNoError;
6054 }
6055
[email protected]c6aef902012-02-14 03:31:426056 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316057 return error::kNoError;
6058 }
6059
[email protected]8eee29c2010-04-29 03:38:296060 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086061 Buffer* element_array_buffer =
6062 state_.vertex_attrib_manager->element_array_buffer();
6063
6064 if (!element_array_buffer->GetMaxValueForRange(
6065 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516066 LOCAL_SET_GL_ERROR(
6067 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296068 return error::kNoError;
6069 }
6070
[email protected]ad84a3a2012-06-08 21:42:436071 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206072 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516073 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206074 return error::kNoError;
6075 }
[email protected]c13e1da62011-09-09 21:48:306076 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436077 if (!SimulateAttrib0(
6078 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306079 return error::kNoError;
6080 }
[email protected]8fbedc02010-11-18 18:43:406081 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436082 if (SimulateFixedAttribs(
6083 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6084 primcount)) {
[email protected]e56131d22013-07-28 16:14:116085 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466086 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086087 // TODO(gman): Refactor to hide these details in BufferManager or
6088 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406089 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086090 bool used_client_side_array = false;
6091 if (element_array_buffer->IsClientSideArray()) {
6092 used_client_side_array = true;
6093 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6094 indices = element_array_buffer->GetRange(offset, 0);
6095 }
6096
[email protected]c6aef902012-02-14 03:31:426097 if (!instanced) {
6098 glDrawElements(mode, count, type, indices);
6099 } else {
6100 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6101 }
[email protected]17cfbe0e2013-03-07 01:26:086102
6103 if (used_client_side_array) {
6104 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6105 element_array_buffer->service_id());
6106 }
6107
[email protected]22e3f552012-03-13 01:54:196108 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406109 if (textures_set) {
6110 RestoreStateForNonRenderableTextures();
6111 }
6112 if (simulated_fixed_attribs) {
6113 RestoreStateForSimulatedFixedAttribs();
6114 }
[email protected]ba3176a2009-12-16 18:19:466115 }
[email protected]b1122982010-05-17 23:04:246116 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286117 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246118 }
[email protected]96449d2c2009-11-25 00:01:326119 }
[email protected]f7a64ee2010-02-01 22:24:146120 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326121}
6122
[email protected]c6aef902012-02-14 03:31:426123error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356124 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436125 return DoDrawElements("glDrawElements",
6126 false,
[email protected]c6aef902012-02-14 03:31:426127 static_cast<GLenum>(c.mode),
6128 static_cast<GLsizei>(c.count),
6129 static_cast<GLenum>(c.type),
6130 static_cast<int32>(c.index_offset),
6131 0);
6132}
6133
6134error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356135 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156136 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516137 LOCAL_SET_GL_ERROR(
6138 GL_INVALID_OPERATION,
6139 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426140 return error::kNoError;
6141 }
[email protected]ad84a3a2012-06-08 21:42:436142 return DoDrawElements("glDrawElementsInstancedANGLE",
6143 true,
[email protected]c6aef902012-02-14 03:31:426144 static_cast<GLenum>(c.mode),
6145 static_cast<GLsizei>(c.count),
6146 static_cast<GLenum>(c.type),
6147 static_cast<int32>(c.index_offset),
6148 static_cast<GLsizei>(c.primcount));
6149}
6150
[email protected]269200b12010-11-18 22:53:066151GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236152 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6153 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076154 Buffer* buffer = GetBuffer(buffer_id);
6155 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036156 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516157 LOCAL_SET_GL_ERROR(
6158 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236159 } else {
[email protected]b10492f2013-03-08 05:24:076160 if (!buffer->GetMaxValueForRange(
6161 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036162 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516163 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066164 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436165 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236166 }
6167 }
6168 return max_vertex_accessed;
6169}
6170
[email protected]96449d2c2009-11-25 00:01:326171// Calls glShaderSource for the various versions of the ShaderSource command.
6172// Assumes that data / data_size points to a piece of memory that is in range
6173// of whatever context it came from (shared memory, immediate memory, bucket
6174// memory.)
[email protected]45bf5152010-02-12 00:11:316175error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036176 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576177 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426178 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6179 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316180 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326181 }
[email protected]45bf5152010-02-12 00:11:316182 // Note: We don't actually call glShaderSource here. We wait until
6183 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426184 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146185 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326186}
6187
[email protected]f7a64ee2010-02-01 22:24:146188error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356189 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326190 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316191 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326192 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466193 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146194 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326195 }
[email protected]ae51d192010-04-27 00:48:036196 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326197}
6198
[email protected]f7a64ee2010-02-01 22:24:146199error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]ed9f9cd2013-02-27 21:12:356200 uint32 immediate_data_size, const cmds::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:326201 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316202 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:306203 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:466204 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146205 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326206 }
[email protected]ae51d192010-04-27 00:48:036207 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:316208}
6209
[email protected]558847a2010-03-24 07:02:546210error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356211 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546212 Bucket* bucket = GetBucket(c.data_bucket_id);
6213 if (!bucket || bucket->size() == 0) {
6214 return error::kInvalidArguments;
6215 }
6216 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036217 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546218 bucket->size() - 1);
6219}
6220
[email protected]ae51d192010-04-27 00:48:036221void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386222 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426223 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6224 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316225 return;
6226 }
[email protected]f57bb282010-11-12 00:51:346227 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186228 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426229 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456230 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416231 }
[email protected]de17df392010-04-23 21:09:416232
[email protected]7cd76fd2013-06-02 21:11:116233 program_manager()->DoCompileShader(shader, translator, feature_info_.get());
[email protected]45bf5152010-02-12 00:11:316234};
6235
[email protected]ddd968b82010-03-02 00:44:296236void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426237 GLuint shader_id, GLenum pname, GLint* params) {
6238 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6239 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296240 return;
6241 }
[email protected]8f1ccdac2010-05-19 21:01:486242 switch (pname) {
6243 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426244 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486245 return;
6246 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426247 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416248 return;
[email protected]8f1ccdac2010-05-19 21:01:486249 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426250 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416251 return;
[email protected]d6a53e42011-10-05 00:09:366252 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426253 *params = shader->translated_source() ?
6254 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366255 return;
[email protected]8f1ccdac2010-05-19 21:01:486256 default:
6257 break;
[email protected]ddd968b82010-03-02 00:44:296258 }
[email protected]df37b9932013-03-08 05:21:426259 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296260}
6261
[email protected]ae51d192010-04-27 00:48:036262error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356263 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426264 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036265 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6266 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426267 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6268 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296269 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296270 return error::kNoError;
6271 }
[email protected]df37b9932013-03-08 05:21:426272 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036273 return error::kNoError;
6274}
6275
[email protected]d6a53e42011-10-05 00:09:366276error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6277 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356278 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426279 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366280 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6281 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426282 Shader* shader = GetShaderInfoNotProgram(
6283 shader_id, "glTranslatedGetShaderSourceANGLE");
6284 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366285 bucket->SetSize(0);
6286 return error::kNoError;
6287 }
[email protected]d6a53e42011-10-05 00:09:366288
[email protected]df37b9932013-03-08 05:21:426289 bucket->SetFromString(shader->translated_source() ?
6290 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366291 return error::kNoError;
6292}
6293
[email protected]ae51d192010-04-27 00:48:036294error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356295 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426296 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586297 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6298 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426299 Program* program = GetProgramInfoNotShader(
6300 program_id, "glGetProgramInfoLog");
6301 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466302 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036303 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316304 }
[email protected]df37b9932013-03-08 05:21:426305 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036306 return error::kNoError;
6307}
6308
6309error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356310 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426311 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586312 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6313 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426314 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6315 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466316 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036317 return error::kNoError;
6318 }
[email protected]df37b9932013-03-08 05:21:426319 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036320 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326321}
6322
[email protected]d058bca2012-11-26 10:27:266323bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6324 return state_.GetEnabled(cap);
6325}
6326
[email protected]1958e0e2010-04-22 05:17:156327bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216328 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106329 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156330}
6331
6332bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356333 const Framebuffer* framebuffer =
6334 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106335 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156336}
6337
6338bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366339 // IsProgram is true for programs as soon as they are created, until they are
6340 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356341 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106342 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156343}
6344
6345bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356346 const Renderbuffer* renderbuffer =
6347 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106348 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156349}
6350
6351bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366352 // IsShader is true for shaders as soon as they are created, until they
6353 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356354 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106355 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156356}
6357
6358bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496359 const TextureRef* texture_ref = GetTexture(client_id);
6360 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036361}
6362
6363void GLES2DecoderImpl::DoAttachShader(
6364 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426365 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586366 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426367 if (!program) {
[email protected]ae51d192010-04-27 00:48:036368 return;
[email protected]1958e0e2010-04-22 05:17:156369 }
[email protected]df37b9932013-03-08 05:21:426370 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6371 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036372 return;
6373 }
[email protected]df37b9932013-03-08 05:21:426374 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516375 LOCAL_SET_GL_ERROR(
6376 GL_INVALID_OPERATION,
6377 "glAttachShader",
6378 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316379 return;
6380 }
[email protected]df37b9932013-03-08 05:21:426381 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036382}
6383
6384void GLES2DecoderImpl::DoDetachShader(
6385 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426386 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586387 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426388 if (!program) {
[email protected]ae51d192010-04-27 00:48:036389 return;
6390 }
[email protected]df37b9932013-03-08 05:21:426391 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6392 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036393 return;
6394 }
[email protected]df37b9932013-03-08 05:21:426395 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516396 LOCAL_SET_GL_ERROR(
6397 GL_INVALID_OPERATION,
6398 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226399 return;
6400 }
[email protected]df37b9932013-03-08 05:21:426401 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036402}
6403
6404void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426405 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586406 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426407 if (!program) {
[email protected]ae51d192010-04-27 00:48:036408 return;
6409 }
[email protected]df37b9932013-03-08 05:21:426410 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156411}
6412
[email protected]ac77603c72013-03-08 13:52:066413void GLES2DecoderImpl::GetVertexAttribHelper(
6414 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246415 switch (pname) {
6416 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066417 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246418 if (buffer && !buffer->IsDeleted()) {
6419 GLuint client_id;
6420 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6421 *params = client_id;
6422 }
6423 break;
6424 }
6425 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066426 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246427 break;
6428 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066429 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246430 break;
6431 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066432 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246433 break;
6434 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066435 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246436 break;
6437 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066438 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246439 break;
[email protected]c6aef902012-02-14 03:31:426440 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066441 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426442 break;
[email protected]ac77603c72013-03-08 13:52:066443 default:
6444 NOTREACHED();
6445 break;
6446 }
6447}
6448
6449void GLES2DecoderImpl::DoGetVertexAttribfv(
6450 GLuint index, GLenum pname, GLfloat* params) {
6451 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6452 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516453 LOCAL_SET_GL_ERROR(
6454 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066455 return;
6456 }
6457 switch (pname) {
6458 case GL_CURRENT_VERTEX_ATTRIB: {
6459 const Vec4& value = state_.attrib_values[index];
6460 params[0] = value.v[0];
6461 params[1] = value.v[1];
6462 params[2] = value.v[2];
6463 params[3] = value.v[3];
6464 break;
6465 }
6466 default: {
6467 GLint value = 0;
6468 GetVertexAttribHelper(attrib, pname, &value);
6469 *params = static_cast<GLfloat>(value);
6470 break;
6471 }
6472 }
6473}
6474
6475void GLES2DecoderImpl::DoGetVertexAttribiv(
6476 GLuint index, GLenum pname, GLint* params) {
6477 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6478 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516479 LOCAL_SET_GL_ERROR(
6480 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066481 return;
6482 }
6483 switch (pname) {
[email protected]af6380962012-11-29 23:24:136484 case GL_CURRENT_VERTEX_ATTRIB: {
6485 const Vec4& value = state_.attrib_values[index];
6486 params[0] = static_cast<GLint>(value.v[0]);
6487 params[1] = static_cast<GLint>(value.v[1]);
6488 params[2] = static_cast<GLint>(value.v[2]);
6489 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246490 break;
[email protected]af6380962012-11-29 23:24:136491 }
[email protected]b1122982010-05-17 23:04:246492 default:
[email protected]ac77603c72013-03-08 13:52:066493 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246494 break;
6495 }
6496}
6497
[email protected]af6380962012-11-29 23:24:136498bool GLES2DecoderImpl::SetVertexAttribValue(
6499 const char* function_name, GLuint index, const GLfloat* value) {
6500 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516501 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136502 return false;
[email protected]b1122982010-05-17 23:04:246503 }
[email protected]af6380962012-11-29 23:24:136504 Vec4& v = state_.attrib_values[index];
6505 v.v[0] = value[0];
6506 v.v[1] = value[1];
6507 v.v[2] = value[2];
6508 v.v[3] = value[3];
6509 return true;
6510}
6511
6512void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6513 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6514 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6515 glVertexAttrib1f(index, v0);
6516 }
[email protected]b1122982010-05-17 23:04:246517}
6518
6519void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136520 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6521 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6522 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246523 }
[email protected]b1122982010-05-17 23:04:246524}
6525
6526void GLES2DecoderImpl::DoVertexAttrib3f(
6527 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136528 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6529 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6530 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246531 }
[email protected]b1122982010-05-17 23:04:246532}
6533
6534void GLES2DecoderImpl::DoVertexAttrib4f(
6535 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136536 GLfloat v[4] = { v0, v1, v2, v3, };
6537 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6538 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246539 }
[email protected]b1122982010-05-17 23:04:246540}
6541
6542void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136543 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6544 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6545 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246546 }
[email protected]b1122982010-05-17 23:04:246547}
6548
6549void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136550 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6551 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6552 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246553 }
[email protected]b1122982010-05-17 23:04:246554}
6555
6556void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136557 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6558 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6559 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246560 }
[email protected]b1122982010-05-17 23:04:246561}
6562
6563void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136564 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6565 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246566 }
[email protected]b1122982010-05-17 23:04:246567}
6568
[email protected]f7a64ee2010-02-01 22:24:146569error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:356570 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466571
[email protected]7cd76fd2013-06-02 21:11:116572 if (!state_.bound_array_buffer.get() ||
6573 state_.bound_array_buffer->IsDeleted()) {
6574 if (state_.vertex_attrib_manager.get() ==
6575 default_vertex_attrib_manager_.get()) {
[email protected]ab09b612013-03-11 22:11:516576 LOCAL_SET_GL_ERROR(
6577 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:466578 return error::kNoError;
6579 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:516580 LOCAL_SET_GL_ERROR(
6581 GL_INVALID_VALUE,
6582 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:466583 return error::kNoError;
6584 }
[email protected]96449d2c2009-11-25 00:01:326585 }
[email protected]8eee29c2010-04-29 03:38:296586
6587 GLuint indx = c.indx;
6588 GLint size = c.size;
6589 GLenum type = c.type;
6590 GLboolean normalized = c.normalized;
6591 GLsizei stride = c.stride;
6592 GLsizei offset = c.offset;
6593 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056594 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516595 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296596 return error::kNoError;
6597 }
[email protected]9438b012010-06-15 22:55:056598 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:516599 LOCAL_SET_GL_ERROR(
6600 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296601 return error::kNoError;
6602 }
6603 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516604 LOCAL_SET_GL_ERROR(
6605 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296606 return error::kNoError;
6607 }
6608 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:516609 LOCAL_SET_GL_ERROR(
6610 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296611 return error::kNoError;
6612 }
6613 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:516614 LOCAL_SET_GL_ERROR(
6615 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296616 return error::kNoError;
6617 }
6618 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516619 LOCAL_SET_GL_ERROR(
6620 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296621 return error::kNoError;
6622 }
6623 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316624 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296625 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516626 LOCAL_SET_GL_ERROR(
6627 GL_INVALID_OPERATION,
6628 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316629 return error::kNoError;
6630 }
6631 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516632 LOCAL_SET_GL_ERROR(
6633 GL_INVALID_OPERATION,
6634 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296635 return error::kNoError;
6636 }
[email protected]7cd76fd2013-06-02 21:11:116637 state_.vertex_attrib_manager
6638 ->SetAttribInfo(indx,
6639 state_.bound_array_buffer.get(),
6640 size,
6641 type,
6642 normalized,
6643 stride,
6644 stride != 0 ? stride : component_size * size,
6645 offset);
[email protected]8fbedc02010-11-18 18:43:406646 if (type != GL_FIXED) {
6647 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6648 }
[email protected]f7a64ee2010-02-01 22:24:146649 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326650}
6651
[email protected]43410e92012-04-20 17:06:286652void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6653 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246654 state_.viewport_x = x;
6655 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026656 state_.viewport_width = std::min(width, viewport_max_width_);
6657 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286658 glViewport(x, y, width, height);
6659}
6660
[email protected]c6aef902012-02-14 03:31:426661error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356662 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156663 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516664 LOCAL_SET_GL_ERROR(
6665 GL_INVALID_OPERATION,
6666 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426667 }
6668 GLuint index = c.index;
6669 GLuint divisor = c.divisor;
6670 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516671 LOCAL_SET_GL_ERROR(
6672 GL_INVALID_VALUE,
6673 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426674 return error::kNoError;
6675 }
6676
[email protected]e259eb412012-10-13 05:47:246677 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426678 index,
6679 divisor);
6680 glVertexAttribDivisorANGLE(index, divisor);
6681 return error::kNoError;
6682}
6683
[email protected]5a36dc132013-07-23 23:17:556684void GLES2DecoderImpl::FinishReadPixels(
6685 const cmds::ReadPixels& c,
6686 GLuint buffer) {
6687 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
6688 GLsizei width = c.width;
6689 GLsizei height = c.height;
6690 GLenum format = c.format;
6691 GLenum type = c.type;
6692 typedef cmds::ReadPixels::Result Result;
6693 uint32 pixels_size;
6694 Result* result = NULL;
6695 if (c.result_shm_id != 0) {
6696 result = GetSharedMemoryAs<Result*>(
6697 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6698 if (!result) {
6699 if (buffer != 0) {
6700 glDeleteBuffersARB(1, &buffer);
6701 }
6702 return;
6703 }
6704 }
6705 GLES2Util::ComputeImageDataSizes(
6706 width, height, format, type, state_.pack_alignment, &pixels_size,
6707 NULL, NULL);
6708 void* pixels = GetSharedMemoryAs<void*>(
6709 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
6710 if (!pixels) {
6711 if (buffer != 0) {
6712 glDeleteBuffersARB(1, &buffer);
6713 }
6714 return;
6715 }
6716
6717 if (buffer != 0) {
6718 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
6719 void* data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
6720 memcpy(pixels, data, pixels_size);
6721 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
6722 // have to restore the state.
6723 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
6724 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
6725 glDeleteBuffersARB(1, &buffer);
6726 }
6727
6728 if (result != NULL) {
6729 *result = true;
6730 }
6731
6732 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6733 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
6734 if ((channels_exist & 0x0008) == 0 &&
6735 workarounds().clear_alpha_in_readpixels) {
6736 // Set the alpha to 255 because some drivers are buggy in this regard.
6737 uint32 temp_size;
6738
6739 uint32 unpadded_row_size;
6740 uint32 padded_row_size;
6741 if (!GLES2Util::ComputeImageDataSizes(
6742 width, 2, format, type, state_.pack_alignment, &temp_size,
6743 &unpadded_row_size, &padded_row_size)) {
6744 return;
6745 }
6746 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6747 // of this implementation.
6748 if (type != GL_UNSIGNED_BYTE) {
6749 return;
6750 }
6751 switch (format) {
6752 case GL_RGBA:
6753 case GL_BGRA_EXT:
6754 case GL_ALPHA: {
6755 int offset = (format == GL_ALPHA) ? 0 : 3;
6756 int step = (format == GL_ALPHA) ? 1 : 4;
6757 uint8* dst = static_cast<uint8*>(pixels) + offset;
6758 for (GLint yy = 0; yy < height; ++yy) {
6759 uint8* end = dst + unpadded_row_size;
6760 for (uint8* d = dst; d < end; d += step) {
6761 *d = 255;
6762 }
6763 dst += padded_row_size;
6764 }
6765 break;
6766 }
6767 default:
6768 break;
6769 }
6770 }
6771}
6772
6773
[email protected]f7a64ee2010-02-01 22:24:146774error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:356775 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:446776 if (ShouldDeferReads())
6777 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:316778 GLint x = c.x;
6779 GLint y = c.y;
6780 GLsizei width = c.width;
6781 GLsizei height = c.height;
6782 GLenum format = c.format;
6783 GLenum type = c.type;
[email protected]5a36dc132013-07-23 23:17:556784 GLboolean async = c.async;
[email protected]57f223832010-03-19 01:57:566785 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:516786 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566787 return error::kNoError;
6788 }
[email protected]ed9f9cd2013-02-27 21:12:356789 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186790 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346791 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246792 width, height, format, type, state_.pack_alignment, &pixels_size,
6793 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186794 return error::kOutOfBounds;
6795 }
[email protected]612d2f82009-12-08 20:49:316796 void* pixels = GetSharedMemoryAs<void*>(
6797 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:106798 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:146799 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466800 }
[email protected]de43f082013-04-02 01:16:106801 Result* result = NULL;
6802 if (c.result_shm_id != 0) {
6803 result = GetSharedMemoryAs<Result*>(
6804 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6805 if (!result) {
6806 return error::kOutOfBounds;
6807 }
6808 }
[email protected]a51788e2010-02-24 21:54:256809
[email protected]9438b012010-06-15 22:55:056810 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:516811 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296812 return error::kNoError;
6813 }
[email protected]9438b012010-06-15 22:55:056814 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516815 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:126816 return error::kNoError;
6817 }
[email protected]57f223832010-03-19 01:57:566818 if (width == 0 || height == 0) {
6819 return error::kNoError;
6820 }
6821
[email protected]57f223832010-03-19 01:57:566822 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:306823 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:566824
[email protected]3aad1a32012-09-07 20:54:476825 int32 max_x;
6826 int32 max_y;
6827 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:516828 LOCAL_SET_GL_ERROR(
6829 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:146830 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:316831 }
[email protected]57f223832010-03-19 01:57:566832
[email protected]0d6bfdc2011-11-02 01:32:206833 if (!CheckBoundFramebuffersValid("glReadPixels")) {
6834 return error::kNoError;
6835 }
6836
[email protected]ab09b612013-03-11 22:11:516837 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel");
[email protected]a0b78dc2011-11-11 10:43:106838
6839 ScopedResolvedFrameBufferBinder binder(this, false, true);
6840
[email protected]d37231fa2010-04-09 21:16:026841 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:566842 // The user requested an out of range area. Get the results 1 line
6843 // at a time.
6844 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346845 uint32 unpadded_row_size;
6846 uint32 padded_row_size;
6847 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246848 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346849 &unpadded_row_size, &padded_row_size)) {
[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 GLint dest_x_offset = std::max(-x, 0);
6856 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:346857 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246858 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
6859 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:516860 LOCAL_SET_GL_ERROR(
6861 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566862 return error::kNoError;
6863 }
6864
6865 // Copy each row into the larger dest rect.
6866 int8* dst = static_cast<int8*>(pixels);
6867 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:026868 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:566869 GLint read_width = read_end_x - read_x;
6870 for (GLint yy = 0; yy < height; ++yy) {
6871 GLint ry = y + yy;
6872
6873 // Clear the row.
6874 memset(dst, 0, unpadded_row_size);
6875
6876 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:026877 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:566878 glReadPixels(
6879 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6880 }
6881 dst += padded_row_size;
6882 }
6883 } else {
[email protected]5a36dc132013-07-23 23:17:556884 if (async && features().use_async_readpixels) {
6885 GLuint buffer;
6886 glGenBuffersARB(1, &buffer);
6887 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
6888 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
6889 GLenum error = glGetError();
6890 if (error == GL_NO_ERROR) {
6891 glReadPixels(x, y, width, height, format, type, 0);
6892 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
6893 new FenceCallback()));
6894 WaitForReadPixels(base::Bind(
6895 &GLES2DecoderImpl::FinishReadPixels,
6896 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
6897 <GLES2DecoderImpl>(this),
6898 c, buffer));
6899 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
6900 return error::kNoError;
6901 }
6902 }
[email protected]57f223832010-03-19 01:57:566903 glReadPixels(x, y, width, height, format, type, pixels);
6904 }
[email protected]ab09b612013-03-11 22:11:516905 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:256906 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:106907 if (result != NULL) {
6908 *result = true;
6909 }
[email protected]5a36dc132013-07-23 23:17:556910 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:256911 }
[email protected]4848b9f82011-03-10 18:37:566912
[email protected]f7a64ee2010-02-01 22:24:146913 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326914}
6915
[email protected]f7a64ee2010-02-01 22:24:146916error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:356917 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:196918 GLenum pname = c.pname;
6919 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:056920 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:516921 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:126922 return error::kNoError;
6923 }
[email protected]222471d2011-11-30 18:06:396924 switch (pname) {
6925 case GL_PACK_ALIGNMENT:
6926 case GL_UNPACK_ALIGNMENT:
6927 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:516928 LOCAL_SET_GL_ERROR(
6929 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:396930 return error::kNoError;
6931 }
[email protected]164d6d52012-05-05 00:55:036932 break;
[email protected]0a1e9ad2012-05-04 21:13:036933 case GL_UNPACK_FLIP_Y_CHROMIUM:
6934 unpack_flip_y_ = (param != 0);
6935 return error::kNoError;
6936 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
6937 unpack_premultiply_alpha_ = (param != 0);
6938 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:176939 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
6940 unpack_unpremultiply_alpha_ = (param != 0);
6941 return error::kNoError;
[email protected]222471d2011-11-30 18:06:396942 default:
6943 break;
[email protected]b9849abf2009-11-25 19:13:196944 }
6945 glPixelStorei(pname, param);
6946 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:436947 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246948 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436949 break;
6950 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:426951 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:436952 break;
6953 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246954 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436955 break;
6956 default:
6957 // Validation should have prevented us from getting here.
6958 NOTREACHED();
6959 break;
[email protected]b9849abf2009-11-25 19:13:196960 }
[email protected]f7a64ee2010-02-01 22:24:146961 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196962}
6963
[email protected]1c75a3702011-11-11 14:15:286964error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:356965 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:386966 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:456967 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:516968 LOCAL_SET_GL_ERROR(
6969 GL_INVALID_OPERATION,
6970 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:286971 return error::kNoError;
6972 }
[email protected]7794d512012-04-17 20:36:496973 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:286974 return error::kNoError;
[email protected]7794d512012-04-17 20:36:496975 } else {
6976 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:286977 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:496978 }
[email protected]1c75a3702011-11-11 14:15:286979}
6980
[email protected]558847a2010-03-24 07:02:546981error::Error GLES2DecoderImpl::GetAttribLocationHelper(
6982 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6983 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576984 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:516985 LOCAL_SET_GL_ERROR(
6986 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576987 return error::kNoError;
6988 }
[email protected]df37b9932013-03-08 05:21:426989 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586990 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:426991 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:146992 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196993 }
[email protected]df37b9932013-03-08 05:21:426994 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:516995 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436996 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256997 return error::kNoError;
6998 }
[email protected]b9849abf2009-11-25 19:13:196999 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547000 location_shm_id, location_shm_offset, sizeof(GLint));
7001 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147002 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197003 }
[email protected]558847a2010-03-24 07:02:547004 // Require the client to init this incase the context is lost and we are no
7005 // longer executing commands.
7006 if (*location != -1) {
7007 return error::kGenericError;
7008 }
[email protected]df37b9932013-03-08 05:21:427009 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147010 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197011}
7012
[email protected]558847a2010-03-24 07:02:547013error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357014 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547015 uint32 name_size = c.data_size;
7016 const char* name = GetSharedMemoryAs<const char*>(
7017 c.name_shm_id, c.name_shm_offset, name_size);
7018 if (!name) {
7019 return error::kOutOfBounds;
7020 }
7021 String name_str(name, name_size);
7022 return GetAttribLocationHelper(
7023 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7024}
7025
[email protected]f7a64ee2010-02-01 22:24:147026error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357027 uint32 immediate_data_size, const cmds::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:547028 uint32 name_size = c.data_size;
7029 const char* name = GetImmediateDataAs<const char*>(
7030 c, name_size, immediate_data_size);
7031 if (!name) {
7032 return error::kOutOfBounds;
7033 }
7034 String name_str(name, name_size);
7035 return GetAttribLocationHelper(
7036 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7037}
7038
7039error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357040 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547041 Bucket* bucket = GetBucket(c.name_bucket_id);
7042 if (!bucket) {
7043 return error::kInvalidArguments;
7044 }
7045 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187046 if (!bucket->GetAsString(&name_str)) {
7047 return error::kInvalidArguments;
7048 }
[email protected]558847a2010-03-24 07:02:547049 return GetAttribLocationHelper(
7050 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7051}
7052
7053error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7054 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7055 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577056 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517057 LOCAL_SET_GL_ERROR(
7058 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577059 return error::kNoError;
7060 }
[email protected]df37b9932013-03-08 05:21:427061 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587062 client_id, "glUniformLocation");
[email protected]df37b9932013-03-08 05:21:427063 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147064 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197065 }
[email protected]df37b9932013-03-08 05:21:427066 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517067 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437068 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257069 return error::kNoError;
7070 }
[email protected]b9849abf2009-11-25 19:13:197071 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547072 location_shm_id, location_shm_offset, sizeof(GLint));
7073 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147074 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197075 }
[email protected]558847a2010-03-24 07:02:547076 // Require the client to init this incase the context is lost an we are no
7077 // longer executing commands.
7078 if (*location != -1) {
7079 return error::kGenericError;
7080 }
[email protected]df37b9932013-03-08 05:21:427081 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147082 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197083}
7084
[email protected]f7a64ee2010-02-01 22:24:147085error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357086 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197087 uint32 name_size = c.data_size;
7088 const char* name = GetSharedMemoryAs<const char*>(
7089 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547090 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147091 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197092 }
7093 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547094 return GetUniformLocationHelper(
7095 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197096}
7097
[email protected]f7a64ee2010-02-01 22:24:147098error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357099 uint32 immediate_data_size, const cmds::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197100 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:307101 const char* name = GetImmediateDataAs<const char*>(
7102 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:547103 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147104 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197105 }
7106 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547107 return GetUniformLocationHelper(
7108 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7109}
7110
7111error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357112 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547113 Bucket* bucket = GetBucket(c.name_bucket_id);
7114 if (!bucket) {
7115 return error::kInvalidArguments;
7116 }
7117 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187118 if (!bucket->GetAsString(&name_str)) {
7119 return error::kInvalidArguments;
7120 }
[email protected]558847a2010-03-24 07:02:547121 return GetUniformLocationHelper(
7122 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197123}
7124
[email protected]ddd968b82010-03-02 00:44:297125error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357126 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297127 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057128 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517129 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297130 return error::kNoError;
7131 }
[email protected]1958e0e2010-04-22 05:17:157132 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
7133 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:047134 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157135 switch (name) {
7136 case GL_VERSION:
7137 str = "OpenGL ES 2.0 Chromium";
7138 break;
7139 case GL_SHADING_LANGUAGE_VERSION:
7140 str = "OpenGL ES GLSL ES 1.0 Chromium";
7141 break;
[email protected]32939602012-05-09 06:25:167142 case GL_RENDERER:
7143 str = "Chromium";
7144 break;
7145 case GL_VENDOR:
7146 str = "Chromium";
7147 break;
[email protected]1958e0e2010-04-22 05:17:157148 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047149 {
[email protected]70dc60932013-06-04 03:33:497150 // For WebGL contexts, strip out the OES derivatives and
7151 // EXT frag depth extensions if they have not been enabled.
7152 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047153 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497154 if (!derivatives_explicitly_enabled_) {
7155 size_t offset = extensions.find(kOESDerivativeExtension);
7156 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097157 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497158 std::string());
7159 }
7160 }
7161 if (!frag_depth_explicitly_enabled_) {
7162 size_t offset = extensions.find(kEXTFragDepthExtension);
7163 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097164 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497165 std::string());
7166 }
[email protected]f0d74742011-10-03 16:31:047167 }
[email protected]aff39ac82013-06-08 04:53:137168 if (!draw_buffers_explicitly_enabled_) {
7169 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7170 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097171 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137172 std::string());
7173 }
7174 }
[email protected]f0d74742011-10-03 16:31:047175 } else {
[email protected]6f5fac9d12012-06-26 21:02:457176 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047177 }
[email protected]6f5fac9d12012-06-26 21:02:457178 std::string surface_extensions = surface_->GetExtensions();
7179 if (!surface_extensions.empty())
7180 extensions += " " + surface_extensions;
7181 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047182 }
[email protected]1958e0e2010-04-22 05:17:157183 break;
7184 default:
7185 str = gl_str;
7186 break;
7187 }
[email protected]ddd968b82010-03-02 00:44:297188 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157189 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297190 return error::kNoError;
7191}
7192
[email protected]0c86dbf2010-03-05 08:14:117193error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357194 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117195 GLenum target = static_cast<GLenum>(c.target);
7196 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7197 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7198 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7199 GLenum usage = static_cast<GLenum>(c.usage);
7200 const void* data = NULL;
7201 if (data_shm_id != 0 || data_shm_offset != 0) {
7202 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7203 if (!data) {
7204 return error::kOutOfBounds;
7205 }
7206 }
[email protected]0fbba3732013-07-17 15:40:137207 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147208 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197209}
7210
[email protected]f7a64ee2010-02-01 22:24:147211error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357212 uint32 immediate_data_size, const cmds::BufferDataImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197213 GLenum target = static_cast<GLenum>(c.target);
7214 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:307215 const void* data = GetImmediateDataAs<const void*>(
7216 c, size, immediate_data_size);
7217 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147218 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:307219 }
[email protected]b9849abf2009-11-25 19:13:197220 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0fbba3732013-07-17 15:40:137221 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]0c86dbf2010-03-05 08:14:117222 return error::kNoError;
7223}
7224
7225void GLES2DecoderImpl::DoBufferSubData(
7226 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137227 // Just delegate it. Some validation is actually done before this.
7228 buffer_manager()->ValidateAndDoBufferSubData(
7229 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197230}
7231
[email protected]0d6bfdc2011-11-02 01:32:207232bool GLES2DecoderImpl::ClearLevel(
7233 unsigned service_id,
7234 unsigned bind_target,
7235 unsigned target,
7236 int level,
7237 unsigned format,
7238 unsigned type,
7239 int width,
[email protected]4502e6492011-12-14 19:39:157240 int height,
7241 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007242 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7243 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7244 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7245 // on depth formats.
7246 GLuint fb = 0;
7247 glGenFramebuffersEXT(1, &fb);
7248 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7249
7250 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7251 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7252 GL_DEPTH_ATTACHMENT;
7253
7254 glFramebufferTexture2DEXT(
7255 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7256 // ANGLE promises a depth only attachment ok.
7257 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7258 GL_FRAMEBUFFER_COMPLETE) {
7259 return false;
7260 }
7261 glClearStencil(0);
7262 glStencilMask(-1);
7263 glClearDepth(1.0f);
7264 glDepthMask(true);
7265 glDisable(GL_SCISSOR_TEST);
7266 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7267
7268 RestoreClearState();
7269
7270 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357271 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007272 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7273 GLuint fb_service_id =
7274 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7275 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7276 return true;
7277 }
7278
[email protected]45d15a62012-04-18 14:33:177279 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7280
7281 uint32 size;
7282 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347283 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247284 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177285 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207286 return false;
7287 }
[email protected]45d15a62012-04-18 14:33:177288
[email protected]a5d3dad2012-05-26 04:34:447289 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7290
[email protected]45d15a62012-04-18 14:33:177291 int tile_height;
7292
7293 if (size > kMaxZeroSize) {
7294 if (kMaxZeroSize < padded_row_size) {
7295 // That'd be an awfully large texture.
7296 return false;
7297 }
7298 // We should never have a large total size with a zero row size.
7299 DCHECK_GT(padded_row_size, 0U);
7300 tile_height = kMaxZeroSize / padded_row_size;
7301 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247302 width, tile_height, format, type, state_.unpack_alignment, &size,
7303 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177304 return false;
7305 }
[email protected]4502e6492011-12-14 19:39:157306 } else {
[email protected]45d15a62012-04-18 14:33:177307 tile_height = height;
7308 }
7309
7310 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557311 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177312 memset(zero.get(), 0, size);
7313 glBindTexture(bind_target, service_id);
7314
7315 GLint y = 0;
7316 while (y < height) {
7317 GLint h = y + tile_height > height ? height - y : tile_height;
7318 if (is_texture_immutable || h != height) {
7319 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7320 } else {
[email protected]8f1d2aa2013-05-10 23:45:387321 glTexImage2D(
[email protected]45d15a62012-04-18 14:33:177322 target, level, format, width, h, 0, format, type, zero.get());
7323 }
7324 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157325 }
[email protected]c986af502013-08-14 01:04:447326 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
7327 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:077328 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207329 return true;
7330}
7331
[email protected]ad84a3a2012-06-08 21:42:437332namespace {
7333
7334const int kS3TCBlockWidth = 4;
7335const int kS3TCBlockHeight = 4;
7336const int kS3TCDXT1BlockSize = 8;
7337const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077338const int kETC1BlockWidth = 4;
7339const int kETC1BlockHeight = 4;
7340const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437341
7342bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517343 return (size == 1) ||
7344 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437345}
7346
7347} // anonymous namespace.
7348
7349bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7350 const char* function_name,
7351 GLsizei width, GLsizei height, GLenum format, size_t size) {
7352 unsigned int bytes_required = 0;
7353
7354 switch (format) {
7355 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7356 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7357 int num_blocks_across =
7358 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7359 int num_blocks_down =
7360 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7361 int num_blocks = num_blocks_across * num_blocks_down;
7362 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7363 break;
7364 }
7365 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7366 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7367 int num_blocks_across =
7368 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7369 int num_blocks_down =
7370 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7371 int num_blocks = num_blocks_across * num_blocks_down;
7372 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7373 break;
7374 }
[email protected]2d3765b2012-10-03 00:31:077375 case GL_ETC1_RGB8_OES: {
7376 int num_blocks_across =
7377 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7378 int num_blocks_down =
7379 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7380 int num_blocks = num_blocks_across * num_blocks_down;
7381 bytes_required = num_blocks * kETC1BlockSize;
7382 break;
7383 }
[email protected]ad84a3a2012-06-08 21:42:437384 default:
[email protected]ab09b612013-03-11 22:11:517385 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437386 return false;
7387 }
7388
7389 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517390 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437391 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7392 return false;
7393 }
7394
7395 return true;
7396}
7397
7398bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7399 const char* function_name,
7400 GLint level, GLsizei width, GLsizei height, GLenum format) {
7401 switch (format) {
7402 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7403 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7404 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7405 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7406 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517407 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437408 GL_INVALID_OPERATION, function_name,
7409 "width or height invalid for level");
7410 return false;
7411 }
7412 return true;
7413 }
[email protected]2d3765b2012-10-03 00:31:077414 case GL_ETC1_RGB8_OES:
7415 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517416 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077417 GL_INVALID_OPERATION, function_name,
7418 "width or height invalid for level");
7419 return false;
7420 }
7421 return true;
[email protected]ad84a3a2012-06-08 21:42:437422 default:
7423 return false;
7424 }
7425}
7426
7427bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7428 const char* function_name,
7429 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7430 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357431 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437432 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517433 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437434 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7435 return false;
7436 }
7437
7438 switch (format) {
7439 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7440 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7441 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7442 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7443 const int kBlockWidth = 4;
7444 const int kBlockHeight = 4;
7445 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517446 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437447 GL_INVALID_OPERATION, function_name,
7448 "xoffset or yoffset not multiple of 4");
7449 return false;
7450 }
7451 GLsizei tex_width = 0;
7452 GLsizei tex_height = 0;
7453 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7454 width - xoffset > tex_width ||
7455 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517456 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437457 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7458 return false;
7459 }
7460 return ValidateCompressedTexDimensions(
7461 function_name, level, width, height, format);
7462 }
[email protected]2d3765b2012-10-03 00:31:077463 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517464 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077465 GL_INVALID_OPERATION, function_name,
7466 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7467 return false;
7468 }
[email protected]ad84a3a2012-06-08 21:42:437469 default:
7470 return false;
7471 }
7472}
7473
[email protected]a93bb842010-02-16 23:03:477474error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7475 GLenum target,
7476 GLint level,
7477 GLenum internal_format,
7478 GLsizei width,
7479 GLsizei height,
7480 GLint border,
7481 GLsizei image_size,
7482 const void* data) {
[email protected]a93bb842010-02-16 23:03:477483 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057484 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517485 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7486 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297487 return error::kNoError;
7488 }
[email protected]9438b012010-06-15 22:55:057489 if (!validators_->compressed_texture_format.IsValid(
7490 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517491 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537492 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477493 return error::kNoError;
7494 }
[email protected]80eb6b52012-01-19 00:14:417495 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477496 border != 0) {
[email protected]ab09b612013-03-11 22:11:517497 LOCAL_SET_GL_ERROR(
7498 GL_INVALID_VALUE,
7499 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477500 return error::kNoError;
7501 }
[email protected]c986af502013-08-14 01:04:447502 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7503 &state_, target);
[email protected]370eaf12013-05-18 09:19:497504 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517505 LOCAL_SET_GL_ERROR(
7506 GL_INVALID_VALUE,
7507 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477508 return error::kNoError;
7509 }
[email protected]370eaf12013-05-18 09:19:497510 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077511 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517512 LOCAL_SET_GL_ERROR(
7513 GL_INVALID_OPERATION,
7514 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:437515 return error::kNoError;
7516 }
7517
7518 if (!ValidateCompressedTexDimensions(
7519 "glCompressedTexImage2D", level, width, height, internal_format) ||
7520 !ValidateCompressedTexFuncData(
7521 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177522 return error::kNoError;
7523 }
[email protected]968351b2011-12-20 08:26:517524
[email protected]7989c9e2013-01-23 06:39:267525 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:517526 LOCAL_SET_GL_ERROR(
7527 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267528 return error::kNoError;
7529 }
7530
[email protected]02965c22013-03-09 02:40:077531 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:447532 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:517533 }
7534
[email protected]40d90a22013-04-09 03:39:557535 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:477536 if (!data) {
7537 zero.reset(new int8[image_size]);
7538 memset(zero.get(), 0, image_size);
7539 data = zero.get();
7540 }
[email protected]ab09b612013-03-11 22:11:517541 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:477542 glCompressedTexImage2D(
7543 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:517544 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437545 if (error == GL_NO_ERROR) {
7546 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497547 texture_ref, target, level, internal_format,
7548 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:437549 }
[email protected]a93bb842010-02-16 23:03:477550 return error::kNoError;
7551}
7552
[email protected]f7a64ee2010-02-01 22:24:147553error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357554 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:197555 GLenum target = static_cast<GLenum>(c.target);
7556 GLint level = static_cast<GLint>(c.level);
7557 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7558 GLsizei width = static_cast<GLsizei>(c.width);
7559 GLsizei height = static_cast<GLsizei>(c.height);
7560 GLint border = static_cast<GLint>(c.border);
7561 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7562 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7563 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7564 const void* data = NULL;
7565 if (data_shm_id != 0 || data_shm_offset != 0) {
7566 data = GetSharedMemoryAs<const void*>(
7567 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467568 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147569 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197570 }
7571 }
[email protected]a93bb842010-02-16 23:03:477572 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197573 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197574}
7575
[email protected]f7a64ee2010-02-01 22:24:147576error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357577 uint32 immediate_data_size, const cmds::CompressedTexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197578 GLenum target = static_cast<GLenum>(c.target);
7579 GLint level = static_cast<GLint>(c.level);
7580 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7581 GLsizei width = static_cast<GLsizei>(c.width);
7582 GLsizei height = static_cast<GLsizei>(c.height);
7583 GLint border = static_cast<GLint>(c.border);
7584 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307585 const void* data = GetImmediateDataAs<const void*>(
7586 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467587 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147588 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467589 }
[email protected]a93bb842010-02-16 23:03:477590 return DoCompressedTexImage2D(
7591 target, level, internal_format, width, height, border, image_size, data);
7592}
7593
[email protected]b6140d02010-05-17 14:47:167594error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:357595 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167596 GLenum target = static_cast<GLenum>(c.target);
7597 GLint level = static_cast<GLint>(c.level);
7598 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7599 GLsizei width = static_cast<GLsizei>(c.width);
7600 GLsizei height = static_cast<GLsizei>(c.height);
7601 GLint border = static_cast<GLint>(c.border);
7602 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287603 if (!bucket) {
7604 return error::kInvalidArguments;
7605 }
7606 uint32 data_size = bucket->size();
7607 GLsizei imageSize = data_size;
7608 const void* data = bucket->GetData(0, data_size);
7609 if (!data) {
7610 return error::kInvalidArguments;
7611 }
[email protected]b6140d02010-05-17 14:47:167612 return DoCompressedTexImage2D(
7613 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287614 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167615}
7616
7617error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7618 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:357619 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167620 GLenum target = static_cast<GLenum>(c.target);
7621 GLint level = static_cast<GLint>(c.level);
7622 GLint xoffset = static_cast<GLint>(c.xoffset);
7623 GLint yoffset = static_cast<GLint>(c.yoffset);
7624 GLsizei width = static_cast<GLsizei>(c.width);
7625 GLsizei height = static_cast<GLsizei>(c.height);
7626 GLenum format = static_cast<GLenum>(c.format);
7627 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287628 if (!bucket) {
7629 return error::kInvalidArguments;
7630 }
[email protected]b6140d02010-05-17 14:47:167631 uint32 data_size = bucket->size();
7632 GLsizei imageSize = data_size;
7633 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287634 if (!data) {
7635 return error::kInvalidArguments;
7636 }
[email protected]9438b012010-06-15 22:55:057637 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517638 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:537639 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167640 return error::kNoError;
7641 }
[email protected]9438b012010-06-15 22:55:057642 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517643 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7644 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057645 return error::kNoError;
7646 }
[email protected]b6140d02010-05-17 14:47:167647 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:517648 LOCAL_SET_GL_ERROR(
7649 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167650 return error::kNoError;
7651 }
7652 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:517653 LOCAL_SET_GL_ERROR(
7654 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167655 return error::kNoError;
7656 }
7657 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:517658 LOCAL_SET_GL_ERROR(
7659 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167660 return error::kNoError;
7661 }
[email protected]cadde4a2010-07-31 17:10:437662 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167663 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7664 return error::kNoError;
7665}
7666
[email protected]f7a64ee2010-02-01 22:24:147667error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357668 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387669 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]c986af502013-08-14 01:04:447670 // Set as failed for now, but if it successed, this will be set to not failed.
7671 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:197672 GLenum target = static_cast<GLenum>(c.target);
7673 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:447674 // TODO(kloveless): Change TexImage2D command to use unsigned integer
7675 // for internalformat.
7676 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197677 GLsizei width = static_cast<GLsizei>(c.width);
7678 GLsizei height = static_cast<GLsizei>(c.height);
7679 GLint border = static_cast<GLint>(c.border);
7680 GLenum format = static_cast<GLenum>(c.format);
7681 GLenum type = static_cast<GLenum>(c.type);
7682 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7683 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187684 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347685 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247686 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347687 NULL)) {
[email protected]a76b0052010-03-05 00:33:187688 return error::kOutOfBounds;
7689 }
[email protected]b9849abf2009-11-25 19:13:197690 const void* pixels = NULL;
7691 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7692 pixels = GetSharedMemoryAs<const void*>(
7693 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467694 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147695 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197696 }
7697 }
[email protected]f598f422012-12-07 08:30:037698
[email protected]c986af502013-08-14 01:04:447699 TextureManager::DoTextImage2DArguments args = {
7700 target, level, internal_format, width, height, border, format, type,
7701 pixels, pixels_size};
7702 texture_manager()->ValidateAndDoTexImage2D(
7703 &texture_state_, &state_, &framebuffer_state_, args);
[email protected]f598f422012-12-07 08:30:037704 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197705}
7706
[email protected]f7a64ee2010-02-01 22:24:147707error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357708 uint32 immediate_data_size, const cmds::TexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197709 GLenum target = static_cast<GLenum>(c.target);
7710 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:447711 // TODO(kloveless): Change TexImage2DImmediate command to use unsigned
7712 // integer for internalformat.
7713 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197714 GLsizei width = static_cast<GLsizei>(c.width);
7715 GLsizei height = static_cast<GLsizei>(c.height);
7716 GLint border = static_cast<GLint>(c.border);
7717 GLenum format = static_cast<GLenum>(c.format);
7718 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:187719 uint32 size;
[email protected]3458a64a2012-04-10 17:39:347720 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247721 width, height, format, type, state_.unpack_alignment, &size,
7722 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187723 return error::kOutOfBounds;
7724 }
[email protected]07f54fcc2009-12-22 02:46:307725 const void* pixels = GetImmediateDataAs<const void*>(
7726 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467727 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147728 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467729 }
[email protected]c986af502013-08-14 01:04:447730
7731 TextureManager::DoTextImage2DArguments args = {
7732 target, level, internal_format, width, height, border, format, type,
7733 pixels, size};
7734 texture_manager()->ValidateAndDoTexImage2D(
7735 &texture_state_, &state_, &framebuffer_state_, args);
[email protected]f7a64ee2010-02-01 22:24:147736 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327737}
7738
[email protected]cadde4a2010-07-31 17:10:437739void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7740 GLenum target,
7741 GLint level,
7742 GLint xoffset,
7743 GLint yoffset,
7744 GLsizei width,
7745 GLsizei height,
7746 GLenum format,
7747 GLsizei image_size,
7748 const void * data) {
[email protected]c986af502013-08-14 01:04:447749 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7750 &state_, target);
[email protected]370eaf12013-05-18 09:19:497751 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517752 LOCAL_SET_GL_ERROR(
7753 GL_INVALID_OPERATION,
7754 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437755 return;
7756 }
[email protected]370eaf12013-05-18 09:19:497757 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:437758 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527759 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:077760 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:517761 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527762 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437763 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527764 return;
7765 }
7766 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:517767 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527768 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437769 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527770 return;
7771 }
[email protected]02965c22013-03-09 02:40:077772 if (!texture->ValidForTexture(
[email protected]df6cf1ad2011-01-29 01:20:527773 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:517774 LOCAL_SET_GL_ERROR(
7775 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437776 return;
7777 }
[email protected]ad84a3a2012-06-08 21:42:437778
7779 if (!ValidateCompressedTexFuncData(
7780 "glCompressedTexSubImage2D", width, height, format, image_size) ||
7781 !ValidateCompressedTexSubDimensions(
7782 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:077783 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:437784 return;
7785 }
7786
7787
[email protected]0d6bfdc2011-11-02 01:32:207788 // Note: There is no need to deal with texture cleared tracking here
7789 // because the validation above means you can only get here if the level
7790 // is already a matching compressed format and in that case
7791 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:437792 glCompressedTexSubImage2D(
7793 target, level, xoffset, yoffset, width, height, format, image_size, data);
7794}
7795
[email protected]6e288612010-12-21 20:45:037796static void Clip(
7797 GLint start, GLint range, GLint sourceRange,
7798 GLint* out_start, GLint* out_range) {
7799 DCHECK(out_start);
7800 DCHECK(out_range);
7801 if (start < 0) {
7802 range += start;
7803 start = 0;
7804 }
7805 GLint end = start + range;
7806 if (end > sourceRange) {
7807 range -= end - sourceRange;
7808 }
7809 *out_start = start;
7810 *out_range = range;
7811}
7812
[email protected]cadde4a2010-07-31 17:10:437813void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:447814 GLenum target,
7815 GLint level,
7816 GLenum internal_format,
7817 GLint x,
7818 GLint y,
7819 GLsizei width,
7820 GLsizei height,
7821 GLint border) {
[email protected]09e17272012-11-30 10:30:447822 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:447823 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7824 &state_, target);
[email protected]370eaf12013-05-18 09:19:497825 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517826 LOCAL_SET_GL_ERROR(
7827 GL_INVALID_OPERATION,
7828 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437829 return;
7830 }
[email protected]370eaf12013-05-18 09:19:497831 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077832 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517833 LOCAL_SET_GL_ERROR(
7834 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:177835 }
[email protected]80eb6b52012-01-19 00:14:417836 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:187837 border != 0) {
[email protected]ab09b612013-03-11 22:11:517838 LOCAL_SET_GL_ERROR(
7839 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:187840 return;
7841 }
[email protected]c986af502013-08-14 01:04:447842 if (!texture_manager()->ValidateTextureParameters(
7843 state_.GetErrorState(), "glCopyTexImage2D", target, internal_format,
7844 GL_UNSIGNED_BYTE, level)) {
[email protected]81375742012-06-08 00:04:007845 return;
7846 }
[email protected]f5719fb2010-08-04 18:27:187847
[email protected]9edc6b22010-12-23 02:00:267848 // Check we have compatible formats.
7849 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7850 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7851 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
7852
7853 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:517854 LOCAL_SET_GL_ERROR(
7855 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:267856 return;
7857 }
7858
[email protected]81375742012-06-08 00:04:007859 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:517860 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:007861 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:267862 "glCopyTexImage2D", "can not be used with depth or stencil textures");
7863 return;
7864 }
7865
7866 uint32 estimated_size = 0;
7867 if (!GLES2Util::ComputeImageDataSizes(
7868 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
7869 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517870 LOCAL_SET_GL_ERROR(
7871 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:267872 return;
7873 }
7874
7875 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:517876 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:007877 return;
7878 }
7879
[email protected]a0b78dc2011-11-11 10:43:107880 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
7881 return;
7882 }
7883
[email protected]ab09b612013-03-11 22:11:517884 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:277885 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:037886 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:267887
[email protected]02965c22013-03-09 02:40:077888 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:447889 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:467890 }
7891
[email protected]9edc6b22010-12-23 02:00:267892 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:037893 GLint copyX = 0;
7894 GLint copyY = 0;
7895 GLint copyWidth = 0;
7896 GLint copyHeight = 0;
7897 Clip(x, width, size.width(), &copyX, &copyWidth);
7898 Clip(y, height, size.height(), &copyY, &copyHeight);
7899
7900 if (copyX != x ||
7901 copyY != y ||
7902 copyWidth != width ||
7903 copyHeight != height) {
7904 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:207905 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:077906 texture->service_id(), texture->target(),
[email protected]4502e6492011-12-14 19:39:157907 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
[email protected]02965c22013-03-09 02:40:077908 texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:517909 LOCAL_SET_GL_ERROR(
7910 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:037911 return;
7912 }
[email protected]6e288612010-12-21 20:45:037913 if (copyHeight > 0 && copyWidth > 0) {
7914 GLint dx = copyX - x;
7915 GLint dy = copyY - y;
7916 GLint destX = dx;
7917 GLint destY = dy;
7918 glCopyTexSubImage2D(target, level,
7919 destX, destY, copyX, copyY,
7920 copyWidth, copyHeight);
7921 }
7922 } else {
7923 glCopyTexImage2D(target, level, internal_format,
7924 copyX, copyY, copyWidth, copyHeight, border);
7925 }
[email protected]ab09b612013-03-11 22:11:517926 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437927 if (error == GL_NO_ERROR) {
7928 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497929 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:207930 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:437931 }
7932}
7933
7934void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:447935 GLenum target,
7936 GLint level,
7937 GLint xoffset,
7938 GLint yoffset,
7939 GLint x,
7940 GLint y,
7941 GLsizei width,
7942 GLsizei height) {
[email protected]09e17272012-11-30 10:30:447943 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:447944 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7945 &state_, target);
[email protected]370eaf12013-05-18 09:19:497946 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517947 LOCAL_SET_GL_ERROR(
7948 GL_INVALID_OPERATION,
7949 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437950 return;
7951 }
[email protected]370eaf12013-05-18 09:19:497952 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:437953 GLenum type = 0;
7954 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:077955 if (!texture->GetLevelType(target, level, &type, &format) ||
7956 !texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:437957 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:517958 LOCAL_SET_GL_ERROR(
7959 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437960 return;
7961 }
[email protected]85a4ac22013-05-31 01:58:477962 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:517963 LOCAL_SET_GL_ERROR(
7964 GL_INVALID_OPERATION,
7965 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:597966 return;
7967 }
[email protected]9edc6b22010-12-23 02:00:267968
7969 // Check we have compatible formats.
7970 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7971 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7972 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
7973
[email protected]2d3765b2012-10-03 00:31:077974 if (!channels_needed ||
7975 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:517976 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437977 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:267978 return;
7979 }
7980
[email protected]81375742012-06-08 00:04:007981 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:517982 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:007983 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437984 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:007985 return;
7986 }
7987
[email protected]a0b78dc2011-11-11 10:43:107988 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
7989 return;
7990 }
7991
[email protected]de26b3c2011-08-03 21:54:277992 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:037993 gfx::Size size = GetBoundReadFrameBufferSize();
7994 GLint copyX = 0;
7995 GLint copyY = 0;
7996 GLint copyWidth = 0;
7997 GLint copyHeight = 0;
7998 Clip(x, width, size.width(), &copyX, &copyWidth);
7999 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208000
[email protected]370eaf12013-05-18 09:19:498001 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518002 LOCAL_SET_GL_ERROR(
8003 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208004 return;
8005 }
8006
[email protected]6e288612010-12-21 20:45:038007 if (copyX != x ||
8008 copyY != y ||
8009 copyWidth != width ||
8010 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208011 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038012 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348013 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248014 width, height, format, type, state_.unpack_alignment, &pixels_size,
8015 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518016 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438017 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038018 return;
8019 }
[email protected]40d90a22013-04-09 03:39:558020 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038021 memset(zero.get(), 0, pixels_size);
8022 glTexSubImage2D(
8023 target, level, xoffset, yoffset, width, height,
8024 format, type, zero.get());
8025 }
[email protected]0d6bfdc2011-11-02 01:32:208026
[email protected]6e288612010-12-21 20:45:038027 if (copyHeight > 0 && copyWidth > 0) {
8028 GLint dx = copyX - x;
8029 GLint dy = copyY - y;
8030 GLint destX = xoffset + dx;
8031 GLint destY = yoffset + dy;
8032 glCopyTexSubImage2D(target, level,
8033 destX, destY, copyX, copyY,
8034 copyWidth, copyHeight);
8035 }
[email protected]cadde4a2010-07-31 17:10:438036}
8037
[email protected]f598f422012-12-07 08:30:038038bool GLES2DecoderImpl::ValidateTexSubImage2D(
8039 error::Error* error,
8040 const char* function_name,
8041 GLenum target,
8042 GLint level,
8043 GLint xoffset,
8044 GLint yoffset,
8045 GLsizei width,
8046 GLsizei height,
8047 GLenum format,
8048 GLenum type,
8049 const void * data) {
8050 (*error) = error::kNoError;
8051 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518052 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038053 return false;
8054 }
8055 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518056 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038057 return false;
8058 }
8059 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518060 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038061 return false;
8062 }
8063 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518064 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:038065 return false;
8066 }
8067 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518068 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:038069 return false;
8070 }
[email protected]c986af502013-08-14 01:04:448071 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8072 &state_, target);
[email protected]370eaf12013-05-18 09:19:498073 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518074 LOCAL_SET_GL_ERROR(
8075 GL_INVALID_OPERATION,
8076 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038077 return false;
[email protected]cadde4a2010-07-31 17:10:438078 }
[email protected]370eaf12013-05-18 09:19:498079 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528080 GLenum current_type = 0;
8081 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078082 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518083 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038084 GL_INVALID_OPERATION, function_name, "level does not exist.");
8085 return false;
[email protected]df6cf1ad2011-01-29 01:20:528086 }
8087 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:518088 LOCAL_SET_GL_ERROR(
8089 GL_INVALID_OPERATION,
8090 function_name, "format does not match internal format.");
[email protected]f598f422012-12-07 08:30:038091 return false;
[email protected]df6cf1ad2011-01-29 01:20:528092 }
8093 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518094 LOCAL_SET_GL_ERROR(
8095 GL_INVALID_OPERATION,
8096 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038097 return false;
[email protected]df6cf1ad2011-01-29 01:20:528098 }
[email protected]85a4ac22013-05-31 01:58:478099 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518100 LOCAL_SET_GL_ERROR(
8101 GL_INVALID_OPERATION,
8102 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598103 return false;
8104 }
[email protected]02965c22013-03-09 02:40:078105 if (!texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438106 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518107 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038108 return false;
[email protected]cadde4a2010-07-31 17:10:438109 }
[email protected]81375742012-06-08 00:04:008110 if ((GLES2Util::GetChannelsForFormat(format) &
8111 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518112 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008113 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038114 function_name, "can not supply data for depth or stencil textures");
8115 return false;
[email protected]81375742012-06-08 00:04:008116 }
[email protected]f598f422012-12-07 08:30:038117 if (data == NULL) {
8118 (*error) = error::kOutOfBounds;
8119 return false;
8120 }
8121 return true;
8122}
[email protected]81375742012-06-08 00:04:008123
[email protected]f598f422012-12-07 08:30:038124error::Error GLES2DecoderImpl::DoTexSubImage2D(
8125 GLenum target,
8126 GLint level,
8127 GLint xoffset,
8128 GLint yoffset,
8129 GLsizei width,
8130 GLsizei height,
8131 GLenum format,
8132 GLenum type,
8133 const void * data) {
8134 error::Error error = error::kNoError;
8135 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8136 xoffset, yoffset, width, height, format, type, data)) {
8137 return error;
8138 }
[email protected]c986af502013-08-14 01:04:448139 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8140 &state_, target);
[email protected]370eaf12013-05-18 09:19:498141 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158142 GLsizei tex_width = 0;
8143 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078144 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158145 DCHECK(ok);
8146 if (xoffset != 0 || yoffset != 0 ||
8147 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498148 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8149 target, level)) {
[email protected]ab09b612013-03-11 22:11:518150 LOCAL_SET_GL_ERROR(
8151 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038152 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308153 }
[email protected]c986af502013-08-14 01:04:448154 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158155 glTexSubImage2D(
8156 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038157 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208158 }
[email protected]4502e6492011-12-14 19:39:158159
[email protected]c986af502013-08-14 01:04:448160 if (texture_state_.teximage2d_faster_than_texsubimage2d &&
8161 !texture->IsImmutable()) {
8162 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158163 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8164 // same as internal_foramt. If that changes we'll need to look them up.
[email protected]8f1d2aa2013-05-10 23:45:388165 glTexImage2D(
[email protected]4502e6492011-12-14 19:39:158166 target, level, format, width, height, 0, format, type, data);
8167 } else {
[email protected]c986af502013-08-14 01:04:448168 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158169 glTexSubImage2D(
8170 target, level, xoffset, yoffset, width, height, format, type, data);
8171 }
[email protected]370eaf12013-05-18 09:19:498172 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038173 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438174}
8175
[email protected]b493ee622011-04-13 23:52:008176error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358177 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388178 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008179 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448180 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008181 return error::kNoError;
8182
8183 GLenum target = static_cast<GLenum>(c.target);
8184 GLint level = static_cast<GLint>(c.level);
8185 GLint xoffset = static_cast<GLint>(c.xoffset);
8186 GLint yoffset = static_cast<GLint>(c.yoffset);
8187 GLsizei width = static_cast<GLsizei>(c.width);
8188 GLsizei height = static_cast<GLsizei>(c.height);
8189 GLenum format = static_cast<GLenum>(c.format);
8190 GLenum type = static_cast<GLenum>(c.type);
8191 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348192 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248193 width, height, format, type, state_.unpack_alignment, &data_size,
8194 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008195 return error::kOutOfBounds;
8196 }
8197 const void* pixels = GetSharedMemoryAs<const void*>(
8198 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038199 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008200 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008201}
8202
8203error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:358204 uint32 immediate_data_size, const cmds::TexSubImage2DImmediate& c) {
[email protected]b493ee622011-04-13 23:52:008205 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448206 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008207 return error::kNoError;
8208
8209 GLenum target = static_cast<GLenum>(c.target);
8210 GLint level = static_cast<GLint>(c.level);
8211 GLint xoffset = static_cast<GLint>(c.xoffset);
8212 GLint yoffset = static_cast<GLint>(c.yoffset);
8213 GLsizei width = static_cast<GLsizei>(c.width);
8214 GLsizei height = static_cast<GLsizei>(c.height);
8215 GLenum format = static_cast<GLenum>(c.format);
8216 GLenum type = static_cast<GLenum>(c.type);
8217 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348218 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248219 width, height, format, type, state_.unpack_alignment, &data_size,
8220 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008221 return error::kOutOfBounds;
8222 }
8223 const void* pixels = GetImmediateDataAs<const void*>(
8224 c, data_size, immediate_data_size);
[email protected]f598f422012-12-07 08:30:038225 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008226 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008227}
8228
[email protected]f7a64ee2010-02-01 22:24:148229error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358230 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368231 GLuint index = static_cast<GLuint>(c.index);
8232 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358233 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258234 Result* result = GetSharedMemoryAs<Result*>(
8235 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368236 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148237 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368238 }
[email protected]07d0cc82010-02-17 04:51:408239 // Check that the client initialized the result.
8240 if (result->size != 0) {
8241 return error::kInvalidArguments;
8242 }
[email protected]9438b012010-06-15 22:55:058243 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518244 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8245 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148246 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368247 }
[email protected]3916c97e2010-02-25 03:20:508248 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518249 LOCAL_SET_GL_ERROR(
8250 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148251 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368252 }
[email protected]0bfd9882010-02-05 23:02:258253 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088254 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358255 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148256 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328257}
8258
[email protected]f7b85372010-02-03 01:11:378259bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428260 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378261 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128262 error::Error* error, GLint* real_location,
8263 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108264 DCHECK(error);
8265 DCHECK(service_id);
8266 DCHECK(result_pointer);
8267 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128268 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378269 *error = error::kNoError;
8270 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258271 SizedResult<GLint>* result;
8272 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8273 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8274 if (!result) {
[email protected]f7b85372010-02-03 01:11:378275 *error = error::kOutOfBounds;
8276 return false;
8277 }
[email protected]0bfd9882010-02-05 23:02:258278 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378279 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258280 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428281 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8282 if (!program) {
[email protected]ae51d192010-04-27 00:48:038283 return false;
8284 }
[email protected]df37b9932013-03-08 05:21:428285 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378286 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518287 LOCAL_SET_GL_ERROR(
8288 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378289 return false;
8290 }
[email protected]df37b9932013-03-08 05:21:428291 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368292 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358293 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428294 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128295 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368296 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378297 // No such location.
[email protected]ab09b612013-03-11 22:11:518298 LOCAL_SET_GL_ERROR(
8299 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378300 return false;
8301 }
[email protected]43c2f1f2011-03-25 18:35:368302 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508303 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378304 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518305 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378306 return false;
8307 }
[email protected]0bfd9882010-02-05 23:02:258308 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8309 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8310 if (!result) {
[email protected]f7b85372010-02-03 01:11:378311 *error = error::kOutOfBounds;
8312 return false;
8313 }
[email protected]0bfd9882010-02-05 23:02:258314 result->size = size;
[email protected]939e7362010-05-13 20:49:108315 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378316 return true;
8317}
8318
[email protected]f7a64ee2010-02-01 22:24:148319error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358320 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378321 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338322 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378323 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108324 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128325 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378326 Error error;
[email protected]0bfd9882010-02-05 23:02:258327 void* result;
[email protected]f7b85372010-02-03 01:11:378328 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128329 program, fake_location, c.params_shm_id, c.params_shm_offset,
8330 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258331 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128332 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358333 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378334 }
8335 return error;
[email protected]96449d2c2009-11-25 00:01:328336}
8337
[email protected]f7a64ee2010-02-01 22:24:148338error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358339 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378340 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338341 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378342 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128343 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378344 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358345 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108346 Result* result;
8347 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378348 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128349 program, fake_location, c.params_shm_id, c.params_shm_offset,
8350 &error, &real_location, &service_id,
8351 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108352 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8353 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8354 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558355 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128356 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108357 GLfloat* dst = result->GetData();
8358 for (GLsizei ii = 0; ii < num_values; ++ii) {
8359 dst[ii] = (temp[ii] != 0);
8360 }
8361 } else {
[email protected]1b0a6752012-02-22 03:44:128362 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108363 }
[email protected]f7b85372010-02-03 01:11:378364 }
8365 return error;
[email protected]96449d2c2009-11-25 00:01:328366}
8367
[email protected]f7a64ee2010-02-01 22:24:148368error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358369 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258370 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8371 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358372 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258373 Result* result = GetSharedMemoryAs<Result*>(
8374 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8375 if (!result) {
8376 return error::kOutOfBounds;
8377 }
[email protected]07d0cc82010-02-17 04:51:408378 // Check that the client initialized the result.
8379 if (result->success != 0) {
8380 return error::kInvalidArguments;
8381 }
[email protected]9438b012010-06-15 22:55:058382 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518383 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538384 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298385 return error::kNoError;
8386 }
[email protected]9438b012010-06-15 22:55:058387 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518388 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538389 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298390 return error::kNoError;
8391 }
8392
8393 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408394
[email protected]46c86752013-05-21 05:08:398395 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:408396 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218397 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408398
8399 result->min_range = range[0];
8400 result->max_range = range[1];
8401 result->precision = precision;
8402
[email protected]f7a64ee2010-02-01 22:24:148403 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328404}
8405
[email protected]f7a64ee2010-02-01 22:24:148406error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358407 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258408 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428409 GLuint program_id = static_cast<GLuint>(c.program);
8410 Program* program = GetProgramInfoNotShader(
8411 program_id, "glGetAttachedShaders");
8412 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258413 return error::kNoError;
8414 }
[email protected]ed9f9cd2013-02-27 21:12:358415 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258416 uint32 max_count = Result::ComputeMaxResults(result_size);
8417 Result* result = GetSharedMemoryAs<Result*>(
8418 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8419 if (!result) {
8420 return error::kOutOfBounds;
8421 }
[email protected]07d0cc82010-02-17 04:51:408422 // Check that the client initialized the result.
8423 if (result->size != 0) {
8424 return error::kInvalidArguments;
8425 }
[email protected]0bfd9882010-02-05 23:02:258426 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038427 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428428 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258429 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038430 if (!shader_manager()->GetClientId(result->GetData()[ii],
8431 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258432 NOTREACHED();
8433 return error::kGenericError;
8434 }
8435 }
8436 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148437 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328438}
8439
[email protected]f7a64ee2010-02-01 22:24:148440error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358441 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428442 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258443 GLuint index = c.index;
8444 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358445 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258446 Result* result = GetSharedMemoryAs<Result*>(
8447 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8448 if (!result) {
8449 return error::kOutOfBounds;
8450 }
[email protected]07d0cc82010-02-17 04:51:408451 // Check that the client initialized the result.
8452 if (result->success != 0) {
8453 return error::kInvalidArguments;
8454 }
[email protected]df37b9932013-03-08 05:21:428455 Program* program = GetProgramInfoNotShader(
8456 program_id, "glGetActiveUniform");
8457 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258458 return error::kNoError;
8459 }
[email protected]ed9f9cd2013-02-27 21:12:358460 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428461 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258462 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518463 LOCAL_SET_GL_ERROR(
8464 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258465 return error::kNoError;
8466 }
8467 result->success = 1; // true.
8468 result->size = uniform_info->size;
8469 result->type = uniform_info->type;
8470 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298471 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148472 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328473}
8474
[email protected]f7a64ee2010-02-01 22:24:148475error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358476 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428477 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258478 GLuint index = c.index;
8479 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358480 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258481 Result* result = GetSharedMemoryAs<Result*>(
8482 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8483 if (!result) {
8484 return error::kOutOfBounds;
8485 }
[email protected]07d0cc82010-02-17 04:51:408486 // Check that the client initialized the result.
8487 if (result->success != 0) {
8488 return error::kInvalidArguments;
8489 }
[email protected]df37b9932013-03-08 05:21:428490 Program* program = GetProgramInfoNotShader(
8491 program_id, "glGetActiveAttrib");
8492 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258493 return error::kNoError;
8494 }
[email protected]ed9f9cd2013-02-27 21:12:358495 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428496 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258497 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518498 LOCAL_SET_GL_ERROR(
8499 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258500 return error::kNoError;
8501 }
8502 result->success = 1; // true.
8503 result->size = attrib_info->size;
8504 result->type = attrib_info->type;
8505 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298506 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148507 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328508}
8509
[email protected]b273e432010-04-12 17:23:588510error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358511 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588512#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518513 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588514 return error::kNoError;
8515#else
8516 GLsizei n = static_cast<GLsizei>(c.n);
8517 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518518 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588519 return error::kNoError;
8520 }
8521 GLsizei length = static_cast<GLsizei>(c.length);
8522 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518523 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588524 return error::kNoError;
8525 }
8526 uint32 data_size;
8527 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8528 return error::kOutOfBounds;
8529 }
8530 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8531 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8532 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8533 const void* binary = GetSharedMemoryAs<const void*>(
8534 c.binary_shm_id, c.binary_shm_offset, length);
8535 if (shaders == NULL || binary == NULL) {
8536 return error::kOutOfBounds;
8537 }
8538 scoped_array<GLuint> service_ids(new GLuint[n]);
8539 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428540 Shader* shader = GetShader(shaders[ii]);
8541 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518542 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588543 return error::kNoError;
8544 }
[email protected]df37b9932013-03-08 05:21:428545 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588546 }
8547 // TODO(gman): call glShaderBinary
8548 return error::kNoError;
8549#endif
8550}
8551
[email protected]6d792ee12013-05-15 00:40:568552void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:498553 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088554
[email protected]64ace852011-05-19 21:49:498555 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428556 // TRACE_EVENT for gpu tests:
8557 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428558 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428559 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8560 "width", (is_offscreen ? offscreen_size_.width() :
8561 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:568562 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:498563 "offscreen", is_offscreen,
8564 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358565 // If offscreen then don't actually SwapBuffers to the display. Just copy
8566 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498567 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318568 TRACE_EVENT2("gpu", "Offscreen",
8569 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538570 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8571 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8572 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8573 // fix this.
[email protected]62e155e2012-10-23 22:43:158574 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538575 offscreen_saved_frame_buffer_->Create();
8576 glFinish();
8577 }
8578
8579 // Allocate the offscreen saved color texture.
8580 DCHECK(offscreen_saved_color_format_);
8581 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098582 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538583
8584 offscreen_saved_frame_buffer_->AttachRenderTexture(
8585 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:058586 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
8587 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8588 GL_FRAMEBUFFER_COMPLETE) {
8589 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8590 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:568591 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
8592 return;
[email protected]f0cfe752013-01-14 01:09:058593 }
[email protected]1fb8c482011-08-31 01:01:538594
[email protected]f0cfe752013-01-14 01:09:058595 // Clear the offscreen color texture.
8596 // TODO(piman): Is this still necessary?
8597 {
8598 ScopedFrameBufferBinder binder(this,
8599 offscreen_saved_frame_buffer_->id());
8600 glClearColor(0, 0, 0, 0);
8601 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8602 glDisable(GL_SCISSOR_TEST);
8603 glClear(GL_COLOR_BUFFER_BIT);
8604 RestoreClearState();
8605 }
[email protected]1fb8c482011-08-31 01:01:538606 }
8607
8608 UpdateParentTextureInfo();
8609 }
8610
[email protected]f0cfe752013-01-14 01:09:058611 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:568612 return;
[email protected]ab09b612013-03-11 22:11:518613 ScopedGLErrorSuppressor suppressor(
[email protected]6d792ee12013-05-15 00:40:568614 "GLES2DecoderImpl::DoSwapBuffers", this);
[email protected]6217d392010-03-25 22:08:358615
[email protected]34ff8b0c2010-10-01 20:06:028616 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138617 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278618 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:488619 } else {
[email protected]069944672012-04-25 20:52:238620 ScopedFrameBufferBinder binder(this,
8621 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138622
[email protected]069944672012-04-25 20:52:238623 if (offscreen_target_buffer_preserved_) {
8624 // Copy the target frame buffer to the saved offscreen texture.
8625 offscreen_saved_color_texture_->Copy(
8626 offscreen_saved_color_texture_->size(),
8627 offscreen_saved_color_format_);
8628 } else {
8629 // Flip the textures in the parent context via the texture manager.
8630 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:498631 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:238632 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568633
[email protected]069944672012-04-25 20:52:238634 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8635 offscreen_target_frame_buffer_->AttachRenderTexture(
8636 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488637 }
[email protected]069944672012-04-25 20:52:238638
8639 // Ensure the side effects of the copy are visible to the parent
8640 // context. There is no need to do this for ANGLE because it uses a
8641 // single D3D device for all contexts.
8642 if (!IsAngle())
8643 glFlush();
[email protected]0c8c9d22010-06-25 17:36:398644 }
[email protected]6217d392010-03-25 22:08:358645 } else {
[email protected]111975c62012-09-06 01:37:318646 TRACE_EVENT2("gpu", "Onscreen",
8647 "width", surface_->GetSize().width(),
8648 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158649 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018650 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:568651 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:018652 }
[email protected]6217d392010-03-25 22:08:358653 }
[email protected]6217d392010-03-25 22:08:358654}
8655
[email protected]d4239852011-08-12 04:51:228656error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358657 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188658 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288659 if (!bucket || bucket->size() == 0) {
8660 return error::kInvalidArguments;
8661 }
[email protected]ed9f9cd2013-02-27 21:12:358662 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188663 Result* result = GetSharedMemoryAs<Result*>(
8664 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8665 if (!result) {
8666 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108667 }
[email protected]b1d2dcb2010-05-17 19:24:188668 // Check that the client initialized the result.
8669 if (*result != 0) {
8670 return error::kInvalidArguments;
8671 }
8672 std::string feature_str;
8673 if (!bucket->GetAsString(&feature_str)) {
8674 return error::kInvalidArguments;
8675 }
8676
8677 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228678 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188679 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228680 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408681 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8682 // TODO(gman): decide how to remove the need for this const_cast.
8683 // I could make validators_ non const but that seems bad as this is the only
8684 // place it is needed. I could make some special friend class of validators
8685 // just to allow this to set them. That seems silly. I could refactor this
8686 // code to use the extension mechanism or the initialization attributes to
8687 // turn this feature on. Given that the only real point of this is to make
8688 // the conformance tests pass and given that there is lots of real work that
8689 // needs to be done it seems like refactoring for one to one of those
8690 // methods is a very low priority.
8691 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048692 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8693 force_webgl_glsl_validation_ = true;
8694 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188695 } else {
8696 return error::kNoError;
8697 }
8698
8699 *result = 1; // true.
8700 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108701}
8702
[email protected]c2f8c8402010-12-06 18:07:248703error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8704 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358705 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248706 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:358707 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:298708 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:248709 bucket->SetFromString(info->extensions().c_str());
8710 return error::kNoError;
8711}
8712
8713error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358714 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248715 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288716 if (!bucket || bucket->size() == 0) {
8717 return error::kInvalidArguments;
8718 }
[email protected]c2f8c8402010-12-06 18:07:248719 std::string feature_str;
8720 if (!bucket->GetAsString(&feature_str)) {
8721 return error::kInvalidArguments;
8722 }
8723
[email protected]4b7eba92013-01-08 02:23:568724 bool desire_webgl_glsl_validation =
8725 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
8726 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:498727 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:138728 bool desire_draw_buffers = false;
[email protected]4b7eba92013-01-08 02:23:568729 if (force_webgl_glsl_validation_) {
8730 desire_standard_derivatives =
8731 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:498732 desire_frag_depth =
8733 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:138734 desire_draw_buffers =
8735 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:048736 }
8737
[email protected]4b7eba92013-01-08 02:23:568738 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:498739 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:138740 desire_frag_depth != frag_depth_explicitly_enabled_ ||
8741 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:498742 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
8743 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
8744 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:138745 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]c2f8c8402010-12-06 18:07:248746 InitializeShaderTranslator();
8747 }
8748
[email protected]302ce6d2011-07-07 23:28:118749 UpdateCapabilities();
8750
[email protected]c2f8c8402010-12-06 18:07:248751 return error::kNoError;
8752}
8753
[email protected]372e0412011-06-28 16:08:568754error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358755 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:568756 GLuint count = c.count;
8757 uint32 pnames_size;
8758 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8759 return error::kOutOfBounds;
8760 }
8761 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8762 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8763 if (pnames == NULL) {
8764 return error::kOutOfBounds;
8765 }
8766
8767 // We have to copy them since we use them twice so the client
8768 // can't change them between the time we validate them and the time we use
8769 // them.
[email protected]40d90a22013-04-09 03:39:558770 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:568771 memcpy(enums.get(), pnames, pnames_size);
8772
8773 // Count up the space needed for the result.
8774 uint32 num_results = 0;
8775 for (GLuint ii = 0; ii < count; ++ii) {
8776 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8777 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:518778 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8779 "glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568780 return error::kNoError;
8781 }
8782 // Num will never be more than 4.
8783 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478784 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568785 return error::kOutOfBounds;
8786 }
8787 }
8788
8789 uint32 result_size = 0;
8790 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8791 return error::kOutOfBounds;
8792 }
8793
8794 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:518795 LOCAL_SET_GL_ERROR(
8796 GL_INVALID_VALUE,
8797 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:568798 return error::kNoError;
8799 }
8800
8801 GLint* results = GetSharedMemoryAs<GLint*>(
8802 c.results_shm_id, c.results_shm_offset, result_size);
8803 if (results == NULL) {
8804 return error::kOutOfBounds;
8805 }
8806
8807 // Check the results have been cleared in case the context was lost.
8808 for (uint32 ii = 0; ii < num_results; ++ii) {
8809 if (results[ii]) {
8810 return error::kInvalidArguments;
8811 }
8812 }
8813
8814 // Get each result.
8815 GLint* start = results;
8816 for (GLuint ii = 0; ii < count; ++ii) {
8817 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:268818 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:538819 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:488820 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:568821 }
8822 results += num_written;
8823 }
8824
8825 // Just to verify. Should this be a DCHECK?
8826 if (static_cast<uint32>(results - start) != num_results) {
8827 return error::kOutOfBounds;
8828 }
8829
8830 return error::kNoError;
8831}
8832
[email protected]2318d342011-07-11 22:27:428833error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358834 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:428835 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:428836 uint32 bucket_id = c.bucket_id;
8837 Bucket* bucket = CreateBucket(bucket_id);
8838 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:428839 Program* program = NULL;
8840 program = GetProgram(program_id);
8841 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:468842 return error::kNoError;
[email protected]2318d342011-07-11 22:27:428843 }
[email protected]df37b9932013-03-08 05:21:428844 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:428845 return error::kNoError;
8846}
8847
[email protected]38d139d2011-07-14 00:38:438848error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
8849 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:438850 case GL_NO_ERROR:
8851 // TODO(kbr): improve the precision of the error code in this case.
8852 // Consider delegating to context for error code if MakeCurrent fails.
8853 return error::kUnknown;
8854 case GL_GUILTY_CONTEXT_RESET_ARB:
8855 return error::kGuilty;
8856 case GL_INNOCENT_CONTEXT_RESET_ARB:
8857 return error::kInnocent;
8858 case GL_UNKNOWN_CONTEXT_RESET_ARB:
8859 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:438860 }
8861
8862 NOTREACHED();
8863 return error::kUnknown;
8864}
8865
8866bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:098867 if (reset_status_ != GL_NO_ERROR) {
8868 return true;
8869 }
[email protected]706b69f2012-07-27 04:59:308870 if (context_->WasAllocatedUsingRobustnessExtension()) {
8871 GLenum status = GL_NO_ERROR;
8872 if (has_robustness_extension_)
8873 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:438874 if (status != GL_NO_ERROR) {
8875 // The graphics card was reset. Signal a lost context to the application.
8876 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:228877 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:438878 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:098879 << " context lost via ARB/EXT_robustness. Reset status = "
8880 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:438881 return true;
8882 }
8883 }
8884 return false;
8885}
8886
[email protected]93a7d98f2013-07-11 00:04:228887bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
8888 return WasContextLost() && reset_by_robustness_extension_;
8889}
8890
[email protected]c4485aad62012-12-17 10:19:098891void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
8892 // Only loses the context once.
8893 if (reset_status_ != GL_NO_ERROR) {
8894 return;
8895 }
8896
8897 // Marks this context as lost.
8898 reset_status_ = reset_status;
8899 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:098900}
8901
8902error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358903 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:098904 GLenum current = static_cast<GLenum>(c.current);
8905 GLenum other = static_cast<GLenum>(c.other);
8906 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:518907 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8908 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:098909 }
8910 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:518911 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:098912 }
8913 group_->LoseContexts(other);
8914 reset_status_ = current;
8915 current_decoder_error_ = error::kLostContext;
8916 return error::kLostContext;
8917}
8918
[email protected]b096d032013-03-08 03:08:018919error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
8920 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
8921 return error::kUnknownCommand;
8922}
8923
[email protected]840a7e462013-02-27 01:29:518924error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358925 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:518926 if (wait_sync_point_callback_.is_null())
8927 return error::kNoError;
8928
8929 return wait_sync_point_callback_.Run(c.sync_point) ?
8930 error::kNoError : error::kDeferCommandUntilLater;
8931}
8932
[email protected]882ba1e22012-03-08 19:02:538933bool GLES2DecoderImpl::GenQueriesEXTHelper(
8934 GLsizei n, const GLuint* client_ids) {
8935 for (GLsizei ii = 0; ii < n; ++ii) {
8936 if (query_manager_->GetQuery(client_ids[ii])) {
8937 return false;
8938 }
8939 }
[email protected]c45f1972012-03-14 07:27:368940 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:538941 return true;
8942}
8943
8944void GLES2DecoderImpl::DeleteQueriesEXTHelper(
8945 GLsizei n, const GLuint* client_ids) {
8946 for (GLsizei ii = 0; ii < n; ++ii) {
8947 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
8948 if (query && !query->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:118949 if (query == state_.current_query.get()) {
[email protected]e259eb412012-10-13 05:47:248950 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:538951 }
[email protected]c45f1972012-03-14 07:27:368952 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:538953 query_manager_->RemoveQuery(client_ids[ii]);
8954 }
8955 }
8956}
8957
[email protected]22e3f552012-03-13 01:54:198958bool GLES2DecoderImpl::ProcessPendingQueries() {
8959 if (query_manager_.get() == NULL) {
8960 return false;
8961 }
[email protected]c45f1972012-03-14 07:27:368962 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:198963 current_decoder_error_ = error::kOutOfBounds;
8964 }
8965 return query_manager_->HavePendingQueries();
8966}
8967
[email protected]5a36dc132013-07-23 23:17:558968// Note that if there are no pending readpixels right now,
8969// this function will call the callback immediately.
8970void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
8971 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
8972 pending_readpixel_fences_.back()->callbacks.push_back(callback);
8973 } else {
8974 callback.Run();
8975 }
8976}
8977
8978void GLES2DecoderImpl::ProcessPendingReadPixels() {
8979 while (!pending_readpixel_fences_.empty() &&
8980 pending_readpixel_fences_.front()->fence->HasCompleted()) {
8981 std::vector<base::Closure> callbacks =
8982 pending_readpixel_fences_.front()->callbacks;
8983 pending_readpixel_fences_.pop();
8984 for (size_t i = 0; i < callbacks.size(); i++) {
8985 callbacks[i].Run();
8986 }
8987 }
8988}
8989
[email protected]2b1767cf2013-03-16 09:25:058990bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:558991 return !pending_readpixel_fences_.empty() ||
8992 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:058993}
8994
8995void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:558996 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:488997 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:058998 return;
[email protected]b68b100752013-06-05 08:34:488999 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059000 ProcessFinishedAsyncTransfers();
9001}
9002
[email protected]882ba1e22012-03-08 19:02:539003error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359004 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539005 GLenum target = static_cast<GLenum>(c.target);
9006 GLuint client_id = static_cast<GLuint>(c.id);
9007 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9008 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9009
[email protected]c45f1972012-03-14 07:27:369010 switch (target) {
9011 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559012 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]0713f43d2012-12-14 22:41:309013 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
[email protected]5a36dc132013-07-23 23:17:559014 case GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009015 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369016 break;
9017 default:
[email protected]62e155e2012-10-23 22:43:159018 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519019 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009020 GL_INVALID_OPERATION, "glBeginQueryEXT",
9021 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369022 return error::kNoError;
9023 }
9024 break;
[email protected]882ba1e22012-03-08 19:02:539025 }
9026
[email protected]5a36dc132013-07-23 23:17:559027 // TODO(hubbe): Make it possible to have one query per type running at the
9028 // same time.
[email protected]7cd76fd2013-06-02 21:11:119029 if (state_.current_query.get()) {
[email protected]ab09b612013-03-11 22:11:519030 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439031 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539032 return error::kNoError;
9033 }
9034
9035 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519036 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539037 return error::kNoError;
9038 }
9039
9040 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9041 if (!query) {
[email protected]c45f1972012-03-14 07:27:369042 // TODO(gman): Decide if we need this check.
9043 //
[email protected]882ba1e22012-03-08 19:02:539044 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369045 //
9046 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9047 // for all Query ids but from the POV of the command buffer service maybe
9048 // you don't.
9049 //
9050 // The client can enforce this. I don't think the service cares.
9051 //
9052 // IdAllocatorInterface* id_allocator =
9053 // group_->GetIdAllocator(id_namespaces::kQueries);
9054 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519055 // LOCAL_SET_GL_ERROR(
9056 // GL_INVALID_OPERATION,
9057 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369058 // return error::kNoError;
9059 // }
9060 query = query_manager_->CreateQuery(
9061 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539062 }
9063
[email protected]c45f1972012-03-14 07:27:369064 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519065 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439066 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539067 return error::kNoError;
9068 } else if (query->shm_id() != sync_shm_id ||
9069 query->shm_offset() != sync_shm_offset) {
9070 DLOG(ERROR) << "Shared memory used by query not the same as before";
9071 return error::kInvalidArguments;
9072 }
9073
[email protected]c45f1972012-03-14 07:27:369074 if (!query_manager_->BeginQuery(query)) {
9075 return error::kOutOfBounds;
9076 }
[email protected]882ba1e22012-03-08 19:02:539077
[email protected]e259eb412012-10-13 05:47:249078 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539079 return error::kNoError;
9080}
9081
9082error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359083 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539084 GLenum target = static_cast<GLenum>(c.target);
9085 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9086
[email protected]7cd76fd2013-06-02 21:11:119087 if (!state_.current_query.get()) {
[email protected]ab09b612013-03-11 22:11:519088 LOCAL_SET_GL_ERROR(
9089 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539090 return error::kNoError;
9091 }
[email protected]e259eb412012-10-13 05:47:249092 if (state_.current_query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519093 LOCAL_SET_GL_ERROR(
9094 GL_INVALID_OPERATION,
9095 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539096 return error::kNoError;
9097 }
[email protected]882ba1e22012-03-08 19:02:539098
[email protected]7cd76fd2013-06-02 21:11:119099 if (!query_manager_->EndQuery(state_.current_query.get(), submit_count)) {
[email protected]c45f1972012-03-14 07:27:369100 return error::kOutOfBounds;
9101 }
9102
[email protected]fe8d73c2013-02-16 22:37:329103 query_manager_->ProcessPendingTransferQueries();
9104
[email protected]e259eb412012-10-13 05:47:249105 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539106 return error::kNoError;
9107}
9108
[email protected]944b62f32012-09-27 02:20:469109bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9110 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469111 for (GLsizei ii = 0; ii < n; ++ii) {
9112 if (GetVertexAttribManager(client_ids[ii])) {
9113 return false;
9114 }
9115 }
[email protected]ab4fd7282012-10-12 16:25:579116
[email protected]62e155e2012-10-23 22:43:159117 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579118 // Emulated VAO
9119 for (GLsizei ii = 0; ii < n; ++ii) {
9120 CreateVertexAttribManager(client_ids[ii], 0);
9121 }
9122 } else {
[email protected]40d90a22013-04-09 03:39:559123 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579124
9125 glGenVertexArraysOES(n, service_ids.get());
9126 for (GLsizei ii = 0; ii < n; ++ii) {
9127 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9128 }
[email protected]944b62f32012-09-27 02:20:469129 }
[email protected]ab4fd7282012-10-12 16:25:579130
[email protected]944b62f32012-09-27 02:20:469131 return true;
9132}
9133
9134void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9135 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469136 for (GLsizei ii = 0; ii < n; ++ii) {
9137 VertexAttribManager* vao =
9138 GetVertexAttribManager(client_ids[ii]);
9139 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119140 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]e259eb412012-10-13 05:47:249141 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469142 }
9143 RemoveVertexAttribManager(client_ids[ii]);
9144 }
9145 }
9146}
9147
9148void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469149 VertexAttribManager* vao = NULL;
9150 GLuint service_id = 0;
9151 if (client_id != 0) {
9152 vao = GetVertexAttribManager(client_id);
9153 if (!vao) {
9154 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9155 // only allows names that have been previously generated. As such, we do
9156 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519157 LOCAL_SET_GL_ERROR(
9158 GL_INVALID_OPERATION,
9159 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469160 current_decoder_error_ = error::kNoError;
9161 return;
9162 } else {
9163 service_id = vao->service_id();
9164 }
[email protected]944b62f32012-09-27 02:20:469165 } else {
[email protected]7cd76fd2013-06-02 21:11:119166 vao = default_vertex_attrib_manager_.get();
[email protected]944b62f32012-09-27 02:20:469167 }
9168
[email protected]ab4fd7282012-10-12 16:25:579169 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:119170 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:249171 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159172 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579173 EmulateVertexArrayState();
9174 } else {
9175 glBindVertexArrayOES(service_id);
9176 }
9177 }
9178}
9179
9180// Used when OES_vertex_array_object isn't natively supported
9181void GLES2DecoderImpl::EmulateVertexArrayState() {
9182 // Setup the Vertex attribute state
9183 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9184 RestoreStateForAttrib(vv);
9185 }
9186
9187 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219188 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249189 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579190 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9191 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469192}
9193
9194bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469195 const VertexAttribManager* vao =
9196 GetVertexAttribManager(client_id);
9197 return vao && vao->IsValid() && !vao->IsDeleted();
9198}
9199
[email protected]b0af4f52011-09-28 22:04:429200error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9201 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359202 const cmds::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159203 if (!features().chromium_stream_texture) {
[email protected]ab09b612013-03-11 22:11:519204 LOCAL_SET_GL_ERROR(
9205 GL_INVALID_OPERATION,
9206 "glOpenStreamTextureCHROMIUM", "not supported.");
[email protected]b0af4f52011-09-28 22:04:429207 return error::kNoError;
9208 }
9209
9210 uint32 client_id = c.client_id;
[email protected]ed9f9cd2013-02-27 21:12:359211 typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
[email protected]b0af4f52011-09-28 22:04:429212 Result* result = GetSharedMemoryAs<Result*>(
9213 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9214
[email protected]e5081262012-01-05 23:09:039215 if (!result)
9216 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429217 *result = GL_ZERO;
[email protected]370eaf12013-05-18 09:19:499218 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
9219 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519220 LOCAL_SET_GL_ERROR(
9221 GL_INVALID_VALUE,
9222 "glCreateStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429223 return error::kNoError;
9224 }
9225
[email protected]370eaf12013-05-18 09:19:499226 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079227 if (texture->IsStreamTexture()) {
[email protected]ab09b612013-03-11 22:11:519228 LOCAL_SET_GL_ERROR(
9229 GL_INVALID_OPERATION,
9230 "glCreateStreamTextureCHROMIUM", "is already a stream texture.");
[email protected]b0af4f52011-09-28 22:04:429231 return error::kNoError;
9232 }
9233
[email protected]02965c22013-03-09 02:40:079234 if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:519235 LOCAL_SET_GL_ERROR(
9236 GL_INVALID_OPERATION,
9237 "glCreateStreamTextureCHROMIUM",
9238 "is already bound to incompatible target.");
[email protected]b0af4f52011-09-28 22:04:429239 return error::kNoError;
9240 }
9241
[email protected]4f9958142013-07-02 03:58:079242 if (!stream_texture_manager())
[email protected]b0af4f52011-09-28 22:04:429243 return error::kInvalidArguments;
9244
[email protected]4f9958142013-07-02 03:58:079245 GLuint object_id = stream_texture_manager()->CreateStreamTexture(
[email protected]02965c22013-03-09 02:40:079246 texture->service_id(), client_id);
[email protected]b0af4f52011-09-28 22:04:429247
9248 if (object_id) {
[email protected]370eaf12013-05-18 09:19:499249 texture_manager()->SetStreamTexture(texture_ref, true);
[email protected]b0af4f52011-09-28 22:04:429250 } else {
[email protected]ab09b612013-03-11 22:11:519251 LOCAL_SET_GL_ERROR(
9252 GL_OUT_OF_MEMORY,
9253 "glCreateStreamTextureCHROMIUM", "failed to create platform texture.");
[email protected]b0af4f52011-09-28 22:04:429254 }
9255
9256 *result = object_id;
9257 return error::kNoError;
9258}
9259
9260error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9261 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359262 const cmds::DestroyStreamTextureCHROMIUM& c) {
[email protected]b0af4f52011-09-28 22:04:429263 GLuint client_id = c.texture;
[email protected]370eaf12013-05-18 09:19:499264 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
[email protected]4f9958142013-07-02 03:58:079265 if (texture_ref && texture_manager()->IsStreamTextureOwner(texture_ref)) {
9266 if (!stream_texture_manager())
[email protected]b0af4f52011-09-28 22:04:429267 return error::kInvalidArguments;
9268
[email protected]4f9958142013-07-02 03:58:079269 stream_texture_manager()->DestroyStreamTexture(texture_ref->service_id());
[email protected]370eaf12013-05-18 09:19:499270 texture_manager()->SetStreamTexture(texture_ref, false);
[email protected]b0af4f52011-09-28 22:04:429271 } else {
[email protected]ab09b612013-03-11 22:11:519272 LOCAL_SET_GL_ERROR(
9273 GL_INVALID_VALUE,
9274 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429275 }
9276
9277 return error::kNoError;
9278}
9279
[email protected]e51bdf32011-11-23 22:21:469280#if defined(OS_MACOSX)
9281void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9282 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9283 texture_id);
9284 if (it != texture_to_io_surface_map_.end()) {
9285 // Found a previous IOSurface bound to this texture; release it.
9286 CFTypeRef surface = it->second;
9287 CFRelease(surface);
9288 texture_to_io_surface_map_.erase(it);
9289 }
9290}
9291#endif
9292
9293void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9294 GLenum target, GLsizei width, GLsizei height,
9295 GLuint io_surface_id, GLuint plane) {
9296#if defined(OS_MACOSX)
9297 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519298 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439299 GL_INVALID_OPERATION,
9300 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469301 return;
9302 }
9303
9304 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9305 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519306 LOCAL_SET_GL_ERROR(
9307 GL_INVALID_OPERATION,
9308 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469309 return;
9310 }
9311
9312 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9313 // This might be supported in the future, and if we could require
9314 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9315 // could delete a lot of code. For now, perform strict validation so we
9316 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519317 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469318 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439319 "glTexImageIOSurface2DCHROMIUM",
9320 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469321 return;
9322 }
9323
[email protected]09d50362012-10-18 20:54:379324 // Default target might be conceptually valid, but disallow it to avoid
9325 // accidents.
[email protected]c986af502013-08-14 01:04:449326 TextureRef* texture_ref =
9327 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:499328 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519329 LOCAL_SET_GL_ERROR(
9330 GL_INVALID_OPERATION,
9331 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469332 return;
9333 }
[email protected]e51bdf32011-11-23 22:21:469334
9335 // Look up the new IOSurface. Note that because of asynchrony
9336 // between processes this might fail; during live resizing the
9337 // plugin process might allocate and release an IOSurface before
9338 // this process gets a chance to look it up. Hold on to any old
9339 // IOSurface in this case.
9340 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9341 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519342 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439343 GL_INVALID_OPERATION,
9344 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469345 return;
9346 }
9347
9348 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499349 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469350
9351 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9352 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499353 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469354
9355 CGLContextObj context =
9356 static_cast<CGLContextObj>(context_->GetHandle());
9357
9358 CGLError err = surface_support->CGLTexImageIOSurface2D(
9359 context,
9360 target,
9361 GL_RGBA,
9362 width,
9363 height,
9364 GL_BGRA,
9365 GL_UNSIGNED_INT_8_8_8_8_REV,
9366 surface,
9367 plane);
9368
9369 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519370 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469371 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439372 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469373 return;
9374 }
9375
9376 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499377 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469378 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9379
9380#else
[email protected]ab09b612013-03-11 22:11:519381 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439382 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469383#endif
9384}
9385
[email protected]97dc7cbe2011-12-06 17:26:179386static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9387 switch (internalformat) {
9388 case GL_RGB565:
9389 return GL_RGB;
9390 case GL_RGBA4:
9391 return GL_RGBA;
9392 case GL_RGB5_A1:
9393 return GL_RGBA;
9394 case GL_RGB8_OES:
9395 return GL_RGB;
9396 case GL_RGBA8_OES:
9397 return GL_RGBA;
9398 case GL_LUMINANCE8_ALPHA8_EXT:
9399 return GL_LUMINANCE_ALPHA;
9400 case GL_LUMINANCE8_EXT:
9401 return GL_LUMINANCE;
9402 case GL_ALPHA8_EXT:
9403 return GL_ALPHA;
9404 case GL_RGBA32F_EXT:
9405 return GL_RGBA;
9406 case GL_RGB32F_EXT:
9407 return GL_RGB;
9408 case GL_ALPHA32F_EXT:
9409 return GL_ALPHA;
9410 case GL_LUMINANCE32F_EXT:
9411 return GL_LUMINANCE;
9412 case GL_LUMINANCE_ALPHA32F_EXT:
9413 return GL_LUMINANCE_ALPHA;
9414 case GL_RGBA16F_EXT:
9415 return GL_RGBA;
9416 case GL_RGB16F_EXT:
9417 return GL_RGB;
9418 case GL_ALPHA16F_EXT:
9419 return GL_ALPHA;
9420 case GL_LUMINANCE16F_EXT:
9421 return GL_LUMINANCE;
9422 case GL_LUMINANCE_ALPHA16F_EXT:
9423 return GL_LUMINANCE_ALPHA;
9424 case GL_BGRA8_EXT:
9425 return GL_BGRA_EXT;
9426 default:
9427 return GL_NONE;
9428 }
9429}
9430
[email protected]43410e92012-04-20 17:06:289431void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039432 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549433 GLenum internal_format, GLenum dest_type) {
[email protected]370eaf12013-05-18 09:19:499434 TextureRef* dest_texture_ref = GetTexture(dest_id);
9435 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289436
[email protected]370eaf12013-05-18 09:19:499437 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519438 LOCAL_SET_GL_ERROR(
9439 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289440 return;
9441 }
9442
9443 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519444 LOCAL_SET_GL_ERROR(
9445 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289446 return;
9447 }
9448
[email protected]370eaf12013-05-18 09:19:499449 Texture* source_texture = source_texture_ref->texture();
9450 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079451 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259452 (source_texture->target() != GL_TEXTURE_2D &&
9453 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]ab09b612013-03-11 22:11:519454 LOCAL_SET_GL_ERROR(
9455 GL_INVALID_VALUE,
9456 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039457 return;
9458 }
9459
[email protected]43410e92012-04-20 17:06:289460 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289461
[email protected]9bc9a2e82013-04-03 03:56:259462 if (source_texture->target() == GL_TEXTURE_2D) {
9463 if (!source_texture->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
9464 &source_height)) {
9465 LOCAL_SET_GL_ERROR(
9466 GL_INVALID_VALUE,
9467 "glCopyTextureChromium", "source texture has no level 0");
9468 return;
9469 }
9470
9471 // Check that this type of texture is allowed.
9472 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
9473 source_height, 1)) {
9474 LOCAL_SET_GL_ERROR(
9475 GL_INVALID_VALUE,
9476 "glCopyTextureCHROMIUM", "Bad dimensions");
9477 return;
9478 }
[email protected]43410e92012-04-20 17:06:289479 }
9480
[email protected]377976552013-05-14 23:32:569481 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
[email protected]e56131d22013-07-28 16:14:119482 UpdateStreamTextureIfNeeded(source_texture);
[email protected]4f9958142013-07-02 03:58:079483 DCHECK(stream_texture_manager());
[email protected]377976552013-05-14 23:32:569484 StreamTexture* stream_tex =
[email protected]4f9958142013-07-02 03:58:079485 stream_texture_manager()->LookupStreamTexture(
[email protected]377976552013-05-14 23:32:569486 source_texture->service_id());
9487 if (!stream_tex) {
9488 LOCAL_SET_GL_ERROR(
9489 GL_INVALID_VALUE,
9490 "glCopyTextureChromium", "Stream texture lookup failed");
9491 return;
9492 }
9493 gfx::Size size = stream_tex->GetSize();
9494 source_width = size.width();
9495 source_height = size.height();
9496 if (source_width <= 0 || source_height <= 0) {
9497 LOCAL_SET_GL_ERROR(
9498 GL_INVALID_VALUE,
9499 "glCopyTextureChromium", "invalid streamtexture size");
9500 return;
9501 }
9502 }
9503
[email protected]cf6b8f62012-05-25 21:43:379504 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9505 // needed because it takes 10s of milliseconds to initialize.
9506 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519507 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379508 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279509 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379510 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519511 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379512 return;
9513 }
9514
[email protected]a4a6bdd12013-04-19 20:46:549515 GLenum dest_type_previous;
[email protected]0a1e9ad2012-05-04 21:13:039516 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079517 bool dest_level_defined = dest_texture->GetLevelSize(
9518 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289519
[email protected]0a1e9ad2012-05-04 21:13:039520 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:549521 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:079522 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039523 }
9524
9525 // Resize the destination texture to the dimensions of the source texture.
9526 if (!dest_level_defined || dest_width != source_width ||
9527 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:549528 dest_internal_format != internal_format ||
9529 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:289530 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519531 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079532 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:389533 glTexImage2D(
[email protected]43410e92012-04-20 17:06:289534 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039535 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519536 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039537 if (error != GL_NO_ERROR) {
9538 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289539 return;
[email protected]0a1e9ad2012-05-04 21:13:039540 }
[email protected]43410e92012-04-20 17:06:289541
9542 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499543 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039544 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259545 } else {
[email protected]02965c22013-03-09 02:40:079546 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:499547 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289548 }
9549
[email protected]5394a4102013-04-18 05:41:379550 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9551 // before presenting.
9552 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9553 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9554 // instead of using default matrix crbug.com/226218.
9555 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9556 0.0f, 1.0f, 0.0f, 0.0f,
9557 0.0f, 0.0f, 1.0f, 0.0f,
9558 0.0f, 0.0f, 0.0f, 1.0f};
9559 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9560 this,
9561 source_texture->target(),
9562 dest_texture->target(),
9563 source_texture->service_id(),
9564 dest_texture->service_id(), level,
9565 source_width, source_height,
9566 unpack_flip_y_,
9567 unpack_premultiply_alpha_,
9568 unpack_unpremultiply_alpha_,
9569 default_matrix);
9570 } else {
9571 copy_texture_CHROMIUM_->DoCopyTexture(
9572 this,
9573 source_texture->target(),
9574 dest_texture->target(),
9575 source_texture->service_id(),
9576 dest_texture->service_id(), level,
9577 source_width, source_height,
9578 unpack_flip_y_,
9579 unpack_premultiply_alpha_,
9580 unpack_unpremultiply_alpha_);
9581 }
[email protected]43410e92012-04-20 17:06:289582}
9583
[email protected]97dc7cbe2011-12-06 17:26:179584static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9585 switch (internalformat) {
9586 case GL_RGB565:
9587 return GL_UNSIGNED_SHORT_5_6_5;
9588 case GL_RGBA4:
9589 return GL_UNSIGNED_SHORT_4_4_4_4;
9590 case GL_RGB5_A1:
9591 return GL_UNSIGNED_SHORT_5_5_5_1;
9592 case GL_RGB8_OES:
9593 return GL_UNSIGNED_BYTE;
9594 case GL_RGBA8_OES:
9595 return GL_UNSIGNED_BYTE;
9596 case GL_LUMINANCE8_ALPHA8_EXT:
9597 return GL_UNSIGNED_BYTE;
9598 case GL_LUMINANCE8_EXT:
9599 return GL_UNSIGNED_BYTE;
9600 case GL_ALPHA8_EXT:
9601 return GL_UNSIGNED_BYTE;
9602 case GL_RGBA32F_EXT:
9603 return GL_FLOAT;
9604 case GL_RGB32F_EXT:
9605 return GL_FLOAT;
9606 case GL_ALPHA32F_EXT:
9607 return GL_FLOAT;
9608 case GL_LUMINANCE32F_EXT:
9609 return GL_FLOAT;
9610 case GL_LUMINANCE_ALPHA32F_EXT:
9611 return GL_FLOAT;
9612 case GL_RGBA16F_EXT:
9613 return GL_HALF_FLOAT_OES;
9614 case GL_RGB16F_EXT:
9615 return GL_HALF_FLOAT_OES;
9616 case GL_ALPHA16F_EXT:
9617 return GL_HALF_FLOAT_OES;
9618 case GL_LUMINANCE16F_EXT:
9619 return GL_HALF_FLOAT_OES;
9620 case GL_LUMINANCE_ALPHA16F_EXT:
9621 return GL_HALF_FLOAT_OES;
9622 case GL_BGRA8_EXT:
9623 return GL_UNSIGNED_BYTE;
9624 default:
9625 return GL_NONE;
9626 }
9627}
9628
9629void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449630 GLenum target,
9631 GLint levels,
9632 GLenum internal_format,
9633 GLsizei width,
9634 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389635 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419636 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179637 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:519638 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439639 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179640 return;
9641 }
[email protected]c986af502013-08-14 01:04:449642 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9643 &state_, target);
[email protected]370eaf12013-05-18 09:19:499644 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519645 LOCAL_SET_GL_ERROR(
9646 GL_INVALID_OPERATION,
9647 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179648 return;
9649 }
[email protected]370eaf12013-05-18 09:19:499650 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079651 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449652 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:179653 }
[email protected]02965c22013-03-09 02:40:079654 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519655 LOCAL_SET_GL_ERROR(
9656 GL_INVALID_OPERATION,
9657 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179658 return;
9659 }
[email protected]7989c9e2013-01-23 06:39:269660
9661 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9662 GLenum type = ExtractTypeFromStorageFormat(internal_format);
9663
9664 {
9665 GLsizei level_width = width;
9666 GLsizei level_height = height;
9667 uint32 estimated_size = 0;
9668 for (int ii = 0; ii < levels; ++ii) {
9669 uint32 level_size = 0;
9670 if (!GLES2Util::ComputeImageDataSizes(
9671 level_width, level_height, format, type, state_.unpack_alignment,
9672 &estimated_size, NULL, NULL) ||
9673 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519674 LOCAL_SET_GL_ERROR(
9675 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269676 return;
9677 }
9678 level_width = std::max(1, level_width >> 1);
9679 level_height = std::max(1, level_height >> 1);
9680 }
9681 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519682 LOCAL_SET_GL_ERROR(
9683 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269684 return;
9685 }
9686 }
9687
[email protected]ab09b612013-03-11 22:11:519688 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:389689 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:519690 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:179691 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:159692 GLsizei level_width = width;
9693 GLsizei level_height = height;
9694 for (int ii = 0; ii < levels; ++ii) {
9695 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499696 texture_ref, target, ii, format,
9697 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:159698 level_width = std::max(1, level_width >> 1);
9699 level_height = std::max(1, level_height >> 1);
9700 }
[email protected]02965c22013-03-09 02:40:079701 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:179702 }
[email protected]97dc7cbe2011-12-06 17:26:179703}
[email protected]e51bdf32011-11-23 22:21:469704
[email protected]78b514b2012-05-01 21:50:599705error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359706 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]78b514b2012-05-01 21:50:599707 MailboxName name;
9708 mailbox_manager()->GenerateMailboxName(&name);
9709 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
9710 Bucket* bucket = CreateBucket(bucket_id);
9711
9712 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
9713 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
9714
9715 return error::kNoError;
9716}
9717
9718void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9719 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029720 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329721 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029722 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9723
[email protected]c986af502013-08-14 01:04:449724 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9725 &state_, target);
[email protected]370eaf12013-05-18 09:19:499726 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519727 LOCAL_SET_GL_ERROR(
9728 GL_INVALID_OPERATION,
9729 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599730 return;
9731 }
9732
[email protected]62e65f02013-05-29 22:28:109733 Texture* produced = texture_manager()->Produce(texture_ref);
9734 if (!produced) {
[email protected]ab09b612013-03-11 22:11:519735 LOCAL_SET_GL_ERROR(
9736 GL_INVALID_OPERATION,
9737 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599738 return;
9739 }
9740
9741 if (!group_->mailbox_manager()->ProduceTexture(
9742 target,
9743 *reinterpret_cast<const MailboxName*>(mailbox),
[email protected]62e65f02013-05-29 22:28:109744 produced)) {
[email protected]ab09b612013-03-11 22:11:519745 LOCAL_SET_GL_ERROR(
9746 GL_INVALID_OPERATION,
9747 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599748 return;
9749 }
[email protected]78b514b2012-05-01 21:50:599750}
9751
9752void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9753 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029754 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329755 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029756 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9757
[email protected]62e65f02013-05-29 22:28:109758 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:449759 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:119760 if (!texture_ref.get()) {
9761 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9762 "glConsumeTextureCHROMIUM",
9763 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599764 return;
9765 }
[email protected]62e65f02013-05-29 22:28:109766 GLuint client_id = texture_ref->client_id();
9767 if (!client_id) {
9768 LOCAL_SET_GL_ERROR(
9769 GL_INVALID_OPERATION,
9770 "glConsumeTextureCHROMIUM", "unknown texture for target");
9771 return;
9772 }
9773 Texture* texture =
[email protected]78b514b2012-05-01 21:50:599774 group_->mailbox_manager()->ConsumeTexture(
9775 target,
[email protected]62e65f02013-05-29 22:28:109776 *reinterpret_cast<const MailboxName*>(mailbox));
9777 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519778 LOCAL_SET_GL_ERROR(
9779 GL_INVALID_OPERATION,
9780 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599781 return;
9782 }
[email protected]62e65f02013-05-29 22:28:109783 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:519784 LOCAL_SET_GL_ERROR(
9785 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:109786 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:599787 return;
9788 }
[email protected]62e65f02013-05-29 22:28:109789
9790 DeleteTexturesHelper(1, &client_id);
9791 texture_ref = texture_manager()->Consume(client_id, texture);
9792 glBindTexture(target, texture_ref->service_id());
9793
9794 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
9795 unit.bind_target = target;
9796 switch (target) {
9797 case GL_TEXTURE_2D:
9798 unit.bound_texture_2d = texture_ref;
9799 break;
9800 case GL_TEXTURE_CUBE_MAP:
9801 unit.bound_texture_cube_map = texture_ref;
9802 break;
9803 case GL_TEXTURE_EXTERNAL_OES:
9804 unit.bound_texture_external_oes = texture_ref;
9805 break;
9806 case GL_TEXTURE_RECTANGLE_ARB:
9807 unit.bound_texture_rectangle_arb = texture_ref;
9808 break;
9809 default:
9810 NOTREACHED(); // Validation should prevent us getting here.
9811 break;
9812 }
[email protected]78b514b2012-05-01 21:50:599813}
9814
[email protected]d2a0e1a2012-08-12 02:25:019815void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9816 GLsizei length, const GLchar* marker) {
9817 if (!marker) {
9818 marker = "";
9819 }
9820 debug_marker_manager_.SetMarker(
9821 length ? std::string(marker, length) : std::string(marker));
9822}
9823
9824void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9825 GLsizei length, const GLchar* marker) {
9826 if (!marker) {
9827 marker = "";
9828 }
9829 debug_marker_manager_.PushGroup(
9830 length ? std::string(marker, length) : std::string(marker));
9831}
9832
9833void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9834 debug_marker_manager_.PopGroup();
9835}
9836
[email protected]09d50362012-10-18 20:54:379837void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9838 GLenum target, GLint image_id) {
9839 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9840 if (target != GL_TEXTURE_2D) {
9841 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:519842 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:379843 GL_INVALID_OPERATION,
9844 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9845 return;
9846 }
9847
9848 // Default target might be conceptually valid, but disallow it to avoid
9849 // accidents.
[email protected]c986af502013-08-14 01:04:449850 TextureRef* texture_ref =
9851 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:499852 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519853 LOCAL_SET_GL_ERROR(
9854 GL_INVALID_OPERATION,
9855 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:379856 return;
9857 }
9858
9859 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9860 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:519861 LOCAL_SET_GL_ERROR(
9862 GL_INVALID_OPERATION,
9863 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:379864 return;
9865 }
9866
[email protected]b8160812013-04-09 00:41:049867 {
9868 ScopedGLErrorSuppressor suppressor(
9869 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", this);
9870 if (!gl_image->BindTexImage()) {
9871 LOCAL_SET_GL_ERROR(
9872 GL_INVALID_OPERATION,
9873 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
9874 return;
9875 }
[email protected]09d50362012-10-18 20:54:379876 }
9877
9878 gfx::Size size = gl_image->GetSize();
9879 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499880 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:379881 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:499882 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:379883}
9884
9885void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
9886 GLenum target, GLint image_id) {
9887 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
9888 if (target != GL_TEXTURE_2D) {
9889 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:519890 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:379891 GL_INVALID_OPERATION,
9892 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9893 return;
9894 }
9895
9896 // Default target might be conceptually valid, but disallow it to avoid
9897 // accidents.
[email protected]c986af502013-08-14 01:04:449898 TextureRef* texture_ref =
9899 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:499900 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519901 LOCAL_SET_GL_ERROR(
9902 GL_INVALID_OPERATION,
9903 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:379904 return;
9905 }
9906
9907 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9908 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:519909 LOCAL_SET_GL_ERROR(
9910 GL_INVALID_OPERATION,
9911 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:379912 return;
9913 }
9914
9915 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:499916 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:379917 return;
9918
[email protected]b8160812013-04-09 00:41:049919 {
9920 ScopedGLErrorSuppressor suppressor(
9921 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", this);
9922 gl_image->ReleaseTexImage();
9923 }
[email protected]09d50362012-10-18 20:54:379924
9925 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499926 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:379927 GL_RGBA, GL_UNSIGNED_BYTE, false);
9928}
[email protected]d2a0e1a2012-08-12 02:25:019929
[email protected]94307712012-11-16 23:26:119930error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359931 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:119932 Bucket* bucket = GetBucket(c.bucket_id);
9933 if (!bucket || bucket->size() == 0) {
9934 return error::kInvalidArguments;
9935 }
9936 std::string command_name;
9937 if (!bucket->GetAsString(&command_name)) {
9938 return error::kInvalidArguments;
9939 }
[email protected]fb97b662013-02-20 23:02:149940 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
9941 if (!gpu_tracer_->Begin(command_name)) {
[email protected]ab09b612013-03-11 22:11:519942 LOCAL_SET_GL_ERROR(
9943 GL_INVALID_OPERATION,
9944 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:149945 return error::kNoError;
9946 }
[email protected]94307712012-11-16 23:26:119947 return error::kNoError;
9948}
9949
9950void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:149951 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:519952 LOCAL_SET_GL_ERROR(
9953 GL_INVALID_OPERATION,
9954 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:119955 return;
9956 }
[email protected]fb97b662013-02-20 23:02:149957 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
9958 gpu_tracer_->End();
[email protected]94307712012-11-16 23:26:119959}
9960
[email protected]2f143d482013-03-14 18:04:499961void GLES2DecoderImpl::DoDrawBuffersEXT(
9962 GLsizei count, const GLenum* bufs) {
9963 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
9964 LOCAL_SET_GL_ERROR(
9965 GL_INVALID_VALUE,
9966 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
9967 return;
9968 }
9969
9970 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
9971 if (framebuffer) {
9972 for (GLsizei i = 0; i < count; ++i) {
9973 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
9974 bufs[i] != GL_NONE) {
9975 LOCAL_SET_GL_ERROR(
9976 GL_INVALID_OPERATION,
9977 "glDrawBuffersEXT",
9978 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
9979 return;
9980 }
9981 }
9982 glDrawBuffersARB(count, bufs);
9983 framebuffer->SetDrawBuffers(count, bufs);
9984 } else { // backbuffer
9985 if (count > 1 ||
9986 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
9987 LOCAL_SET_GL_ERROR(
9988 GL_INVALID_OPERATION,
9989 "glDrawBuffersEXT",
9990 "more than one buffer or bufs not GL_NONE or GL_BACK");
9991 return;
9992 }
9993 GLenum mapped_buf = bufs[0];
9994 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
9995 bufs[0] == GL_BACK) {
9996 mapped_buf = GL_COLOR_ATTACHMENT0;
9997 }
9998 glDrawBuffersARB(count, &mapped_buf);
9999 group_->set_draw_buffer(bufs[0]);
10000 }
10001}
10002
[email protected]32145a92012-12-17 09:01:5910003bool GLES2DecoderImpl::ValidateAsyncTransfer(
10004 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710005 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910006 GLenum target,
10007 GLint level,
10008 const void * data) {
10009 // We only support async uploads to 2D textures for now.
10010 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110011 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910012 return false;
10013 }
10014 // We only support uploads to level zero for now.
10015 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110016 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910017 return false;
10018 }
10019 // A transfer buffer must be bound, even for asyncTexImage2D.
10020 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110021 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910022 return false;
10023 }
10024 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710025 if (!texture_ref ||
10026 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110027 LOCAL_SET_GL_ERROR(
10028 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910029 function_name, "transfer already in progress");
10030 return false;
10031 }
10032 return true;
10033}
10034
[email protected]69023942012-11-30 19:57:1610035error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510036 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610037 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610038 GLenum target = static_cast<GLenum>(c.target);
10039 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4410040 // TODO(kloveless): Change HandleAsyncTexImage2DCHROMIUM command to use
10041 // unsigned integer for internalformat.
10042 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1610043 GLsizei width = static_cast<GLsizei>(c.width);
10044 GLsizei height = static_cast<GLsizei>(c.height);
10045 GLint border = static_cast<GLint>(c.border);
10046 GLenum format = static_cast<GLenum>(c.format);
10047 GLenum type = static_cast<GLenum>(c.type);
10048 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10049 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10050 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910051
10052 // TODO(epenner): Move this and copies of this memory validation
10053 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610054 if (!GLES2Util::ComputeImageDataSizes(
10055 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10056 NULL)) {
10057 return error::kOutOfBounds;
10058 }
10059 const void* pixels = NULL;
10060 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10061 pixels = GetSharedMemoryAs<const void*>(
10062 pixels_shm_id, pixels_shm_offset, pixels_size);
10063 if (!pixels) {
10064 return error::kOutOfBounds;
10065 }
10066 }
10067
[email protected]c986af502013-08-14 01:04:4410068 TextureManager::DoTextImage2DArguments args = {
10069 target, level, internal_format, width, height, border, format, type,
10070 pixels, pixels_size};
10071 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5910072 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4410073 if (!texture_manager()->ValidateTexImage2D(
10074 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5910075 return error::kNoError;
10076 }
10077
10078 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910079 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910080 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710081 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910082 return error::kNoError;
10083
10084 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710085 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110086 LOCAL_SET_GL_ERROR(
10087 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910088 "glAsyncTexImage2DCHROMIUM", "already defined");
10089 return error::kNoError;
10090 }
10091
[email protected]7989c9e2013-01-23 06:39:2610092 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110093 LOCAL_SET_GL_ERROR(
10094 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610095 return error::kNoError;
10096 }
10097
[email protected]32145a92012-12-17 09:01:5910098 // We know the memory/size is safe, so get the real shared memory since
10099 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110100 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910101 base::SharedMemory* shared_memory = buffer.shared_memory;
10102 uint32 shm_size = buffer.size;
10103 uint32 shm_data_offset = c.pixels_shm_offset;
10104 uint32 shm_data_size = pixels_size;
10105
[email protected]5b3a8e02013-03-13 05:36:4410106 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810107 AsyncTexImage2DParams tex_params = {
10108 target, level, static_cast<GLenum>(internal_format),
10109 width, height, border, format, type};
10110 AsyncMemoryParams mem_params = {
10111 shared_memory, shm_size, shm_data_offset, shm_data_size};
[email protected]32145a92012-12-17 09:01:5910112
[email protected]5b3a8e02013-03-13 05:36:4410113 // Set up the async state if needed, and make the texture
10114 // immutable so the async state stays valid. The level info
10115 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1810116 AsyncPixelTransferDelegate* delegate =
10117 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
10118 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4410119 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910120
[email protected]896425e2013-06-12 17:27:1810121 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410122 tex_params,
10123 mem_params,
10124 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910125 // The callback is only invoked if the transfer delegate still
10126 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410127 // ownership that both of these pointers are valid.
10128 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910129 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410130 tex_params));
[email protected]f598f422012-12-07 08:30:0310131 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610132}
10133
10134error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510135 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610136 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610137 GLenum target = static_cast<GLenum>(c.target);
10138 GLint level = static_cast<GLint>(c.level);
10139 GLint xoffset = static_cast<GLint>(c.xoffset);
10140 GLint yoffset = static_cast<GLint>(c.yoffset);
10141 GLsizei width = static_cast<GLsizei>(c.width);
10142 GLsizei height = static_cast<GLsizei>(c.height);
10143 GLenum format = static_cast<GLenum>(c.format);
10144 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910145
10146 // TODO(epenner): Move this and copies of this memory validation
10147 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610148 uint32 data_size;
10149 if (!GLES2Util::ComputeImageDataSizes(
10150 width, height, format, type, state_.unpack_alignment, &data_size,
10151 NULL, NULL)) {
10152 return error::kOutOfBounds;
10153 }
10154 const void* pixels = GetSharedMemoryAs<const void*>(
10155 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910156
10157 // All the normal glTexSubImage2D validation.
10158 error::Error error = error::kNoError;
10159 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10160 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10161 return error;
[email protected]69023942012-11-30 19:57:1610162 }
10163
[email protected]32145a92012-12-17 09:01:5910164 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4410165 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10166 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910167 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910168 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710169 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910170 return error::kNoError;
10171
10172 // Guarantee async textures are always 'cleared' as follows:
10173 // - AsyncTexImage2D can not redefine an existing texture
10174 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10175 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10176 // - Textures become immutable after an async call.
10177 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710178 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910179 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10180 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110181 LOCAL_SET_GL_ERROR(
10182 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510183 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910184 return error::kNoError;
10185 }
10186 }
10187
10188 // We know the memory/size is safe, so get the real shared memory since
10189 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110190 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910191 base::SharedMemory* shared_memory = buffer.shared_memory;
10192 uint32 shm_size = buffer.size;
10193 uint32 shm_data_offset = c.data_shm_offset;
10194 uint32 shm_data_size = data_size;
10195
[email protected]5b3a8e02013-03-13 05:36:4410196 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310197 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910198 width, height, format, type};
[email protected]2a7568a2013-05-09 23:12:0310199 AsyncMemoryParams mem_params = {shared_memory, shm_size,
[email protected]32145a92012-12-17 09:01:5910200 shm_data_offset, shm_data_size};
[email protected]896425e2013-06-12 17:27:1810201 AsyncPixelTransferDelegate* delegate =
10202 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10203 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4410204 // TODO(epenner): We may want to enforce exclusive use
10205 // of async APIs in which case this should become an error,
10206 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310207 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410208 0, 0, 0, 0, 0, 0};
10209 texture->GetLevelSize(target, level, &define_params.width,
10210 &define_params.height);
10211 texture->GetLevelType(target, level, &define_params.type,
10212 &define_params.internal_format);
10213 // Set up the async state if needed, and make the texture
10214 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1810215 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4710216 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4410217 texture->SetImmutable(true);
10218 }
10219
[email protected]896425e2013-06-12 17:27:1810220 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910221 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610222}
10223
[email protected]a00c1f742013-03-05 17:02:1610224error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10225 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10226 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10227 GLenum target = static_cast<GLenum>(c.target);
10228
10229 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110230 LOCAL_SET_GL_ERROR(
10231 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610232 return error::kNoError;
10233 }
[email protected]c986af502013-08-14 01:04:4410234 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10235 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910236 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110237 LOCAL_SET_GL_ERROR(
10238 GL_INVALID_OPERATION,
10239 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610240 return error::kNoError;
10241 }
[email protected]896425e2013-06-12 17:27:1810242 AsyncPixelTransferDelegate* delegate =
10243 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10244 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4910245 LOCAL_SET_GL_ERROR(
10246 GL_INVALID_OPERATION,
10247 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10248 return error::kNoError;
10249 }
[email protected]896425e2013-06-12 17:27:1810250 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0910251 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610252 return error::kNoError;
10253}
10254
[email protected]96449d2c2009-11-25 00:01:3210255// Include the auto-generated part of this file. We split this because it means
10256// we can easily edit the non-auto generated parts right here in this file
10257// instead of having to edit some template or the code generator.
10258#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10259
10260} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510261} // namespace gpu