blob: 7b9bbc6c744b6c0a0604d60d0fd3d5d595563110 [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]9d37f062011-11-22 01:24:5217#include "base/bind.h"
[email protected]e844ae22012-01-14 03:36:2618#include "base/command_line.h"
[email protected]1078f912011-12-23 13:12:1419#include "base/debug/trace_event.h"
[email protected]b2e92592014-01-10 15:47:1520#include "base/debug/trace_event_synthetic_delay.h"
[email protected]3b63f8f42011-03-28 01:54:1521#include "base/memory/scoped_ptr.h"
[email protected]f4390962013-06-11 07:29:2222#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1223#include "base/strings/string_split.h"
[email protected]d37231fa2010-04-09 21:16:0224#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3225#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2226#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3227#include "gpu/command_buffer/common/gles2_cmd_format.h"
28#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1029#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5130#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2231#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
32#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5033#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3234#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5035#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2436#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5037#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1138#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5839#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3240#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2841#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4642#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1343#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2644#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1445#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3746#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5947#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2548#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4749#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5350#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5851#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4752#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4553#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0454#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4755#include "gpu/command_buffer/service/texture_manager.h"
[email protected]944b62f32012-09-27 02:20:4656#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2257#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]d8bc3ec2013-03-07 06:28:4058#include "ui/gl/gl_bindings.h"
[email protected]5a36dc132013-07-23 23:17:5559#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3760#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2761#include "ui/gl/gl_implementation.h"
62#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2763
[email protected]e51bdf32011-11-23 22:21:4664#if defined(OS_MACOSX)
[email protected]423e644f2013-06-19 00:48:2765#include "ui/gl/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4666#endif
[email protected]de17df392010-04-23 21:09:4167
[email protected]6eb775352013-08-27 05:57:1668#if defined(OS_WIN)
69#include "base/win/win_util.h"
70#endif
71
[email protected]693ca512012-11-13 18:09:1372// TODO(zmo): we can't include "City.h" due to type def conflicts.
73extern uint64 CityHash64(const char*, size_t);
74
[email protected]a7a27ace2009-12-12 00:11:2575namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3276namespace gles2 {
77
[email protected]f0d74742011-10-03 16:31:0478namespace {
[email protected]693ca512012-11-13 18:09:1379
[email protected]f0d74742011-10-03 16:31:0480static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4981static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1382static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]693ca512012-11-13 18:09:1383
[email protected]3d944a82013-02-12 19:09:0284#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]693ca512012-11-13 18:09:1385khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
86 return static_cast<khronos_uint64_t>(
87 CityHash64(name, static_cast<size_t>(len)));
88}
[email protected]3d944a82013-02-12 19:09:0289#endif
[email protected]693ca512012-11-13 18:09:1390
[email protected]448e459e2013-06-12 17:00:4191static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
92 GLint rangeMax,
93 GLint precision) {
94 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
95}
96
[email protected]8dc1bf92013-03-12 03:58:2197static void GetShaderPrecisionFormatImpl(GLenum shader_type,
98 GLenum precision_type,
99 GLint *range, GLint *precision) {
100 switch (precision_type) {
101 case GL_LOW_INT:
102 case GL_MEDIUM_INT:
103 case GL_HIGH_INT:
104 // These values are for a 32-bit twos-complement integer format.
105 range[0] = 31;
106 range[1] = 30;
107 *precision = 0;
108 break;
109 case GL_LOW_FLOAT:
110 case GL_MEDIUM_FLOAT:
111 case GL_HIGH_FLOAT:
112 // These values are for an IEEE single-precision floating-point format.
113 range[0] = 127;
114 range[1] = 127;
115 *precision = 23;
116 break;
117 default:
118 NOTREACHED();
119 break;
120 }
121
[email protected]8af4d5e2013-03-15 23:55:33122 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
123 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21124 // This function is sometimes defined even though it's really just
125 // a stub, so we need to set range and precision as if it weren't
126 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44127 // On Mac OS with some GPUs, calling this generates a
128 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
129 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21130 glGetShaderPrecisionFormat(shader_type, precision_type,
131 range, precision);
[email protected]448e459e2013-06-12 17:00:41132
133 // TODO(brianderson): Make the following official workarounds.
134
135 // Some drivers have bugs where they report the ranges as a negative number.
136 // Taking the absolute value here shouldn't hurt because negative numbers
137 // aren't expected anyway.
138 range[0] = abs(range[0]);
139 range[1] = abs(range[1]);
140
141 // If the driver reports a precision for highp float that isn't actually
142 // highp, don't pretend like it's supported because shader compilation will
143 // fail anyway.
144 if (precision_type == GL_HIGH_FLOAT &&
145 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
146 range[0] = 0;
147 range[1] = 0;
148 *precision = 0;
149 }
[email protected]8dc1bf92013-03-12 03:58:21150 }
151}
152
[email protected]b04e24c2013-01-08 18:35:25153} // namespace
[email protected]f0d74742011-10-03 16:31:04154
[email protected]6217d392010-03-25 22:08:35155class GLES2DecoderImpl;
156
[email protected]ab09b612013-03-11 22:11:51157// Local versions of the SET_GL_ERROR macros
158#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50159 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51160#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50161 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
162 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51163#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50164 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
165 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51166#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50167 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
168 function_name)
[email protected]ab09b612013-03-11 22:11:51169#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50170 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51171#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50172 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51173#define LOCAL_PERFORMANCE_WARNING(msg) \
174 PerformanceWarning(__FILE__, __LINE__, msg)
175#define LOCAL_RENDER_WARNING(msg) \
176 RenderWarning(__FILE__, __LINE__, msg)
177
[email protected]07f54fcc2009-12-22 02:46:30178// Check that certain assumptions the code makes are true. There are places in
179// the code where shared memory is passed direclty to GL. Example, glUniformiv,
180// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
181// a few others) are 32bits. If they are not 32bits the code will have to change
182// to call those GL functions with service side memory and then copy the results
183// to shared memory, converting the sizes.
184COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
185 GLint_not_same_size_as_uint32);
186COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
187 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37188COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
189 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30190
[email protected]43f28f832010-02-03 02:28:48191// TODO(kbr): the use of this anonymous namespace core dumps the
192// linker on Mac OS X 10.6 when the symbol ordering file is used
193// namespace {
[email protected]96449d2c2009-11-25 00:01:32194
195// Returns the address of the first byte after a struct.
196template <typename T>
197const void* AddressAfterStruct(const T& pod) {
198 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
199}
200
[email protected]07f54fcc2009-12-22 02:46:30201// Returns the address of the frst byte after the struct or NULL if size >
202// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32203template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30204RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
205 uint32 size,
206 uint32 immediate_data_size) {
207 return (size <= immediate_data_size) ?
208 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
209 NULL;
[email protected]96449d2c2009-11-25 00:01:32210}
211
[email protected]07f54fcc2009-12-22 02:46:30212// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18213bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32214 GLuint count,
215 size_t size,
[email protected]a76b0052010-03-05 00:33:18216 unsigned int elements_per_unit,
217 uint32* dst) {
218 uint32 value;
219 if (!SafeMultiplyUint32(count, size, &value)) {
220 return false;
221 }
222 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
223 return false;
224 }
225 *dst = value;
226 return true;
[email protected]96449d2c2009-11-25 00:01:32227}
228
229// A struct to hold info about each command.
230struct CommandInfo {
[email protected]cac16542014-01-15 17:53:51231 uint8 arg_flags; // How to handle the arguments for this command
232 uint8 cmd_flags; // How to handle this command
233 uint16 arg_count; // How many arguments are expected for this command.
[email protected]96449d2c2009-11-25 00:01:32234};
235
[email protected]cac16542014-01-15 17:53:51236// cmds::name::cmd_flags,
[email protected]96449d2c2009-11-25 00:01:32237// A table of CommandInfo for all the commands.
238const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35239 #define GLES2_CMD_OP(name) { \
240 cmds::name::kArgFlags, \
[email protected]cac16542014-01-15 17:53:51241 cmds::name::cmd_flags, \
242 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */
[email protected]96449d2c2009-11-25 00:01:32243
244 GLES2_COMMAND_LIST(GLES2_CMD_OP)
245
246 #undef GLES2_CMD_OP
247};
248
[email protected]258a3313f2011-10-18 20:13:57249// Return true if a character belongs to the ASCII subset as defined in
250// GLSL ES 1.0 spec section 3.1.
251static bool CharacterIsValidForGLES(unsigned char c) {
252 // Printing characters are valid except " $ ` @ \ ' DEL.
253 if (c >= 32 && c <= 126 &&
254 c != '"' &&
255 c != '$' &&
256 c != '`' &&
257 c != '@' &&
258 c != '\\' &&
259 c != '\'') {
260 return true;
261 }
262 // Horizontal tab, line feed, vertical tab, form feed, carriage return
263 // are also valid.
264 if (c >= 9 && c <= 13) {
265 return true;
266 }
267
268 return false;
269}
270
271static bool StringIsValidForGLES(const char* str) {
272 for (; *str; ++str) {
273 if (!CharacterIsValidForGLES(*str)) {
274 return false;
275 }
276 }
277 return true;
278}
279
[email protected]297ca1c2011-06-20 23:08:46280// Wrapper for glEnable/glDisable that doesn't suck.
281static void EnableDisable(GLenum pname, bool enable) {
282 if (enable) {
283 glEnable(pname);
284 } else {
285 glDisable(pname);
286 }
287}
288
[email protected]6217d392010-03-25 22:08:35289// This class prevents any GL errors that occur when it is in scope from
290// being reported to the client.
291class ScopedGLErrorSuppressor {
292 public:
[email protected]ab09b612013-03-11 22:11:51293 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30294 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35295 ~ScopedGLErrorSuppressor();
296 private:
[email protected]ab09b612013-03-11 22:11:51297 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30298 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35299 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
300};
301
[email protected]2b10c02d2014-01-29 16:43:02302// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35303// object goes out of scope. Also temporarily switches to using active texture
304// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02305class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35306 public:
[email protected]2b10c02d2014-01-29 16:43:02307 ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
308 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35309
310 private:
[email protected]ce296892013-10-24 22:04:36311 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02312 GLenum target_;
313 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35314};
315
316// Temporarily changes a decoder's bound render buffer and restore it when this
317// object goes out of scope.
318class ScopedRenderBufferBinder {
319 public:
[email protected]18e785a2013-10-09 03:29:41320 ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35321 ~ScopedRenderBufferBinder();
322
323 private:
[email protected]18e785a2013-10-09 03:29:41324 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35325 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
326};
327
328// Temporarily changes a decoder's bound frame buffer and restore it when this
329// object goes out of scope.
330class ScopedFrameBufferBinder {
331 public:
332 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
333 ~ScopedFrameBufferBinder();
334
335 private:
336 GLES2DecoderImpl* decoder_;
337 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
338};
339
[email protected]34ff8b0c2010-10-01 20:06:02340// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52341// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27342// if it is bound or enforce_internal_framebuffer is true. If internal is
343// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02344class ScopedResolvedFrameBufferBinder {
345 public:
[email protected]e7e38032011-07-26 17:25:25346 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27347 bool enforce_internal_framebuffer,
348 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02349 ~ScopedResolvedFrameBufferBinder();
350
351 private:
352 GLES2DecoderImpl* decoder_;
353 bool resolve_and_bind_;
354 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
355};
356
[email protected]6217d392010-03-25 22:08:35357// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35358class BackTexture {
[email protected]6217d392010-03-25 22:08:35359 public:
[email protected]ce296892013-10-24 22:04:36360 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35361 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35362
363 // Create a new render texture.
364 void Create();
365
366 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09367 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35368
369 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58370 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35371
372 // Destroy the render texture. This must be explicitly called before
373 // destroying this object.
374 void Destroy();
375
[email protected]97872062010-11-03 19:07:05376 // Invalidate the texture. This can be used when a context is lost and it is
377 // not possible to make it current in order to free the resource.
378 void Invalidate();
379
[email protected]6217d392010-03-25 22:08:35380 GLuint id() const {
381 return id_;
382 }
383
[email protected]d37231fa2010-04-09 21:16:02384 gfx::Size size() const {
385 return size_;
386 }
387
[email protected]6217d392010-03-25 22:08:35388 private:
[email protected]ff6493f2012-07-31 19:52:25389 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36390 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48391 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35392 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02393 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35394 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35395};
396
397// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35398class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35399 public:
[email protected]d5a28e452013-10-10 01:01:40400 explicit BackRenderbuffer(
401 RenderbufferManager* renderbuffer_manager,
402 MemoryTracker* memory_tracker,
403 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35404 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35405
406 // Create a new render buffer.
407 void Create();
408
409 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18410 bool AllocateStorage(const FeatureInfo* feature_info,
411 const gfx::Size& size,
412 GLenum format,
413 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35414
415 // Destroy the render buffer. This must be explicitly called before destroying
416 // this object.
417 void Destroy();
418
[email protected]97872062010-11-03 19:07:05419 // Invalidate the render buffer. This can be used when a context is lost and
420 // it is not possible to make it current in order to free the resource.
421 void Invalidate();
422
[email protected]6217d392010-03-25 22:08:35423 GLuint id() const {
424 return id_;
425 }
426
427 private:
[email protected]d5a28e452013-10-10 01:01:40428 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25429 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40430 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48431 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35432 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35433 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35434};
435
436// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35437class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35438 public:
[email protected]ed9f9cd2013-02-27 21:12:35439 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
440 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35441
442 // Create a new frame buffer.
443 void Create();
444
445 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35446 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35447
[email protected]b9363b22010-06-09 22:06:15448 // Attach a render buffer to a frame buffer. Note that this unbinds any
449 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35450 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35451
[email protected]6217d392010-03-25 22:08:35452 // Destroy the frame buffer. This must be explicitly called before destroying
453 // this object.
454 void Destroy();
455
[email protected]97872062010-11-03 19:07:05456 // Invalidate the frame buffer. This can be used when a context is lost and it
457 // is not possible to make it current in order to free the resource.
458 void Invalidate();
459
[email protected]6217d392010-03-25 22:08:35460 // See glCheckFramebufferStatusEXT.
461 GLenum CheckStatus();
462
463 GLuint id() const {
464 return id_;
465 }
466
467 private:
468 GLES2DecoderImpl* decoder_;
469 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35470 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35471};
[email protected]34ff8b0c2010-10-01 20:06:02472
[email protected]5a36dc132013-07-23 23:17:55473struct FenceCallback {
474 explicit FenceCallback()
475 : fence(gfx::GLFence::Create()) {
476 DCHECK(fence);
477 }
[email protected]5a36dc132013-07-23 23:17:55478 std::vector<base::Closure> callbacks;
479 scoped_ptr<gfx::GLFence> fence;
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]cac16542014-01-15 17:53:51498void GLES2Decoder::BeginDecoding() {}
499
500void GLES2Decoder::EndDecoding() {}
501
[email protected]f39f4b3f2010-05-12 17:04:08502// This class implements GLES2Decoder so we don't have to expose all the GLES2
503// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54504class GLES2DecoderImpl : public GLES2Decoder,
505 public FramebufferManager::TextureDetachObserver {
[email protected]f39f4b3f2010-05-12 17:04:08506 public:
[email protected]476ccb72012-12-06 15:52:52507 // Used by PrepForSetUniformByLocation to validate types.
508 struct BaseUniformInfo {
509 const GLenum* const valid_types;
510 size_t num_valid_types;
511 };
512
[email protected]aa7666122011-09-02 19:45:52513 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00514 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08515
[email protected]96449d2c2009-11-25 00:01:32516 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14517 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50518 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00519 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32520
521 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00522 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32523
524 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38525 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
526 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23527 bool offscreen,
[email protected]6217d392010-03-25 22:08:35528 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29529 const DisallowedFeatures& disallowed_features,
[email protected]b8e97b62012-09-30 15:09:00530 const std::vector<int32>& attribs) OVERRIDE;
531 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38532 virtual void SetSurface(
533 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]2ad674132013-06-05 07:48:51534 virtual bool ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00535 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39536 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00537 virtual bool MakeCurrent() OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00538 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
539 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
540 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]6d668892013-12-04 21:37:12541 virtual Capabilities GetCapabilities() OVERRIDE;
[email protected]5baa86bc2014-01-16 04:33:16542 virtual void RestoreState(const ContextState* prev_state) const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06543
544 virtual void RestoreActiveTexture() const OVERRIDE {
545 state_.RestoreActiveTexture();
546 }
[email protected]5baa86bc2014-01-16 04:33:16547 virtual void RestoreAllTextureUnitBindings(
548 const ContextState* prev_state) const OVERRIDE {
549 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55550 }
[email protected]29a4d902013-02-26 20:18:06551 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
552 state_.RestoreAttribute(index);
553 }
554 virtual void RestoreBufferBindings() const OVERRIDE {
555 state_.RestoreBufferBindings();
556 }
557 virtual void RestoreGlobalState() const OVERRIDE {
558 state_.RestoreGlobalState();
559 }
560 virtual void RestoreProgramBindings() const OVERRIDE {
561 state_.RestoreProgramBindings();
562 }
[email protected]29a4d902013-02-26 20:18:06563 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
[email protected]5baa86bc2014-01-16 04:33:16564 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06565 }
566 virtual void RestoreFramebufferBindings() const OVERRIDE;
567 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
568
[email protected]b8e97b62012-09-30 15:09:00569 virtual QueryManager* GetQueryManager() OVERRIDE {
570 return query_manager_.get();
571 }
572 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46573 return vertex_array_manager_.get();
574 }
[email protected]b8e97b62012-09-30 15:09:00575 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05576 virtual bool HasMoreIdleWork() OVERRIDE;
577 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48578
[email protected]5a36dc132013-07-23 23:17:55579 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
580
[email protected]9d37f062011-11-22 01:24:52581 virtual void SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:07582 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00583
[email protected]1d82e822013-04-10 21:32:32584 virtual Logger* GetLogger() OVERRIDE;
[email protected]cac16542014-01-15 17:53:51585
586 virtual void BeginDecoding() OVERRIDE;
587 virtual void EndDecoding() OVERRIDE;
588
[email protected]d3eba342013-04-18 21:11:50589 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]5baa86bc2014-01-16 04:33:16590 virtual const ContextState* GetContextState() OVERRIDE { return &state_; }
[email protected]1d82e822013-04-10 21:32:32591
[email protected]e3932abb2013-03-13 00:01:37592 virtual void SetShaderCacheCallback(
593 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51594 virtual void SetWaitSyncPointCallback(
595 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00596
[email protected]85a4ac22013-05-31 01:58:47597 virtual AsyncPixelTransferManager*
598 GetAsyncPixelTransferManager() OVERRIDE;
599 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]498b5c072013-06-04 19:30:07600 virtual void SetAsyncPixelTransferManagerForTest(
601 AsyncPixelTransferManager* manager) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09602 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59603
[email protected]1318e922010-09-17 22:03:16604 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00605 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48606
[email protected]63b465922012-09-06 02:04:52607 virtual uint32 GetTextureUploadCount() OVERRIDE;
608 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
609 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30610 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52611
[email protected]8e3e0662010-08-23 18:46:30612 // Restores the current state to the user's settings.
613 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30614
[email protected]297ca1c2011-06-20 23:08:46615 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
616 void ApplyDirtyState();
617
618 // These check the state of the currently bound framebuffer or the
619 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54620 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
621 // check with all attached and enabled color attachments.
622 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46623 bool BoundFramebufferHasDepthAttachment();
624 bool BoundFramebufferHasStencilAttachment();
625
[email protected]b8e97b62012-09-30 15:09:00626 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43627
[email protected]91c94eb2013-10-22 10:32:54628 // Overridden from FramebufferManager::TextureDetachObserver:
629 virtual void OnTextureRefDetachedFromFramebuffer(
630 TextureRef* texture) OVERRIDE;
631
[email protected]f42f05b2013-11-15 21:46:18632 // Helpers to facilitate calling into compatible extensions.
633 static void RenderbufferStorageMultisampleHelper(
634 const FeatureInfo* feature_info,
635 GLenum target,
636 GLsizei samples,
637 GLenum internal_format,
638 GLsizei width,
639 GLsizei height);
640
641 void BlitFramebufferHelper(GLint srcX0,
642 GLint srcY0,
643 GLint srcX1,
644 GLint srcY1,
645 GLint dstX0,
646 GLint dstY0,
647 GLint dstX1,
648 GLint dstY1,
649 GLbitfield mask,
650 GLenum filter);
[email protected]345ba902013-11-14 21:39:00651
[email protected]96449d2c2009-11-25 00:01:32652 private:
[email protected]70d34263c2013-01-09 00:27:45653 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02654 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35655 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35656
[email protected]c2f8c8402010-12-06 18:07:24657 // Initialize or re-initialize the shader translator.
658 bool InitializeShaderTranslator();
659
[email protected]302ce6d2011-07-07 23:28:11660 void UpdateCapabilities();
661
[email protected]ae51d192010-04-27 00:48:03662 // Helpers for the glGen and glDelete functions.
663 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
664 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
665 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
666 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
667 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
668 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
669 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
670 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53671 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
672 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46673 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
674 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47675
[email protected]70d34263c2013-01-09 00:27:45676 // Workarounds
677 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51678 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45679
[email protected]3916c97e2010-02-25 03:20:50680 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50681 BufferManager* buffer_manager() {
682 return group_->buffer_manager();
683 }
684
[email protected]a25fa872010-03-25 02:57:58685 RenderbufferManager* renderbuffer_manager() {
686 return group_->renderbuffer_manager();
687 }
688
689 FramebufferManager* framebuffer_manager() {
690 return group_->framebuffer_manager();
691 }
692
[email protected]3916c97e2010-02-25 03:20:50693 ProgramManager* program_manager() {
694 return group_->program_manager();
695 }
696
697 ShaderManager* shader_manager() {
698 return group_->shader_manager();
699 }
700
[email protected]29a4d902013-02-26 20:18:06701 const TextureManager* texture_manager() const {
702 return group_->texture_manager();
703 }
704
[email protected]3916c97e2010-02-25 03:20:50705 TextureManager* texture_manager() {
706 return group_->texture_manager();
707 }
708
[email protected]78b514b2012-05-01 21:50:59709 MailboxManager* mailbox_manager() {
710 return group_->mailbox_manager();
711 }
712
[email protected]09d50362012-10-18 20:54:37713 ImageManager* image_manager() {
714 return group_->image_manager();
715 }
716
[email protected]944b62f32012-09-27 02:20:46717 VertexArrayManager* vertex_array_manager() {
718 return vertex_array_manager_.get();
719 }
720
[email protected]7989c9e2013-01-23 06:39:26721 MemoryTracker* memory_tracker() {
722 return group_->memory_tracker();
723 }
724
725 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
726 MemoryTracker* tracker = memory_tracker();
727 if (tracker) {
728 return tracker->EnsureGPUMemoryAvailable(estimated_size);
729 }
730 return true;
731 }
732
[email protected]34ff8b0c2010-10-01 20:06:02733 bool IsOffscreenBufferMultisampled() const {
734 return offscreen_target_samples_ > 1;
735 }
736
[email protected]ed9f9cd2013-02-27 21:12:35737 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49738 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03739 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35740 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47741 }
742
743 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49744 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07745 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47746 }
747
748 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35749 void RemoveTexture(GLuint client_id) {
750 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50751 }
[email protected]a93bb842010-02-16 23:03:47752
[email protected]d37231fa2010-04-09 21:16:02753 // Get the size (in pixels) of the currently bound frame buffer (either FBO
754 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30755 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02756
[email protected]9edc6b22010-12-23 02:00:26757 // Get the format of the currently bound frame buffer (either FBO or regular
758 // back buffer)
[email protected]68586372013-12-11 01:27:59759 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26760 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46761 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26762
[email protected]a93bb842010-02-16 23:03:47763 // Wrapper for CompressedTexImage2D commands.
764 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37765 GLenum target,
766 GLint level,
767 GLenum internal_format,
768 GLsizei width,
769 GLsizei height,
770 GLint border,
771 GLsizei image_size,
772 const void* data);
[email protected]a93bb842010-02-16 23:03:47773
[email protected]cadde4a2010-07-31 17:10:43774 // Wrapper for CompressedTexSubImage2D.
775 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37776 GLenum target,
777 GLint level,
778 GLint xoffset,
779 GLint yoffset,
780 GLsizei width,
781 GLsizei height,
782 GLenum format,
783 GLsizei imageSize,
784 const void * data);
[email protected]cadde4a2010-07-31 17:10:43785
786 // Wrapper for CopyTexImage2D.
787 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37788 GLenum target,
789 GLint level,
790 GLenum internal_format,
791 GLint x,
792 GLint y,
793 GLsizei width,
794 GLsizei height,
795 GLint border);
[email protected]cadde4a2010-07-31 17:10:43796
[email protected]6d792ee12013-05-15 00:40:56797 // Wrapper for SwapBuffers.
798 void DoSwapBuffers();
799
[email protected]cadde4a2010-07-31 17:10:43800 // Wrapper for CopyTexSubImage2D.
801 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37802 GLenum target,
803 GLint level,
804 GLint xoffset,
805 GLint yoffset,
806 GLint x,
807 GLint y,
808 GLsizei width,
809 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43810
[email protected]f598f422012-12-07 08:30:03811 // Validation for TexSubImage2D.
812 bool ValidateTexSubImage2D(
813 error::Error* error,
814 const char* function_name,
815 GLenum target,
816 GLint level,
817 GLint xoffset,
818 GLint yoffset,
819 GLsizei width,
820 GLsizei height,
821 GLenum format,
822 GLenum type,
823 const void * data);
824
[email protected]cadde4a2010-07-31 17:10:43825 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03826 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37827 GLenum target,
828 GLint level,
829 GLint xoffset,
830 GLint yoffset,
831 GLsizei width,
832 GLsizei height,
833 GLenum format,
834 GLenum type,
835 const void * data);
[email protected]cadde4a2010-07-31 17:10:43836
[email protected]32145a92012-12-17 09:01:59837 // Extra validation for async tex(Sub)Image2D.
838 bool ValidateAsyncTransfer(
839 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47840 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59841 GLenum target,
842 GLint level,
843 const void * data);
844
[email protected]e51bdf32011-11-23 22:21:46845 // Wrapper for TexImageIOSurface2DCHROMIUM.
846 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37847 GLenum target,
848 GLsizei width,
849 GLsizei height,
850 GLuint io_surface_id,
851 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46852
[email protected]43410e92012-04-20 17:06:28853 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37854 GLenum target,
855 GLuint source_id,
856 GLuint target_id,
857 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54858 GLenum internal_format,
859 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28860
[email protected]97dc7cbe2011-12-06 17:26:17861 // Wrapper for TexStorage2DEXT.
862 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37863 GLenum target,
864 GLint levels,
865 GLenum internal_format,
866 GLsizei width,
867 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17868
[email protected]78b514b2012-05-01 21:50:59869 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
870 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
871
[email protected]09d50362012-10-18 20:54:37872 void DoBindTexImage2DCHROMIUM(
873 GLenum target,
874 GLint image_id);
875 void DoReleaseTexImage2DCHROMIUM(
876 GLenum target,
877 GLint image_id);
878
[email protected]94307712012-11-16 23:26:11879 void DoTraceEndCHROMIUM(void);
880
[email protected]2f143d482013-03-14 18:04:49881 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
882
[email protected]ed9f9cd2013-02-27 21:12:35883 // Creates a Program for the given program.
884 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57885 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35886 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47887 }
888
[email protected]07f54fcc2009-12-22 02:46:30889 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35890 Program* GetProgram(GLuint client_id) {
891 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46892 }
[email protected]07f54fcc2009-12-22 02:46:30893
[email protected]cae20172012-12-07 00:06:19894#if defined(NDEBUG)
895 void LogClientServiceMapping(
896 const char* /* function_name */,
897 GLuint /* client_id */,
898 GLuint /* service_id */) {
899 }
900 template<typename T>
901 void LogClientServiceForInfo(
902 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
903 }
904#else
905 void LogClientServiceMapping(
906 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26907 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:47908 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
909 << ": client_id = " << client_id
910 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:26911 }
[email protected]cae20172012-12-07 00:06:19912 }
913 template<typename T>
914 void LogClientServiceForInfo(
915 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26916 if (info) {
[email protected]cae20172012-12-07 00:06:19917 LogClientServiceMapping(function_name, client_id, info->service_id());
918 }
919 }
920#endif
921
[email protected]6b8cf1a2010-05-06 16:13:58922 // Gets the program info for the given program. If it's not a program
923 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35924 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58925 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42926 Program* program = GetProgram(client_id);
927 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35928 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51929 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43930 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58931 } else {
[email protected]ab09b612013-03-11 22:11:51932 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58933 }
934 }
[email protected]df37b9932013-03-08 05:21:42935 LogClientServiceForInfo(program, client_id, function_name);
936 return program;
[email protected]6b8cf1a2010-05-06 16:13:58937 }
938
939
[email protected]ed9f9cd2013-02-27 21:12:35940 // Creates a Shader for the given shader.
941 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57942 GLuint client_id,
943 GLuint service_id,
944 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:35945 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:57946 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31947 }
948
949 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35950 Shader* GetShader(GLuint client_id) {
951 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:31952 }
953
[email protected]6b8cf1a2010-05-06 16:13:58954 // Gets the shader info for the given shader. If it's not a shader generates a
955 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:35956 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:58957 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42958 Shader* shader = GetShader(client_id);
959 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:35960 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:51961 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43962 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58963 } else {
[email protected]ab09b612013-03-11 22:11:51964 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43965 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58966 }
967 }
[email protected]df37b9932013-03-08 05:21:42968 LogClientServiceForInfo(shader, client_id, function_name);
969 return shader;
[email protected]6b8cf1a2010-05-06 16:13:58970 }
971
[email protected]a93bb842010-02-16 23:03:47972 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:35973 void CreateBuffer(GLuint client_id, GLuint service_id) {
974 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47975 }
976
[email protected]07f54fcc2009-12-22 02:46:30977 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:21978 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:07979 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
980 return buffer;
[email protected]1d32bc82010-01-13 22:06:46981 }
[email protected]07f54fcc2009-12-22 02:46:30982
[email protected]a93bb842010-02-16 23:03:47983 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
984 // on glDeleteBuffers so we can make sure the user does not try to render
985 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:35986 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:47987
[email protected]a25fa872010-03-25 02:57:58988 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35989 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
990 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58991 }
992
993 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:06994 Framebuffer* GetFramebuffer(GLuint client_id) {
995 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58996 }
997
998 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35999 void RemoveFramebuffer(GLuint client_id) {
1000 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581001 }
1002
1003 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351004 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1005 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031006 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581007 }
1008
1009 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271010 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1011 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581012 }
1013
1014 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351015 void RemoveRenderbuffer(GLuint client_id) {
1016 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581017 }
1018
[email protected]944b62f32012-09-27 02:20:461019 // Gets the vertex attrib manager for the given vertex array.
1020 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1021 VertexAttribManager* info =
1022 vertex_array_manager()->GetVertexAttribManager(client_id);
1023 return info;
1024 }
1025
1026 // Removes the vertex attrib manager for the given vertex array.
1027 void RemoveVertexAttribManager(GLuint client_id) {
1028 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1029 }
1030
1031 // Creates a vertex attrib manager for the given vertex array.
1032 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1033 return vertex_array_manager()->CreateVertexAttribManager(
1034 client_id, service_id, group_->max_vertex_attribs());
1035 }
1036
[email protected]258a3313f2011-10-18 20:13:571037 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331038 void DoBindUniformLocationCHROMIUM(
1039 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571040
[email protected]558847a2010-03-24 07:02:541041 error::Error GetAttribLocationHelper(
1042 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1043 const std::string& name_str);
1044
1045 error::Error GetUniformLocationHelper(
1046 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1047 const std::string& name_str);
1048
[email protected]3916c97e2010-02-25 03:20:501049 // Helper for glShaderSource.
1050 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031051 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301052
[email protected]0d6bfdc2011-11-02 01:32:201053 // Clear any textures used by the current program.
1054 bool ClearUnclearedTextures();
1055
[email protected]0d6bfdc2011-11-02 01:32:201056 // Clears any uncleared attachments attached to the given frame buffer.
1057 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061058 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281059
[email protected]0d6bfdc2011-11-02 01:32:201060 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001061 virtual bool ClearLevel(unsigned service_id,
1062 unsigned bind_target,
1063 unsigned target,
1064 int level,
1065 unsigned format,
1066 unsigned type,
1067 int width,
1068 int height,
1069 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201070
[email protected]c007aa02010-09-02 22:22:401071 // Restore all GL state that affects clearing.
1072 void RestoreClearState();
1073
[email protected]3a2e7c7b2010-08-06 01:12:281074 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461075 // Returns: true if glEnable/glDisable should actually be called.
1076 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281077
[email protected]0d6bfdc2011-11-02 01:32:201078 // Check that the currently bound framebuffers are valid.
1079 // Generates GL error if not.
1080 bool CheckBoundFramebuffersValid(const char* func_name);
1081
1082 // Check if a framebuffer meets our requirements.
1083 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351084 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201085 GLenum target,
1086 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271087
[email protected]939e7362010-05-13 20:49:101088 // Checks if the current program exists and is valid. If not generates the
1089 // appropriate GL error. Returns true if the current program is in a usable
1090 // state.
1091 bool CheckCurrentProgram(const char* function_name);
1092
1093 // Checks if the current program exists and is valid and that location is not
1094 // -1. If the current program is not valid generates the appropriate GL
1095 // error. Returns true if the current program is in a usable state and
1096 // location is not -1.
1097 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1098
1099 // Gets the type of a uniform for a location in the current program. Sets GL
1100 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361101 // program is valid and the location exists. Adjusts count so it
1102 // does not overflow the uniform.
1103 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121104 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521105 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121106 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101107
[email protected]b177ae22011-11-01 03:29:111108 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021109 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111110
[email protected]b273e432010-04-12 17:23:581111 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1112 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1113
[email protected]ac77603c72013-03-08 13:52:061114 // Helper for glGetVertexAttrib
1115 void GetVertexAttribHelper(
1116 const VertexAttrib* attrib, GLenum pname, GLint* param);
1117
[email protected]96449d2c2009-11-25 00:01:321118 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031119 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321120
1121 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031122 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321123
[email protected]3916c97e2010-02-25 03:20:501124 // Wrapper for glActiveTexture
1125 void DoActiveTexture(GLenum texture_unit);
1126
[email protected]ae51d192010-04-27 00:48:031127 // Wrapper for glAttachShader
1128 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1129
[email protected]96449d2c2009-11-25 00:01:321130 // Wrapper for glBindBuffer since we need to track the current targets.
1131 void DoBindBuffer(GLenum target, GLuint buffer);
1132
[email protected]86093972010-03-11 00:13:561133 // Wrapper for glBindFramebuffer since we need to track the current targets.
1134 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1135
1136 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1137 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1138
[email protected]a93bb842010-02-16 23:03:471139 // Wrapper for glBindTexture since we need to track the current targets.
1140 void DoBindTexture(GLenum target, GLuint texture);
1141
[email protected]944b62f32012-09-27 02:20:461142 // Wrapper for glBindVertexArrayOES
1143 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571144 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461145
[email protected]49cabed2013-11-13 18:15:181146 // Wrapper for glBlitFramebufferCHROMIUM.
1147 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301148 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1149 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1150 GLbitfield mask, GLenum filter);
1151
[email protected]36cef8ce2010-03-16 07:34:451152 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111153 void DoBufferSubData(
1154 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1155
[email protected]36cef8ce2010-03-16 07:34:451156 // Wrapper for glCheckFramebufferStatus
1157 GLenum DoCheckFramebufferStatus(GLenum target);
1158
[email protected]3a03a8f2011-03-19 00:51:271159 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081160 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271161
[email protected]88a61bf2012-10-27 13:00:421162 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421163 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251164 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281165
[email protected]45bf5152010-02-12 00:11:311166 // Wrapper for glCompileShader.
1167 void DoCompileShader(GLuint shader);
1168
[email protected]269200b12010-11-18 22:53:061169 // Helper for DeleteSharedIdsCHROMIUM commands.
1170 void DoDeleteSharedIdsCHROMIUM(
1171 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101172
[email protected]ae51d192010-04-27 00:48:031173 // Wrapper for glDetachShader
1174 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1175
[email protected]3a2e7c7b2010-08-06 01:12:281176 // Wrapper for glDisable
1177 void DoDisable(GLenum cap);
1178
[email protected]07f54fcc2009-12-22 02:46:301179 // Wrapper for glDisableVertexAttribArray.
1180 void DoDisableVertexAttribArray(GLuint index);
1181
[email protected]60f22d32012-12-12 00:31:581182 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1183 // attachments.
1184 void DoDiscardFramebufferEXT(GLenum target,
1185 GLsizei numAttachments,
1186 const GLenum* attachments);
1187
[email protected]3a2e7c7b2010-08-06 01:12:281188 // Wrapper for glEnable
1189 void DoEnable(GLenum cap);
1190
[email protected]07f54fcc2009-12-22 02:46:301191 // Wrapper for glEnableVertexAttribArray.
1192 void DoEnableVertexAttribArray(GLuint index);
1193
[email protected]882ba1e22012-03-08 19:02:531194 // Wrapper for glFinish.
1195 void DoFinish();
1196
1197 // Wrapper for glFlush.
1198 void DoFlush();
1199
[email protected]36cef8ce2010-03-16 07:34:451200 // Wrapper for glFramebufferRenderbufffer.
1201 void DoFramebufferRenderbuffer(
1202 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1203 GLuint renderbuffer);
1204
1205 // Wrapper for glFramebufferTexture2D.
1206 void DoFramebufferTexture2D(
1207 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1208 GLint level);
1209
[email protected]7d3c36e2013-07-12 14:13:161210 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1211 void DoFramebufferTexture2DMultisample(
1212 GLenum target, GLenum attachment, GLenum textarget,
1213 GLuint texture, GLint level, GLsizei samples);
1214
1215 // Common implementation for both DoFramebufferTexture2D wrappers.
1216 void DoFramebufferTexture2DCommon(const char* name,
1217 GLenum target, GLenum attachment, GLenum textarget,
1218 GLuint texture, GLint level, GLsizei samples);
1219
[email protected]a93bb842010-02-16 23:03:471220 // Wrapper for glGenerateMipmap
1221 void DoGenerateMipmap(GLenum target);
1222
[email protected]269200b12010-11-18 22:53:061223 // Helper for GenSharedIdsCHROMIUM commands.
1224 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101225 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1226
[email protected]7d3c36e2013-07-12 14:13:161227 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1228 // to account for different pname values defined in different extension
1229 // variants.
1230 GLenum AdjustGetPname(GLenum pname);
1231
[email protected]b273e432010-04-12 17:23:581232 // Wrapper for DoGetBooleanv.
1233 void DoGetBooleanv(GLenum pname, GLboolean* params);
1234
1235 // Wrapper for DoGetFloatv.
1236 void DoGetFloatv(GLenum pname, GLfloat* params);
1237
[email protected]36cef8ce2010-03-16 07:34:451238 // Wrapper for glGetFramebufferAttachmentParameteriv.
1239 void DoGetFramebufferAttachmentParameteriv(
1240 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1241
[email protected]a0c3e972010-04-21 00:49:131242 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581243 void DoGetIntegerv(GLenum pname, GLint* params);
1244
[email protected]29a9eb52010-04-13 09:04:231245 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061246 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231247 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1248
[email protected]17cfbe0e2013-03-07 01:26:081249 // Wrapper for glGetBufferParameteriv.
1250 void DoGetBufferParameteriv(
1251 GLenum target, GLenum pname, GLint* params);
1252
[email protected]a0c3e972010-04-21 00:49:131253 // Wrapper for glGetProgramiv.
1254 void DoGetProgramiv(
1255 GLuint program_id, GLenum pname, GLint* params);
1256
[email protected]36cef8ce2010-03-16 07:34:451257 // Wrapper for glRenderbufferParameteriv.
1258 void DoGetRenderbufferParameteriv(
1259 GLenum target, GLenum pname, GLint* params);
1260
[email protected]ddd968b82010-03-02 00:44:291261 // Wrapper for glGetShaderiv
1262 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1263
[email protected]b1122982010-05-17 23:04:241264 // Wrappers for glGetVertexAttrib.
1265 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1266 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1267
[email protected]1958e0e2010-04-22 05:17:151268 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241269 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151270 bool DoIsBuffer(GLuint client_id);
1271 bool DoIsFramebuffer(GLuint client_id);
1272 bool DoIsProgram(GLuint client_id);
1273 bool DoIsRenderbuffer(GLuint client_id);
1274 bool DoIsShader(GLuint client_id);
1275 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461276 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151277
[email protected]07f54fcc2009-12-22 02:46:301278 // Wrapper for glLinkProgram
1279 void DoLinkProgram(GLuint program);
1280
[email protected]269200b12010-11-18 22:53:061281 // Helper for RegisterSharedIdsCHROMIUM.
1282 void DoRegisterSharedIdsCHROMIUM(
1283 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101284
[email protected]36cef8ce2010-03-16 07:34:451285 // Wrapper for glRenderbufferStorage.
1286 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031287 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451288
[email protected]49cabed2013-11-13 18:15:181289 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1290 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301291 GLenum target, GLsizei samples, GLenum internalformat,
1292 GLsizei width, GLsizei height);
1293
[email protected]49cabed2013-11-13 18:15:181294 // Handler for glRenderbufferStorageMultisampleEXT
1295 // (multisampled_render_to_texture).
1296 void DoRenderbufferStorageMultisampleEXT(
1297 GLenum target, GLsizei samples, GLenum internalformat,
1298 GLsizei width, GLsizei height);
1299
1300 // Common validation for multisample extensions.
1301 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1302 GLenum internalformat,
1303 GLsizei width,
1304 GLsizei height);
1305
[email protected]4a4c18b2013-09-13 22:50:101306 // Verifies that the currently bound multisample renderbuffer is valid
1307 // Very slow! Only done on platforms with driver bugs that return invalid
1308 // buffers under memory pressure
1309 bool VerifyMultisampleRenderbufferIntegrity(
1310 GLuint renderbuffer, GLenum format);
1311
[email protected]b273e432010-04-12 17:23:581312 // Wrapper for glReleaseShaderCompiler.
1313 void DoReleaseShaderCompiler() { }
1314
[email protected]3916c97e2010-02-25 03:20:501315 // Wrappers for glTexParameter functions.
1316 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1317 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1318 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1319 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1320
1321 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1322 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121323 void DoUniform1i(GLint fake_location, GLint v0);
1324 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1325 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1326 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1327 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101328
1329 // Wrappers for glUniformfv because some drivers don't correctly accept
1330 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121331 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1332 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1333 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1334 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501335
[email protected]43c2f1f2011-03-25 18:35:361336 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121337 GLint fake_location, GLsizei count, GLboolean transpose,
1338 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361339 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121340 GLint fake_location, GLsizei count, GLboolean transpose,
1341 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361342 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121343 GLint fake_location, GLsizei count, GLboolean transpose,
1344 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361345
[email protected]af6380962012-11-29 23:24:131346 bool SetVertexAttribValue(
1347 const char* function_name, GLuint index, const GLfloat* value);
1348
[email protected]b1122982010-05-17 23:04:241349 // Wrappers for glVertexAttrib??
1350 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1351 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1352 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1353 void DoVertexAttrib4f(
1354 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1355 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1356 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1357 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1358 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1359
[email protected]43410e92012-04-20 17:06:281360 // Wrapper for glViewport
1361 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1362
[email protected]07f54fcc2009-12-22 02:46:301363 // Wrapper for glUseProgram
1364 void DoUseProgram(GLuint program);
1365
[email protected]ae51d192010-04-27 00:48:031366 // Wrapper for glValidateProgram.
1367 void DoValidateProgram(GLuint program_client_id);
1368
[email protected]d2a0e1a2012-08-12 02:25:011369 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1370 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1371 void DoPopGroupMarkerEXT(void);
1372
[email protected]4e8a5b122010-05-08 22:00:101373 // Gets the number of values that will be returned by glGetXXX. Returns
1374 // false if pname is unknown.
1375 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1376
[email protected]07f54fcc2009-12-22 02:46:301377 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431378 bool IsDrawValid(
1379 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301380
[email protected]c13e1da62011-09-09 21:48:301381 // Returns true if successful, simulated will be true if attrib0 was
1382 // simulated.
[email protected]c6aef902012-02-14 03:31:421383 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431384 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281385 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241386
[email protected]91c94eb2013-10-22 10:32:541387 // If an image is bound to texture, this will call Will/DidUseTexImage
1388 // if needed.
1389 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1390 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1391
1392 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111393 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541394 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501395
[email protected]8fbedc02010-11-18 18:43:401396 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421397 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431398 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421399 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401400 void RestoreStateForSimulatedFixedAttribs();
1401
[email protected]c6aef902012-02-14 03:31:421402 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1403 // cases (primcount is 0 for non-instanced).
1404 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431405 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421406 bool instanced, GLenum mode, GLint first, GLsizei count,
1407 GLsizei primcount);
1408 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431409 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421410 bool instanced, GLenum mode, GLsizei count, GLenum type,
1411 int32 offset, GLsizei primcount);
1412
[email protected]61eeb33f2011-07-26 15:30:311413 GLenum GetBindTargetForSamplerType(GLenum type) {
1414 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461415 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1416 switch (type) {
1417 case GL_SAMPLER_2D:
1418 return GL_TEXTURE_2D;
1419 case GL_SAMPLER_CUBE:
1420 return GL_TEXTURE_CUBE_MAP;
1421 case GL_SAMPLER_EXTERNAL_OES:
1422 return GL_TEXTURE_EXTERNAL_OES;
1423 case GL_SAMPLER_2D_RECT_ARB:
1424 return GL_TEXTURE_RECTANGLE_ARB;
1425 }
1426
1427 NOTREACHED();
1428 return 0;
[email protected]61eeb33f2011-07-26 15:30:311429 }
1430
[email protected]8e3e0662010-08-23 18:46:301431 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061432 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1433 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301434 switch (target) {
1435 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451436 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341437 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301438 break;
[email protected]ebfb73c2012-08-15 02:37:451439 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341440 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301441 break;
1442 default:
1443 NOTREACHED();
1444 break;
1445 }
[email protected]4d8f0dd2013-03-09 14:37:061446 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301447 }
1448
[email protected]ed9f9cd2013-02-27 21:12:351449 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201450 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271451 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201452 switch (target) {
1453 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111454 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201455 break;
1456 default:
1457 NOTREACHED();
1458 break;
1459 }
[email protected]ee2a79c32013-03-10 03:50:271460 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201461 }
1462
[email protected]f7b85372010-02-03 01:11:371463 // Validates the program and location for a glGetUniform call and returns
1464 // a SizeResult setup to receive the result. Returns true if glGetUniform
1465 // should be called.
1466 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121467 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371468 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121469 error::Error* error, GLint* real_location, GLuint* service_id,
1470 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371471
[email protected]a10b4a02012-11-26 23:09:501472 virtual bool WasContextLost() OVERRIDE;
[email protected]93a7d98f2013-07-11 00:04:221473 virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091474 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431475
[email protected]e51bdf32011-11-23 22:21:461476#if defined(OS_MACOSX)
1477 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1478#endif
1479
[email protected]ad84a3a2012-06-08 21:42:431480 bool ValidateCompressedTexDimensions(
1481 const char* function_name,
1482 GLint level, GLsizei width, GLsizei height, GLenum format);
1483 bool ValidateCompressedTexFuncData(
1484 const char* function_name,
1485 GLsizei width, GLsizei height, GLenum format, size_t size);
1486 bool ValidateCompressedTexSubDimensions(
1487 const char* function_name,
1488 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1489 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351490 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431491
[email protected]ab09b612013-03-11 22:11:511492 void RenderWarning(const char* filename, int line, const std::string& msg);
1493 void PerformanceWarning(
1494 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011495
[email protected]62e155e2012-10-23 22:43:151496 const FeatureInfo::FeatureFlags& features() const {
1497 return feature_info_->feature_flags();
1498 }
1499
1500 const FeatureInfo::Workarounds& workarounds() const {
1501 return feature_info_->workarounds();
1502 }
1503
[email protected]a7266a92012-06-28 02:11:081504 bool ShouldDeferDraws() {
1505 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341506 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081507 surface_->DeferDraws();
1508 }
1509
[email protected]09e17272012-11-30 10:30:441510 bool ShouldDeferReads() {
1511 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341512 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441513 surface_->DeferDraws();
1514 }
1515
[email protected]c76fe672013-12-13 23:30:221516 error::Error WillAccessBoundFramebufferForDraw() {
1517 if (ShouldDeferDraws())
1518 return error::kDeferCommandUntilLater;
1519 if (!offscreen_target_frame_buffer_.get() &&
1520 !framebuffer_state_.bound_draw_framebuffer.get() &&
1521 !surface_->SetBackbufferAllocation(true))
1522 return error::kLostContext;
1523 return error::kNoError;
1524 }
1525
1526 error::Error WillAccessBoundFramebufferForRead() {
1527 if (ShouldDeferReads())
1528 return error::kDeferCommandUntilLater;
1529 if (!offscreen_target_frame_buffer_.get() &&
1530 !framebuffer_state_.bound_read_framebuffer.get() &&
1531 !surface_->SetBackbufferAllocation(true))
1532 return error::kLostContext;
1533 return error::kNoError;
1534 }
1535
[email protected]5a36dc132013-07-23 23:17:551536 void ProcessPendingReadPixels();
1537 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1538
[email protected]96449d2c2009-11-25 00:01:321539 // Generate a member function prototype for each command in an automated and
1540 // typesafe way.
1541 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141542 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351543 uint32 immediate_data_size, \
1544 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321545
1546 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1547
1548 #undef GLES2_CMD_OP
1549
[email protected]2f2d7042010-04-14 21:45:581550 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381551 scoped_refptr<gfx::GLSurface> surface_;
1552 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021553
[email protected]a3ded6d2010-10-19 06:44:391554 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351555 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391556
[email protected]1d82e822013-04-10 21:32:321557 DebugMarkerManager debug_marker_manager_;
1558 Logger logger_;
1559
[email protected]e259eb412012-10-13 05:47:241560 // All the state for this context.
1561 ContextState state_;
1562
[email protected]34ff8b0c2010-10-01 20:06:021563 // Current width and height of the offscreen frame buffer.
1564 gfx::Size offscreen_size_;
1565
[email protected]96449d2c2009-11-25 00:01:321566 // Util to help with GL.
1567 GLES2Util util_;
1568
[email protected]43410e92012-04-20 17:06:281569 // unpack flip y as last set by glPixelStorei
1570 bool unpack_flip_y_;
1571
[email protected]6c75c712012-06-19 15:43:171572 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281573 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171574 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281575
[email protected]944b62f32012-09-27 02:20:461576 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351577 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301578
[email protected]b1122982010-05-17 23:04:241579 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1580 GLuint attrib_0_buffer_id_;
1581
1582 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131583 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241584
[email protected]fc753442011-02-04 19:49:491585 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1586 bool attrib_0_buffer_matches_value_;
1587
[email protected]b1122982010-05-17 23:04:241588 // The size of attrib 0.
1589 GLsizei attrib_0_size_;
1590
[email protected]8fbedc02010-11-18 18:43:401591 // The buffer used to simulate GL_FIXED attribs.
1592 GLuint fixed_attrib_buffer_id_;
1593
1594 // The size of fiixed attrib buffer.
1595 GLsizei fixed_attrib_buffer_size_;
1596
[email protected]b9363b22010-06-09 22:06:151597 // The offscreen frame buffer that the client renders to. With EGL, the
1598 // depth and stencil buffers are separate. With regular GL there is a single
1599 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1600 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351601 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1602 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1603 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1604 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1605 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021606 GLenum offscreen_target_color_format_;
1607 GLenum offscreen_target_depth_format_;
1608 GLenum offscreen_target_stencil_format_;
1609 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561610 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351611
[email protected]de26b3c2011-08-03 21:54:271612 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351613 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1614 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491615 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351616 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271617
1618 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351619 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1620 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051621 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351622
[email protected]882ba1e22012-03-08 19:02:531623 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531624
[email protected]944b62f32012-09-27 02:20:461625 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1626
[email protected]729c0b42013-05-26 02:05:071627 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001628
[email protected]840a7e462013-02-27 01:29:511629 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481630
[email protected]e3932abb2013-03-13 00:01:371631 ShaderCacheCallback shader_cache_callback_;
1632
[email protected]85a4ac22013-05-31 01:58:471633 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421634
[email protected]32fe9aa2011-01-21 23:47:131635 // The format of the back buffer_
1636 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461637 bool back_buffer_has_depth_;
1638 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131639
[email protected]60f22d32012-12-12 00:31:581640 // Backbuffer attachments that are currently undefined.
1641 uint32 backbuffer_needs_clear_bits_;
1642
[email protected]a3a93e7b2010-08-28 00:48:561643 // The current decoder error.
1644 error::Error current_decoder_error_;
1645
[email protected]b1d2dcb2010-05-17 19:24:181646 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041647 scoped_refptr<ShaderTranslator> vertex_translator_;
1648 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181649
[email protected]e82fb792011-09-22 00:33:291650 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411651
[email protected]915a59a12010-09-30 21:29:111652 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051653 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351654 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051655
[email protected]65225772011-05-12 21:10:241656 int frame_number_;
1657
[email protected]706b69f2012-07-27 04:59:301658 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431659 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221660 bool reset_by_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431661
[email protected]f0d74742011-10-03 16:31:041662 // These flags are used to override the state of the shared feature_info_
1663 // member. Because the same FeatureInfo instance may be shared among many
1664 // contexts, the assumptions on the availablity of extensions in WebGL
1665 // contexts may be broken. These flags override the shared state to preserve
1666 // WebGL semantics.
1667 bool force_webgl_glsl_validation_;
1668 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491669 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131670 bool draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041671
[email protected]062c38b2012-01-18 03:25:101672 bool compile_shader_always_succeeds_;
1673
[email protected]cae20172012-12-07 00:06:191674 // Log extra info.
1675 bool service_logging_;
1676
[email protected]e51bdf32011-11-23 22:21:461677#if defined(OS_MACOSX)
1678 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1679 TextureToIOSurfaceMap texture_to_io_surface_map_;
1680#endif
1681
[email protected]43410e92012-04-20 17:06:281682 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1683
[email protected]1868a342012-11-07 15:56:021684 // Cached values of the currently assigned viewport dimensions.
1685 GLsizei viewport_max_width_;
1686 GLsizei viewport_max_height_;
1687
[email protected]63b465922012-09-06 02:04:521688 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521689 base::TimeDelta total_processing_commands_time_;
1690
[email protected]c986af502013-08-14 01:04:441691 // States related to each manager.
1692 DecoderTextureState texture_state_;
1693 DecoderFramebufferState framebuffer_state_;
1694
[email protected]fb97b662013-02-20 23:02:141695 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131696 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
[email protected]cac16542014-01-15 17:53:511697 int gpu_trace_level_;
1698 bool gpu_trace_commands_;
[email protected]94307712012-11-16 23:26:111699
[email protected]5a36dc132013-07-23 23:17:551700 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1701
[email protected]4a4c18b2013-09-13 22:50:101702 // Used to validate multisample renderbuffers if needed
1703 GLuint validation_texture_;
1704 GLuint validation_fbo_multisample_;
1705 GLuint validation_fbo_;
1706
[email protected]96449d2c2009-11-25 00:01:321707 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1708};
1709
[email protected]ab09b612013-03-11 22:11:511710ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301711 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511712 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301713 error_state_(error_state) {
1714 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351715}
1716
1717ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301718 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351719}
1720
[email protected]2b10c02d2014-01-29 16:43:021721static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361722 TextureUnit& info = state->texture_units[0];
1723 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021724 scoped_refptr<TextureRef> texture_ref;
1725 switch (target) {
1726 case GL_TEXTURE_2D:
1727 texture_ref = info.bound_texture_2d;
1728 break;
1729 case GL_TEXTURE_CUBE_MAP:
1730 texture_ref = info.bound_texture_cube_map;
1731 break;
1732 case GL_TEXTURE_EXTERNAL_OES:
1733 texture_ref = info.bound_texture_external_oes;
1734 break;
1735 case GL_TEXTURE_RECTANGLE_ARB:
1736 texture_ref = info.bound_texture_rectangle_arb;
1737 break;
1738 default:
1739 NOTREACHED();
1740 break;
1741 }
1742 if (texture_ref.get()) {
1743 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361744 } else {
1745 last_id = 0;
1746 }
1747
[email protected]2b10c02d2014-01-29 16:43:021748 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361749 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1750}
1751
[email protected]2b10c02d2014-01-29 16:43:021752ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1753 GLuint id,
1754 GLenum target)
1755 : state_(state),
1756 target_(target) {
[email protected]ab09b612013-03-11 22:11:511757 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021758 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351759
1760 // TODO(apatrick): Check if there are any other states that need to be reset
1761 // before binding a new texture.
1762 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021763 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351764}
1765
[email protected]2b10c02d2014-01-29 16:43:021766ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511767 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021768 "ScopedTextureBinder::dtor", state_->GetErrorState());
1769 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351770}
1771
[email protected]18e785a2013-10-09 03:29:411772ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351773 GLuint id)
[email protected]18e785a2013-10-09 03:29:411774 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511775 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411776 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351777 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1778}
1779
1780ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511781 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411782 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1783 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351784}
1785
1786ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1787 GLuint id)
1788 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511789 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301790 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351791 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451792 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351793}
1794
1795ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511796 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301797 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301798 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351799}
1800
[email protected]34ff8b0c2010-10-01 20:06:021801ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271802 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521803 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341804 resolve_and_bind_ = (
1805 decoder_->offscreen_target_frame_buffer_.get() &&
1806 decoder_->IsOffscreenBufferMultisampled() &&
1807 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1808 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021809 if (!resolve_and_bind_)
1810 return;
1811
[email protected]ab09b612013-03-11 22:11:511812 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301813 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021814 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1815 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271816 GLuint targetid;
1817 if (internal) {
1818 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1819 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351820 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271821 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351822 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:361823 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:271824 decoder_->offscreen_resolved_color_texture_->Create();
1825
1826 DCHECK(decoder_->offscreen_saved_color_format_);
1827 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091828 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1829 false);
[email protected]de26b3c2011-08-03 21:54:271830 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1831 decoder_->offscreen_resolved_color_texture_.get());
1832 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1833 GL_FRAMEBUFFER_COMPLETE) {
1834 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1835 << "because offscreen resolved FBO was incomplete.";
1836 return;
1837 }
1838 }
1839 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1840 } else {
1841 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1842 }
1843 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021844 const int width = decoder_->offscreen_size_.width();
1845 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181846 glDisable(GL_SCISSOR_TEST);
[email protected]f42f05b2013-11-15 21:46:181847 decoder->BlitFramebufferHelper(0,
1848 0,
1849 width,
1850 height,
1851 0,
1852 0,
1853 width,
1854 height,
1855 GL_COLOR_BUFFER_BIT,
1856 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:271857 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021858}
1859
1860ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1861 if (!resolve_and_bind_)
1862 return;
1863
[email protected]ab09b612013-03-11 22:11:511864 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301865 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021866 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221867 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181868 glEnable(GL_SCISSOR_TEST);
1869 }
[email protected]34ff8b0c2010-10-01 20:06:021870}
1871
[email protected]ce296892013-10-24 22:04:361872BackTexture::BackTexture(
1873 MemoryTracker* memory_tracker,
1874 ContextState* state)
1875 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
1876 state_(state),
[email protected]68e81a4a62012-12-13 01:16:481877 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251878 id_(0) {
[email protected]6217d392010-03-25 22:08:351879}
1880
[email protected]ed9f9cd2013-02-27 21:12:351881BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351882 // This does not destroy the render texture because that would require that
1883 // the associated GL context was current. Just check that it was explicitly
1884 // destroyed.
1885 DCHECK_EQ(id_, 0u);
1886}
1887
[email protected]ed9f9cd2013-02-27 21:12:351888void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:301889 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:361890 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351891 Destroy();
1892 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:021893 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]3a4d0c52011-06-29 23:11:581894 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1895 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1896 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1897 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161898
1899 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1900 // never called on an offscreen context, no data will ever be uploaded to the
1901 // saved offscreen color texture (it is deferred until to when SwapBuffers
1902 // is called). My idea is that some nvidia drivers might have a bug where
1903 // deleting a texture that has never been populated might cause a
1904 // crash.
1905 glTexImage2D(
1906 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481907
1908 bytes_allocated_ = 16u * 16u * 4u;
1909 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351910}
1911
[email protected]ed9f9cd2013-02-27 21:12:351912bool BackTexture::AllocateStorage(
1913 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351914 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:301915 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:361916 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:021917 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:091918 uint32 image_size = 0;
1919 GLES2Util::ComputeImageDataSizes(
1920 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1921 NULL, NULL);
1922
[email protected]7989c9e2013-01-23 06:39:261923 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
1924 return false;
1925 }
1926
[email protected]40d90a22013-04-09 03:39:551927 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:091928 if (zero) {
1929 zero_data.reset(new char[image_size]);
1930 memset(zero_data.get(), 0, image_size);
1931 }
[email protected]6217d392010-03-25 22:08:351932
[email protected]8f1d2aa2013-05-10 23:45:381933 glTexImage2D(GL_TEXTURE_2D,
1934 0, // mip level
1935 format,
1936 size.width(),
1937 size.height(),
1938 0, // border
1939 format,
1940 GL_UNSIGNED_BYTE,
1941 zero_data.get());
[email protected]6217d392010-03-25 22:08:351942
[email protected]d37231fa2010-04-09 21:16:021943 size_ = size;
1944
[email protected]1078f912011-12-23 13:12:141945 bool success = glGetError() == GL_NO_ERROR;
1946 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481947 memory_tracker_.TrackMemFree(bytes_allocated_);
1948 bytes_allocated_ = image_size;
1949 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141950 }
1951 return success;
[email protected]6217d392010-03-25 22:08:351952}
1953
[email protected]ed9f9cd2013-02-27 21:12:351954void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351955 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:301956 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:361957 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:021958 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:351959 glCopyTexImage2D(GL_TEXTURE_2D,
1960 0, // level
[email protected]3a4d0c52011-06-29 23:11:581961 format,
[email protected]6217d392010-03-25 22:08:351962 0, 0,
1963 size.width(),
1964 size.height(),
1965 0); // border
1966}
1967
[email protected]ed9f9cd2013-02-27 21:12:351968void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:351969 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:301970 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:361971 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351972 glDeleteTextures(1, &id_);
1973 id_ = 0;
1974 }
[email protected]68e81a4a62012-12-13 01:16:481975 memory_tracker_.TrackMemFree(bytes_allocated_);
1976 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351977}
1978
[email protected]ed9f9cd2013-02-27 21:12:351979void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:051980 id_ = 0;
1981}
1982
[email protected]d5a28e452013-10-10 01:01:401983BackRenderbuffer::BackRenderbuffer(
1984 RenderbufferManager* renderbuffer_manager,
1985 MemoryTracker* memory_tracker,
1986 ContextState* state)
1987 : renderbuffer_manager_(renderbuffer_manager),
1988 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
1989 state_(state),
[email protected]68e81a4a62012-12-13 01:16:481990 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251991 id_(0) {
[email protected]6217d392010-03-25 22:08:351992}
1993
[email protected]ed9f9cd2013-02-27 21:12:351994BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:351995 // This does not destroy the render buffer because that would require that
1996 // the associated GL context was current. Just check that it was explicitly
1997 // destroyed.
1998 DCHECK_EQ(id_, 0u);
1999}
2000
[email protected]ed9f9cd2013-02-27 21:12:352001void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302002 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402003 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352004 Destroy();
2005 glGenRenderbuffersEXT(1, &id_);
2006}
2007
[email protected]f42f05b2013-11-15 21:46:182008bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2009 const gfx::Size& size,
2010 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352011 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512012 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402013 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2014 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262015
2016 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402017 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232018 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262019 return false;
2020 }
2021
2022 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2023 return false;
2024 }
2025
[email protected]34ff8b0c2010-10-01 20:06:022026 if (samples <= 1) {
2027 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2028 format,
2029 size.width(),
2030 size.height());
2031 } else {
[email protected]f42f05b2013-11-15 21:46:182032 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2033 GL_RENDERBUFFER,
2034 samples,
2035 format,
2036 size.width(),
2037 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022038 }
[email protected]1078f912011-12-23 13:12:142039 bool success = glGetError() == GL_NO_ERROR;
2040 if (success) {
[email protected]d5a28e452013-10-10 01:01:402041 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482042 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262043 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402044 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482045 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142046 }
2047 return success;
[email protected]6217d392010-03-25 22:08:352048}
2049
[email protected]ed9f9cd2013-02-27 21:12:352050void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352051 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302052 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402053 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352054 glDeleteRenderbuffersEXT(1, &id_);
2055 id_ = 0;
2056 }
[email protected]68e81a4a62012-12-13 01:16:482057 memory_tracker_.TrackMemFree(bytes_allocated_);
2058 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352059}
2060
[email protected]ed9f9cd2013-02-27 21:12:352061void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052062 id_ = 0;
2063}
2064
[email protected]ed9f9cd2013-02-27 21:12:352065BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352066 : decoder_(decoder),
2067 id_(0) {
2068}
2069
[email protected]ed9f9cd2013-02-27 21:12:352070BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352071 // This does not destroy the frame buffer because that would require that
2072 // the associated GL context was current. Just check that it was explicitly
2073 // destroyed.
2074 DCHECK_EQ(id_, 0u);
2075}
2076
[email protected]ed9f9cd2013-02-27 21:12:352077void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302078 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2079 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352080 Destroy();
2081 glGenFramebuffersEXT(1, &id_);
2082}
2083
[email protected]ed9f9cd2013-02-27 21:12:352084void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352085 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512086 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302087 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352088 ScopedFrameBufferBinder binder(decoder_, id_);
2089 GLuint attach_id = texture ? texture->id() : 0;
2090 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2091 GL_COLOR_ATTACHMENT0,
2092 GL_TEXTURE_2D,
2093 attach_id,
2094 0);
2095}
2096
[email protected]ed9f9cd2013-02-27 21:12:352097void BackFramebuffer::AttachRenderBuffer(GLenum target,
2098 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352099 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512100 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302101 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352102 ScopedFrameBufferBinder binder(decoder_, id_);
2103 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2104 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152105 target,
[email protected]6217d392010-03-25 22:08:352106 GL_RENDERBUFFER,
2107 attach_id);
2108}
2109
[email protected]ed9f9cd2013-02-27 21:12:352110void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352111 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302112 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2113 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352114 glDeleteFramebuffersEXT(1, &id_);
2115 id_ = 0;
2116 }
2117}
2118
[email protected]ed9f9cd2013-02-27 21:12:352119void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052120 id_ = 0;
2121}
2122
[email protected]ed9f9cd2013-02-27 21:12:352123GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352124 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302125 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2126 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352127 ScopedFrameBufferBinder binder(decoder_, id_);
2128 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2129}
2130
[email protected]aa7666122011-09-02 19:45:522131GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2132 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322133}
2134
[email protected]aa7666122011-09-02 19:45:522135GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392136 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572137 group_(group),
[email protected]1d82e822013-04-10 21:32:322138 logger_(&debug_marker_manager_),
[email protected]d3eba342013-04-18 21:11:502139 state_(group_->feature_info(), &logger_),
[email protected]43410e92012-04-20 17:06:282140 unpack_flip_y_(false),
2141 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172142 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242143 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492144 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242145 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402146 fixed_attrib_buffer_id_(0),
2147 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022148 offscreen_target_color_format_(0),
2149 offscreen_target_depth_format_(0),
2150 offscreen_target_stencil_format_(0),
2151 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562152 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052153 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132154 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462155 back_buffer_has_depth_(false),
2156 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582157 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562158 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052159 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112160 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002161 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432162 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302163 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512164 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222165 reset_by_robustness_extension_(false),
[email protected]f0d74742011-10-03 16:31:042166 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102167 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492168 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132169 draw_buffers_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282170 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192171 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2172 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022173 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102174 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002175 texture_state_(group_->feature_info()
2176 ->workarounds()
2177 .texsubimage2d_faster_than_teximage2d),
[email protected]4a4c18b2013-09-13 22:50:102178 validation_texture_(0),
2179 validation_fbo_multisample_(0),
2180 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572181 DCHECK(group);
2182
[email protected]b1122982010-05-17 23:04:242183 attrib_0_value_.v[0] = 0.0f;
2184 attrib_0_value_.v[1] = 0.0f;
2185 attrib_0_value_.v[2] = 0.0f;
2186 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152187
[email protected]c2f8c8402010-12-06 18:07:242188 // The shader translator is used for WebGL even when running on EGL
2189 // because additional restrictions are needed (like only enabling
2190 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562191 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2192 // the empty string to CompileShader and this is not a valid shader.
2193 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002194 CommandLine::ForCurrentProcess()->HasSwitch(
2195 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152196 use_shader_translator_ = false;
2197 }
[email protected]96449d2c2009-11-25 00:01:322198}
2199
[email protected]80eb6b52012-01-19 00:14:412200GLES2DecoderImpl::~GLES2DecoderImpl() {
2201}
2202
[email protected]c410da802011-03-14 19:17:412203bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382204 const scoped_refptr<gfx::GLSurface>& surface,
2205 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232206 bool offscreen,
[email protected]c410da802011-03-14 19:17:412207 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292208 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242209 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322210 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382211 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302212 DCHECK(!context_.get());
2213
[email protected]55e136f2013-04-03 18:50:062214 set_initialized();
[email protected]bccc0f32014-01-10 03:18:082215 gpu_tracer_ = GPUTracer::Create(this);
[email protected]8f9b8dd2013-09-12 18:05:132216 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]cac16542014-01-15 17:53:512217 // TODO(vmiura): Enable changing gpu_trace_level_ at runtime
2218 gpu_trace_level_ = 2;
2219 gpu_trace_commands_ = false;
[email protected]fb97b662013-02-20 23:02:142220
[email protected]e844ae22012-01-14 03:36:262221 if (CommandLine::ForCurrentProcess()->HasSwitch(
2222 switches::kEnableGPUDebugging)) {
2223 set_debug(true);
2224 }
2225
[email protected]39ba4f02012-03-26 01:16:002226 if (CommandLine::ForCurrentProcess()->HasSwitch(
2227 switches::kEnableGPUCommandLogging)) {
2228 set_log_commands(true);
2229 }
2230
[email protected]062c38b2012-01-18 03:25:102231 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2232 switches::kCompileShaderAlwaysSucceeds);
2233
[email protected]f62a5ab2011-05-23 20:34:152234
[email protected]63c9b052012-05-17 18:27:382235 // Take ownership of the context and surface. The surface can be replaced with
2236 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382237 context_ = context;
[email protected]63c9b052012-05-17 18:27:382238 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182239
[email protected]65f7efe2013-11-28 03:11:472240 ContextCreationAttribHelper attrib_parser;
2241 if (!attrib_parser.Parse(attribs))
2242 return false;
2243
2244 // If the failIfMajorPerformanceCaveat context creation attribute was true
2245 // and we are using a software renderer, fail.
2246 if (attrib_parser.fail_if_major_perf_caveat_ &&
2247 feature_info_->feature_flags().is_swiftshader) {
2248 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2249 Destroy(true);
2250 return false;
2251 }
2252
[email protected]956aec52013-09-05 15:41:192253 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222254 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392255 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422256 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382257 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032258 return false;
[email protected]a3ded6d2010-10-19 06:44:392259 }
[email protected]b64c24952012-04-19 03:20:272260 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282261
[email protected]e82fb792011-09-22 00:33:292262 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502263
[email protected]af6380962012-11-29 23:24:132264 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462265 default_vertex_attrib_manager_ = new VertexAttribManager();
2266 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2267
[email protected]ab4fd7282012-10-12 16:25:572268 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2269 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322270
[email protected]7cd76fd2013-06-02 21:11:112271 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]944b62f32012-09-27 02:20:462272 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532273
[email protected]302ce6d2011-07-07 23:28:112274 util_.set_num_compressed_texture_formats(
2275 validators_->compressed_texture_format.GetValues().size());
2276
[email protected]1071e572011-02-09 20:00:122277 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2278 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2279 // OpenGL ES 2.0 does not have this issue.
2280 glEnableVertexAttribArray(0);
2281 }
[email protected]b1122982010-05-17 23:04:242282 glGenBuffersARB(1, &attrib_0_buffer_id_);
2283 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2284 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2285 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402286 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082287
[email protected]1868a342012-11-07 15:56:022288 state_.texture_units.resize(group_->max_texture_units());
2289 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492290 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312291 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492292 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152293 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492294 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072295 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492296 state_.texture_units[tt].bound_texture_external_oes = ref;
2297 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id());
[email protected]61eeb33f2011-07-26 15:30:312298 }
[email protected]62e155e2012-10-23 22:43:152299 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492300 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072301 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492302 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2303 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id());
[email protected]e51bdf32011-11-23 22:21:462304 }
[email protected]370eaf12013-05-18 09:19:492305 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2306 state_.texture_units[tt].bound_texture_cube_map = ref;
2307 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id());
2308 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2309 state_.texture_units[tt].bound_texture_2d = ref;
2310 glBindTexture(GL_TEXTURE_2D, ref->service_id());
[email protected]1958e0e2010-04-22 05:17:152311 }
[email protected]00f893d2010-08-24 18:55:492312 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502313 CHECK_GL_ERROR();
2314
[email protected]069944672012-04-25 20:52:232315 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022316 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542317 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022318 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432319 // max_sample_count must be initialized to a sane value. If
2320 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2321 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022322 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2323 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2324 max_sample_count);
2325 } else {
2326 offscreen_target_samples_ = 1;
2327 }
[email protected]8a61d872012-01-20 12:43:562328 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022329
2330 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2331 const bool rgb8_supported =
2332 context_->HasExtension("GL_OES_rgb8_rgba8");
2333 // The only available default render buffer formats in GLES2 have very
2334 // little precision. Don't enable multisampling unless 8-bit render
2335 // buffer formats are available--instead fall back to 8-bit textures.
2336 if (rgb8_supported && offscreen_target_samples_ > 1) {
2337 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2338 GL_RGBA8 : GL_RGB8;
2339 } else {
2340 offscreen_target_samples_ = 1;
2341 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2342 GL_RGBA : GL_RGB;
2343 }
2344
2345 // ANGLE only supports packed depth/stencil formats, so use it if it is
2346 // available.
2347 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182348 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272349 VLOG(1) << "GL_OES_packed_depth_stencil "
2350 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002351 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2352 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022353 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2354 offscreen_target_stencil_format_ = 0;
2355 } else {
2356 // It may be the case that this depth/stencil combination is not
2357 // supported, but this will be checked later by CheckFramebufferStatus.
2358 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2359 GL_DEPTH_COMPONENT16 : 0;
2360 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2361 GL_STENCIL_INDEX8 : 0;
2362 }
2363 } else {
2364 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2365 GL_RGBA : GL_RGB;
2366
2367 // If depth is requested at all, use the packed depth stencil format if
2368 // it's available, as some desktop GL drivers don't support any non-packed
2369 // formats for depth attachments.
2370 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182371 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272372 VLOG(1) << "GL_EXT_packed_depth_stencil "
2373 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022374
[email protected]71ee3642010-10-14 18:08:002375 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2376 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022377 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2378 offscreen_target_stencil_format_ = 0;
2379 } else {
2380 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2381 GL_DEPTH_COMPONENT : 0;
2382 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2383 GL_STENCIL_INDEX : 0;
2384 }
2385 }
2386
[email protected]97872062010-11-03 19:07:052387 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2388 GL_RGBA : GL_RGB;
2389
[email protected]6217d392010-03-25 22:08:352390 // Create the target frame buffer. This is the one that the client renders
2391 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352392 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352393 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022394 // Due to GLES2 format limitations, either the color texture (for
2395 // non-multisampling) or the color render buffer (for multisampling) will be
2396 // attached to the offscreen frame buffer. The render buffer has more
2397 // limited formats available to it, but the texture can't do multisampling.
2398 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402399 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2400 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022401 offscreen_target_color_render_buffer_->Create();
2402 } else {
[email protected]ce296892013-10-24 22:04:362403 offscreen_target_color_texture_.reset(new BackTexture(
2404 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022405 offscreen_target_color_texture_->Create();
2406 }
[email protected]d5a28e452013-10-10 01:01:402407 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2408 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152409 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402410 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2411 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152412 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352413
2414 // Create the saved offscreen texture. The target frame buffer is copied
2415 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352416 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022417 offscreen_saved_frame_buffer_->Create();
2418 //
[email protected]ce296892013-10-24 22:04:362419 offscreen_saved_color_texture_.reset(new BackTexture(
2420 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352421 offscreen_saved_color_texture_->Create();
2422
[email protected]6217d392010-03-25 22:08:352423 // Allocate the render buffers at their initial size and check the status
2424 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592425 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012426 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382427 Destroy(true);
[email protected]6217d392010-03-25 22:08:352428 return false;
2429 }
2430
[email protected]678a73f2012-12-19 19:22:092431 // Allocate the offscreen saved color texture.
2432 DCHECK(offscreen_saved_color_format_);
2433 offscreen_saved_color_texture_->AllocateStorage(
2434 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2435
2436 offscreen_saved_frame_buffer_->AttachRenderTexture(
2437 offscreen_saved_color_texture_.get());
2438 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2439 GL_FRAMEBUFFER_COMPLETE) {
2440 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2441 Destroy(true);
2442 return false;
2443 }
2444
[email protected]6217d392010-03-25 22:08:352445 // Bind to the new default frame buffer (the offscreen target frame buffer).
2446 // This should now be associated with ID zero.
2447 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102448 } else {
2449 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2450 // These are NOT if the back buffer has these proprorties. They are
2451 // if we want the command buffer to enforce them regardless of what
2452 // the real backbuffer is assuming the real back buffer gives us more than
2453 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2454 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2455 // can't do anything about that.
2456
2457 GLint v = 0;
2458 glGetIntegerv(GL_ALPHA_BITS, &v);
2459 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2460 // user requested RGB then RGB. If the user did not specify a preference
2461 // than use whatever we were given. Same for DEPTH and STENCIL.
2462 back_buffer_color_format_ =
2463 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2464 glGetIntegerv(GL_DEPTH_BITS, &v);
2465 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2466 glGetIntegerv(GL_STENCIL_BITS, &v);
2467 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
[email protected]6217d392010-03-25 22:08:352468 }
2469
[email protected]76a0ee102010-04-07 21:03:042470 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2471 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2472 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372473 // mailing list archives. It also implicitly enables the desktop GL
2474 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2475 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152476 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2477 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372478 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152479 }
[email protected]de17df392010-04-23 21:09:412480
[email protected]706b69f2012-07-27 04:59:302481 has_robustness_extension_ =
2482 context->HasExtension("GL_ARB_robustness") ||
2483 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432484
[email protected]c2f8c8402010-12-06 18:07:242485 if (!InitializeShaderTranslator()) {
2486 return false;
[email protected]de17df392010-04-23 21:09:412487 }
[email protected]76a0ee102010-04-07 21:03:042488
[email protected]e259eb412012-10-13 05:47:242489 state_.viewport_width = size.width();
2490 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282491
[email protected]5904806b2012-05-08 18:10:222492 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282493 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022494 viewport_max_width_ = viewport_params[0];
2495 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282496
[email protected]88a61bf2012-10-27 13:00:422497 state_.scissor_width = state_.viewport_width;
2498 state_.scissor_height = state_.viewport_height;
2499
[email protected]11f3e702012-06-19 19:00:012500 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222501 state_.InitCapabilities();
2502 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242503 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012504
2505 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2506 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2507 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2508 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2509
[email protected]88cfd132013-07-11 00:59:002510 bool call_gl_clear = true;
2511#if defined(OS_ANDROID)
2512 // Temporary workaround for Android WebView because this clear ignores the
2513 // clip and corrupts that external UI of the App. Not calling glClear is ok
2514 // because the system already clears the buffer before each draw. Proper
2515 // fix might be setting the scissor clip properly before initialize. See
2516 // crbug.com/259023 for details.
2517 call_gl_clear = surface_->GetHandle();
2518#endif
2519 if (call_gl_clear) {
2520 // Clear the backbuffer.
2521 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2522 }
[email protected]561cc0a62013-05-07 18:34:452523
[email protected]62e155e2012-10-23 22:43:152524 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462525 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2526 }
[email protected]dd289a5d62012-06-30 22:05:462527
[email protected]9b753992013-04-27 02:04:412528 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2529 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242530 }
[email protected]85cb4682013-04-20 00:54:242531
[email protected]40245ccf2013-11-13 04:00:492532 if (feature_info_->workarounds().release_image_after_use) {
2533 image_manager()->SetReleaseAfterUse();
2534 }
2535
[email protected]97419c02013-04-10 02:52:382536 // Only compositor contexts are known to use only the subset of GL
2537 // that can be safely migrated between the iGPU and the dGPU. Mark
2538 // those contexts as safe to forcibly transition between the GPUs.
2539 // http://crbug.com/180876, http://crbug.com/227228
2540 if (!offscreen)
2541 context_->SetSafeToForceGpuSwitch();
2542
[email protected]85a4ac22013-05-31 01:58:472543 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072544 AsyncPixelTransferManager::Create(context.get()));
2545 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592546
[email protected]91c94eb2013-10-22 10:32:542547 framebuffer_manager()->AddObserver(this);
2548
[email protected]246a70452010-03-05 21:53:502549 return true;
[email protected]96449d2c2009-11-25 00:01:322550}
2551
[email protected]6d668892013-12-04 21:37:122552Capabilities GLES2DecoderImpl::GetCapabilities() {
2553 DCHECK(initialized());
2554
2555 Capabilities caps;
2556
2557 caps.fast_npot_mo8_textures =
2558 feature_info_->workarounds().enable_chromium_fast_npot_mo8_textures;
2559 caps.egl_image_external =
2560 feature_info_->feature_flags().oes_egl_image_external;
2561 caps.texture_format_bgra8888 =
2562 feature_info_->feature_flags().ext_texture_format_bgra8888;
2563 caps.texture_format_etc1 =
2564 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
2565 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2566 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2567 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2568 caps.discard_framebuffer =
2569 feature_info_->feature_flags().ext_discard_framebuffer;
2570
2571#if defined(OS_MACOSX)
2572 // This is unconditionally true on mac, no need to test for it at runtime.
2573 caps.iosurface = true;
2574#endif
2575
[email protected]35387b3b2014-01-11 22:50:112576 caps.post_sub_buffer = surface_->HasExtension("GL_CHROMIUM_post_sub_buffer");
[email protected]6d668892013-12-04 21:37:122577
2578 return caps;
2579}
2580
[email protected]302ce6d2011-07-07 23:28:112581void GLES2DecoderImpl::UpdateCapabilities() {
2582 util_.set_num_compressed_texture_formats(
2583 validators_->compressed_texture_format.GetValues().size());
2584 util_.set_num_shader_binary_formats(
2585 validators_->shader_binary_format.GetValues().size());
2586}
2587
[email protected]c2f8c8402010-12-06 18:07:242588bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442589 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2590
[email protected]c2f8c8402010-12-06 18:07:242591 if (!use_shader_translator_) {
2592 return true;
2593 }
2594 ShBuiltInResources resources;
2595 ShInitBuiltInResources(&resources);
2596 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2597 resources.MaxVertexUniformVectors =
2598 group_->max_vertex_uniform_vectors();
2599 resources.MaxVaryingVectors = group_->max_varying_vectors();
2600 resources.MaxVertexTextureImageUnits =
2601 group_->max_vertex_texture_image_units();
2602 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2603 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2604 resources.MaxFragmentUniformVectors =
2605 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492606 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242607 resources.MaxExpressionComplexity = 256;
2608 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042609
[email protected]9e98f61b2013-03-05 02:21:142610#if (ANGLE_SH_VERSION >= 110)
[email protected]46c86752013-05-21 05:08:392611 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212612 GLint precision = 0;
2613 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2614 range, &precision);
[email protected]448e459e2013-06-12 17:00:412615 resources.FragmentPrecisionHigh =
2616 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142617#endif
2618
[email protected]f0d74742011-10-03 16:31:042619 if (force_webgl_glsl_validation_) {
2620 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492621 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132622 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442623 if (!draw_buffers_explicitly_enabled_)
2624 resources.MaxDrawBuffers = 1;
[email protected]f0d74742011-10-03 16:31:042625 } else {
2626 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152627 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462628 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152629 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062630 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152631 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492632 resources.EXT_draw_buffers =
2633 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492634 resources.EXT_frag_depth =
2635 features().ext_frag_depth ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042636 }
2637
[email protected]26b61442013-03-17 16:12:012638 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2639 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052640 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022641#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052642 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022643#else
2644 resources.HashFunction = &CityHash64;
2645#endif
[email protected]6aedcdc2013-01-24 01:25:052646 else
2647 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122648 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2649 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2650 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212651 int driver_bug_workarounds = 0;
2652 if (workarounds().needs_glsl_built_in_function_emulation)
2653 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542654 if (workarounds().init_gl_position_in_vertex_shader)
2655 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112656 if (workarounds().unfold_short_circuit_as_ternary_operation)
2657 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]87fb6ab2012-06-13 22:28:042658
2659 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2660 vertex_translator_ = cache->GetTranslator(
2661 SH_VERTEX_SHADER, shader_spec, &resources,
[email protected]a6739bc2013-09-07 04:45:212662 implementation_type,
2663 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042664 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242665 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382666 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242667 return false;
2668 }
[email protected]87fb6ab2012-06-13 22:28:042669
2670 fragment_translator_ = cache->GetTranslator(
2671 SH_FRAGMENT_SHADER, shader_spec, &resources,
[email protected]a6739bc2013-09-07 04:45:212672 implementation_type,
2673 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042674 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242675 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382676 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242677 return false;
2678 }
2679 return true;
2680}
2681
[email protected]ae51d192010-04-27 00:48:032682bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472683 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352684 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032685 return false;
2686 }
2687 }
[email protected]40d90a22013-04-09 03:39:552688 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032689 glGenBuffersARB(n, service_ids.get());
2690 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352691 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032692 }
2693 return true;
2694}
2695
2696bool GLES2DecoderImpl::GenFramebuffersHelper(
2697 GLsizei n, const GLuint* client_ids) {
2698 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352699 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032700 return false;
2701 }
2702 }
[email protected]40d90a22013-04-09 03:39:552703 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032704 glGenFramebuffersEXT(n, service_ids.get());
2705 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352706 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032707 }
2708 return true;
2709}
2710
2711bool GLES2DecoderImpl::GenRenderbuffersHelper(
2712 GLsizei n, const GLuint* client_ids) {
2713 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352714 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032715 return false;
2716 }
2717 }
[email protected]40d90a22013-04-09 03:39:552718 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032719 glGenRenderbuffersEXT(n, service_ids.get());
2720 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352721 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032722 }
2723 return true;
2724}
2725
2726bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2727 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352728 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032729 return false;
2730 }
2731 }
[email protected]40d90a22013-04-09 03:39:552732 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032733 glGenTextures(n, service_ids.get());
2734 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352735 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032736 }
2737 return true;
2738}
2739
2740void GLES2DecoderImpl::DeleteBuffersHelper(
2741 GLsizei n, const GLuint* client_ids) {
2742 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212743 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102744 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242745 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112746 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242747 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102748 }
[email protected]ed9f9cd2013-02-27 21:12:352749 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032750 }
[email protected]a93bb842010-02-16 23:03:472751 }
[email protected]07f54fcc2009-12-22 02:46:302752}
2753
[email protected]ae51d192010-04-27 00:48:032754void GLES2DecoderImpl::DeleteFramebuffersHelper(
2755 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452756 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152757 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112758
[email protected]a25fa872010-03-25 02:57:582759 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352760 Framebuffer* framebuffer =
2761 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102762 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:342763 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2764 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442765 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452766 GLenum target = supports_separate_framebuffer_binds ?
2767 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112768 glBindFramebufferEXT(target, GetBackbufferServiceId());
2769 }
[email protected]9d3b2e12013-10-02 01:04:342770 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2771 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452772 GLenum target = supports_separate_framebuffer_binds ?
2773 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112774 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462775 }
[email protected]70d34263c2013-01-09 00:27:452776 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352777 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032778 }
[email protected]a25fa872010-03-25 02:57:582779 }
[email protected]07f54fcc2009-12-22 02:46:302780}
2781
[email protected]ae51d192010-04-27 00:48:032782void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2783 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452784 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152785 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582786 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352787 Renderbuffer* renderbuffer =
2788 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102789 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112790 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242791 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102792 }
2793 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452794 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342795 if (framebuffer_state_.bound_read_framebuffer.get()) {
2796 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112797 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102798 }
[email protected]9d3b2e12013-10-02 01:04:342799 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2800 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112801 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102802 }
2803 } else {
[email protected]9d3b2e12013-10-02 01:04:342804 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2805 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112806 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102807 }
2808 }
[email protected]c986af502013-08-14 01:04:442809 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:352810 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032811 }
[email protected]a25fa872010-03-25 02:57:582812 }
[email protected]07f54fcc2009-12-22 02:46:302813}
2814
[email protected]ae51d192010-04-27 00:48:032815void GLES2DecoderImpl::DeleteTexturesHelper(
2816 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452817 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152818 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472819 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492820 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2821 if (texture_ref) {
2822 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102823 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:442824 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462825 }
[email protected]370eaf12013-05-18 09:19:492826 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:022827 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:492828 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102829 }
2830 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452831 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342832 if (framebuffer_state_.bound_read_framebuffer.get()) {
2833 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112834 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102835 }
[email protected]9d3b2e12013-10-02 01:04:342836 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2837 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112838 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102839 }
2840 } else {
[email protected]9d3b2e12013-10-02 01:04:342841 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2842 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112843 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102844 }
2845 }
[email protected]e51bdf32011-11-23 22:21:462846#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:072847 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:462848 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2849 ReleaseIOSurfaceForTexture(service_id);
2850 }
2851#endif
[email protected]ed9f9cd2013-02-27 21:12:352852 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032853 }
[email protected]a93bb842010-02-16 23:03:472854 }
[email protected]07f54fcc2009-12-22 02:46:302855}
2856
[email protected]43f28f832010-02-03 02:28:482857// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322858
[email protected]eb54a562010-01-20 21:55:182859bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:342860 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:382861 return false;
2862
[email protected]177d1342013-12-07 04:20:342863 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432864 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292865
2866 // Some D3D drivers cannot recover from device lost in the GPU process
2867 // sandbox. Allow a new GPU process to launch.
2868 if (workarounds().exit_on_context_lost) {
2869 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2870 << " a D3D device in the Chrome GPU process sandbox.";
[email protected]6eb775352013-08-27 05:57:162871#if defined(OS_WIN)
2872 base::win::SetShouldCrashOnProcessDetach(false);
2873#endif
[email protected]e9f0ca82013-04-01 23:52:292874 exit(0);
2875 }
2876
[email protected]63c9b052012-05-17 18:27:382877 return false;
[email protected]38d139d2011-07-14 00:38:432878 }
2879
[email protected]69a8701e2013-03-07 21:31:092880 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:092881
[email protected]9b753992013-04-27 02:04:412882 // Rebind the FBO if it was unbound by the context.
2883 if (workarounds().unbind_fbo_on_context_switch)
2884 RestoreFramebufferBindings();
2885
[email protected]c986af502013-08-14 01:04:442886 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:492887
[email protected]69a8701e2013-03-07 21:31:092888 return true;
2889}
2890
2891void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:552892 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:322893 if (engine() && query_manager_.get())
2894 query_manager_->ProcessPendingTransferQueries();
2895
[email protected]5b3a8e02013-03-13 05:36:442896 // TODO(epenner): Is there a better place to do this?
2897 // This needs to occur before we execute any batch of commands
2898 // from the client, as the client may have recieved an async
2899 // completion while issuing those commands.
2900 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:482901 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:182902}
2903
[email protected]8e3e0662010-08-23 18:46:302904static void RebindCurrentFramebuffer(
2905 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062906 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242907 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062908 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462909
[email protected]a3783712012-01-20 22:18:242910 if (framebuffer_id == 0) {
2911 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302912 }
[email protected]297ca1c2011-06-20 23:08:462913
[email protected]8e3e0662010-08-23 18:46:302914 glBindFramebufferEXT(target, framebuffer_id);
2915}
2916
2917void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:442918 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462919
[email protected]62e155e2012-10-23 22:43:152920 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302921 RebindCurrentFramebuffer(
2922 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:342923 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242924 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302925 } else {
2926 RebindCurrentFramebuffer(
2927 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:342928 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242929 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302930 RebindCurrentFramebuffer(
2931 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:342932 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242933 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302934 }
[email protected]70d34263c2013-01-09 00:27:452935 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302936}
2937
[email protected]0d6bfdc2011-11-02 01:32:202938bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352939 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202940 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102941 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582942 if (backbuffer_needs_clear_bits_) {
2943 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2944 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2945 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2946 glClearStencil(0);
2947 glStencilMask(-1);
2948 glClearDepth(1.0f);
2949 glDepthMask(true);
2950 glDisable(GL_SCISSOR_TEST);
2951 glClear(backbuffer_needs_clear_bits_);
2952 backbuffer_needs_clear_bits_ = 0;
2953 RestoreClearState();
2954 }
[email protected]0d6bfdc2011-11-02 01:32:202955 return true;
2956 }
2957
[email protected]968351b2011-12-20 08:26:512958 if (framebuffer_manager()->IsComplete(framebuffer)) {
2959 return true;
2960 }
2961
[email protected]0d6bfdc2011-11-02 01:32:202962 GLenum completeness = framebuffer->IsPossiblyComplete();
2963 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512964 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432965 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272966 return false;
2967 }
[email protected]0d6bfdc2011-11-02 01:32:202968
2969 // Are all the attachments cleared?
2970 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2971 texture_manager()->HaveUnclearedMips()) {
2972 if (!framebuffer->IsCleared()) {
2973 // Can we clear them?
[email protected]73276522012-11-09 05:50:202974 if (framebuffer->GetStatus(texture_manager(), target) !=
2975 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512976 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432977 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2978 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202979 return false;
2980 }
2981 ClearUnclearedAttachments(target, framebuffer);
2982 }
2983 }
2984
[email protected]968351b2011-12-20 08:26:512985 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202986 if (framebuffer->GetStatus(texture_manager(), target) !=
2987 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512988 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432989 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2990 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512991 return false;
2992 }
2993 framebuffer_manager()->MarkAsComplete(framebuffer);
2994 }
2995
[email protected]0d6bfdc2011-11-02 01:32:202996 // NOTE: At this point we don't know if the framebuffer is complete but
2997 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272998 return true;
2999}
3000
[email protected]0d6bfdc2011-11-02 01:32:203001bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153002 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513003 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343004 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3005 func_name);
[email protected]28718a92013-04-04 12:12:513006
3007 if (valid)
3008 OnUseFramebuffer();
3009
3010 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203011 }
[email protected]9d3b2e12013-10-02 01:04:343012 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113013 GL_DRAW_FRAMEBUFFER_EXT,
3014 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343015 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113016 GL_READ_FRAMEBUFFER_EXT,
3017 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203018}
3019
[email protected]8e3e0662010-08-23 18:46:303020gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353021 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453022 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203023 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353024 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203025 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263026 if (attachment) {
3027 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503028 }
[email protected]9edc6b22010-12-23 02:00:263029 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023030 } else if (offscreen_target_frame_buffer_.get()) {
3031 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353032 } else {
[email protected]f62a5ab2011-05-23 20:34:153033 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023034 }
[email protected]246a70452010-03-05 21:53:503035}
3036
[email protected]68586372013-12-11 01:27:593037GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3038 Framebuffer* framebuffer =
3039 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3040 if (framebuffer != NULL) {
3041 return framebuffer->GetColorAttachmentTextureType();
3042 } else {
3043 return GL_UNSIGNED_BYTE;
3044 }
3045}
3046
[email protected]9edc6b22010-12-23 02:00:263047GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353048 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453049 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203050 if (framebuffer != NULL) {
3051 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463052 } else if (offscreen_target_frame_buffer_.get()) {
3053 return offscreen_target_color_format_;
3054 } else {
3055 return back_buffer_color_format_;
3056 }
3057}
3058
3059GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353060 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453061 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203062 if (framebuffer != NULL) {
3063 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263064 } else if (offscreen_target_frame_buffer_.get()) {
3065 return offscreen_target_color_format_;
3066 } else {
[email protected]32fe9aa2011-01-21 23:47:133067 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263068 }
3069}
3070
[email protected]9a5afa432011-07-22 18:16:393071void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513072 if (!offscreen_saved_color_texture_info_.get())
3073 return;
3074 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3075 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3076 texture_manager()->SetLevelInfo(
3077 offscreen_saved_color_texture_info_.get(),
3078 GL_TEXTURE_2D,
3079 0, // level
3080 GL_RGBA,
3081 offscreen_size_.width(),
3082 offscreen_size_.height(),
3083 1, // depth
3084 0, // border
3085 GL_RGBA,
3086 GL_UNSIGNED_BYTE,
3087 true);
3088 texture_manager()->SetParameter(
3089 "UpdateParentTextureInfo",
3090 GetErrorState(),
3091 offscreen_saved_color_texture_info_.get(),
3092 GL_TEXTURE_MAG_FILTER,
3093 GL_NEAREST);
3094 texture_manager()->SetParameter(
3095 "UpdateParentTextureInfo",
3096 GetErrorState(),
3097 offscreen_saved_color_texture_info_.get(),
3098 GL_TEXTURE_MIN_FILTER,
3099 GL_NEAREST);
3100 texture_manager()->SetParameter(
3101 "UpdateParentTextureInfo",
3102 GetErrorState(),
3103 offscreen_saved_color_texture_info_.get(),
3104 GL_TEXTURE_WRAP_S,
3105 GL_CLAMP_TO_EDGE);
3106 texture_manager()->SetParameter(
3107 "UpdateParentTextureInfo",
3108 GetErrorState(),
3109 offscreen_saved_color_texture_info_.get(),
3110 GL_TEXTURE_WRAP_T,
3111 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443112 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3113 &state_, target);
[email protected]2ad674132013-06-05 07:48:513114 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353115}
3116
[email protected]799b4b22011-08-22 17:09:593117void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073118 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523119 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003120}
3121
[email protected]1d82e822013-04-10 21:32:323122Logger* GLES2DecoderImpl::GetLogger() {
3123 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523124}
3125
[email protected]cac16542014-01-15 17:53:513126void GLES2DecoderImpl::BeginDecoding() {
3127 gpu_tracer_->BeginDecoding();
3128 gpu_trace_commands_ = gpu_tracer_->IsTracing();
3129}
3130
3131void GLES2DecoderImpl::EndDecoding() {
3132 gpu_tracer_->EndDecoding();
3133}
3134
[email protected]d3eba342013-04-18 21:11:503135ErrorState* GLES2DecoderImpl::GetErrorState() {
3136 return state_.GetErrorState();
3137}
3138
[email protected]e3932abb2013-03-13 00:01:373139void GLES2DecoderImpl::SetShaderCacheCallback(
3140 const ShaderCacheCallback& callback) {
3141 shader_cache_callback_ = callback;
3142}
3143
[email protected]840a7e462013-02-27 01:29:513144void GLES2DecoderImpl::SetWaitSyncPointCallback(
3145 const WaitSyncPointCallback& callback) {
3146 wait_sync_point_callback_ = callback;
3147}
3148
[email protected]85a4ac22013-05-31 01:58:473149AsyncPixelTransferManager*
3150 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3151 return async_pixel_transfer_manager_.get();
3152}
3153
3154void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3155 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593156}
3157
[email protected]498b5c072013-06-04 19:30:073158void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3159 AsyncPixelTransferManager* manager) {
3160 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3161}
3162
[email protected]1318e922010-09-17 22:03:163163bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3164 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493165 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3166 if (texture_ref) {
3167 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163168 return true;
3169 }
3170 return false;
3171}
3172
[email protected]63b465922012-09-06 02:04:523173uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443174 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483175 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523176}
3177
3178base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443179 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483180 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523181}
3182
3183base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3184 return total_processing_commands_time_;
3185}
3186
[email protected]dc25dda2012-09-27 21:36:303187void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3188 total_processing_commands_time_ += time;
3189}
3190
[email protected]63c9b052012-05-17 18:27:383191void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063192 if (!initialized())
3193 return;
3194
[email protected]63c9b052012-05-17 18:27:383195 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053196
[email protected]80eb6b52012-01-19 00:14:413197 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243198 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463199 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023200 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243201 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133202 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343203 framebuffer_state_.bound_read_framebuffer = NULL;
3204 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243205 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413206
[email protected]cadac622013-06-11 16:46:363207 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513208 DCHECK(offscreen_target_color_texture_);
3209 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3210 offscreen_saved_color_texture_->id());
3211 offscreen_saved_color_texture_->Invalidate();
3212 offscreen_saved_color_texture_info_ = NULL;
3213 }
[email protected]eadc96792010-10-27 19:39:393214 if (have_context) {
[email protected]c322e882012-05-23 18:06:183215 if (copy_texture_CHROMIUM_.get()) {
3216 copy_texture_CHROMIUM_->Destroy();
3217 copy_texture_CHROMIUM_.reset();
3218 }
[email protected]43410e92012-04-20 17:06:283219
[email protected]7cd76fd2013-06-02 21:11:113220 if (state_.current_program.get()) {
3221 program_manager()->UnuseProgram(shader_manager(),
3222 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143223 }
3224
[email protected]b1122982010-05-17 23:04:243225 if (attrib_0_buffer_id_) {
3226 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3227 }
[email protected]8fbedc02010-11-18 18:43:403228 if (fixed_attrib_buffer_id_) {
3229 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3230 }
[email protected]b1122982010-05-17 23:04:243231
[email protected]4a4c18b2013-09-13 22:50:103232 if (validation_texture_) {
3233 glDeleteTextures(1, &validation_texture_);
3234 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3235 glDeleteFramebuffersEXT(1, &validation_fbo_);
3236 }
3237
[email protected]97872062010-11-03 19:07:053238 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543239 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053240 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543241 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053242 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023243 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053244 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153245 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053246 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153247 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053248 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023249 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053250 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543251 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273252 if (offscreen_resolved_frame_buffer_.get())
3253 offscreen_resolved_frame_buffer_->Destroy();
3254 if (offscreen_resolved_color_texture_.get())
3255 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053256 } else {
3257 if (offscreen_target_frame_buffer_.get())
3258 offscreen_target_frame_buffer_->Invalidate();
3259 if (offscreen_target_color_texture_.get())
3260 offscreen_target_color_texture_->Invalidate();
3261 if (offscreen_target_color_render_buffer_.get())
3262 offscreen_target_color_render_buffer_->Invalidate();
3263 if (offscreen_target_depth_render_buffer_.get())
3264 offscreen_target_depth_render_buffer_->Invalidate();
3265 if (offscreen_target_stencil_render_buffer_.get())
3266 offscreen_target_stencil_render_buffer_->Invalidate();
3267 if (offscreen_saved_frame_buffer_.get())
3268 offscreen_saved_frame_buffer_->Invalidate();
3269 if (offscreen_saved_color_texture_.get())
3270 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273271 if (offscreen_resolved_frame_buffer_.get())
3272 offscreen_resolved_frame_buffer_->Invalidate();
3273 if (offscreen_resolved_color_texture_.get())
3274 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023275 }
[email protected]83a52d032013-07-24 10:30:373276
3277 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3278 // Otherwise, we can leak objects. http://crbug.com/258772.
3279 // state_.current_program must be reset before group_ is reset because
3280 // the later deletes the ProgramManager object that referred by
3281 // state_.current_program object.
3282 state_.current_program = NULL;
3283
[email protected]43410e92012-04-20 17:06:283284 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053285
[email protected]882ba1e22012-03-08 19:02:533286 if (query_manager_.get()) {
3287 query_manager_->Destroy(have_context);
3288 query_manager_.reset();
3289 }
3290
[email protected]944b62f32012-09-27 02:20:463291 if (vertex_array_manager_ .get()) {
3292 vertex_array_manager_->Destroy(have_context);
3293 vertex_array_manager_.reset();
3294 }
3295
[email protected]97872062010-11-03 19:07:053296 offscreen_target_frame_buffer_.reset();
3297 offscreen_target_color_texture_.reset();
3298 offscreen_target_color_render_buffer_.reset();
3299 offscreen_target_depth_render_buffer_.reset();
3300 offscreen_target_stencil_render_buffer_.reset();
3301 offscreen_saved_frame_buffer_.reset();
3302 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273303 offscreen_resolved_frame_buffer_.reset();
3304 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463305
[email protected]85a4ac22013-05-31 01:58:473306 // Should destroy the transfer manager before the texture manager held
3307 // by the context group.
3308 async_pixel_transfer_manager_.reset();
3309
[email protected]7cd76fd2013-06-02 21:11:113310 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393311 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233312 group_->Destroy(this, have_context);
3313 group_ = NULL;
3314 }
3315
3316 if (context_.get()) {
3317 context_->ReleaseCurrent(NULL);
3318 context_ = NULL;
3319 }
3320
[email protected]e51bdf32011-11-23 22:21:463321#if defined(OS_MACOSX)
3322 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3323 it != texture_to_io_surface_map_.end(); ++it) {
3324 CFRelease(it->second);
3325 }
3326 texture_to_io_surface_map_.clear();
3327#endif
[email protected]96449d2c2009-11-25 00:01:323328}
3329
[email protected]63c9b052012-05-17 18:27:383330void GLES2DecoderImpl::SetSurface(
3331 const scoped_refptr<gfx::GLSurface>& surface) {
3332 DCHECK(context_->IsCurrent(NULL));
3333 DCHECK(surface_.get());
3334 surface_ = surface;
3335 RestoreCurrentFramebufferBindings();
3336}
3337
[email protected]2ad674132013-06-05 07:48:513338bool GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
[email protected]9a5afa432011-07-22 18:16:393339 if (!offscreen_saved_color_texture_.get())
3340 return false;
[email protected]2ad674132013-06-05 07:48:513341 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243342 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073343 offscreen_saved_color_texture_info_ = TextureRef::Create(
3344 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513345 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3346 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393347 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243348 }
[email protected]2ad674132013-06-05 07:48:513349 gpu::gles2::MailboxName name;
3350 memcpy(name.key, mailbox.name, sizeof(mailbox.name));
3351 return mailbox_manager()->ProduceTexture(
3352 GL_TEXTURE_2D, name, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243353}
3354
[email protected]799b4b22011-08-22 17:09:593355bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3356 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3357 if (!is_offscreen) {
3358 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3359 << " with an onscreen framebuffer.";
3360 return false;
3361 }
3362
3363 if (offscreen_size_ == size)
3364 return true;
3365
3366 offscreen_size_ = size;
3367 int w = offscreen_size_.width();
3368 int h = offscreen_size_.height();
3369 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3370 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3371 << "to allocate storage due to excessive dimensions.";
3372 return false;
3373 }
3374
3375 // Reallocate the offscreen target buffers.
3376 DCHECK(offscreen_target_color_format_);
3377 if (IsOffscreenBufferMultisampled()) {
3378 if (!offscreen_target_color_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183379 feature_info_, offscreen_size_, offscreen_target_color_format_,
[email protected]799b4b22011-08-22 17:09:593380 offscreen_target_samples_)) {
3381 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3382 << "to allocate storage for offscreen target color buffer.";
3383 return false;
3384 }
3385 } else {
3386 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093387 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593388 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3389 << "to allocate storage for offscreen target color texture.";
3390 return false;
3391 }
3392 }
3393 if (offscreen_target_depth_format_ &&
3394 !offscreen_target_depth_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183395 feature_info_, offscreen_size_, offscreen_target_depth_format_,
[email protected]799b4b22011-08-22 17:09:593396 offscreen_target_samples_)) {
3397 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3398 << "to allocate storage for offscreen target depth buffer.";
3399 return false;
3400 }
3401 if (offscreen_target_stencil_format_ &&
3402 !offscreen_target_stencil_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183403 feature_info_, offscreen_size_, offscreen_target_stencil_format_,
[email protected]799b4b22011-08-22 17:09:593404 offscreen_target_samples_)) {
3405 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3406 << "to allocate storage for offscreen target stencil buffer.";
3407 return false;
3408 }
3409
3410 // Attach the offscreen target buffers to the target frame buffer.
3411 if (IsOffscreenBufferMultisampled()) {
3412 offscreen_target_frame_buffer_->AttachRenderBuffer(
3413 GL_COLOR_ATTACHMENT0,
3414 offscreen_target_color_render_buffer_.get());
3415 } else {
3416 offscreen_target_frame_buffer_->AttachRenderTexture(
3417 offscreen_target_color_texture_.get());
3418 }
3419 if (offscreen_target_depth_format_) {
3420 offscreen_target_frame_buffer_->AttachRenderBuffer(
3421 GL_DEPTH_ATTACHMENT,
3422 offscreen_target_depth_render_buffer_.get());
3423 }
3424 const bool packed_depth_stencil =
3425 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3426 if (packed_depth_stencil) {
3427 offscreen_target_frame_buffer_->AttachRenderBuffer(
3428 GL_STENCIL_ATTACHMENT,
3429 offscreen_target_depth_render_buffer_.get());
3430 } else if (offscreen_target_stencil_format_) {
3431 offscreen_target_frame_buffer_->AttachRenderBuffer(
3432 GL_STENCIL_ATTACHMENT,
3433 offscreen_target_stencil_render_buffer_.get());
3434 }
3435
3436 if (offscreen_target_frame_buffer_->CheckStatus() !=
3437 GL_FRAMEBUFFER_COMPLETE) {
3438 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3439 << "because offscreen FBO was incomplete.";
3440 return false;
3441 }
3442
3443 // Clear the target frame buffer.
3444 {
3445 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3446 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3447 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3448 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3449 glClearStencil(0);
3450 glStencilMaskSeparate(GL_FRONT, -1);
3451 glStencilMaskSeparate(GL_BACK, -1);
3452 glClearDepth(0);
3453 glDepthMask(GL_TRUE);
3454 glDisable(GL_SCISSOR_TEST);
3455 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3456 RestoreClearState();
3457 }
[email protected]d85ef76d2011-09-08 22:21:433458
3459 // Destroy the offscreen resolved framebuffers.
3460 if (offscreen_resolved_frame_buffer_.get())
3461 offscreen_resolved_frame_buffer_->Destroy();
3462 if (offscreen_resolved_color_texture_.get())
3463 offscreen_resolved_color_texture_->Destroy();
3464 offscreen_resolved_color_texture_.reset();
3465 offscreen_resolved_frame_buffer_.reset();
3466
[email protected]799b4b22011-08-22 17:09:593467 return true;
[email protected]6217d392010-03-25 22:08:353468}
3469
[email protected]799b4b22011-08-22 17:09:593470error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353471 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443472 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023473 return error::kDeferCommandUntilLater;
3474
[email protected]799b4b22011-08-22 17:09:593475 GLuint width = static_cast<GLuint>(c.width);
3476 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073477 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593478 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413479
3480 width = std::max(1U, width);
3481 height = std::max(1U, height);
3482
[email protected]a0d989162011-11-22 13:15:073483#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3484 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003485 // Make sure that we are done drawing to the back buffer before resizing.
3486 glFinish();
3487#endif
[email protected]799b4b22011-08-22 17:09:593488 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3489 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493490 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3491 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3492 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593493 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493494 }
[email protected]7ff86b92010-11-25 17:50:003495 }
[email protected]799b4b22011-08-22 17:09:593496
[email protected]9d37f062011-11-22 01:24:523497 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073498 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443499 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493500 if (!context_->IsCurrent(surface_.get())) {
3501 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3502 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053503 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493504 }
[email protected]658f7562011-09-09 05:24:053505 }
[email protected]799b4b22011-08-22 17:09:593506
3507 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393508}
3509
[email protected]96449d2c2009-11-25 00:01:323510const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3511 if (command_id > kStartPoint && command_id < kNumCommands) {
3512 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3513 }
3514 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3515}
3516
3517// Decode command with its arguments, and call the corresponding GL function.
3518// Note: args is a pointer to the command buffer. As such, it could be changed
3519// by a (malicious) client at any time, so if validation has to happen, it
3520// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143521error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323522 unsigned int command,
3523 unsigned int arg_count,
3524 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143525 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263526 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003527 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
[email protected]65f7efe2013-11-28 03:11:473528 // VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323529 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013530 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193531 }
[email protected]96449d2c2009-11-25 00:01:323532 unsigned int command_index = command - kStartPoint - 1;
3533 if (command_index < arraysize(g_command_info)) {
3534 const CommandInfo& info = g_command_info[command_index];
3535 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3536 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3537 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]cac16542014-01-15 17:53:513538 bool doing_gpu_trace = false;
3539 if (gpu_trace_commands_) {
3540 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3541 doing_gpu_trace = true;
3542 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3543 }
3544 }
3545
[email protected]b9849abf2009-11-25 19:13:193546 uint32 immediate_data_size =
3547 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323548 switch (command) {
3549 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353550 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193551 result = Handle ## name( \
3552 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353553 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193554 break; \
[email protected]96449d2c2009-11-25 00:01:323555
3556 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323557 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383558 }
[email protected]cac16542014-01-15 17:53:513559
3560 if (doing_gpu_trace)
3561 gpu_tracer_->End(kTraceDecoder);
3562
[email protected]bf0985e2009-12-17 03:04:383563 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303564 GLenum error;
3565 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323566 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003567 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3568 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513569 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193570 }
[email protected]96449d2c2009-11-25 00:01:323571 }
3572 } else {
[email protected]f7a64ee2010-02-01 22:24:143573 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323574 }
[email protected]b9849abf2009-11-25 19:13:193575 } else {
3576 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323577 }
[email protected]a3a93e7b2010-08-28 00:48:563578 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3579 result = current_decoder_error_;
3580 current_decoder_error_ = error::kNoError;
3581 }
[email protected]b9849abf2009-11-25 19:13:193582 return result;
[email protected]96449d2c2009-11-25 00:01:323583}
3584
[email protected]ed9f9cd2013-02-27 21:12:353585void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3586 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503587}
3588
[email protected]ae51d192010-04-27 00:48:033589bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353590 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033591 return false;
3592 }
[email protected]96449d2c2009-11-25 00:01:323593 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033594 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353595 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323596 }
[email protected]ae51d192010-04-27 00:48:033597 return true;
[email protected]96449d2c2009-11-25 00:01:323598}
3599
[email protected]ae51d192010-04-27 00:48:033600bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353601 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033602 return false;
[email protected]96449d2c2009-11-25 00:01:323603 }
[email protected]ae51d192010-04-27 00:48:033604 GLuint service_id = glCreateShader(type);
3605 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353606 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033607 }
3608 return true;
[email protected]96449d2c2009-11-25 00:01:323609}
3610
[email protected]882ba1e22012-03-08 19:02:533611void GLES2DecoderImpl::DoFinish() {
3612 glFinish();
[email protected]5a36dc132013-07-23 23:17:553613 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193614 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533615}
3616
3617void GLES2DecoderImpl::DoFlush() {
3618 glFlush();
[email protected]22e3f552012-03-13 01:54:193619 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533620}
3621
[email protected]3916c97e2010-02-25 03:20:503622void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453623 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023624 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513625 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533626 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503627 return;
3628 }
[email protected]e259eb412012-10-13 05:47:243629 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453630 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503631}
3632
[email protected]051b1372010-04-12 02:42:083633void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073634 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083635 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033636 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073637 buffer = GetBuffer(client_id);
3638 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353639 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153640 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3641 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353642 return;
3643 }
3644
[email protected]b10492f2013-03-08 05:24:073645 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033646 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353647 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073648 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573649 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103650 group_->GetIdAllocator(id_namespaces::kBuffers);
3651 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033652 }
[email protected]051b1372010-04-12 02:42:083653 }
[email protected]b10492f2013-03-08 05:24:073654 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3655 if (buffer) {
3656 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513657 LOCAL_SET_GL_ERROR(
3658 GL_INVALID_OPERATION,
3659 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473660 return;
3661 }
[email protected]b10492f2013-03-08 05:24:073662 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473663 }
[email protected]96449d2c2009-11-25 00:01:323664 switch (target) {
3665 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073666 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323667 break;
3668 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073669 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323670 break;
3671 default:
[email protected]a93bb842010-02-16 23:03:473672 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323673 break;
3674 }
[email protected]051b1372010-04-12 02:42:083675 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323676}
3677
[email protected]f3b191b2013-06-19 03:43:543678bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3679 bool all_draw_buffers) {
3680 Framebuffer* framebuffer =
3681 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3682 if (!all_draw_buffers || !framebuffer) {
3683 return (GLES2Util::GetChannelsForFormat(
3684 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3685 }
3686 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463687}
3688
3689bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353690 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453691 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203692 if (framebuffer) {
3693 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463694 }
3695 if (offscreen_target_frame_buffer_.get()) {
3696 return offscreen_target_depth_format_ != 0;
3697 }
3698 return back_buffer_has_depth_;
3699}
3700
3701bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353702 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453703 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203704 if (framebuffer) {
3705 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463706 }
3707 if (offscreen_target_frame_buffer_.get()) {
3708 return offscreen_target_stencil_format_ != 0 ||
3709 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3710 }
3711 return back_buffer_has_stencil_;
3712}
3713
3714void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:443715 if (framebuffer_state_.clear_state_dirty) {
[email protected]297ca1c2011-06-20 23:08:463716 glColorMask(
[email protected]e259eb412012-10-13 05:47:243717 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3718 state_.color_mask_alpha &&
[email protected]f3b191b2013-06-19 03:43:543719 BoundFramebufferHasColorAttachmentWithAlpha(true));
[email protected]297ca1c2011-06-20 23:08:463720 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243721 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223722 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463723 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243724 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423725 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243726 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423727 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223728 EnableDisable(
3729 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3730 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3731 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3732 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]c986af502013-08-14 01:04:443733 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:463734 }
3735}
3736
[email protected]1868a342012-11-07 15:56:023737GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:113738 return (offscreen_target_frame_buffer_.get())
3739 ? offscreen_target_frame_buffer_->id()
3740 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:023741}
3742
[email protected]5baa86bc2014-01-16 04:33:163743void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) const {
[email protected]962bfbe72013-05-24 11:16:143744 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3745 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:063746 // Restore the Framebuffer first because of bugs in Intel drivers.
3747 // Intel drivers incorrectly clip the viewport settings to
3748 // the size of the current framebuffer object.
3749 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:163750 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:063751}
3752
3753void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:343754 GLuint service_id =
3755 framebuffer_state_.bound_draw_framebuffer.get()
3756 ? framebuffer_state_.bound_draw_framebuffer->service_id()
3757 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063758 if (!features().chromium_framebuffer_multisample) {
3759 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3760 } else {
3761 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:343762 service_id = framebuffer_state_.bound_read_framebuffer.get()
3763 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:113764 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063765 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3766 }
[email protected]70d34263c2013-01-09 00:27:453767 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063768}
3769
3770void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:103771 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3772 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:253773 GLenum target = texture->target();
3774 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063775 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253776 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063777 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253778 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063779 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253780 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063781 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253782 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063783 RestoreTextureUnitBindings(state_.active_texture_unit);
3784 }
[email protected]70d34263c2013-01-09 00:27:453785}
3786
3787void GLES2DecoderImpl::OnFboChanged() const {
3788 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513789 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3790}
3791
3792// Called after the FBO is checked for completeness.
3793void GLES2DecoderImpl::OnUseFramebuffer() const {
3794 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3795 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323796 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513797 glScissor(state_.scissor_x,
3798 state_.scissor_y,
3799 state_.scissor_width,
3800 state_.scissor_height);
3801
3802 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3803 // it's unclear how this bug works.
3804 glFlush();
3805 }
[email protected]b177ae22011-11-01 03:29:113806}
3807
[email protected]051b1372010-04-12 02:42:083808void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063809 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083810 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033811 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063812 framebuffer = GetFramebuffer(client_id);
3813 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353814 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153815 LOG(ERROR)
3816 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3817 current_decoder_error_ = error::kGenericError;
3818 return;
[email protected]bf5a8d132011-08-16 08:39:353819 }
3820
[email protected]4d8f0dd2013-03-09 14:37:063821 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033822 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353823 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063824 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573825 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103826 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3827 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033828 } else {
[email protected]4d8f0dd2013-03-09 14:37:063829 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083830 }
[email protected]4d8f0dd2013-03-09 14:37:063831 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083832 }
[email protected]4d8f0dd2013-03-09 14:37:063833 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303834
3835 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:343836 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303837 }
[email protected]cac16542014-01-15 17:53:513838
3839 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:303840 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:343841 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303842 }
[email protected]6217d392010-03-25 22:08:353843
[email protected]c986af502013-08-14 01:04:443844 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463845
[email protected]b177ae22011-11-01 03:29:113846 // If we are rendering to the backbuffer get the FBO id for any simulated
3847 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063848 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113849 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463850 }
[email protected]6217d392010-03-25 22:08:353851
[email protected]051b1372010-04-12 02:42:083852 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453853 OnFboChanged();
[email protected]86093972010-03-11 00:13:563854}
3855
[email protected]051b1372010-04-12 02:42:083856void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273857 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083858 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033859 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273860 renderbuffer = GetRenderbuffer(client_id);
3861 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353862 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153863 LOG(ERROR)
3864 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3865 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353866 return;
3867 }
3868
[email protected]ee2a79c32013-03-10 03:50:273869 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033870 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353871 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273872 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573873 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103874 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3875 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033876 } else {
[email protected]ee2a79c32013-03-10 03:50:273877 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083878 }
[email protected]ee2a79c32013-03-10 03:50:273879 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083880 }
[email protected]ee2a79c32013-03-10 03:50:273881 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer");
3882 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083883 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563884}
3885
[email protected]051b1372010-04-12 02:42:083886void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:493887 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:083888 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033889 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:493890 texture_ref = GetTexture(client_id);
3891 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:353892 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153893 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3894 current_decoder_error_ = error::kGenericError;
3895 return;
[email protected]bf5a8d132011-08-16 08:39:353896 }
3897
[email protected]02965c22013-03-09 02:40:073898 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033899 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413900 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353901 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:493902 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:573903 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103904 group_->GetIdAllocator(id_namespaces::kTextures);
3905 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033906 }
3907 } else {
[email protected]370eaf12013-05-18 09:19:493908 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083909 }
[email protected]370eaf12013-05-18 09:19:493910 Texture* texture = texture_ref->texture();
[email protected]ae51d192010-04-27 00:48:033911
[email protected]1958e0e2010-04-22 05:17:153912 // Check the texture exists
3913 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073914 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513915 LOCAL_SET_GL_ERROR(
3916 GL_INVALID_OPERATION,
3917 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153918 return;
3919 }
[email protected]02965c22013-03-09 02:40:073920 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3921 if (texture->target() == 0) {
[email protected]370eaf12013-05-18 09:19:493922 texture_manager()->SetTarget(texture_ref, target);
[email protected]a93bb842010-02-16 23:03:473923 }
[email protected]02965c22013-03-09 02:40:073924 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593925
[email protected]e259eb412012-10-13 05:47:243926 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503927 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473928 switch (target) {
3929 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:493930 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:473931 break;
3932 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:493933 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:473934 break;
[email protected]61eeb33f2011-07-26 15:30:313935 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:493936 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:313937 break;
[email protected]e51bdf32011-11-23 22:21:463938 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:493939 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:463940 break;
[email protected]a93bb842010-02-16 23:03:473941 default:
3942 NOTREACHED(); // Validation should prevent us getting here.
3943 break;
3944 }
3945}
3946
[email protected]07f54fcc2009-12-22 02:46:303947void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243948 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123949 if (index != 0 ||
3950 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243951 glDisableVertexAttribArray(index);
3952 }
[email protected]07f54fcc2009-12-22 02:46:303953 } else {
[email protected]ab09b612013-03-11 22:11:513954 LOCAL_SET_GL_ERROR(
3955 GL_INVALID_VALUE,
3956 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303957 }
3958}
3959
[email protected]60f22d32012-12-12 00:31:583960void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3961 GLsizei numAttachments,
3962 const GLenum* attachments) {
[email protected]680aa412013-10-31 18:08:013963 if (!features().ext_discard_framebuffer) {
3964 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3965 "glDiscardFramebufferEXT",
3966 "function not available");
3967 return;
3968 }
3969
[email protected]ed9f9cd2013-02-27 21:12:353970 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:583971 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3972
3973 // Validates the attachments. If one of them fails
3974 // the whole command fails.
3975 for (GLsizei i = 0; i < numAttachments; ++i) {
3976 if ((framebuffer &&
3977 !validators_->attachment.IsValid(attachments[i])) ||
3978 (!framebuffer &&
3979 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:513980 LOCAL_SET_GL_ERROR_INVALID_ENUM(
3981 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:583982 return;
3983 }
3984 }
3985
3986 // Marks each one of them as not cleared
3987 for (GLsizei i = 0; i < numAttachments; ++i) {
3988 if (framebuffer) {
3989 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3990 texture_manager(),
3991 attachments[i],
3992 false);
3993 } else {
3994 switch (attachments[i]) {
3995 case GL_COLOR_EXT:
3996 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3997 break;
3998 case GL_DEPTH_EXT:
3999 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4000 case GL_STENCIL_EXT:
4001 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4002 break;
4003 default:
4004 NOTREACHED();
4005 break;
4006 }
4007 }
4008 }
4009
[email protected]d49c5402013-09-11 15:39:024010 // If the default framebuffer is bound but we are still rendering to an
4011 // FBO, translate attachment names that refer to default framebuffer
4012 // channels to corresponding framebuffer attachments.
4013 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4014 for (GLsizei i = 0; i < numAttachments; ++i) {
4015 GLenum attachment = attachments[i];
4016 if (!framebuffer && GetBackbufferServiceId()) {
4017 switch (attachment) {
4018 case GL_COLOR_EXT:
4019 attachment = GL_COLOR_ATTACHMENT0;
4020 break;
4021 case GL_DEPTH_EXT:
4022 attachment = GL_DEPTH_ATTACHMENT;
4023 break;
4024 case GL_STENCIL_EXT:
4025 attachment = GL_STENCIL_ATTACHMENT;
4026 break;
4027 default:
4028 NOTREACHED();
4029 return;
4030 }
4031 }
4032 translated_attachments[i] = attachment;
4033 }
4034
4035 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584036}
4037
[email protected]07f54fcc2009-12-22 02:46:304038void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244039 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304040 glEnableVertexAttribArray(index);
4041 } else {
[email protected]ab09b612013-03-11 22:11:514042 LOCAL_SET_GL_ERROR(
4043 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304044 }
4045}
4046
[email protected]a93bb842010-02-16 23:03:474047void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444048 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4049 &state_, target);
[email protected]370eaf12013-05-18 09:19:494050 if (!texture_ref ||
4051 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514052 LOCAL_SET_GL_ERROR(
4053 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474054 return;
4055 }
[email protected]38c0a972012-05-12 00:48:024056
[email protected]12d95352012-12-14 07:23:544057 if (target == GL_TEXTURE_CUBE_MAP) {
4058 for (int i = 0; i < 6; ++i) {
4059 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494060 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514061 LOCAL_SET_GL_ERROR(
4062 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544063 return;
4064 }
4065 }
4066 } else {
[email protected]370eaf12013-05-18 09:19:494067 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514068 LOCAL_SET_GL_ERROR(
4069 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544070 return;
4071 }
[email protected]7687479c2012-05-14 23:54:044072 }
4073
[email protected]ab09b612013-03-11 22:11:514074 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194075 // Workaround for Mac driver bug. In the large scheme of things setting
4076 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564077 // hit so there's probably no need to make this conditional. The bug appears
4078 // to be that if the filtering mode is set to something that doesn't require
4079 // mipmaps for rendering, or is never set to something other than the default,
4080 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154081 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194082 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4083 }
[email protected]a93bb842010-02-16 23:03:474084 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154085 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494086 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4087 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194088 }
[email protected]ab09b612013-03-11 22:11:514089 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024090 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494091 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024092 }
[email protected]a93bb842010-02-16 23:03:474093}
4094
[email protected]b273e432010-04-12 17:23:584095bool GLES2DecoderImpl::GetHelper(
4096 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584097 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154098 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4099 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434100 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4101 *num_written = 1;
4102 if (params) {
[email protected]68586372013-12-11 01:27:594103 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4104 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434105 }
4106 return true;
4107 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4108 *num_written = 1;
4109 if (params) {
[email protected]68586372013-12-11 01:27:594110 *params = GLES2Util::GetPreferredGLReadPixelsType(
4111 GetBoundReadFrameBufferInternalFormat(),
4112 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434113 }
4114 return true;
4115 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4116 *num_written = 1;
4117 if (params) {
4118 *params = group_->max_fragment_uniform_vectors();
4119 }
4120 return true;
4121 case GL_MAX_VARYING_VECTORS:
4122 *num_written = 1;
4123 if (params) {
4124 *params = group_->max_varying_vectors();
4125 }
4126 return true;
4127 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4128 *num_written = 1;
4129 if (params) {
4130 *params = group_->max_vertex_uniform_vectors();
4131 }
4132 return true;
[email protected]4e8a5b122010-05-08 22:00:104133 }
[email protected]5cb735d2011-10-13 01:37:234134 }
4135 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244136 case GL_MAX_VIEWPORT_DIMS:
4137 if (offscreen_target_frame_buffer_.get()) {
4138 *num_written = 2;
4139 if (params) {
4140 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4141 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4142 }
4143 return true;
4144 }
[email protected]5cb735d2011-10-13 01:37:234145 return false;
[email protected]84afefa2011-10-19 21:45:534146 case GL_MAX_SAMPLES:
4147 *num_written = 1;
4148 if (params) {
4149 params[0] = renderbuffer_manager()->max_samples();
4150 }
4151 return true;
4152 case GL_MAX_RENDERBUFFER_SIZE:
4153 *num_written = 1;
4154 if (params) {
4155 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4156 }
4157 return true;
[email protected]5cb735d2011-10-13 01:37:234158 case GL_MAX_TEXTURE_SIZE:
4159 *num_written = 1;
4160 if (params) {
4161 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4162 }
4163 return true;
4164 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4165 *num_written = 1;
4166 if (params) {
4167 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4168 }
4169 return true;
[email protected]2f143d482013-03-14 18:04:494170 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4171 *num_written = 1;
4172 if (params) {
4173 params[0] = group_->max_color_attachments();
4174 }
4175 return true;
4176 case GL_MAX_DRAW_BUFFERS_ARB:
4177 *num_written = 1;
4178 if (params) {
4179 params[0] = group_->max_draw_buffers();
4180 }
4181 return true;
[email protected]297ca1c2011-06-20 23:08:464182 case GL_ALPHA_BITS:
4183 *num_written = 1;
4184 if (params) {
4185 GLint v = 0;
4186 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544187 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464188 }
4189 return true;
4190 case GL_DEPTH_BITS:
4191 *num_written = 1;
4192 if (params) {
4193 GLint v = 0;
4194 glGetIntegerv(GL_DEPTH_BITS, &v);
4195 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4196 }
4197 return true;
4198 case GL_STENCIL_BITS:
4199 *num_written = 1;
4200 if (params) {
4201 GLint v = 0;
4202 glGetIntegerv(GL_STENCIL_BITS, &v);
4203 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4204 }
4205 return true;
[email protected]656dcaad2010-05-07 17:18:374206 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114207 *num_written = validators_->compressed_texture_format.GetValues().size();
4208 if (params) {
4209 for (GLint ii = 0; ii < *num_written; ++ii) {
4210 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4211 }
4212 }
[email protected]656dcaad2010-05-07 17:18:374213 return true;
[email protected]b273e432010-04-12 17:23:584214 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4215 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104216 if (params) {
[email protected]302ce6d2011-07-07 23:28:114217 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104218 }
[email protected]b273e432010-04-12 17:23:584219 return true;
4220 case GL_NUM_SHADER_BINARY_FORMATS:
4221 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104222 if (params) {
[email protected]302ce6d2011-07-07 23:28:114223 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104224 }
[email protected]b273e432010-04-12 17:23:584225 return true;
4226 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114227 *num_written = validators_->shader_binary_format.GetValues().size();
4228 if (params) {
4229 for (GLint ii = 0; ii < *num_written; ++ii) {
4230 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4231 }
4232 }
4233 return true;
[email protected]b273e432010-04-12 17:23:584234 case GL_SHADER_COMPILER:
4235 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104236 if (params) {
4237 *params = GL_TRUE;
4238 }
[email protected]b273e432010-04-12 17:23:584239 return true;
[email protected]6b8cf1a2010-05-06 16:13:584240 case GL_ARRAY_BUFFER_BINDING:
4241 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104242 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114243 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104244 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244245 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104246 &client_id);
4247 *params = client_id;
4248 } else {
4249 *params = 0;
4250 }
[email protected]6b8cf1a2010-05-06 16:13:584251 }
4252 return true;
4253 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4254 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104255 if (params) {
[email protected]e259eb412012-10-13 05:47:244256 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104257 GLuint client_id = 0;
4258 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254259 state_.vertex_attrib_manager->element_array_buffer()->
4260 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104261 *params = client_id;
4262 } else {
4263 *params = 0;
4264 }
[email protected]6b8cf1a2010-05-06 16:13:584265 }
4266 return true;
4267 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304268 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584269 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104270 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354271 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454272 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204273 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104274 GLuint client_id = 0;
4275 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204276 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304277 *params = client_id;
4278 } else {
4279 *params = 0;
4280 }
4281 }
4282 return true;
[email protected]ebfb73c2012-08-15 02:37:454283 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304284 *num_written = 1;
4285 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354286 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454287 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204288 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304289 GLuint client_id = 0;
4290 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204291 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104292 *params = client_id;
4293 } else {
4294 *params = 0;
4295 }
[email protected]6b8cf1a2010-05-06 16:13:584296 }
4297 return true;
4298 case GL_RENDERBUFFER_BINDING:
4299 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104300 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354301 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204302 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4303 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104304 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104305 } else {
4306 *params = 0;
4307 }
[email protected]6b8cf1a2010-05-06 16:13:584308 }
4309 return true;
4310 case GL_CURRENT_PROGRAM:
4311 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104312 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114313 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104314 GLuint client_id = 0;
4315 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244316 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104317 *params = client_id;
4318 } else {
4319 *params = 0;
4320 }
[email protected]6b8cf1a2010-05-06 16:13:584321 }
4322 return true;
[email protected]bf835842012-11-19 15:21:514323 case GL_VERTEX_ARRAY_BINDING_OES:
4324 *num_written = 1;
4325 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114326 if (state_.vertex_attrib_manager.get() !=
4327 default_vertex_attrib_manager_.get()) {
[email protected]bf835842012-11-19 15:21:514328 GLuint client_id = 0;
4329 vertex_array_manager_->GetClientId(
4330 state_.vertex_attrib_manager->service_id(), &client_id);
4331 *params = client_id;
4332 } else {
4333 *params = 0;
4334 }
4335 }
4336 return true;
[email protected]4e8a5b122010-05-08 22:00:104337 case GL_TEXTURE_BINDING_2D:
4338 *num_written = 1;
4339 if (params) {
[email protected]e259eb412012-10-13 05:47:244340 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114341 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104342 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584343 } else {
4344 *params = 0;
4345 }
[email protected]6b8cf1a2010-05-06 16:13:584346 }
[email protected]4e8a5b122010-05-08 22:00:104347 return true;
4348 case GL_TEXTURE_BINDING_CUBE_MAP:
4349 *num_written = 1;
4350 if (params) {
[email protected]e259eb412012-10-13 05:47:244351 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114352 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104353 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584354 } else {
4355 *params = 0;
4356 }
[email protected]6b8cf1a2010-05-06 16:13:584357 }
[email protected]4e8a5b122010-05-08 22:00:104358 return true;
[email protected]61eeb33f2011-07-26 15:30:314359 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4360 *num_written = 1;
4361 if (params) {
[email protected]e259eb412012-10-13 05:47:244362 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114363 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104364 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314365 } else {
4366 *params = 0;
4367 }
4368 }
4369 return true;
[email protected]e51bdf32011-11-23 22:21:464370 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4371 *num_written = 1;
4372 if (params) {
[email protected]e259eb412012-10-13 05:47:244373 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114374 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104375 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464376 } else {
4377 *params = 0;
4378 }
4379 }
4380 return true;
[email protected]6c75c712012-06-19 15:43:174381 case GL_UNPACK_FLIP_Y_CHROMIUM:
4382 *num_written = 1;
4383 if (params) {
4384 params[0] = unpack_flip_y_;
4385 }
4386 return true;
4387 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4388 *num_written = 1;
4389 if (params) {
4390 params[0] = unpack_premultiply_alpha_;
4391 }
4392 return true;
4393 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4394 *num_written = 1;
4395 if (params) {
4396 params[0] = unpack_unpremultiply_alpha_;
4397 }
4398 return true;
[email protected]b273e432010-04-12 17:23:584399 default:
[email protected]2f143d482013-03-14 18:04:494400 if (pname >= GL_DRAW_BUFFER0_ARB &&
4401 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4402 *num_written = 1;
4403 if (params) {
4404 Framebuffer* framebuffer =
4405 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4406 if (framebuffer) {
4407 params[0] = framebuffer->GetDrawBuffer(pname);
4408 } else { // backbuffer
4409 if (pname == GL_DRAW_BUFFER0_ARB)
4410 params[0] = group_->draw_buffer();
4411 else
4412 params[0] = GL_NONE;
4413 }
4414 }
4415 return true;
4416 }
[email protected]4e8a5b122010-05-08 22:00:104417 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534418 return false;
[email protected]b273e432010-04-12 17:23:584419 }
4420}
4421
[email protected]4e8a5b122010-05-08 22:00:104422bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4423 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264424 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534425 return true;
4426 }
[email protected]4e8a5b122010-05-08 22:00:104427 return GetHelper(pname, NULL, num_values);
4428}
4429
[email protected]7d3c36e2013-07-12 14:13:164430GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4431 if (GL_MAX_SAMPLES == pname &&
4432 features().use_img_for_multisampled_render_to_texture) {
4433 return GL_MAX_SAMPLES_IMG;
4434 }
4435 return pname;
4436}
4437
[email protected]b273e432010-04-12 17:23:584438void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4439 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104440 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534441 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554442 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264443 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534444 GetHelper(pname, values.get(), &num_written);
4445 }
[email protected]b273e432010-04-12 17:23:584446 for (GLsizei ii = 0; ii < num_written; ++ii) {
4447 params[ii] = static_cast<GLboolean>(values[ii]);
4448 }
4449 } else {
[email protected]7d3c36e2013-07-12 14:13:164450 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584451 glGetBooleanv(pname, params);
4452 }
4453}
4454
4455void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4456 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104457 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264458 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534459 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554460 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534461 GetHelper(pname, values.get(), &num_written);
4462 for (GLsizei ii = 0; ii < num_written; ++ii) {
4463 params[ii] = static_cast<GLfloat>(values[ii]);
4464 }
4465 } else {
[email protected]7d3c36e2013-07-12 14:13:164466 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534467 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584468 }
[email protected]b273e432010-04-12 17:23:584469 }
4470}
4471
4472void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4473 DCHECK(params);
4474 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264475 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534476 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164477 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584478 glGetIntegerv(pname, params);
4479 }
4480}
4481
[email protected]a0c3e972010-04-21 00:49:134482void GLES2DecoderImpl::DoGetProgramiv(
4483 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424484 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4485 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134486 return;
4487 }
[email protected]df37b9932013-03-08 05:21:424488 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134489}
4490
[email protected]17cfbe0e2013-03-07 01:26:084491void GLES2DecoderImpl::DoGetBufferParameteriv(
4492 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134493 // Just delegate it. Some validation is actually done before this.
4494 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4495 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084496}
4497
[email protected]258a3313f2011-10-18 20:13:574498void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424499 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574500 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514501 LOCAL_SET_GL_ERROR(
4502 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574503 return;
4504 }
[email protected]68dcb1f2012-04-07 00:14:564505 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514506 LOCAL_SET_GL_ERROR(
4507 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564508 return;
4509 }
4510 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514511 LOCAL_SET_GL_ERROR(
4512 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564513 return;
4514 }
[email protected]df37b9932013-03-08 05:21:424515 Program* program = GetProgramInfoNotShader(
4516 program_id, "glBindAttribLocation");
4517 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574518 return;
[email protected]558847a2010-03-24 07:02:544519 }
[email protected]df37b9932013-03-08 05:21:424520 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4521 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574522}
4523
4524error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354525 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574526 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544527 GLuint index = static_cast<GLuint>(c.index);
4528 uint32 name_size = c.data_size;
4529 const char* name = GetSharedMemoryAs<const char*>(
4530 c.name_shm_id, c.name_shm_offset, name_size);
4531 if (name == NULL) {
4532 return error::kOutOfBounds;
4533 }
4534 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574535 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544536 return error::kNoError;
4537}
4538
[email protected]558847a2010-03-24 07:02:544539error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354540 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584541 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544542 GLuint index = static_cast<GLuint>(c.index);
4543 Bucket* bucket = GetBucket(c.name_bucket_id);
4544 if (!bucket || bucket->size() == 0) {
4545 return error::kInvalidArguments;
4546 }
4547 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184548 if (!bucket->GetAsString(&name_str)) {
4549 return error::kInvalidArguments;
4550 }
[email protected]258a3313f2011-10-18 20:13:574551 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544552 return error::kNoError;
4553}
4554
[email protected]2be6abf32012-06-26 00:28:334555void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424556 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334557 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514558 LOCAL_SET_GL_ERROR(
4559 GL_INVALID_VALUE,
4560 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334561 return;
4562 }
4563 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514564 LOCAL_SET_GL_ERROR(
4565 GL_INVALID_OPERATION,
4566 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334567 return;
4568 }
4569 if (location < 0 || static_cast<uint32>(location) >=
4570 (group_->max_fragment_uniform_vectors() +
4571 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514572 LOCAL_SET_GL_ERROR(
4573 GL_INVALID_VALUE,
4574 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334575 return;
4576 }
[email protected]df37b9932013-03-08 05:21:424577 Program* program = GetProgramInfoNotShader(
4578 program_id, "glBindUniformLocationCHROMIUM");
4579 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334580 return;
4581 }
[email protected]df37b9932013-03-08 05:21:424582 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514583 LOCAL_SET_GL_ERROR(
4584 GL_INVALID_VALUE,
4585 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334586 }
4587}
4588
4589error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354590 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334591 GLuint program = static_cast<GLuint>(c.program);
4592 GLint location = static_cast<GLint>(c.location);
4593 uint32 name_size = c.data_size;
4594 const char* name = GetSharedMemoryAs<const char*>(
4595 c.name_shm_id, c.name_shm_offset, name_size);
4596 if (name == NULL) {
4597 return error::kOutOfBounds;
4598 }
4599 String name_str(name, name_size);
4600 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4601 return error::kNoError;
4602}
4603
[email protected]2be6abf32012-06-26 00:28:334604error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4605 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354606 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334607 GLuint program = static_cast<GLuint>(c.program);
4608 GLint location = static_cast<GLint>(c.location);
4609 Bucket* bucket = GetBucket(c.name_bucket_id);
4610 if (!bucket || bucket->size() == 0) {
4611 return error::kInvalidArguments;
4612 }
4613 std::string name_str;
4614 if (!bucket->GetAsString(&name_str)) {
4615 return error::kInvalidArguments;
4616 }
4617 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4618 return error::kNoError;
4619}
4620
[email protected]f7a64ee2010-02-01 22:24:144621error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354622 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034623 GLuint client_id = c.shader;
4624 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424625 Shader* shader = GetShader(client_id);
4626 if (shader) {
4627 if (!shader->IsDeleted()) {
4628 glDeleteShader(shader->service_id());
4629 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144630 }
[email protected]ae51d192010-04-27 00:48:034631 } else {
[email protected]ab09b612013-03-11 22:11:514632 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034633 }
[email protected]96449d2c2009-11-25 00:01:324634 }
[email protected]f7a64ee2010-02-01 22:24:144635 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324636}
4637
[email protected]f7a64ee2010-02-01 22:24:144638error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354639 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034640 GLuint client_id = c.program;
4641 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424642 Program* program = GetProgram(client_id);
4643 if (program) {
4644 if (!program->IsDeleted()) {
4645 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144646 }
[email protected]ae51d192010-04-27 00:48:034647 } else {
[email protected]ab09b612013-03-11 22:11:514648 LOCAL_SET_GL_ERROR(
4649 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034650 }
[email protected]96449d2c2009-11-25 00:01:324651 }
[email protected]f7a64ee2010-02-01 22:24:144652 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324653}
4654
[email protected]269200b12010-11-18 22:53:064655void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104656 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574657 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104658 for (GLsizei ii = 0; ii < n; ++ii) {
4659 id_allocator->FreeID(ids[ii]);
4660 }
4661}
4662
[email protected]269200b12010-11-18 22:53:064663error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354664 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104665 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4666 GLsizei n = static_cast<GLsizei>(c.n);
4667 uint32 data_size;
4668 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4669 return error::kOutOfBounds;
4670 }
4671 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4672 c.ids_shm_id, c.ids_shm_offset, data_size);
4673 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514674 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104675 return error::kNoError;
4676 }
4677 if (ids == NULL) {
4678 return error::kOutOfBounds;
4679 }
[email protected]269200b12010-11-18 22:53:064680 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104681 return error::kNoError;
4682}
4683
[email protected]269200b12010-11-18 22:53:064684void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104685 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574686 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104687 if (id_offset == 0) {
4688 for (GLsizei ii = 0; ii < n; ++ii) {
4689 ids[ii] = id_allocator->AllocateID();
4690 }
4691 } else {
4692 for (GLsizei ii = 0; ii < n; ++ii) {
4693 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4694 id_offset = ids[ii] + 1;
4695 }
4696 }
4697}
4698
[email protected]269200b12010-11-18 22:53:064699error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354700 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104701 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4702 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4703 GLsizei n = static_cast<GLsizei>(c.n);
4704 uint32 data_size;
4705 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4706 return error::kOutOfBounds;
4707 }
4708 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4709 c.ids_shm_id, c.ids_shm_offset, data_size);
4710 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514711 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104712 return error::kNoError;
4713 }
4714 if (ids == NULL) {
4715 return error::kOutOfBounds;
4716 }
[email protected]269200b12010-11-18 22:53:064717 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104718 return error::kNoError;
4719}
4720
[email protected]269200b12010-11-18 22:53:064721void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104722 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574723 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104724 for (GLsizei ii = 0; ii < n; ++ii) {
4725 if (!id_allocator->MarkAsUsed(ids[ii])) {
4726 for (GLsizei jj = 0; jj < ii; ++jj) {
4727 id_allocator->FreeID(ids[jj]);
4728 }
[email protected]ab09b612013-03-11 22:11:514729 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434730 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4731 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104732 return;
4733 }
4734 }
4735}
4736
[email protected]269200b12010-11-18 22:53:064737error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354738 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104739 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4740 GLsizei n = static_cast<GLsizei>(c.n);
4741 uint32 data_size;
4742 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4743 return error::kOutOfBounds;
4744 }
4745 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4746 c.ids_shm_id, c.ids_shm_offset, data_size);
4747 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514748 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104749 return error::kNoError;
4750 }
4751 if (ids == NULL) {
4752 return error::kOutOfBounds;
4753 }
[email protected]269200b12010-11-18 22:53:064754 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104755 return error::kNoError;
4756}
4757
[email protected]a7266a92012-06-28 02:11:084758error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444759 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204760 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:464761 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274762 glClear(mask);
4763 }
[email protected]a7266a92012-06-28 02:11:084764 return error::kNoError;
4765}
4766
[email protected]36cef8ce2010-03-16 07:34:454767void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4768 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034769 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064770 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4771 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514772 LOCAL_SET_GL_ERROR(
4773 GL_INVALID_OPERATION,
4774 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454775 return;
4776 }
[email protected]ae51d192010-04-27 00:48:034777 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274778 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034779 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274780 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4781 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514782 LOCAL_SET_GL_ERROR(
4783 GL_INVALID_OPERATION,
4784 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034785 return;
4786 }
[email protected]ee2a79c32013-03-10 03:50:274787 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034788 }
[email protected]ab09b612013-03-11 22:11:514789 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034790 glFramebufferRenderbufferEXT(
4791 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514792 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264793 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274794 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284795 }
[email protected]9d3b2e12013-10-02 01:04:344796 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:444797 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464798 }
[email protected]81fc9d02013-03-14 23:53:324799 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284800}
4801
[email protected]3a2e7c7b2010-08-06 01:12:284802void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464803 if (SetCapabilityState(cap, false)) {
4804 glDisable(cap);
4805 }
[email protected]3a2e7c7b2010-08-06 01:12:284806}
4807
4808void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464809 if (SetCapabilityState(cap, true)) {
4810 glEnable(cap);
4811 }
[email protected]3a2e7c7b2010-08-06 01:12:284812}
4813
[email protected]88a61bf2012-10-27 13:00:424814void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4815 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4816 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4817 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284818}
4819
[email protected]b04e24c2013-01-08 18:35:254820void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424821 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4822 state_.sample_coverage_invert = (invert != 0);
4823 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284824}
4825
[email protected]0d6bfdc2011-11-02 01:32:204826// Assumes framebuffer is complete.
4827void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064828 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304829 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204830 // bind this to the DRAW point, clear then bind back to READ
4831 // TODO(gman): I don't think there is any guarantee that an FBO that
4832 // is complete on the READ attachment will be complete as a DRAW
4833 // attachment.
4834 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064835 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304836 }
[email protected]3a2e7c7b2010-08-06 01:12:284837 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064838 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464839 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204840 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464841 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064842 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4843 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284844 glColorMask(true, true, true, true);
4845 clear_bits |= GL_COLOR_BUFFER_BIT;
4846 }
4847
[email protected]4d8f0dd2013-03-09 14:37:064848 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4849 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284850 glClearStencil(0);
4851 glStencilMask(-1);
4852 clear_bits |= GL_STENCIL_BUFFER_BIT;
4853 }
4854
[email protected]4d8f0dd2013-03-09 14:37:064855 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4856 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284857 glClearDepth(1.0f);
4858 glDepthMask(true);
4859 clear_bits |= GL_DEPTH_BUFFER_BIT;
4860 }
4861
4862 glDisable(GL_SCISSOR_TEST);
4863 glClear(clear_bits);
4864
[email protected]968351b2011-12-20 08:26:514865 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064866 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284867
[email protected]c007aa02010-09-02 22:22:404868 RestoreClearState();
4869
4870 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064871 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4872 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484873 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064874 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4875 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484876 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404877 }
4878}
4879
4880void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:444881 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:244882 glClearColor(
4883 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4884 state_.color_clear_alpha);
4885 glClearStencil(state_.stencil_clear);
4886 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224887 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284888 glEnable(GL_SCISSOR_TEST);
4889 }
[email protected]36cef8ce2010-03-16 07:34:454890}
4891
4892GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354893 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304894 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204895 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454896 return GL_FRAMEBUFFER_COMPLETE;
4897 }
[email protected]0d6bfdc2011-11-02 01:32:204898 GLenum completeness = framebuffer->IsPossiblyComplete();
4899 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4900 return completeness;
4901 }
[email protected]73276522012-11-09 05:50:204902 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454903}
4904
4905void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034906 GLenum target, GLenum attachment, GLenum textarget,
4907 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:164908 DoFramebufferTexture2DCommon(
4909 "glFramebufferTexture2D", target, attachment,
4910 textarget, client_texture_id, level, 0);
4911}
4912
4913void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
4914 GLenum target, GLenum attachment, GLenum textarget,
4915 GLuint client_texture_id, GLint level, GLsizei samples) {
4916 if (!features().multisampled_render_to_texture) {
4917 LOCAL_SET_GL_ERROR(
4918 GL_INVALID_OPERATION,
4919 "glFramebufferTexture2DMultisample", "function not available");
4920 return;
4921 }
4922 DoFramebufferTexture2DCommon(
4923 "glFramebufferTexture2DMultisample", target, attachment,
4924 textarget, client_texture_id, level, samples);
4925}
4926
4927void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
4928 const char* name, GLenum target, GLenum attachment, GLenum textarget,
4929 GLuint client_texture_id, GLint level, GLsizei samples) {
4930 if (samples > renderbuffer_manager()->max_samples()) {
4931 LOCAL_SET_GL_ERROR(
4932 GL_INVALID_VALUE,
4933 "glFramebufferTexture2DMultisample", "samples too large");
4934 return;
4935 }
[email protected]4d8f0dd2013-03-09 14:37:064936 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4937 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514938 LOCAL_SET_GL_ERROR(
4939 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164940 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454941 return;
4942 }
[email protected]ae51d192010-04-27 00:48:034943 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:494944 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:034945 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:494946 texture_ref = GetTexture(client_texture_id);
4947 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:514948 LOCAL_SET_GL_ERROR(
4949 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164950 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:034951 return;
4952 }
[email protected]370eaf12013-05-18 09:19:494953 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:034954 }
[email protected]0d6bfdc2011-11-02 01:32:204955
[email protected]80eb6b52012-01-19 00:14:414956 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:514957 LOCAL_SET_GL_ERROR(
4958 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:164959 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204960 return;
4961 }
4962
[email protected]91c94eb2013-10-22 10:32:544963 if (texture_ref)
4964 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
4965
[email protected]7d3c36e2013-07-12 14:13:164966 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
4967 if (0 == samples) {
4968 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
4969 } else {
4970 if (features().use_img_for_multisampled_render_to_texture) {
4971 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
4972 service_id, level, samples);
4973 } else {
4974 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
4975 service_id, level, samples);
4976 }
4977 }
4978 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:264979 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:164980 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
4981 samples);
[email protected]3a2e7c7b2010-08-06 01:12:284982 }
[email protected]9d3b2e12013-10-02 01:04:344983 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:444984 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464985 }
[email protected]91c94eb2013-10-22 10:32:544986
4987 if (texture_ref)
4988 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
4989
[email protected]81fc9d02013-03-14 23:53:324990 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:454991}
4992
4993void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4994 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:064995 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4996 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514997 LOCAL_SET_GL_ERROR(
4998 GL_INVALID_OPERATION,
4999 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455000 return;
5001 }
[email protected]74c1ec42010-08-12 01:55:575002 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105003 const Framebuffer::Attachment* attachment_object =
5004 framebuffer->GetAttachment(attachment);
5005 *params = attachment_object ? attachment_object->object_name() : 0;
5006 } else {
[email protected]7d3c36e2013-07-12 14:13:165007 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5008 features().use_img_for_multisampled_render_to_texture) {
5009 pname = GL_TEXTURE_SAMPLES_IMG;
5010 }
[email protected]62e65f02013-05-29 22:28:105011 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575012 }
[email protected]36cef8ce2010-03-16 07:34:455013}
5014
5015void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5016 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355017 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205018 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5019 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515020 LOCAL_SET_GL_ERROR(
5021 GL_INVALID_OPERATION,
5022 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455023 return;
5024 }
[email protected]3a03a8f2011-03-19 00:51:275025 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435026 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5027 *params = renderbuffer->internal_format();
5028 break;
5029 case GL_RENDERBUFFER_WIDTH:
5030 *params = renderbuffer->width();
5031 break;
5032 case GL_RENDERBUFFER_HEIGHT:
5033 *params = renderbuffer->height();
5034 break;
[email protected]7d3c36e2013-07-12 14:13:165035 case GL_RENDERBUFFER_SAMPLES_EXT:
5036 if (features().use_img_for_multisampled_render_to_texture) {
5037 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5038 params);
5039 } else {
5040 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5041 params);
5042 }
[email protected]ad84a3a2012-06-08 21:42:435043 default:
5044 glGetRenderbufferParameterivEXT(target, pname, params);
5045 break;
[email protected]b71f52c2010-06-18 22:20:205046 }
[email protected]36cef8ce2010-03-16 07:34:455047}
5048
[email protected]49cabed2013-11-13 18:15:185049void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305050 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5051 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5052 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445053 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:155054 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:515055 LOCAL_SET_GL_ERROR(
5056 GL_INVALID_OPERATION,
[email protected]49cabed2013-11-13 18:15:185057 "glBlitFramebufferCHROMIUM", "function not available");
[email protected]680aa412013-10-31 18:08:015058 return;
[email protected]8e3e0662010-08-23 18:46:305059 }
[email protected]0c16343f2013-03-08 20:40:165060
[email protected]49cabed2013-11-13 18:15:185061 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165062 return;
5063 }
5064
[email protected]d058bca2012-11-26 10:27:265065 glDisable(GL_SCISSOR_TEST);
[email protected]f42f05b2013-11-15 21:46:185066 BlitFramebufferHelper(
5067 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5068 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
5069}
5070
5071void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5072 const FeatureInfo* feature_info,
5073 GLenum target,
5074 GLsizei samples,
5075 GLenum internal_format,
5076 GLsizei width,
5077 GLsizei height) {
5078 // TODO(sievers): This could be resolved at the GL binding level, but the
5079 // binding process is currently a bit too 'brute force'.
5080 if (feature_info->feature_flags().is_angle) {
5081 glRenderbufferStorageMultisampleANGLE(
5082 target, samples, internal_format, width, height);
5083 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5084 glRenderbufferStorageMultisample(
5085 target, samples, internal_format, width, height);
5086 } else {
5087 glRenderbufferStorageMultisampleEXT(
5088 target, samples, internal_format, width, height);
5089 }
5090}
5091
5092void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5093 GLint srcY0,
5094 GLint srcX1,
5095 GLint srcY1,
5096 GLint dstX0,
5097 GLint dstY0,
5098 GLint dstX1,
5099 GLint dstY1,
5100 GLbitfield mask,
5101 GLenum filter) {
5102 // TODO(sievers): This could be resolved at the GL binding level, but the
5103 // binding process is currently a bit too 'brute force'.
5104 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245105 glBlitFramebufferANGLE(
5106 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185107 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5108 glBlitFramebuffer(
5109 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245110 } else {
5111 glBlitFramebufferEXT(
5112 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5113 }
[email protected]8e3e0662010-08-23 18:46:305114}
5115
[email protected]49cabed2013-11-13 18:15:185116bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5117 GLsizei samples,
5118 GLenum internalformat,
5119 GLsizei width,
5120 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535121 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515122 LOCAL_SET_GL_ERROR(
5123 GL_INVALID_VALUE,
5124 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185125 return false;
[email protected]84afefa2011-10-19 21:45:535126 }
5127
5128 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5129 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515130 LOCAL_SET_GL_ERROR(
5131 GL_INVALID_VALUE,
5132 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185133 return false;
[email protected]84afefa2011-10-19 21:45:535134 }
5135
[email protected]7989c9e2013-01-23 06:39:265136 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235137 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5138 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515139 LOCAL_SET_GL_ERROR(
5140 GL_OUT_OF_MEMORY,
5141 "glRenderbufferStorageMultsample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185142 return false;
[email protected]8e3e0662010-08-23 18:46:305143 }
5144
[email protected]7989c9e2013-01-23 06:39:265145 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515146 LOCAL_SET_GL_ERROR(
5147 GL_OUT_OF_MEMORY,
5148 "glRenderbufferStorageMultsample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185149 return false;
5150 }
5151
5152 return true;
5153}
5154
5155void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5156 GLenum target, GLsizei samples, GLenum internalformat,
5157 GLsizei width, GLsizei height) {
5158 if (!features().chromium_framebuffer_multisample) {
5159 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5160 "glRenderbufferStorageMultisampleCHROMIUM",
5161 "function not available");
5162 return;
5163 }
5164
5165 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5166 if (!renderbuffer) {
5167 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5168 "glRenderbufferStorageMultisampleCHROMIUM",
5169 "no renderbuffer bound");
5170 return;
5171 }
5172
5173 if (!ValidateRenderbufferStorageMultisample(
5174 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265175 return;
5176 }
5177
[email protected]8e102e102013-09-20 22:50:235178 GLenum impl_format =
5179 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5180 internalformat);
[email protected]49cabed2013-11-13 18:15:185181 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5182 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185183 RenderbufferStorageMultisampleHelper(
5184 feature_info_, target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185185 GLenum error =
5186 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265187 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105188
5189 if (workarounds().validate_multisample_buffer_allocation) {
5190 if (!VerifyMultisampleRenderbufferIntegrity(
5191 renderbuffer->service_id(), impl_format)) {
5192 LOCAL_SET_GL_ERROR(
5193 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185194 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105195 return;
5196 }
5197 }
5198
[email protected]968351b2011-12-20 08:26:515199 // TODO(gman): If renderbuffers tracked which framebuffers they were
5200 // attached to we could just mark those framebuffers as not complete.
5201 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205202 renderbuffer_manager()->SetInfo(
5203 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265204 }
[email protected]8e3e0662010-08-23 18:46:305205}
5206
[email protected]49cabed2013-11-13 18:15:185207// This is the handler for multisampled_render_to_texture extensions.
5208void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5209 GLenum target, GLsizei samples, GLenum internalformat,
5210 GLsizei width, GLsizei height) {
5211 if (!features().multisampled_render_to_texture) {
5212 LOCAL_SET_GL_ERROR(
5213 GL_INVALID_OPERATION,
5214 "glRenderbufferStorageMultisampleEXT", "function not available");
5215 return;
5216 }
5217
5218 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5219 if (!renderbuffer) {
5220 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5221 "glRenderbufferStorageMultisampleEXT",
5222 "no renderbuffer bound");
5223 return;
5224 }
5225
5226 if (!ValidateRenderbufferStorageMultisample(
5227 samples, internalformat, width, height)) {
5228 return;
5229 }
5230
5231 GLenum impl_format =
5232 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5233 internalformat);
5234 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5235 if (features().use_img_for_multisampled_render_to_texture) {
5236 glRenderbufferStorageMultisampleIMG(
5237 target, samples, impl_format, width, height);
5238 } else {
5239 glRenderbufferStorageMultisampleEXT(
5240 target, samples, impl_format, width, height);
5241 }
5242 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5243 if (error == GL_NO_ERROR) {
5244 // TODO(gman): If renderbuffers tracked which framebuffers they were
5245 // attached to we could just mark those framebuffers as not complete.
5246 framebuffer_manager()->IncFramebufferStateChangeCount();
5247 renderbuffer_manager()->SetInfo(
5248 renderbuffer, samples, internalformat, width, height);
5249 }
5250}
5251
[email protected]4a4c18b2013-09-13 22:50:105252// This function validates the allocation of a multisampled renderbuffer
5253// by clearing it to a key color, blitting the contents to a texture, and
5254// reading back the color to ensure it matches the key.
5255bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5256 GLuint renderbuffer, GLenum format) {
5257
5258 // Only validate color buffers.
5259 // These formats have been selected because they are very common or are known
5260 // to be used by the WebGL backbuffer. If problems are observed with other
5261 // color formats they can be added here.
5262 switch(format) {
5263 case GL_RGB:
5264 case GL_RGB8:
5265 case GL_RGBA:
5266 case GL_RGBA8:
5267 break;
5268 default:
5269 return true;
5270 }
5271
5272 GLint draw_framebuffer, read_framebuffer;
5273
5274 // Cache framebuffer and texture bindings.
5275 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5276 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5277
5278 if (!validation_texture_) {
5279 GLint bound_texture;
5280 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5281
5282 // Create additional resources needed for the verification.
5283 glGenTextures(1, &validation_texture_);
5284 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5285 glGenFramebuffersEXT(1, &validation_fbo_);
5286
5287 // Texture only needs to be 1x1.
5288 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5289 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5290 GL_UNSIGNED_BYTE, NULL);
5291
5292 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5293 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5294 GL_TEXTURE_2D, validation_texture_, 0);
5295
5296 glBindTexture(GL_TEXTURE_2D, bound_texture);
5297 }
5298
5299 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5300 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5301 GL_RENDERBUFFER, renderbuffer);
5302
5303 // Cache current state and reset it to the values we require.
5304 GLboolean scissor_enabled = false;
5305 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5306 if (scissor_enabled)
5307 glDisable(GL_SCISSOR_TEST);
5308
5309 GLboolean color_mask[4] = {true, true, true, true};
5310 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
5311 glColorMask(true, true, true, true);
5312
5313 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5314 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5315 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5316
5317 // Clear the buffer to the desired key color.
5318 glClear(GL_COLOR_BUFFER_BIT);
5319
5320 // Blit from the multisample buffer to a standard texture.
5321 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5322 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5323
[email protected]f42f05b2013-11-15 21:46:185324 BlitFramebufferHelper(
5325 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105326
5327 // Read a pixel from the buffer.
5328 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5329
5330 unsigned char pixel[3] = {0, 0, 0};
5331 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5332
5333 // Detach the renderbuffer.
5334 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5335 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5336 GL_RENDERBUFFER, 0);
5337
5338 // Restore cached state.
5339 if (scissor_enabled)
5340 glEnable(GL_SCISSOR_TEST);
5341
5342 glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
5343 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5344 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5345 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5346
5347 // Return true if the pixel matched the desired key color.
5348 return (pixel[0] == 0xFF &&
5349 pixel[1] == 0x00 &&
5350 pixel[2] == 0xFF);
5351}
5352
[email protected]36cef8ce2010-03-16 07:34:455353void GLES2DecoderImpl::DoRenderbufferStorage(
5354 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355355 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205356 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5357 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515358 LOCAL_SET_GL_ERROR(
5359 GL_INVALID_OPERATION,
5360 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455361 return;
5362 }
[email protected]876f6fee2010-08-02 23:10:325363
[email protected]84afefa2011-10-19 21:45:535364 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5365 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515366 LOCAL_SET_GL_ERROR(
5367 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535368 return;
5369 }
5370
[email protected]7989c9e2013-01-23 06:39:265371 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235372 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5373 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515374 LOCAL_SET_GL_ERROR(
5375 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265376 return;
5377 }
5378
5379 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515380 LOCAL_SET_GL_ERROR(
5381 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265382 return;
[email protected]b71f52c2010-06-18 22:20:205383 }
[email protected]876f6fee2010-08-02 23:10:325384
[email protected]ab09b612013-03-11 22:11:515385 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265386 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235387 target,
5388 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5389 internalformat),
5390 width,
5391 height);
[email protected]ab09b612013-03-11 22:11:515392 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265393 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515394 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5395 // we could just mark those framebuffers as not complete.
5396 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205397 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265398 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265399 }
[email protected]36cef8ce2010-03-16 07:34:455400}
5401
[email protected]df37b9932013-03-08 05:21:425402void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385403 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425404 Program* program = GetProgramInfoNotShader(
5405 program_id, "glLinkProgram");
5406 if (!program) {
[email protected]a93bb842010-02-16 23:03:475407 return;
5408 }
[email protected]05afda12011-01-20 00:17:345409
[email protected]df37b9932013-03-08 05:21:425410 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395411 ShaderTranslator* vertex_translator = NULL;
5412 ShaderTranslator* fragment_translator = NULL;
5413 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115414 vertex_translator = vertex_translator_.get();
5415 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395416 }
[email protected]df37b9932013-03-08 05:21:425417 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115418 vertex_translator,
5419 fragment_translator,
[email protected]7cd76fd2013-06-02 21:11:115420 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425421 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185422 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425423 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185424 if (workarounds().clear_uniforms_before_first_program_use)
5425 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545426 }
5427 }
[email protected]07f54fcc2009-12-22 02:46:305428};
5429
[email protected]3916c97e2010-02-25 03:20:505430void GLES2DecoderImpl::DoTexParameterf(
5431 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445432 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5433 &state_, target);
[email protected]02965c22013-03-09 02:40:075434 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515435 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245436 return;
[email protected]07f54fcc2009-12-22 02:46:305437 }
[email protected]cbb22e42011-05-12 23:36:245438
[email protected]02965c22013-03-09 02:40:075439 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505440 "glTexParameterf", GetErrorState(), texture, pname,
5441 static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305442}
5443
[email protected]3916c97e2010-02-25 03:20:505444void GLES2DecoderImpl::DoTexParameteri(
5445 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445446 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5447 &state_, target);
[email protected]02965c22013-03-09 02:40:075448 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515449 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245450 return;
[email protected]3916c97e2010-02-25 03:20:505451 }
[email protected]cbb22e42011-05-12 23:36:245452
[email protected]02965c22013-03-09 02:40:075453 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505454 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505455}
5456
5457void GLES2DecoderImpl::DoTexParameterfv(
5458 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445459 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5460 &state_, target);
[email protected]02965c22013-03-09 02:40:075461 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515462 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245463 return;
[email protected]3916c97e2010-02-25 03:20:505464 }
[email protected]cbb22e42011-05-12 23:36:245465
[email protected]02965c22013-03-09 02:40:075466 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505467 "glTexParameterfv", GetErrorState(), texture, pname,
5468 static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505469}
5470
5471void GLES2DecoderImpl::DoTexParameteriv(
5472 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445473 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5474 &state_, target);
[email protected]02965c22013-03-09 02:40:075475 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515476 LOCAL_SET_GL_ERROR(
5477 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245478 return;
[email protected]3916c97e2010-02-25 03:20:505479 }
[email protected]cbb22e42011-05-12 23:36:245480
[email protected]02965c22013-03-09 02:40:075481 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505482 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505483}
5484
[email protected]939e7362010-05-13 20:49:105485bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115486 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435487 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515488 LOCAL_SET_GL_ERROR(
5489 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435490 return false;
[email protected]939e7362010-05-13 20:49:105491 }
[email protected]e259eb412012-10-13 05:47:245492 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515493 LOCAL_SET_GL_ERROR(
5494 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105495 return false;
5496 }
5497 return true;
5498}
5499
5500bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5501 GLint location, const char* function_name) {
5502 if (!CheckCurrentProgram(function_name)) {
5503 return false;
5504 }
5505 return location != -1;
5506}
5507
[email protected]476ccb72012-12-06 15:52:525508namespace {
5509
5510static const GLenum valid_int_vec1_types_list[] = {
5511 GL_INT,
5512 GL_BOOL,
5513 GL_SAMPLER_2D,
5514 GL_SAMPLER_2D_RECT_ARB,
5515 GL_SAMPLER_CUBE,
5516 GL_SAMPLER_EXTERNAL_OES,
5517};
5518
5519static const GLenum valid_int_vec2_types_list[] = {
5520 GL_INT_VEC2,
5521 GL_BOOL_VEC2,
5522};
5523
5524static const GLenum valid_int_vec3_types_list[] = {
5525 GL_INT_VEC3,
5526 GL_BOOL_VEC3,
5527};
5528
5529static const GLenum valid_int_vec4_types_list[] = {
5530 GL_INT_VEC4,
5531 GL_BOOL_VEC4,
5532};
5533
5534static const GLenum valid_float_vec1_types_list[] = {
5535 GL_FLOAT,
5536 GL_BOOL,
5537};
5538
5539static const GLenum valid_float_vec2_types_list[] = {
5540 GL_FLOAT_VEC2,
5541 GL_BOOL_VEC2,
5542};
5543
5544static const GLenum valid_float_vec3_types_list[] = {
5545 GL_FLOAT_VEC3,
5546 GL_BOOL_VEC3,
5547};
5548
5549static const GLenum valid_float_vec4_types_list[] = {
5550 GL_FLOAT_VEC4,
5551 GL_BOOL_VEC4,
5552};
5553
5554static const GLenum valid_float_mat2_types_list[] = {
5555 GL_FLOAT_MAT2,
5556};
5557
5558static const GLenum valid_float_mat3_types_list[] = {
5559 GL_FLOAT_MAT3,
5560};
5561
5562static const GLenum valid_float_mat4_types_list[] = {
5563 GL_FLOAT_MAT4,
5564};
5565
5566static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5567 valid_int_vec1_types_list,
5568 arraysize(valid_int_vec1_types_list),
5569};
5570
5571static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5572 valid_int_vec2_types_list,
5573 arraysize(valid_int_vec2_types_list),
5574};
5575
5576static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5577 valid_int_vec3_types_list,
5578 arraysize(valid_int_vec3_types_list),
5579};
5580
5581static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5582 valid_int_vec4_types_list,
5583 arraysize(valid_int_vec4_types_list),
5584};
5585
5586static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5587 valid_float_vec1_types_list,
5588 arraysize(valid_float_vec1_types_list),
5589};
5590
5591static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5592 valid_float_vec2_types_list,
5593 arraysize(valid_float_vec2_types_list),
5594};
5595
5596static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5597 valid_float_vec3_types_list,
5598 arraysize(valid_float_vec3_types_list),
5599};
5600
5601static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5602 valid_float_vec4_types_list,
5603 arraysize(valid_float_vec4_types_list),
5604};
5605
5606static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5607 valid_float_mat2_types_list,
5608 arraysize(valid_float_mat2_types_list),
5609};
5610
5611static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5612 valid_float_mat3_types_list,
5613 arraysize(valid_float_mat3_types_list),
5614};
5615
5616static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5617 valid_float_mat4_types_list,
5618 arraysize(valid_float_mat4_types_list),
5619};
5620
5621} // anonymous namespace.
5622
[email protected]43c2f1f2011-03-25 18:35:365623bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125624 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525625 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125626 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365627 DCHECK(type);
5628 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125629 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525630
[email protected]1b0a6752012-02-22 03:44:125631 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105632 return false;
5633 }
[email protected]43c2f1f2011-03-25 18:35:365634 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355635 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245636 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125637 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365638 if (!info) {
[email protected]ab09b612013-03-11 22:11:515639 LOCAL_SET_GL_ERROR(
5640 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105641 return false;
5642 }
[email protected]476ccb72012-12-06 15:52:525643 bool okay = false;
5644 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5645 if (base_info.valid_types[ii] == info->type) {
5646 okay = true;
5647 break;
5648 }
5649 }
5650 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515651 LOCAL_SET_GL_ERROR(
5652 GL_INVALID_OPERATION, function_name,
5653 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525654 return false;
5655 }
[email protected]43c2f1f2011-03-25 18:35:365656 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515657 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435658 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365659 return false;
5660 }
5661 *count = std::min(info->size - array_index, *count);
5662 if (*count <= 0) {
5663 return false;
5664 }
5665 *type = info->type;
[email protected]939e7362010-05-13 20:49:105666 return true;
5667}
5668
[email protected]1b0a6752012-02-22 03:44:125669void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5670 GLenum type = 0;
5671 GLsizei count = 1;
5672 GLint real_location = -1;
5673 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525674 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5675 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505676 return;
5677 }
[email protected]e259eb412012-10-13 05:47:245678 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025679 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515680 LOCAL_SET_GL_ERROR(
5681 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465682 return;
5683 }
[email protected]1b0a6752012-02-22 03:44:125684 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505685}
5686
5687void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125688 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365689 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125690 GLint real_location = -1;
5691 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525692 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5693 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365694 return;
5695 }
[email protected]74727112012-06-13 21:18:085696 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5697 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245698 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025699 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515700 LOCAL_SET_GL_ERROR(
5701 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465702 return;
5703 }
[email protected]43c2f1f2011-03-25 18:35:365704 }
[email protected]1b0a6752012-02-22 03:44:125705 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505706}
5707
[email protected]939e7362010-05-13 20:49:105708void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125709 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365710 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125711 GLint real_location = -1;
5712 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525713 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5714 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105715 return;
5716 }
5717 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555718 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105719 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535720 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105721 }
[email protected]1b0a6752012-02-22 03:44:125722 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105723 } else {
[email protected]1b0a6752012-02-22 03:44:125724 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105725 }
5726}
5727
5728void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125729 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365730 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125731 GLint real_location = -1;
5732 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525733 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5734 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105735 return;
5736 }
5737 if (type == GL_BOOL_VEC2) {
5738 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555739 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105740 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535741 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105742 }
[email protected]1b0a6752012-02-22 03:44:125743 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105744 } else {
[email protected]1b0a6752012-02-22 03:44:125745 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105746 }
5747}
5748
5749void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125750 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365751 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125752 GLint real_location = -1;
5753 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525754 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5755 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105756 return;
5757 }
5758 if (type == GL_BOOL_VEC3) {
5759 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555760 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105761 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535762 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105763 }
[email protected]1b0a6752012-02-22 03:44:125764 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105765 } else {
[email protected]1b0a6752012-02-22 03:44:125766 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105767 }
5768}
5769
5770void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125771 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365772 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125773 GLint real_location = -1;
5774 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525775 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5776 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105777 return;
5778 }
5779 if (type == GL_BOOL_VEC4) {
5780 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555781 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105782 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535783 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105784 }
[email protected]1b0a6752012-02-22 03:44:125785 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105786 } else {
[email protected]1b0a6752012-02-22 03:44:125787 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105788 }
5789}
5790
[email protected]43c2f1f2011-03-25 18:35:365791void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125792 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365793 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125794 GLint real_location = -1;
5795 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525796 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5797 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365798 return;
5799 }
[email protected]1b0a6752012-02-22 03:44:125800 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365801}
5802
5803void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125804 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365805 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125806 GLint real_location = -1;
5807 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525808 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5809 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365810 return;
5811 }
[email protected]1b0a6752012-02-22 03:44:125812 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365813}
5814
5815void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125816 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365817 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125818 GLint real_location = -1;
5819 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525820 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5821 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365822 return;
5823 }
[email protected]1b0a6752012-02-22 03:44:125824 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365825}
5826
5827void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125828 GLint fake_location, GLsizei count, GLboolean transpose,
5829 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365830 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125831 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365832 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525833 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5834 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365835 return;
5836 }
[email protected]1b0a6752012-02-22 03:44:125837 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365838}
5839
5840void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125841 GLint fake_location, GLsizei count, GLboolean transpose,
5842 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365843 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125844 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365845 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525846 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5847 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365848 return;
5849 }
[email protected]1b0a6752012-02-22 03:44:125850 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365851}
5852
5853void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125854 GLint fake_location, GLsizei count, GLboolean transpose,
5855 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365856 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125857 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365858 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525859 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5860 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365861 return;
5862 }
[email protected]1b0a6752012-02-22 03:44:125863 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365864}
5865
[email protected]df37b9932013-03-08 05:21:425866void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035867 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425868 Program* program = NULL;
5869 if (program_id) {
5870 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5871 if (!program) {
[email protected]ae51d192010-04-27 00:48:035872 return;
5873 }
[email protected]df37b9932013-03-08 05:21:425874 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505875 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515876 LOCAL_SET_GL_ERROR(
5877 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505878 return;
5879 }
[email protected]df37b9932013-03-08 05:21:425880 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505881 }
[email protected]7cd76fd2013-06-02 21:11:115882 if (state_.current_program.get()) {
5883 program_manager()->UnuseProgram(shader_manager(),
5884 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145885 }
[email protected]df37b9932013-03-08 05:21:425886 state_.current_program = program;
5887 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545888 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:115889 if (state_.current_program.get()) {
5890 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:185891 if (workarounds().clear_uniforms_before_first_program_use)
5892 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:145893 }
[email protected]3916c97e2010-02-25 03:20:505894}
5895
[email protected]ab09b612013-03-11 22:11:515896void GLES2DecoderImpl::RenderWarning(
5897 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325898 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015899}
5900
[email protected]ab09b612013-03-11 22:11:515901void GLES2DecoderImpl::PerformanceWarning(
5902 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505903 logger_.LogMessage(filename, line,
5904 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015905}
5906
[email protected]91c94eb2013-10-22 10:32:545907void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
5908 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:545909 // Image is already in use if texture is attached to a framebuffer.
5910 if (texture && !texture->IsAttachedToFramebuffer()) {
5911 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5912 if (image) {
5913 ScopedGLErrorSuppressor suppressor(
5914 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
5915 GetErrorState());
5916 glBindTexture(textarget, texture->service_id());
5917 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:025918 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:545919 }
5920 }
5921}
5922
5923void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
5924 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:545925 // Image is still in use if texture is attached to a framebuffer.
5926 if (texture && !texture->IsAttachedToFramebuffer()) {
5927 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5928 if (image) {
5929 ScopedGLErrorSuppressor suppressor(
5930 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
5931 GetErrorState());
5932 glBindTexture(textarget, texture->service_id());
5933 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:025934 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:545935 }
5936 }
5937}
5938
[email protected]e56131d22013-07-28 16:14:115939bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:115940 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:545941 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:555942 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:115943 return true;
[email protected]ef526492010-06-02 23:12:255944 }
[email protected]e2367b42013-05-31 03:37:215945
[email protected]ef526492010-06-02 23:12:255946 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:355947 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245948 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505949 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355950 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245951 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505952 DCHECK(uniform_info);
5953 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5954 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025955 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245956 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:545957 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:365958 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:545959 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
5960 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:255961 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505962 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5963 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:545964 textarget,
[email protected]00f893d2010-08-24 18:55:495965 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:515966 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:015967 std::string("texture bound to texture unit ") +
5968 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:295969 " is not renderable. It maybe non-power-of-2 and have"
5970 " incompatible texture filtering or is not"
5971 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:545972 continue;
[email protected]3916c97e2010-02-25 03:20:505973 }
[email protected]91c94eb2013-10-22 10:32:545974
[email protected]4e7b89202014-01-28 01:44:065975 if (textarget != GL_TEXTURE_CUBE_MAP) {
5976 Texture* texture = texture_ref->texture();
5977 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5978 if (image && !texture->IsAttachedToFramebuffer()) {
5979 ScopedGLErrorSuppressor suppressor(
5980 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
5981 textures_set = true;
5982 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5983 image->WillUseTexImage();
5984 continue;
5985 }
[email protected]91c94eb2013-10-22 10:32:545986 }
[email protected]3916c97e2010-02-25 03:20:505987 }
5988 // else: should this be an error?
5989 }
5990 }
[email protected]e56131d22013-07-28 16:14:115991 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:505992}
5993
[email protected]91c94eb2013-10-22 10:32:545994void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:115995 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:355996 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:115997 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505998 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355999 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246000 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506001 DCHECK(uniform_info);
6002 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6003 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026004 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246005 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116006 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546007 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496008 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506009 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496010 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116011 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6012 ? texture_unit.bound_texture_2d.get()
6013 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506014 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496015 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546016 continue;
6017 }
6018
[email protected]4e7b89202014-01-28 01:44:066019 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6020 Texture* texture = texture_ref->texture();
6021 gfx::GLImage* image =
6022 texture->GetLevelImage(texture_unit.bind_target, 0);
6023 if (image && !texture->IsAttachedToFramebuffer()) {
6024 ScopedGLErrorSuppressor suppressor(
6025 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6026 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6027 image->DidUseTexImage();
6028 continue;
6029 }
[email protected]3916c97e2010-02-25 03:20:506030 }
6031 }
6032 }
6033 }
6034 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246035 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306036}
6037
[email protected]0d6bfdc2011-11-02 01:32:206038bool GLES2DecoderImpl::ClearUnclearedTextures() {
6039 // Only check if there are some uncleared textures.
6040 if (!texture_manager()->HaveUnsafeTextures()) {
6041 return true;
6042 }
6043
6044 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116045 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356046 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116047 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206048 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356049 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246050 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206051 DCHECK(uniform_info);
6052 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6053 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026054 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246055 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496056 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366057 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496058 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6059 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206060 return false;
6061 }
6062 }
6063 }
6064 }
6065 }
6066 }
6067 return true;
6068}
6069
[email protected]c6aef902012-02-14 03:31:426070bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:436071 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:036072 // NOTE: We specifically do not check current_program->IsValid() because
6073 // it could never be invalid since glUseProgram would have failed. While
6074 // glLinkProgram could later mark the program as invalid the previous
6075 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116076 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506077 // The program does not exist.
6078 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516079 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506080 return false;
6081 }
[email protected]c6aef902012-02-14 03:31:426082
[email protected]7cd76fd2013-06-02 21:11:116083 return state_.vertex_attrib_manager
6084 ->ValidateBindings(function_name,
6085 this,
6086 feature_info_.get(),
6087 state_.current_program.get(),
6088 max_vertex_accessed,
6089 primcount);
[email protected]b1122982010-05-17 23:04:246090}
6091
[email protected]c13e1da62011-09-09 21:48:306092bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436093 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306094 DCHECK(simulated);
6095 *simulated = false;
6096
[email protected]876f6fee2010-08-02 23:10:326097 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306098 return true;
[email protected]876f6fee2010-08-02 23:10:326099
[email protected]ac77603c72013-03-08 13:52:066100 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356101 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246102 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246103 bool attrib_0_used =
6104 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066105 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306106 return true;
[email protected]b1122982010-05-17 23:04:246107 }
6108
[email protected]b1122982010-05-17 23:04:246109 // Make a buffer with a single repeated vec4 value enough to
6110 // simulate the constant value that is supposed to be here.
6111 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306112 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476113 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306114
6115 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476116 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306117 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516118 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306119 return false;
6120 }
6121
[email protected]ab09b612013-03-11 22:11:516122 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016123 "Attribute 0 is disabled. This has signficant performance penalty");
6124
[email protected]ab09b612013-03-11 22:11:516125 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306126 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6127
[email protected]8f0b86c2f2012-04-10 05:48:286128 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6129 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496130 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306131 GLenum error = glGetError();
6132 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516133 LOCAL_SET_GL_ERROR(
6134 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306135 return false;
6136 }
[email protected]fc753442011-02-04 19:49:496137 }
[email protected]af6380962012-11-29 23:24:136138
6139 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286140 if (new_buffer ||
6141 (attrib_0_used &&
6142 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136143 (value.v[0] != attrib_0_value_.v[0] ||
6144 value.v[1] != attrib_0_value_.v[1] ||
6145 value.v[2] != attrib_0_value_.v[2] ||
6146 value.v[3] != attrib_0_value_.v[3])))) {
6147 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496148 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6149 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136150 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246151 attrib_0_size_ = size_needed;
6152 }
6153
6154 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6155
[email protected]ac77603c72013-03-08 13:52:066156 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426157 glVertexAttribDivisorANGLE(0, 0);
6158
[email protected]c13e1da62011-09-09 21:48:306159 *simulated = true;
[email protected]b1122982010-05-17 23:04:246160 return true;
[email protected]b1122982010-05-17 23:04:246161}
6162
[email protected]ac77603c72013-03-08 13:52:066163void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
6164 const VertexAttrib* attrib =
6165 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
6166 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6167 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:076168 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:246169 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066170 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6171 attrib->gl_stride(), ptr);
6172 if (attrib->divisor())
6173 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246174 glBindBuffer(
6175 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116176 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6177 : 0);
[email protected]43410e92012-04-20 17:06:286178
[email protected]265f8992012-07-20 01:03:146179 // Never touch vertex attribute 0's state (in particular, never
6180 // disable it) when running on desktop GL because it will never be
6181 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066182 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146183 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066184 if (attrib->enabled()) {
6185 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146186 } else {
[email protected]ac77603c72013-03-08 13:52:066187 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146188 }
[email protected]43410e92012-04-20 17:06:286189 }
[email protected]b1122982010-05-17 23:04:246190}
[email protected]07f54fcc2009-12-22 02:46:306191
[email protected]8fbedc02010-11-18 18:43:406192bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436193 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426194 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406195 DCHECK(simulated);
6196 *simulated = false;
6197 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6198 return true;
6199
[email protected]e259eb412012-10-13 05:47:246200 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406201 return true;
6202 }
6203
[email protected]ab09b612013-03-11 22:11:516204 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016205 "GL_FIXED attributes have a signficant performance penalty");
6206
[email protected]8fbedc02010-11-18 18:43:406207 // NOTE: we could be smart and try to check if a buffer is used
6208 // twice in 2 different attribs, find the overlapping parts and therefore
6209 // duplicate the minimum amount of data but this whole code path is not meant
6210 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6211 // tests so we just add to the buffer attrib used.
6212
[email protected]c13e1da62011-09-09 21:48:306213 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066214 const VertexAttribManager::VertexAttribList& enabled_attribs =
6215 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6216 for (VertexAttribManager::VertexAttribList::const_iterator it =
6217 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6218 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356219 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066220 state_.current_program->GetAttribInfoByLocation(attrib->index());
6221 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6222 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426223 GLuint num_vertices = max_accessed + 1;
6224 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516225 LOCAL_SET_GL_ERROR(
6226 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426227 return false;
6228 }
[email protected]8fbedc02010-11-18 18:43:406229 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066230 attrib->CanAccess(max_accessed) &&
6231 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476232 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066233 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476234 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516235 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436236 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406237 return false;
6238 }
6239 }
6240 }
6241
[email protected]3aad1a32012-09-07 20:54:476242 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6243 uint32 size_needed = 0;
6244 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306245 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516246 LOCAL_SET_GL_ERROR(
6247 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406248 return false;
6249 }
6250
[email protected]ab09b612013-03-11 22:11:516251 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406252
6253 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306254 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406255 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306256 GLenum error = glGetError();
6257 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516258 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436259 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306260 return false;
6261 }
[email protected]8fbedc02010-11-18 18:43:406262 }
6263
6264 // Copy the elements and convert to float
6265 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066266 for (VertexAttribManager::VertexAttribList::const_iterator it =
6267 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6268 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356269 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066270 state_.current_program->GetAttribInfoByLocation(attrib->index());
6271 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426272 max_vertex_accessed);
6273 GLuint num_vertices = max_accessed + 1;
6274 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516275 LOCAL_SET_GL_ERROR(
6276 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426277 return false;
6278 }
[email protected]8fbedc02010-11-18 18:43:406279 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066280 attrib->CanAccess(max_accessed) &&
6281 attrib->type() == GL_FIXED) {
6282 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406283 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556284 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406285 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066286 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406287 const int32* end = src + num_elements;
6288 float* dst = data.get();
6289 while (src != end) {
6290 *dst++ = static_cast<float>(*src++) / 65536.0f;
6291 }
6292 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6293 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066294 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406295 reinterpret_cast<GLvoid*>(offset));
6296 offset += size;
6297 }
6298 }
6299 *simulated = true;
6300 return true;
6301}
6302
6303void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6304 // There's no need to call glVertexAttribPointer because we shadow all the
6305 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246306 glBindBuffer(
6307 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116308 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6309 : 0);
[email protected]8fbedc02010-11-18 18:43:406310}
6311
[email protected]ad84a3a2012-06-08 21:42:436312error::Error GLES2DecoderImpl::DoDrawArrays(
6313 const char* function_name,
6314 bool instanced,
6315 GLenum mode,
6316 GLint first,
6317 GLsizei count,
6318 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226319 error::Error error = WillAccessBoundFramebufferForDraw();
6320 if (error != error::kNoError)
6321 return error;
[email protected]38d139d2011-07-14 00:38:436322 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516323 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436324 return error::kNoError;
6325 }
6326 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516327 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436328 return error::kNoError;
6329 }
[email protected]c6aef902012-02-14 03:31:426330 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516331 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426332 return error::kNoError;
6333 }
[email protected]ad84a3a2012-06-08 21:42:436334 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436335 return error::kNoError;
6336 }
6337 // We have to check this here because the prototype for glDrawArrays
6338 // is GLint not GLsizei.
6339 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516340 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436341 return error::kNoError;
6342 }
6343
[email protected]c6aef902012-02-14 03:31:426344 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:516345 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436346 return error::kNoError;
6347 }
6348
6349 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:436350 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206351 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516352 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206353 return error::kNoError;
6354 }
[email protected]c13e1da62011-09-09 21:48:306355 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436356 if (!SimulateAttrib0(
6357 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306358 return error::kNoError;
6359 }
[email protected]38d139d2011-07-14 00:38:436360 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436361 if (SimulateFixedAttribs(
6362 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6363 primcount)) {
[email protected]e56131d22013-07-28 16:14:116364 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436365 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:426366 if (!instanced) {
6367 glDrawArrays(mode, first, count);
6368 } else {
6369 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6370 }
[email protected]22e3f552012-03-13 01:54:196371 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:436372 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546373 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436374 }
6375 if (simulated_fixed_attribs) {
6376 RestoreStateForSimulatedFixedAttribs();
6377 }
6378 }
6379 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286380 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436381 }
[email protected]38d139d2011-07-14 00:38:436382 }
6383 return error::kNoError;
6384}
6385
[email protected]c6aef902012-02-14 03:31:426386error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356387 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436388 return DoDrawArrays("glDrawArrays",
6389 false,
[email protected]c6aef902012-02-14 03:31:426390 static_cast<GLenum>(c.mode),
6391 static_cast<GLint>(c.first),
6392 static_cast<GLsizei>(c.count),
6393 0);
6394}
6395
6396error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356397 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156398 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516399 LOCAL_SET_GL_ERROR(
6400 GL_INVALID_OPERATION,
6401 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426402 return error::kNoError;
6403 }
[email protected]ad84a3a2012-06-08 21:42:436404 return DoDrawArrays("glDrawArraysIntancedANGLE",
6405 true,
[email protected]c6aef902012-02-14 03:31:426406 static_cast<GLenum>(c.mode),
6407 static_cast<GLint>(c.first),
6408 static_cast<GLsizei>(c.count),
6409 static_cast<GLsizei>(c.primcount));
6410}
6411
[email protected]ad84a3a2012-06-08 21:42:436412error::Error GLES2DecoderImpl::DoDrawElements(
6413 const char* function_name,
6414 bool instanced,
6415 GLenum mode,
6416 GLsizei count,
6417 GLenum type,
6418 int32 offset,
6419 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226420 error::Error error = WillAccessBoundFramebufferForDraw();
6421 if (error != error::kNoError)
6422 return error;
[email protected]e259eb412012-10-13 05:47:246423 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516424 LOCAL_SET_GL_ERROR(
6425 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296426 return error::kNoError;
6427 }
6428
[email protected]8eee29c2010-04-29 03:38:296429 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516430 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296431 return error::kNoError;
6432 }
6433 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516434 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296435 return error::kNoError;
6436 }
[email protected]9438b012010-06-15 22:55:056437 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516438 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296439 return error::kNoError;
6440 }
[email protected]9438b012010-06-15 22:55:056441 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516442 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296443 return error::kNoError;
6444 }
[email protected]c6aef902012-02-14 03:31:426445 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516446 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426447 return error::kNoError;
6448 }
[email protected]8eee29c2010-04-29 03:38:296449
[email protected]ad84a3a2012-06-08 21:42:436450 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276451 return error::kNoError;
6452 }
6453
[email protected]c6aef902012-02-14 03:31:426454 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316455 return error::kNoError;
6456 }
6457
[email protected]8eee29c2010-04-29 03:38:296458 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086459 Buffer* element_array_buffer =
6460 state_.vertex_attrib_manager->element_array_buffer();
6461
6462 if (!element_array_buffer->GetMaxValueForRange(
6463 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516464 LOCAL_SET_GL_ERROR(
6465 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296466 return error::kNoError;
6467 }
6468
[email protected]ad84a3a2012-06-08 21:42:436469 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206470 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516471 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206472 return error::kNoError;
6473 }
[email protected]c13e1da62011-09-09 21:48:306474 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436475 if (!SimulateAttrib0(
6476 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306477 return error::kNoError;
6478 }
[email protected]8fbedc02010-11-18 18:43:406479 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436480 if (SimulateFixedAttribs(
6481 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6482 primcount)) {
[email protected]e56131d22013-07-28 16:14:116483 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466484 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086485 // TODO(gman): Refactor to hide these details in BufferManager or
6486 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406487 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086488 bool used_client_side_array = false;
6489 if (element_array_buffer->IsClientSideArray()) {
6490 used_client_side_array = true;
6491 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6492 indices = element_array_buffer->GetRange(offset, 0);
6493 }
6494
[email protected]c6aef902012-02-14 03:31:426495 if (!instanced) {
6496 glDrawElements(mode, count, type, indices);
6497 } else {
6498 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6499 }
[email protected]17cfbe0e2013-03-07 01:26:086500
6501 if (used_client_side_array) {
6502 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6503 element_array_buffer->service_id());
6504 }
6505
[email protected]22e3f552012-03-13 01:54:196506 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406507 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546508 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406509 }
6510 if (simulated_fixed_attribs) {
6511 RestoreStateForSimulatedFixedAttribs();
6512 }
[email protected]ba3176a2009-12-16 18:19:466513 }
[email protected]b1122982010-05-17 23:04:246514 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286515 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246516 }
[email protected]96449d2c2009-11-25 00:01:326517 }
[email protected]f7a64ee2010-02-01 22:24:146518 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326519}
6520
[email protected]c6aef902012-02-14 03:31:426521error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356522 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436523 return DoDrawElements("glDrawElements",
6524 false,
[email protected]c6aef902012-02-14 03:31:426525 static_cast<GLenum>(c.mode),
6526 static_cast<GLsizei>(c.count),
6527 static_cast<GLenum>(c.type),
6528 static_cast<int32>(c.index_offset),
6529 0);
6530}
6531
6532error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356533 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156534 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516535 LOCAL_SET_GL_ERROR(
6536 GL_INVALID_OPERATION,
6537 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426538 return error::kNoError;
6539 }
[email protected]ad84a3a2012-06-08 21:42:436540 return DoDrawElements("glDrawElementsInstancedANGLE",
6541 true,
[email protected]c6aef902012-02-14 03:31:426542 static_cast<GLenum>(c.mode),
6543 static_cast<GLsizei>(c.count),
6544 static_cast<GLenum>(c.type),
6545 static_cast<int32>(c.index_offset),
6546 static_cast<GLsizei>(c.primcount));
6547}
6548
[email protected]269200b12010-11-18 22:53:066549GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236550 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6551 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076552 Buffer* buffer = GetBuffer(buffer_id);
6553 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036554 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516555 LOCAL_SET_GL_ERROR(
6556 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236557 } else {
[email protected]b10492f2013-03-08 05:24:076558 if (!buffer->GetMaxValueForRange(
6559 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036560 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516561 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066562 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436563 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236564 }
6565 }
6566 return max_vertex_accessed;
6567}
6568
[email protected]96449d2c2009-11-25 00:01:326569// Calls glShaderSource for the various versions of the ShaderSource command.
6570// Assumes that data / data_size points to a piece of memory that is in range
6571// of whatever context it came from (shared memory, immediate memory, bucket
6572// memory.)
[email protected]45bf5152010-02-12 00:11:316573error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036574 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576575 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426576 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6577 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316578 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326579 }
[email protected]45bf5152010-02-12 00:11:316580 // Note: We don't actually call glShaderSource here. We wait until
6581 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426582 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146583 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326584}
6585
[email protected]f7a64ee2010-02-01 22:24:146586error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356587 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326588 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316589 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326590 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466591 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146592 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326593 }
[email protected]ae51d192010-04-27 00:48:036594 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326595}
6596
[email protected]558847a2010-03-24 07:02:546597error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356598 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546599 Bucket* bucket = GetBucket(c.data_bucket_id);
6600 if (!bucket || bucket->size() == 0) {
6601 return error::kInvalidArguments;
6602 }
6603 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036604 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546605 bucket->size() - 1);
6606}
6607
[email protected]ae51d192010-04-27 00:48:036608void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386609 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426610 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6611 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316612 return;
6613 }
[email protected]f57bb282010-11-12 00:51:346614 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186615 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426616 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456617 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416618 }
[email protected]de17df392010-04-23 21:09:416619
[email protected]b05955552014-02-06 18:41:186620 program_manager()->DoCompileShader(
6621 shader,
6622 translator,
6623 feature_info_->feature_flags().angle_translated_shader_source ?
6624 ProgramManager::kANGLE : ProgramManager::kGL);
[email protected]45bf5152010-02-12 00:11:316625};
6626
[email protected]ddd968b82010-03-02 00:44:296627void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426628 GLuint shader_id, GLenum pname, GLint* params) {
6629 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6630 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296631 return;
6632 }
[email protected]8f1ccdac2010-05-19 21:01:486633 switch (pname) {
6634 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426635 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486636 return;
6637 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426638 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416639 return;
[email protected]8f1ccdac2010-05-19 21:01:486640 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426641 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416642 return;
[email protected]d6a53e42011-10-05 00:09:366643 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426644 *params = shader->translated_source() ?
6645 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366646 return;
[email protected]8f1ccdac2010-05-19 21:01:486647 default:
6648 break;
[email protected]ddd968b82010-03-02 00:44:296649 }
[email protected]df37b9932013-03-08 05:21:426650 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296651}
6652
[email protected]ae51d192010-04-27 00:48:036653error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356654 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426655 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036656 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6657 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426658 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6659 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296660 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296661 return error::kNoError;
6662 }
[email protected]df37b9932013-03-08 05:21:426663 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036664 return error::kNoError;
6665}
6666
[email protected]d6a53e42011-10-05 00:09:366667error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6668 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356669 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426670 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366671 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6672 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426673 Shader* shader = GetShaderInfoNotProgram(
6674 shader_id, "glTranslatedGetShaderSourceANGLE");
6675 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366676 bucket->SetSize(0);
6677 return error::kNoError;
6678 }
6679
[email protected]df37b9932013-03-08 05:21:426680 bucket->SetFromString(shader->translated_source() ?
6681 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366682 return error::kNoError;
6683}
6684
[email protected]ae51d192010-04-27 00:48:036685error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356686 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426687 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586688 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6689 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426690 Program* program = GetProgramInfoNotShader(
6691 program_id, "glGetProgramInfoLog");
6692 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466693 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036694 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316695 }
[email protected]df37b9932013-03-08 05:21:426696 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036697 return error::kNoError;
6698}
6699
6700error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356701 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426702 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586703 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6704 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426705 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6706 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466707 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036708 return error::kNoError;
6709 }
[email protected]df37b9932013-03-08 05:21:426710 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036711 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326712}
6713
[email protected]d058bca2012-11-26 10:27:266714bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6715 return state_.GetEnabled(cap);
6716}
6717
[email protected]1958e0e2010-04-22 05:17:156718bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216719 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106720 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156721}
6722
6723bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356724 const Framebuffer* framebuffer =
6725 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106726 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156727}
6728
6729bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366730 // IsProgram is true for programs as soon as they are created, until they are
6731 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356732 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106733 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156734}
6735
6736bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356737 const Renderbuffer* renderbuffer =
6738 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106739 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156740}
6741
6742bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366743 // IsShader is true for shaders as soon as they are created, until they
6744 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356745 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106746 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156747}
6748
6749bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496750 const TextureRef* texture_ref = GetTexture(client_id);
6751 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036752}
6753
6754void GLES2DecoderImpl::DoAttachShader(
6755 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426756 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586757 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426758 if (!program) {
[email protected]ae51d192010-04-27 00:48:036759 return;
[email protected]1958e0e2010-04-22 05:17:156760 }
[email protected]df37b9932013-03-08 05:21:426761 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6762 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036763 return;
6764 }
[email protected]df37b9932013-03-08 05:21:426765 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516766 LOCAL_SET_GL_ERROR(
6767 GL_INVALID_OPERATION,
6768 "glAttachShader",
6769 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316770 return;
6771 }
[email protected]df37b9932013-03-08 05:21:426772 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036773}
6774
6775void GLES2DecoderImpl::DoDetachShader(
6776 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426777 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586778 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426779 if (!program) {
[email protected]ae51d192010-04-27 00:48:036780 return;
6781 }
[email protected]df37b9932013-03-08 05:21:426782 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6783 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036784 return;
6785 }
[email protected]df37b9932013-03-08 05:21:426786 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516787 LOCAL_SET_GL_ERROR(
6788 GL_INVALID_OPERATION,
6789 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226790 return;
6791 }
[email protected]df37b9932013-03-08 05:21:426792 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036793}
6794
6795void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426796 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586797 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426798 if (!program) {
[email protected]ae51d192010-04-27 00:48:036799 return;
6800 }
[email protected]df37b9932013-03-08 05:21:426801 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156802}
6803
[email protected]ac77603c72013-03-08 13:52:066804void GLES2DecoderImpl::GetVertexAttribHelper(
6805 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246806 switch (pname) {
6807 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066808 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246809 if (buffer && !buffer->IsDeleted()) {
6810 GLuint client_id;
6811 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6812 *params = client_id;
6813 }
6814 break;
6815 }
6816 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066817 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246818 break;
6819 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066820 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246821 break;
6822 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066823 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246824 break;
6825 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066826 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246827 break;
6828 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066829 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246830 break;
[email protected]c6aef902012-02-14 03:31:426831 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066832 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426833 break;
[email protected]ac77603c72013-03-08 13:52:066834 default:
6835 NOTREACHED();
6836 break;
6837 }
6838}
6839
6840void GLES2DecoderImpl::DoGetVertexAttribfv(
6841 GLuint index, GLenum pname, GLfloat* params) {
6842 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6843 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516844 LOCAL_SET_GL_ERROR(
6845 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066846 return;
6847 }
6848 switch (pname) {
6849 case GL_CURRENT_VERTEX_ATTRIB: {
6850 const Vec4& value = state_.attrib_values[index];
6851 params[0] = value.v[0];
6852 params[1] = value.v[1];
6853 params[2] = value.v[2];
6854 params[3] = value.v[3];
6855 break;
6856 }
6857 default: {
6858 GLint value = 0;
6859 GetVertexAttribHelper(attrib, pname, &value);
6860 *params = static_cast<GLfloat>(value);
6861 break;
6862 }
6863 }
6864}
6865
6866void GLES2DecoderImpl::DoGetVertexAttribiv(
6867 GLuint index, GLenum pname, GLint* params) {
6868 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6869 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516870 LOCAL_SET_GL_ERROR(
6871 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066872 return;
6873 }
6874 switch (pname) {
[email protected]af6380962012-11-29 23:24:136875 case GL_CURRENT_VERTEX_ATTRIB: {
6876 const Vec4& value = state_.attrib_values[index];
6877 params[0] = static_cast<GLint>(value.v[0]);
6878 params[1] = static_cast<GLint>(value.v[1]);
6879 params[2] = static_cast<GLint>(value.v[2]);
6880 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246881 break;
[email protected]af6380962012-11-29 23:24:136882 }
[email protected]b1122982010-05-17 23:04:246883 default:
[email protected]ac77603c72013-03-08 13:52:066884 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246885 break;
6886 }
6887}
6888
[email protected]af6380962012-11-29 23:24:136889bool GLES2DecoderImpl::SetVertexAttribValue(
6890 const char* function_name, GLuint index, const GLfloat* value) {
6891 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516892 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136893 return false;
[email protected]b1122982010-05-17 23:04:246894 }
[email protected]af6380962012-11-29 23:24:136895 Vec4& v = state_.attrib_values[index];
6896 v.v[0] = value[0];
6897 v.v[1] = value[1];
6898 v.v[2] = value[2];
6899 v.v[3] = value[3];
6900 return true;
6901}
6902
6903void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6904 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6905 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6906 glVertexAttrib1f(index, v0);
6907 }
[email protected]b1122982010-05-17 23:04:246908}
6909
6910void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136911 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6912 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6913 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246914 }
[email protected]b1122982010-05-17 23:04:246915}
6916
6917void GLES2DecoderImpl::DoVertexAttrib3f(
6918 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136919 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6920 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6921 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246922 }
[email protected]b1122982010-05-17 23:04:246923}
6924
6925void GLES2DecoderImpl::DoVertexAttrib4f(
6926 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136927 GLfloat v[4] = { v0, v1, v2, v3, };
6928 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6929 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246930 }
[email protected]b1122982010-05-17 23:04:246931}
6932
6933void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136934 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6935 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6936 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246937 }
[email protected]b1122982010-05-17 23:04:246938}
6939
6940void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136941 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6942 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6943 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246944 }
[email protected]b1122982010-05-17 23:04:246945}
6946
6947void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136948 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6949 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6950 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246951 }
[email protected]b1122982010-05-17 23:04:246952}
6953
6954void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136955 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6956 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246957 }
[email protected]b1122982010-05-17 23:04:246958}
6959
[email protected]f7a64ee2010-02-01 22:24:146960error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:356961 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466962
[email protected]7cd76fd2013-06-02 21:11:116963 if (!state_.bound_array_buffer.get() ||
6964 state_.bound_array_buffer->IsDeleted()) {
6965 if (state_.vertex_attrib_manager.get() ==
6966 default_vertex_attrib_manager_.get()) {
[email protected]ab09b612013-03-11 22:11:516967 LOCAL_SET_GL_ERROR(
6968 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:466969 return error::kNoError;
6970 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:516971 LOCAL_SET_GL_ERROR(
6972 GL_INVALID_VALUE,
6973 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:466974 return error::kNoError;
6975 }
[email protected]96449d2c2009-11-25 00:01:326976 }
[email protected]8eee29c2010-04-29 03:38:296977
6978 GLuint indx = c.indx;
6979 GLint size = c.size;
6980 GLenum type = c.type;
6981 GLboolean normalized = c.normalized;
6982 GLsizei stride = c.stride;
6983 GLsizei offset = c.offset;
6984 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056985 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516986 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296987 return error::kNoError;
6988 }
[email protected]9438b012010-06-15 22:55:056989 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:516990 LOCAL_SET_GL_ERROR(
6991 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296992 return error::kNoError;
6993 }
6994 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516995 LOCAL_SET_GL_ERROR(
6996 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296997 return error::kNoError;
6998 }
6999 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517000 LOCAL_SET_GL_ERROR(
7001 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297002 return error::kNoError;
7003 }
7004 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517005 LOCAL_SET_GL_ERROR(
7006 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297007 return error::kNoError;
7008 }
7009 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517010 LOCAL_SET_GL_ERROR(
7011 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297012 return error::kNoError;
7013 }
7014 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317015 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:297016 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:517017 LOCAL_SET_GL_ERROR(
7018 GL_INVALID_OPERATION,
7019 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317020 return error::kNoError;
7021 }
7022 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:517023 LOCAL_SET_GL_ERROR(
7024 GL_INVALID_OPERATION,
7025 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297026 return error::kNoError;
7027 }
[email protected]7cd76fd2013-06-02 21:11:117028 state_.vertex_attrib_manager
7029 ->SetAttribInfo(indx,
7030 state_.bound_array_buffer.get(),
7031 size,
7032 type,
7033 normalized,
7034 stride,
7035 stride != 0 ? stride : component_size * size,
7036 offset);
[email protected]8fbedc02010-11-18 18:43:407037 if (type != GL_FIXED) {
7038 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7039 }
[email protected]f7a64ee2010-02-01 22:24:147040 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327041}
7042
[email protected]43410e92012-04-20 17:06:287043void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7044 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247045 state_.viewport_x = x;
7046 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027047 state_.viewport_width = std::min(width, viewport_max_width_);
7048 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287049 glViewport(x, y, width, height);
7050}
7051
[email protected]c6aef902012-02-14 03:31:427052error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:357053 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:157054 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517055 LOCAL_SET_GL_ERROR(
7056 GL_INVALID_OPERATION,
7057 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427058 }
7059 GLuint index = c.index;
7060 GLuint divisor = c.divisor;
7061 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517062 LOCAL_SET_GL_ERROR(
7063 GL_INVALID_VALUE,
7064 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427065 return error::kNoError;
7066 }
7067
[email protected]e259eb412012-10-13 05:47:247068 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427069 index,
7070 divisor);
7071 glVertexAttribDivisorANGLE(index, divisor);
7072 return error::kNoError;
7073}
7074
[email protected]68586372013-12-11 01:27:597075template <typename pixel_data_type>
7076static void WriteAlphaData(
7077 void *pixels, uint32 row_count, uint32 channel_count,
7078 uint32 alpha_channel_index, uint32 unpadded_row_size,
7079 uint32 padded_row_size, pixel_data_type alpha_value) {
7080 DCHECK_GT(channel_count, 0U);
7081 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7082 uint32 unpadded_row_size_in_elements =
7083 unpadded_row_size / sizeof(pixel_data_type);
7084 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7085 uint32 padded_row_size_in_elements =
7086 padded_row_size / sizeof(pixel_data_type);
7087 pixel_data_type* dst =
7088 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7089 for (uint32 yy = 0; yy < row_count; ++yy) {
7090 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7091 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7092 *d = alpha_value;
7093 }
7094 dst += padded_row_size_in_elements;
7095 }
7096}
7097
[email protected]5a36dc132013-07-23 23:17:557098void GLES2DecoderImpl::FinishReadPixels(
7099 const cmds::ReadPixels& c,
7100 GLuint buffer) {
7101 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7102 GLsizei width = c.width;
7103 GLsizei height = c.height;
7104 GLenum format = c.format;
7105 GLenum type = c.type;
7106 typedef cmds::ReadPixels::Result Result;
7107 uint32 pixels_size;
7108 Result* result = NULL;
7109 if (c.result_shm_id != 0) {
7110 result = GetSharedMemoryAs<Result*>(
7111 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7112 if (!result) {
7113 if (buffer != 0) {
7114 glDeleteBuffersARB(1, &buffer);
7115 }
7116 return;
7117 }
7118 }
7119 GLES2Util::ComputeImageDataSizes(
7120 width, height, format, type, state_.pack_alignment, &pixels_size,
7121 NULL, NULL);
7122 void* pixels = GetSharedMemoryAs<void*>(
7123 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7124 if (!pixels) {
7125 if (buffer != 0) {
7126 glDeleteBuffersARB(1, &buffer);
7127 }
7128 return;
7129 }
7130
7131 if (buffer != 0) {
7132 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337133 void* data;
7134 if (features().map_buffer_range) {
7135 data = glMapBufferRange(
7136 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7137 } else {
7138 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7139 }
[email protected]5a36dc132013-07-23 23:17:557140 memcpy(pixels, data, pixels_size);
7141 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7142 // have to restore the state.
7143 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7144 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7145 glDeleteBuffersARB(1, &buffer);
7146 }
7147
7148 if (result != NULL) {
7149 *result = true;
7150 }
7151
7152 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7153 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7154 if ((channels_exist & 0x0008) == 0 &&
7155 workarounds().clear_alpha_in_readpixels) {
7156 // Set the alpha to 255 because some drivers are buggy in this regard.
7157 uint32 temp_size;
7158
7159 uint32 unpadded_row_size;
7160 uint32 padded_row_size;
7161 if (!GLES2Util::ComputeImageDataSizes(
7162 width, 2, format, type, state_.pack_alignment, &temp_size,
7163 &unpadded_row_size, &padded_row_size)) {
7164 return;
7165 }
[email protected]68586372013-12-11 01:27:597166
7167 uint32 channel_count = 0;
7168 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557169 switch (format) {
7170 case GL_RGBA:
7171 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597172 channel_count = 4;
7173 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557174 break;
[email protected]68586372013-12-11 01:27:597175 case GL_ALPHA:
7176 channel_count = 1;
7177 alpha_channel = 0;
7178 break;
7179 }
7180
7181 if (channel_count > 0) {
7182 switch (type) {
7183 case GL_UNSIGNED_BYTE:
7184 WriteAlphaData<uint8>(
7185 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7186 padded_row_size, 0xFF);
7187 break;
7188 case GL_FLOAT:
7189 WriteAlphaData<float>(
7190 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7191 padded_row_size, 1.0f);
7192 break;
7193 case GL_HALF_FLOAT:
7194 WriteAlphaData<uint16>(
7195 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7196 padded_row_size, 0x3C00);
7197 break;
[email protected]5a36dc132013-07-23 23:17:557198 }
[email protected]5a36dc132013-07-23 23:17:557199 }
7200 }
7201}
7202
7203
[email protected]f7a64ee2010-02-01 22:24:147204error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:357205 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]c76fe672013-12-13 23:30:227206 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7207 if (fbo_error != error::kNoError)
7208 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317209 GLint x = c.x;
7210 GLint y = c.y;
7211 GLsizei width = c.width;
7212 GLsizei height = c.height;
7213 GLenum format = c.format;
7214 GLenum type = c.type;
[email protected]5a36dc132013-07-23 23:17:557215 GLboolean async = c.async;
[email protected]57f223832010-03-19 01:57:567216 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517217 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567218 return error::kNoError;
7219 }
[email protected]ed9f9cd2013-02-27 21:12:357220 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187221 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347222 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247223 width, height, format, type, state_.pack_alignment, &pixels_size,
7224 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187225 return error::kOutOfBounds;
7226 }
[email protected]612d2f82009-12-08 20:49:317227 void* pixels = GetSharedMemoryAs<void*>(
7228 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107229 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147230 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467231 }
[email protected]de43f082013-04-02 01:16:107232 Result* result = NULL;
7233 if (c.result_shm_id != 0) {
7234 result = GetSharedMemoryAs<Result*>(
7235 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7236 if (!result) {
7237 return error::kOutOfBounds;
7238 }
7239 }
[email protected]a51788e2010-02-24 21:54:257240
[email protected]9438b012010-06-15 22:55:057241 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517242 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297243 return error::kNoError;
7244 }
[email protected]68586372013-12-11 01:27:597245 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517246 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127247 return error::kNoError;
7248 }
[email protected]68586372013-12-11 01:27:597249 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7250 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7251 // format and type are acceptable enums but not guaranteed to be supported
7252 // for this framebuffer. Have to ask gl if they are valid.
7253 GLint preferred_format = 0;
7254 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7255 GLint preferred_type = 0;
7256 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7257 if (format != static_cast<GLenum>(preferred_format) ||
7258 type != static_cast<GLenum>(preferred_type)) {
7259 LOCAL_SET_GL_ERROR(
7260 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7261 "with the current read framebuffer");
7262 return error::kNoError;
7263 }
7264 }
[email protected]57f223832010-03-19 01:57:567265 if (width == 0 || height == 0) {
7266 return error::kNoError;
7267 }
7268
[email protected]57f223832010-03-19 01:57:567269 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307270 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567271
[email protected]3aad1a32012-09-07 20:54:477272 int32 max_x;
7273 int32 max_y;
7274 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517275 LOCAL_SET_GL_ERROR(
7276 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147277 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317278 }
[email protected]57f223832010-03-19 01:57:567279
[email protected]0d6bfdc2011-11-02 01:32:207280 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7281 return error::kNoError;
7282 }
7283
[email protected]ab09b612013-03-11 22:11:517284 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel");
[email protected]a0b78dc2011-11-11 10:43:107285
7286 ScopedResolvedFrameBufferBinder binder(this, false, true);
7287
[email protected]d37231fa2010-04-09 21:16:027288 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567289 // The user requested an out of range area. Get the results 1 line
7290 // at a time.
7291 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347292 uint32 unpadded_row_size;
7293 uint32 padded_row_size;
7294 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247295 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347296 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517297 LOCAL_SET_GL_ERROR(
7298 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567299 return error::kNoError;
7300 }
7301
7302 GLint dest_x_offset = std::max(-x, 0);
7303 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347304 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247305 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7306 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517307 LOCAL_SET_GL_ERROR(
7308 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567309 return error::kNoError;
7310 }
7311
7312 // Copy each row into the larger dest rect.
7313 int8* dst = static_cast<int8*>(pixels);
7314 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027315 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567316 GLint read_width = read_end_x - read_x;
7317 for (GLint yy = 0; yy < height; ++yy) {
7318 GLint ry = y + yy;
7319
7320 // Clear the row.
7321 memset(dst, 0, unpadded_row_size);
7322
7323 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027324 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567325 glReadPixels(
7326 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7327 }
7328 dst += padded_row_size;
7329 }
7330 } else {
[email protected]5a36dc132013-07-23 23:17:557331 if (async && features().use_async_readpixels) {
7332 GLuint buffer;
7333 glGenBuffersARB(1, &buffer);
7334 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7335 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7336 GLenum error = glGetError();
7337 if (error == GL_NO_ERROR) {
7338 glReadPixels(x, y, width, height, format, type, 0);
7339 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7340 new FenceCallback()));
7341 WaitForReadPixels(base::Bind(
7342 &GLES2DecoderImpl::FinishReadPixels,
7343 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7344 <GLES2DecoderImpl>(this),
7345 c, buffer));
7346 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7347 return error::kNoError;
7348 }
7349 }
[email protected]57f223832010-03-19 01:57:567350 glReadPixels(x, y, width, height, format, type, pixels);
7351 }
[email protected]ab09b612013-03-11 22:11:517352 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257353 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107354 if (result != NULL) {
7355 *result = true;
7356 }
[email protected]5a36dc132013-07-23 23:17:557357 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257358 }
[email protected]4848b9f82011-03-10 18:37:567359
[email protected]f7a64ee2010-02-01 22:24:147360 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327361}
7362
[email protected]f7a64ee2010-02-01 22:24:147363error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:357364 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:197365 GLenum pname = c.pname;
7366 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057367 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517368 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127369 return error::kNoError;
7370 }
[email protected]222471d2011-11-30 18:06:397371 switch (pname) {
7372 case GL_PACK_ALIGNMENT:
7373 case GL_UNPACK_ALIGNMENT:
7374 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517375 LOCAL_SET_GL_ERROR(
7376 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397377 return error::kNoError;
7378 }
[email protected]164d6d52012-05-05 00:55:037379 break;
[email protected]0a1e9ad2012-05-04 21:13:037380 case GL_UNPACK_FLIP_Y_CHROMIUM:
7381 unpack_flip_y_ = (param != 0);
7382 return error::kNoError;
7383 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7384 unpack_premultiply_alpha_ = (param != 0);
7385 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177386 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7387 unpack_unpremultiply_alpha_ = (param != 0);
7388 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397389 default:
7390 break;
[email protected]b9849abf2009-11-25 19:13:197391 }
7392 glPixelStorei(pname, param);
7393 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437394 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247395 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437396 break;
7397 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427398 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437399 break;
7400 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247401 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437402 break;
7403 default:
7404 // Validation should have prevented us from getting here.
7405 NOTREACHED();
7406 break;
[email protected]b9849abf2009-11-25 19:13:197407 }
[email protected]f7a64ee2010-02-01 22:24:147408 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197409}
7410
[email protected]1c75a3702011-11-11 14:15:287411error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:357412 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:387413 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:457414 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:517415 LOCAL_SET_GL_ERROR(
7416 GL_INVALID_OPERATION,
7417 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287418 return error::kNoError;
7419 }
[email protected]8f9b8dd2013-09-12 18:05:137420 bool is_tracing;
7421 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7422 &is_tracing);
7423 if (is_tracing) {
7424 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7425 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7426 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7427 is_offscreen ? offscreen_size_ : surface_->GetSize());
7428 }
[email protected]7794d512012-04-17 20:36:497429 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287430 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497431 } else {
7432 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287433 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497434 }
[email protected]1c75a3702011-11-11 14:15:287435}
7436
[email protected]558847a2010-03-24 07:02:547437error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7438 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7439 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577440 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517441 LOCAL_SET_GL_ERROR(
7442 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577443 return error::kNoError;
7444 }
[email protected]df37b9932013-03-08 05:21:427445 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587446 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427447 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147448 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197449 }
[email protected]df37b9932013-03-08 05:21:427450 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517451 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437452 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257453 return error::kNoError;
7454 }
[email protected]b9849abf2009-11-25 19:13:197455 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547456 location_shm_id, location_shm_offset, sizeof(GLint));
7457 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147458 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197459 }
[email protected]558847a2010-03-24 07:02:547460 // Require the client to init this incase the context is lost and we are no
7461 // longer executing commands.
7462 if (*location != -1) {
7463 return error::kGenericError;
7464 }
[email protected]df37b9932013-03-08 05:21:427465 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147466 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197467}
7468
[email protected]558847a2010-03-24 07:02:547469error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357470 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547471 uint32 name_size = c.data_size;
7472 const char* name = GetSharedMemoryAs<const char*>(
7473 c.name_shm_id, c.name_shm_offset, name_size);
7474 if (!name) {
7475 return error::kOutOfBounds;
7476 }
7477 String name_str(name, name_size);
7478 return GetAttribLocationHelper(
7479 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7480}
7481
[email protected]558847a2010-03-24 07:02:547482error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357483 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547484 Bucket* bucket = GetBucket(c.name_bucket_id);
7485 if (!bucket) {
7486 return error::kInvalidArguments;
7487 }
7488 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187489 if (!bucket->GetAsString(&name_str)) {
7490 return error::kInvalidArguments;
7491 }
[email protected]558847a2010-03-24 07:02:547492 return GetAttribLocationHelper(
7493 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7494}
7495
7496error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7497 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7498 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577499 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517500 LOCAL_SET_GL_ERROR(
7501 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577502 return error::kNoError;
7503 }
[email protected]df37b9932013-03-08 05:21:427504 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587505 client_id, "glUniformLocation");
[email protected]df37b9932013-03-08 05:21:427506 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147507 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197508 }
[email protected]df37b9932013-03-08 05:21:427509 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517510 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437511 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257512 return error::kNoError;
7513 }
[email protected]b9849abf2009-11-25 19:13:197514 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547515 location_shm_id, location_shm_offset, sizeof(GLint));
7516 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147517 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197518 }
[email protected]558847a2010-03-24 07:02:547519 // Require the client to init this incase the context is lost an we are no
7520 // longer executing commands.
7521 if (*location != -1) {
7522 return error::kGenericError;
7523 }
[email protected]df37b9932013-03-08 05:21:427524 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147525 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197526}
7527
[email protected]f7a64ee2010-02-01 22:24:147528error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357529 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197530 uint32 name_size = c.data_size;
7531 const char* name = GetSharedMemoryAs<const char*>(
7532 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547533 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147534 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197535 }
7536 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547537 return GetUniformLocationHelper(
7538 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197539}
7540
[email protected]558847a2010-03-24 07:02:547541error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357542 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547543 Bucket* bucket = GetBucket(c.name_bucket_id);
7544 if (!bucket) {
7545 return error::kInvalidArguments;
7546 }
7547 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187548 if (!bucket->GetAsString(&name_str)) {
7549 return error::kInvalidArguments;
7550 }
[email protected]558847a2010-03-24 07:02:547551 return GetUniformLocationHelper(
7552 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197553}
7554
[email protected]ddd968b82010-03-02 00:44:297555error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357556 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297557 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057558 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517559 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297560 return error::kNoError;
7561 }
[email protected]959e9072013-09-20 16:58:387562 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:047563 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157564 switch (name) {
7565 case GL_VERSION:
7566 str = "OpenGL ES 2.0 Chromium";
7567 break;
7568 case GL_SHADING_LANGUAGE_VERSION:
7569 str = "OpenGL ES GLSL ES 1.0 Chromium";
7570 break;
[email protected]32939602012-05-09 06:25:167571 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:167572 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:387573 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7574 // They are used by WEBGL_debug_renderer_info.
7575 if (!force_webgl_glsl_validation_)
7576 str = "Chromium";
[email protected]32939602012-05-09 06:25:167577 break;
[email protected]1958e0e2010-04-22 05:17:157578 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047579 {
[email protected]70dc60932013-06-04 03:33:497580 // For WebGL contexts, strip out the OES derivatives and
7581 // EXT frag depth extensions if they have not been enabled.
7582 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047583 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497584 if (!derivatives_explicitly_enabled_) {
7585 size_t offset = extensions.find(kOESDerivativeExtension);
7586 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097587 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497588 std::string());
7589 }
7590 }
7591 if (!frag_depth_explicitly_enabled_) {
7592 size_t offset = extensions.find(kEXTFragDepthExtension);
7593 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097594 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497595 std::string());
7596 }
[email protected]f0d74742011-10-03 16:31:047597 }
[email protected]aff39ac82013-06-08 04:53:137598 if (!draw_buffers_explicitly_enabled_) {
7599 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7600 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097601 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137602 std::string());
7603 }
7604 }
[email protected]f0d74742011-10-03 16:31:047605 } else {
[email protected]6f5fac9d12012-06-26 21:02:457606 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047607 }
[email protected]6f5fac9d12012-06-26 21:02:457608 std::string surface_extensions = surface_->GetExtensions();
7609 if (!surface_extensions.empty())
7610 extensions += " " + surface_extensions;
7611 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047612 }
[email protected]1958e0e2010-04-22 05:17:157613 break;
7614 default:
[email protected]1958e0e2010-04-22 05:17:157615 break;
7616 }
[email protected]ddd968b82010-03-02 00:44:297617 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157618 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297619 return error::kNoError;
7620}
7621
[email protected]0c86dbf2010-03-05 08:14:117622error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357623 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117624 GLenum target = static_cast<GLenum>(c.target);
7625 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7626 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7627 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7628 GLenum usage = static_cast<GLenum>(c.usage);
7629 const void* data = NULL;
7630 if (data_shm_id != 0 || data_shm_offset != 0) {
7631 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7632 if (!data) {
7633 return error::kOutOfBounds;
7634 }
7635 }
[email protected]0fbba3732013-07-17 15:40:137636 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147637 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197638}
7639
[email protected]0c86dbf2010-03-05 08:14:117640void GLES2DecoderImpl::DoBufferSubData(
7641 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137642 // Just delegate it. Some validation is actually done before this.
7643 buffer_manager()->ValidateAndDoBufferSubData(
7644 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197645}
7646
[email protected]0d6bfdc2011-11-02 01:32:207647bool GLES2DecoderImpl::ClearLevel(
7648 unsigned service_id,
7649 unsigned bind_target,
7650 unsigned target,
7651 int level,
7652 unsigned format,
7653 unsigned type,
7654 int width,
[email protected]4502e6492011-12-14 19:39:157655 int height,
7656 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007657 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:007658 if (feature_info_->feature_flags().angle_depth_texture &&
7659 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:007660 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7661 // on depth formats.
7662 GLuint fb = 0;
7663 glGenFramebuffersEXT(1, &fb);
7664 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7665
7666 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7667 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7668 GL_DEPTH_ATTACHMENT;
7669
7670 glFramebufferTexture2DEXT(
7671 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7672 // ANGLE promises a depth only attachment ok.
7673 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7674 GL_FRAMEBUFFER_COMPLETE) {
7675 return false;
7676 }
7677 glClearStencil(0);
7678 glStencilMask(-1);
7679 glClearDepth(1.0f);
7680 glDepthMask(true);
7681 glDisable(GL_SCISSOR_TEST);
7682 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7683
7684 RestoreClearState();
7685
7686 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357687 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007688 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7689 GLuint fb_service_id =
7690 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7691 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7692 return true;
7693 }
7694
[email protected]45d15a62012-04-18 14:33:177695 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7696
7697 uint32 size;
7698 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347699 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247700 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177701 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207702 return false;
7703 }
[email protected]45d15a62012-04-18 14:33:177704
[email protected]a5d3dad2012-05-26 04:34:447705 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7706
[email protected]45d15a62012-04-18 14:33:177707 int tile_height;
7708
7709 if (size > kMaxZeroSize) {
7710 if (kMaxZeroSize < padded_row_size) {
7711 // That'd be an awfully large texture.
7712 return false;
7713 }
7714 // We should never have a large total size with a zero row size.
7715 DCHECK_GT(padded_row_size, 0U);
7716 tile_height = kMaxZeroSize / padded_row_size;
7717 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247718 width, tile_height, format, type, state_.unpack_alignment, &size,
7719 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177720 return false;
7721 }
[email protected]4502e6492011-12-14 19:39:157722 } else {
[email protected]45d15a62012-04-18 14:33:177723 tile_height = height;
7724 }
7725
7726 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557727 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177728 memset(zero.get(), 0, size);
7729 glBindTexture(bind_target, service_id);
7730
7731 GLint y = 0;
7732 while (y < height) {
7733 GLint h = y + tile_height > height ? height - y : tile_height;
7734 if (is_texture_immutable || h != height) {
7735 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7736 } else {
[email protected]8f1d2aa2013-05-10 23:45:387737 glTexImage2D(
[email protected]45d15a62012-04-18 14:33:177738 target, level, format, width, h, 0, format, type, zero.get());
7739 }
7740 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157741 }
[email protected]c986af502013-08-14 01:04:447742 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
7743 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:077744 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207745 return true;
7746}
7747
[email protected]ad84a3a2012-06-08 21:42:437748namespace {
7749
7750const int kS3TCBlockWidth = 4;
7751const int kS3TCBlockHeight = 4;
7752const int kS3TCDXT1BlockSize = 8;
7753const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077754const int kETC1BlockWidth = 4;
7755const int kETC1BlockHeight = 4;
7756const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437757
7758bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517759 return (size == 1) ||
7760 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437761}
7762
7763} // anonymous namespace.
7764
7765bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7766 const char* function_name,
7767 GLsizei width, GLsizei height, GLenum format, size_t size) {
7768 unsigned int bytes_required = 0;
7769
7770 switch (format) {
7771 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7772 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7773 int num_blocks_across =
7774 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7775 int num_blocks_down =
7776 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7777 int num_blocks = num_blocks_across * num_blocks_down;
7778 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7779 break;
7780 }
7781 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7782 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7783 int num_blocks_across =
7784 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7785 int num_blocks_down =
7786 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7787 int num_blocks = num_blocks_across * num_blocks_down;
7788 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7789 break;
7790 }
[email protected]2d3765b2012-10-03 00:31:077791 case GL_ETC1_RGB8_OES: {
7792 int num_blocks_across =
7793 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7794 int num_blocks_down =
7795 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7796 int num_blocks = num_blocks_across * num_blocks_down;
7797 bytes_required = num_blocks * kETC1BlockSize;
7798 break;
7799 }
[email protected]ad84a3a2012-06-08 21:42:437800 default:
[email protected]ab09b612013-03-11 22:11:517801 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437802 return false;
7803 }
7804
7805 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517806 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437807 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7808 return false;
7809 }
7810
7811 return true;
7812}
7813
7814bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7815 const char* function_name,
7816 GLint level, GLsizei width, GLsizei height, GLenum format) {
7817 switch (format) {
7818 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7819 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7820 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7821 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7822 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517823 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437824 GL_INVALID_OPERATION, function_name,
7825 "width or height invalid for level");
7826 return false;
7827 }
7828 return true;
7829 }
[email protected]2d3765b2012-10-03 00:31:077830 case GL_ETC1_RGB8_OES:
7831 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517832 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077833 GL_INVALID_OPERATION, function_name,
7834 "width or height invalid for level");
7835 return false;
7836 }
7837 return true;
[email protected]ad84a3a2012-06-08 21:42:437838 default:
7839 return false;
7840 }
7841}
7842
7843bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7844 const char* function_name,
7845 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7846 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357847 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437848 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517849 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437850 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7851 return false;
7852 }
7853
7854 switch (format) {
7855 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7856 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7857 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7858 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7859 const int kBlockWidth = 4;
7860 const int kBlockHeight = 4;
7861 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517862 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437863 GL_INVALID_OPERATION, function_name,
7864 "xoffset or yoffset not multiple of 4");
7865 return false;
7866 }
7867 GLsizei tex_width = 0;
7868 GLsizei tex_height = 0;
7869 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7870 width - xoffset > tex_width ||
7871 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517872 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437873 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7874 return false;
7875 }
7876 return ValidateCompressedTexDimensions(
7877 function_name, level, width, height, format);
7878 }
[email protected]2d3765b2012-10-03 00:31:077879 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517880 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077881 GL_INVALID_OPERATION, function_name,
7882 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7883 return false;
7884 }
[email protected]ad84a3a2012-06-08 21:42:437885 default:
7886 return false;
7887 }
7888}
7889
[email protected]a93bb842010-02-16 23:03:477890error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7891 GLenum target,
7892 GLint level,
7893 GLenum internal_format,
7894 GLsizei width,
7895 GLsizei height,
7896 GLint border,
7897 GLsizei image_size,
7898 const void* data) {
[email protected]a93bb842010-02-16 23:03:477899 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057900 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517901 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7902 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297903 return error::kNoError;
7904 }
[email protected]9438b012010-06-15 22:55:057905 if (!validators_->compressed_texture_format.IsValid(
7906 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517907 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537908 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477909 return error::kNoError;
7910 }
[email protected]80eb6b52012-01-19 00:14:417911 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477912 border != 0) {
[email protected]ab09b612013-03-11 22:11:517913 LOCAL_SET_GL_ERROR(
7914 GL_INVALID_VALUE,
7915 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477916 return error::kNoError;
7917 }
[email protected]c986af502013-08-14 01:04:447918 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7919 &state_, target);
[email protected]370eaf12013-05-18 09:19:497920 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517921 LOCAL_SET_GL_ERROR(
7922 GL_INVALID_VALUE,
7923 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477924 return error::kNoError;
7925 }
[email protected]370eaf12013-05-18 09:19:497926 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077927 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517928 LOCAL_SET_GL_ERROR(
7929 GL_INVALID_OPERATION,
7930 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:437931 return error::kNoError;
7932 }
7933
7934 if (!ValidateCompressedTexDimensions(
7935 "glCompressedTexImage2D", level, width, height, internal_format) ||
7936 !ValidateCompressedTexFuncData(
7937 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177938 return error::kNoError;
7939 }
[email protected]968351b2011-12-20 08:26:517940
[email protected]7989c9e2013-01-23 06:39:267941 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:517942 LOCAL_SET_GL_ERROR(
7943 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267944 return error::kNoError;
7945 }
7946
[email protected]02965c22013-03-09 02:40:077947 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:447948 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:517949 }
7950
[email protected]40d90a22013-04-09 03:39:557951 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:477952 if (!data) {
7953 zero.reset(new int8[image_size]);
7954 memset(zero.get(), 0, image_size);
7955 data = zero.get();
7956 }
[email protected]ab09b612013-03-11 22:11:517957 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:477958 glCompressedTexImage2D(
7959 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:517960 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437961 if (error == GL_NO_ERROR) {
7962 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497963 texture_ref, target, level, internal_format,
7964 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:437965 }
[email protected]a93bb842010-02-16 23:03:477966 return error::kNoError;
7967}
7968
[email protected]f7a64ee2010-02-01 22:24:147969error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357970 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:197971 GLenum target = static_cast<GLenum>(c.target);
7972 GLint level = static_cast<GLint>(c.level);
7973 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7974 GLsizei width = static_cast<GLsizei>(c.width);
7975 GLsizei height = static_cast<GLsizei>(c.height);
7976 GLint border = static_cast<GLint>(c.border);
7977 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7978 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7979 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7980 const void* data = NULL;
7981 if (data_shm_id != 0 || data_shm_offset != 0) {
7982 data = GetSharedMemoryAs<const void*>(
7983 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467984 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147985 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197986 }
7987 }
[email protected]a93bb842010-02-16 23:03:477988 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197989 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197990}
7991
[email protected]b6140d02010-05-17 14:47:167992error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:357993 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167994 GLenum target = static_cast<GLenum>(c.target);
7995 GLint level = static_cast<GLint>(c.level);
7996 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7997 GLsizei width = static_cast<GLsizei>(c.width);
7998 GLsizei height = static_cast<GLsizei>(c.height);
7999 GLint border = static_cast<GLint>(c.border);
8000 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288001 if (!bucket) {
8002 return error::kInvalidArguments;
8003 }
8004 uint32 data_size = bucket->size();
8005 GLsizei imageSize = data_size;
8006 const void* data = bucket->GetData(0, data_size);
8007 if (!data) {
8008 return error::kInvalidArguments;
8009 }
[email protected]b6140d02010-05-17 14:47:168010 return DoCompressedTexImage2D(
8011 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288012 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168013}
8014
8015error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8016 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358017 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:168018 GLenum target = static_cast<GLenum>(c.target);
8019 GLint level = static_cast<GLint>(c.level);
8020 GLint xoffset = static_cast<GLint>(c.xoffset);
8021 GLint yoffset = static_cast<GLint>(c.yoffset);
8022 GLsizei width = static_cast<GLsizei>(c.width);
8023 GLsizei height = static_cast<GLsizei>(c.height);
8024 GLenum format = static_cast<GLenum>(c.format);
8025 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288026 if (!bucket) {
8027 return error::kInvalidArguments;
8028 }
[email protected]b6140d02010-05-17 14:47:168029 uint32 data_size = bucket->size();
8030 GLsizei imageSize = data_size;
8031 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288032 if (!data) {
8033 return error::kInvalidArguments;
8034 }
[email protected]9438b012010-06-15 22:55:058035 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518036 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538037 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168038 return error::kNoError;
8039 }
[email protected]9438b012010-06-15 22:55:058040 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518041 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8042 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058043 return error::kNoError;
8044 }
[email protected]b6140d02010-05-17 14:47:168045 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518046 LOCAL_SET_GL_ERROR(
8047 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168048 return error::kNoError;
8049 }
8050 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518051 LOCAL_SET_GL_ERROR(
8052 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168053 return error::kNoError;
8054 }
8055 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518056 LOCAL_SET_GL_ERROR(
8057 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168058 return error::kNoError;
8059 }
[email protected]cadde4a2010-07-31 17:10:438060 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168061 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8062 return error::kNoError;
8063}
8064
[email protected]f7a64ee2010-02-01 22:24:148065error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358066 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388067 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]c986af502013-08-14 01:04:448068 // Set as failed for now, but if it successed, this will be set to not failed.
8069 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198070 GLenum target = static_cast<GLenum>(c.target);
8071 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448072 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8073 // for internalformat.
8074 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198075 GLsizei width = static_cast<GLsizei>(c.width);
8076 GLsizei height = static_cast<GLsizei>(c.height);
8077 GLint border = static_cast<GLint>(c.border);
8078 GLenum format = static_cast<GLenum>(c.format);
8079 GLenum type = static_cast<GLenum>(c.type);
8080 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8081 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188082 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348083 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248084 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348085 NULL)) {
[email protected]a76b0052010-03-05 00:33:188086 return error::kOutOfBounds;
8087 }
[email protected]b9849abf2009-11-25 19:13:198088 const void* pixels = NULL;
8089 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8090 pixels = GetSharedMemoryAs<const void*>(
8091 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468092 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148093 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198094 }
8095 }
[email protected]f598f422012-12-07 08:30:038096
[email protected]c986af502013-08-14 01:04:448097 TextureManager::DoTextImage2DArguments args = {
8098 target, level, internal_format, width, height, border, format, type,
8099 pixels, pixels_size};
8100 texture_manager()->ValidateAndDoTexImage2D(
8101 &texture_state_, &state_, &framebuffer_state_, args);
[email protected]f598f422012-12-07 08:30:038102 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198103}
8104
[email protected]cadde4a2010-07-31 17:10:438105void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8106 GLenum target,
8107 GLint level,
8108 GLint xoffset,
8109 GLint yoffset,
8110 GLsizei width,
8111 GLsizei height,
8112 GLenum format,
8113 GLsizei image_size,
8114 const void * data) {
[email protected]c986af502013-08-14 01:04:448115 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8116 &state_, target);
[email protected]370eaf12013-05-18 09:19:498117 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518118 LOCAL_SET_GL_ERROR(
8119 GL_INVALID_OPERATION,
8120 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438121 return;
8122 }
[email protected]370eaf12013-05-18 09:19:498123 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438124 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528125 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078126 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518127 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528128 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438129 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528130 return;
8131 }
8132 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518133 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528134 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438135 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528136 return;
8137 }
[email protected]02965c22013-03-09 02:40:078138 if (!texture->ValidForTexture(
[email protected]df6cf1ad2011-01-29 01:20:528139 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518140 LOCAL_SET_GL_ERROR(
8141 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438142 return;
8143 }
[email protected]ad84a3a2012-06-08 21:42:438144
8145 if (!ValidateCompressedTexFuncData(
8146 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8147 !ValidateCompressedTexSubDimensions(
8148 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078149 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438150 return;
8151 }
8152
8153
[email protected]0d6bfdc2011-11-02 01:32:208154 // Note: There is no need to deal with texture cleared tracking here
8155 // because the validation above means you can only get here if the level
8156 // is already a matching compressed format and in that case
8157 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438158 glCompressedTexSubImage2D(
8159 target, level, xoffset, yoffset, width, height, format, image_size, data);
8160}
8161
[email protected]6e288612010-12-21 20:45:038162static void Clip(
8163 GLint start, GLint range, GLint sourceRange,
8164 GLint* out_start, GLint* out_range) {
8165 DCHECK(out_start);
8166 DCHECK(out_range);
8167 if (start < 0) {
8168 range += start;
8169 start = 0;
8170 }
8171 GLint end = start + range;
8172 if (end > sourceRange) {
8173 range -= end - sourceRange;
8174 }
8175 *out_start = start;
8176 *out_range = range;
8177}
8178
[email protected]cadde4a2010-07-31 17:10:438179void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448180 GLenum target,
8181 GLint level,
8182 GLenum internal_format,
8183 GLint x,
8184 GLint y,
8185 GLsizei width,
8186 GLsizei height,
8187 GLint border) {
[email protected]09e17272012-11-30 10:30:448188 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448189 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8190 &state_, target);
[email protected]370eaf12013-05-18 09:19:498191 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518192 LOCAL_SET_GL_ERROR(
8193 GL_INVALID_OPERATION,
8194 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438195 return;
8196 }
[email protected]370eaf12013-05-18 09:19:498197 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078198 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518199 LOCAL_SET_GL_ERROR(
8200 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:178201 }
[email protected]80eb6b52012-01-19 00:14:418202 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188203 border != 0) {
[email protected]ab09b612013-03-11 22:11:518204 LOCAL_SET_GL_ERROR(
8205 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188206 return;
8207 }
[email protected]c986af502013-08-14 01:04:448208 if (!texture_manager()->ValidateTextureParameters(
8209 state_.GetErrorState(), "glCopyTexImage2D", target, internal_format,
8210 GL_UNSIGNED_BYTE, level)) {
[email protected]81375742012-06-08 00:04:008211 return;
8212 }
[email protected]f5719fb2010-08-04 18:27:188213
[email protected]9edc6b22010-12-23 02:00:268214 // Check we have compatible formats.
8215 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8216 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8217 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8218
8219 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518220 LOCAL_SET_GL_ERROR(
8221 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268222 return;
8223 }
8224
[email protected]81375742012-06-08 00:04:008225 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518226 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008227 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268228 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8229 return;
8230 }
8231
8232 uint32 estimated_size = 0;
8233 if (!GLES2Util::ComputeImageDataSizes(
8234 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8235 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518236 LOCAL_SET_GL_ERROR(
8237 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268238 return;
8239 }
8240
8241 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518242 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008243 return;
8244 }
8245
[email protected]a0b78dc2011-11-11 10:43:108246 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8247 return;
8248 }
8249
[email protected]ab09b612013-03-11 22:11:518250 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278251 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038252 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268253
[email protected]02965c22013-03-09 02:40:078254 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448255 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468256 }
8257
[email protected]9edc6b22010-12-23 02:00:268258 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038259 GLint copyX = 0;
8260 GLint copyY = 0;
8261 GLint copyWidth = 0;
8262 GLint copyHeight = 0;
8263 Clip(x, width, size.width(), &copyX, &copyWidth);
8264 Clip(y, height, size.height(), &copyY, &copyHeight);
8265
8266 if (copyX != x ||
8267 copyY != y ||
8268 copyWidth != width ||
8269 copyHeight != height) {
8270 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208271 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078272 texture->service_id(), texture->target(),
[email protected]4502e6492011-12-14 19:39:158273 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
[email protected]02965c22013-03-09 02:40:078274 texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518275 LOCAL_SET_GL_ERROR(
8276 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038277 return;
8278 }
[email protected]6e288612010-12-21 20:45:038279 if (copyHeight > 0 && copyWidth > 0) {
8280 GLint dx = copyX - x;
8281 GLint dy = copyY - y;
8282 GLint destX = dx;
8283 GLint destY = dy;
8284 glCopyTexSubImage2D(target, level,
8285 destX, destY, copyX, copyY,
8286 copyWidth, copyHeight);
8287 }
8288 } else {
8289 glCopyTexImage2D(target, level, internal_format,
8290 copyX, copyY, copyWidth, copyHeight, border);
8291 }
[email protected]ab09b612013-03-11 22:11:518292 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438293 if (error == GL_NO_ERROR) {
8294 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498295 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208296 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438297 }
8298}
8299
8300void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448301 GLenum target,
8302 GLint level,
8303 GLint xoffset,
8304 GLint yoffset,
8305 GLint x,
8306 GLint y,
8307 GLsizei width,
8308 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448309 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448310 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8311 &state_, target);
[email protected]370eaf12013-05-18 09:19:498312 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518313 LOCAL_SET_GL_ERROR(
8314 GL_INVALID_OPERATION,
8315 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438316 return;
8317 }
[email protected]370eaf12013-05-18 09:19:498318 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438319 GLenum type = 0;
8320 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078321 if (!texture->GetLevelType(target, level, &type, &format) ||
8322 !texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438323 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518324 LOCAL_SET_GL_ERROR(
8325 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438326 return;
8327 }
[email protected]85a4ac22013-05-31 01:58:478328 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518329 LOCAL_SET_GL_ERROR(
8330 GL_INVALID_OPERATION,
8331 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598332 return;
8333 }
[email protected]9edc6b22010-12-23 02:00:268334
8335 // Check we have compatible formats.
8336 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8337 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8338 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8339
[email protected]2d3765b2012-10-03 00:31:078340 if (!channels_needed ||
8341 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518342 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438343 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268344 return;
8345 }
8346
[email protected]81375742012-06-08 00:04:008347 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518348 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008349 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438350 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008351 return;
8352 }
8353
[email protected]a0b78dc2011-11-11 10:43:108354 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8355 return;
8356 }
8357
[email protected]de26b3c2011-08-03 21:54:278358 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038359 gfx::Size size = GetBoundReadFrameBufferSize();
8360 GLint copyX = 0;
8361 GLint copyY = 0;
8362 GLint copyWidth = 0;
8363 GLint copyHeight = 0;
8364 Clip(x, width, size.width(), &copyX, &copyWidth);
8365 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208366
[email protected]370eaf12013-05-18 09:19:498367 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518368 LOCAL_SET_GL_ERROR(
8369 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208370 return;
8371 }
8372
[email protected]6e288612010-12-21 20:45:038373 if (copyX != x ||
8374 copyY != y ||
8375 copyWidth != width ||
8376 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208377 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038378 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348379 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248380 width, height, format, type, state_.unpack_alignment, &pixels_size,
8381 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518382 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438383 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038384 return;
8385 }
[email protected]40d90a22013-04-09 03:39:558386 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038387 memset(zero.get(), 0, pixels_size);
8388 glTexSubImage2D(
8389 target, level, xoffset, yoffset, width, height,
8390 format, type, zero.get());
8391 }
[email protected]0d6bfdc2011-11-02 01:32:208392
[email protected]6e288612010-12-21 20:45:038393 if (copyHeight > 0 && copyWidth > 0) {
8394 GLint dx = copyX - x;
8395 GLint dy = copyY - y;
8396 GLint destX = xoffset + dx;
8397 GLint destY = yoffset + dy;
8398 glCopyTexSubImage2D(target, level,
8399 destX, destY, copyX, copyY,
8400 copyWidth, copyHeight);
8401 }
[email protected]cadde4a2010-07-31 17:10:438402}
8403
[email protected]f598f422012-12-07 08:30:038404bool GLES2DecoderImpl::ValidateTexSubImage2D(
8405 error::Error* error,
8406 const char* function_name,
8407 GLenum target,
8408 GLint level,
8409 GLint xoffset,
8410 GLint yoffset,
8411 GLsizei width,
8412 GLsizei height,
8413 GLenum format,
8414 GLenum type,
8415 const void * data) {
8416 (*error) = error::kNoError;
8417 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518418 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038419 return false;
8420 }
8421 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518422 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038423 return false;
8424 }
8425 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518426 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038427 return false;
8428 }
8429 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518430 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:038431 return false;
8432 }
8433 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518434 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:038435 return false;
8436 }
[email protected]c986af502013-08-14 01:04:448437 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8438 &state_, target);
[email protected]370eaf12013-05-18 09:19:498439 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518440 LOCAL_SET_GL_ERROR(
8441 GL_INVALID_OPERATION,
8442 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038443 return false;
[email protected]cadde4a2010-07-31 17:10:438444 }
[email protected]370eaf12013-05-18 09:19:498445 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528446 GLenum current_type = 0;
8447 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078448 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518449 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038450 GL_INVALID_OPERATION, function_name, "level does not exist.");
8451 return false;
[email protected]df6cf1ad2011-01-29 01:20:528452 }
8453 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:518454 LOCAL_SET_GL_ERROR(
8455 GL_INVALID_OPERATION,
8456 function_name, "format does not match internal format.");
[email protected]f598f422012-12-07 08:30:038457 return false;
[email protected]df6cf1ad2011-01-29 01:20:528458 }
8459 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518460 LOCAL_SET_GL_ERROR(
8461 GL_INVALID_OPERATION,
8462 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038463 return false;
[email protected]df6cf1ad2011-01-29 01:20:528464 }
[email protected]85a4ac22013-05-31 01:58:478465 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518466 LOCAL_SET_GL_ERROR(
8467 GL_INVALID_OPERATION,
8468 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598469 return false;
8470 }
[email protected]02965c22013-03-09 02:40:078471 if (!texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438472 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518473 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038474 return false;
[email protected]cadde4a2010-07-31 17:10:438475 }
[email protected]81375742012-06-08 00:04:008476 if ((GLES2Util::GetChannelsForFormat(format) &
8477 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518478 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008479 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038480 function_name, "can not supply data for depth or stencil textures");
8481 return false;
[email protected]81375742012-06-08 00:04:008482 }
[email protected]f598f422012-12-07 08:30:038483 if (data == NULL) {
8484 (*error) = error::kOutOfBounds;
8485 return false;
8486 }
8487 return true;
8488}
[email protected]81375742012-06-08 00:04:008489
[email protected]f598f422012-12-07 08:30:038490error::Error GLES2DecoderImpl::DoTexSubImage2D(
8491 GLenum target,
8492 GLint level,
8493 GLint xoffset,
8494 GLint yoffset,
8495 GLsizei width,
8496 GLsizei height,
8497 GLenum format,
8498 GLenum type,
8499 const void * data) {
8500 error::Error error = error::kNoError;
8501 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8502 xoffset, yoffset, width, height, format, type, data)) {
8503 return error;
8504 }
[email protected]c986af502013-08-14 01:04:448505 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8506 &state_, target);
[email protected]370eaf12013-05-18 09:19:498507 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158508 GLsizei tex_width = 0;
8509 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078510 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158511 DCHECK(ok);
8512 if (xoffset != 0 || yoffset != 0 ||
8513 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498514 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8515 target, level)) {
[email protected]ab09b612013-03-11 22:11:518516 LOCAL_SET_GL_ERROR(
8517 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038518 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308519 }
[email protected]c986af502013-08-14 01:04:448520 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158521 glTexSubImage2D(
8522 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038523 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208524 }
[email protected]4502e6492011-12-14 19:39:158525
[email protected]345ba902013-11-14 21:39:008526 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:448527 !texture->IsImmutable()) {
8528 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158529 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8530 // same as internal_foramt. If that changes we'll need to look them up.
[email protected]8f1d2aa2013-05-10 23:45:388531 glTexImage2D(
[email protected]4502e6492011-12-14 19:39:158532 target, level, format, width, height, 0, format, type, data);
8533 } else {
[email protected]c986af502013-08-14 01:04:448534 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158535 glTexSubImage2D(
8536 target, level, xoffset, yoffset, width, height, format, type, data);
8537 }
[email protected]370eaf12013-05-18 09:19:498538 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038539 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438540}
8541
[email protected]b493ee622011-04-13 23:52:008542error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358543 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388544 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008545 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448546 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008547 return error::kNoError;
8548
8549 GLenum target = static_cast<GLenum>(c.target);
8550 GLint level = static_cast<GLint>(c.level);
8551 GLint xoffset = static_cast<GLint>(c.xoffset);
8552 GLint yoffset = static_cast<GLint>(c.yoffset);
8553 GLsizei width = static_cast<GLsizei>(c.width);
8554 GLsizei height = static_cast<GLsizei>(c.height);
8555 GLenum format = static_cast<GLenum>(c.format);
8556 GLenum type = static_cast<GLenum>(c.type);
8557 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348558 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248559 width, height, format, type, state_.unpack_alignment, &data_size,
8560 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008561 return error::kOutOfBounds;
8562 }
8563 const void* pixels = GetSharedMemoryAs<const void*>(
8564 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038565 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008566 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008567}
8568
[email protected]f7a64ee2010-02-01 22:24:148569error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358570 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368571 GLuint index = static_cast<GLuint>(c.index);
8572 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358573 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258574 Result* result = GetSharedMemoryAs<Result*>(
8575 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368576 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148577 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368578 }
[email protected]07d0cc82010-02-17 04:51:408579 // Check that the client initialized the result.
8580 if (result->size != 0) {
8581 return error::kInvalidArguments;
8582 }
[email protected]9438b012010-06-15 22:55:058583 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518584 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8585 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148586 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368587 }
[email protected]3916c97e2010-02-25 03:20:508588 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518589 LOCAL_SET_GL_ERROR(
8590 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148591 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368592 }
[email protected]0bfd9882010-02-05 23:02:258593 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088594 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358595 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148596 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328597}
8598
[email protected]f7b85372010-02-03 01:11:378599bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428600 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378601 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128602 error::Error* error, GLint* real_location,
8603 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108604 DCHECK(error);
8605 DCHECK(service_id);
8606 DCHECK(result_pointer);
8607 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128608 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378609 *error = error::kNoError;
8610 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258611 SizedResult<GLint>* result;
8612 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8613 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8614 if (!result) {
[email protected]f7b85372010-02-03 01:11:378615 *error = error::kOutOfBounds;
8616 return false;
8617 }
[email protected]0bfd9882010-02-05 23:02:258618 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378619 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258620 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428621 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8622 if (!program) {
[email protected]ae51d192010-04-27 00:48:038623 return false;
8624 }
[email protected]df37b9932013-03-08 05:21:428625 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378626 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518627 LOCAL_SET_GL_ERROR(
8628 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378629 return false;
8630 }
[email protected]df37b9932013-03-08 05:21:428631 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368632 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358633 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428634 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128635 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368636 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378637 // No such location.
[email protected]ab09b612013-03-11 22:11:518638 LOCAL_SET_GL_ERROR(
8639 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378640 return false;
8641 }
[email protected]43c2f1f2011-03-25 18:35:368642 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508643 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378644 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518645 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378646 return false;
8647 }
[email protected]0bfd9882010-02-05 23:02:258648 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8649 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8650 if (!result) {
[email protected]f7b85372010-02-03 01:11:378651 *error = error::kOutOfBounds;
8652 return false;
8653 }
[email protected]0bfd9882010-02-05 23:02:258654 result->size = size;
[email protected]939e7362010-05-13 20:49:108655 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378656 return true;
8657}
8658
[email protected]f7a64ee2010-02-01 22:24:148659error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358660 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378661 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338662 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378663 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108664 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128665 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378666 Error error;
[email protected]0bfd9882010-02-05 23:02:258667 void* result;
[email protected]f7b85372010-02-03 01:11:378668 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128669 program, fake_location, c.params_shm_id, c.params_shm_offset,
8670 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258671 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128672 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358673 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378674 }
8675 return error;
[email protected]96449d2c2009-11-25 00:01:328676}
8677
[email protected]f7a64ee2010-02-01 22:24:148678error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358679 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378680 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338681 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378682 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128683 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378684 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358685 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108686 Result* result;
8687 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378688 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128689 program, fake_location, c.params_shm_id, c.params_shm_offset,
8690 &error, &real_location, &service_id,
8691 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108692 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8693 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8694 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558695 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128696 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108697 GLfloat* dst = result->GetData();
8698 for (GLsizei ii = 0; ii < num_values; ++ii) {
8699 dst[ii] = (temp[ii] != 0);
8700 }
8701 } else {
[email protected]1b0a6752012-02-22 03:44:128702 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108703 }
[email protected]f7b85372010-02-03 01:11:378704 }
8705 return error;
[email protected]96449d2c2009-11-25 00:01:328706}
8707
[email protected]f7a64ee2010-02-01 22:24:148708error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358709 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258710 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8711 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358712 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258713 Result* result = GetSharedMemoryAs<Result*>(
8714 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8715 if (!result) {
8716 return error::kOutOfBounds;
8717 }
[email protected]07d0cc82010-02-17 04:51:408718 // Check that the client initialized the result.
8719 if (result->success != 0) {
8720 return error::kInvalidArguments;
8721 }
[email protected]9438b012010-06-15 22:55:058722 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518723 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538724 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298725 return error::kNoError;
8726 }
[email protected]9438b012010-06-15 22:55:058727 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518728 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538729 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298730 return error::kNoError;
8731 }
8732
8733 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408734
[email protected]46c86752013-05-21 05:08:398735 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:408736 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218737 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408738
8739 result->min_range = range[0];
8740 result->max_range = range[1];
8741 result->precision = precision;
8742
[email protected]f7a64ee2010-02-01 22:24:148743 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328744}
8745
[email protected]f7a64ee2010-02-01 22:24:148746error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358747 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258748 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428749 GLuint program_id = static_cast<GLuint>(c.program);
8750 Program* program = GetProgramInfoNotShader(
8751 program_id, "glGetAttachedShaders");
8752 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258753 return error::kNoError;
8754 }
[email protected]ed9f9cd2013-02-27 21:12:358755 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258756 uint32 max_count = Result::ComputeMaxResults(result_size);
8757 Result* result = GetSharedMemoryAs<Result*>(
8758 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8759 if (!result) {
8760 return error::kOutOfBounds;
8761 }
[email protected]07d0cc82010-02-17 04:51:408762 // Check that the client initialized the result.
8763 if (result->size != 0) {
8764 return error::kInvalidArguments;
8765 }
[email protected]0bfd9882010-02-05 23:02:258766 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038767 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428768 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258769 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038770 if (!shader_manager()->GetClientId(result->GetData()[ii],
8771 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258772 NOTREACHED();
8773 return error::kGenericError;
8774 }
8775 }
8776 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148777 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328778}
8779
[email protected]f7a64ee2010-02-01 22:24:148780error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358781 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428782 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258783 GLuint index = c.index;
8784 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358785 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258786 Result* result = GetSharedMemoryAs<Result*>(
8787 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8788 if (!result) {
8789 return error::kOutOfBounds;
8790 }
[email protected]07d0cc82010-02-17 04:51:408791 // Check that the client initialized the result.
8792 if (result->success != 0) {
8793 return error::kInvalidArguments;
8794 }
[email protected]df37b9932013-03-08 05:21:428795 Program* program = GetProgramInfoNotShader(
8796 program_id, "glGetActiveUniform");
8797 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258798 return error::kNoError;
8799 }
[email protected]ed9f9cd2013-02-27 21:12:358800 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428801 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258802 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518803 LOCAL_SET_GL_ERROR(
8804 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258805 return error::kNoError;
8806 }
8807 result->success = 1; // true.
8808 result->size = uniform_info->size;
8809 result->type = uniform_info->type;
8810 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298811 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148812 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328813}
8814
[email protected]f7a64ee2010-02-01 22:24:148815error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358816 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428817 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258818 GLuint index = c.index;
8819 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358820 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258821 Result* result = GetSharedMemoryAs<Result*>(
8822 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8823 if (!result) {
8824 return error::kOutOfBounds;
8825 }
[email protected]07d0cc82010-02-17 04:51:408826 // Check that the client initialized the result.
8827 if (result->success != 0) {
8828 return error::kInvalidArguments;
8829 }
[email protected]df37b9932013-03-08 05:21:428830 Program* program = GetProgramInfoNotShader(
8831 program_id, "glGetActiveAttrib");
8832 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258833 return error::kNoError;
8834 }
[email protected]ed9f9cd2013-02-27 21:12:358835 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428836 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258837 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518838 LOCAL_SET_GL_ERROR(
8839 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258840 return error::kNoError;
8841 }
8842 result->success = 1; // true.
8843 result->size = attrib_info->size;
8844 result->type = attrib_info->type;
8845 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298846 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148847 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328848}
8849
[email protected]b273e432010-04-12 17:23:588850error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358851 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588852#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518853 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588854 return error::kNoError;
8855#else
8856 GLsizei n = static_cast<GLsizei>(c.n);
8857 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518858 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588859 return error::kNoError;
8860 }
8861 GLsizei length = static_cast<GLsizei>(c.length);
8862 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518863 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588864 return error::kNoError;
8865 }
8866 uint32 data_size;
8867 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8868 return error::kOutOfBounds;
8869 }
8870 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8871 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8872 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8873 const void* binary = GetSharedMemoryAs<const void*>(
8874 c.binary_shm_id, c.binary_shm_offset, length);
8875 if (shaders == NULL || binary == NULL) {
8876 return error::kOutOfBounds;
8877 }
8878 scoped_array<GLuint> service_ids(new GLuint[n]);
8879 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428880 Shader* shader = GetShader(shaders[ii]);
8881 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518882 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588883 return error::kNoError;
8884 }
[email protected]df37b9932013-03-08 05:21:428885 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588886 }
8887 // TODO(gman): call glShaderBinary
8888 return error::kNoError;
8889#endif
8890}
8891
[email protected]6d792ee12013-05-15 00:40:568892void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:498893 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088894
[email protected]64ace852011-05-19 21:49:498895 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428896 // TRACE_EVENT for gpu tests:
8897 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428898 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428899 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8900 "width", (is_offscreen ? offscreen_size_.width() :
8901 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:568902 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:498903 "offscreen", is_offscreen,
8904 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:158905 {
8906 TRACE_EVENT_SYNTHETIC_DELAY("gpu.SwapBuffers");
8907 }
8908
[email protected]8f9b8dd2013-09-12 18:05:138909 bool is_tracing;
8910 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8911 &is_tracing);
8912 if (is_tracing) {
8913 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8914 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8915 is_offscreen ? offscreen_size_ : surface_->GetSize());
8916 }
8917
[email protected]6217d392010-03-25 22:08:358918 // If offscreen then don't actually SwapBuffers to the display. Just copy
8919 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498920 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318921 TRACE_EVENT2("gpu", "Offscreen",
8922 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538923 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8924 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8925 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8926 // fix this.
[email protected]62e155e2012-10-23 22:43:158927 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538928 offscreen_saved_frame_buffer_->Create();
8929 glFinish();
8930 }
8931
8932 // Allocate the offscreen saved color texture.
8933 DCHECK(offscreen_saved_color_format_);
8934 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098935 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538936
8937 offscreen_saved_frame_buffer_->AttachRenderTexture(
8938 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:058939 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
8940 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8941 GL_FRAMEBUFFER_COMPLETE) {
8942 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8943 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:568944 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
8945 return;
[email protected]f0cfe752013-01-14 01:09:058946 }
[email protected]1fb8c482011-08-31 01:01:538947
[email protected]f0cfe752013-01-14 01:09:058948 // Clear the offscreen color texture.
8949 // TODO(piman): Is this still necessary?
8950 {
8951 ScopedFrameBufferBinder binder(this,
8952 offscreen_saved_frame_buffer_->id());
8953 glClearColor(0, 0, 0, 0);
8954 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8955 glDisable(GL_SCISSOR_TEST);
8956 glClear(GL_COLOR_BUFFER_BIT);
8957 RestoreClearState();
8958 }
[email protected]1fb8c482011-08-31 01:01:538959 }
8960
8961 UpdateParentTextureInfo();
8962 }
8963
[email protected]f0cfe752013-01-14 01:09:058964 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:568965 return;
[email protected]ab09b612013-03-11 22:11:518966 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:308967 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:358968
[email protected]34ff8b0c2010-10-01 20:06:028969 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138970 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278971 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:488972 } else {
[email protected]069944672012-04-25 20:52:238973 ScopedFrameBufferBinder binder(this,
8974 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138975
[email protected]069944672012-04-25 20:52:238976 if (offscreen_target_buffer_preserved_) {
8977 // Copy the target frame buffer to the saved offscreen texture.
8978 offscreen_saved_color_texture_->Copy(
8979 offscreen_saved_color_texture_->size(),
8980 offscreen_saved_color_format_);
8981 } else {
8982 // Flip the textures in the parent context via the texture manager.
8983 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:498984 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:238985 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568986
[email protected]069944672012-04-25 20:52:238987 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8988 offscreen_target_frame_buffer_->AttachRenderTexture(
8989 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488990 }
[email protected]069944672012-04-25 20:52:238991
8992 // Ensure the side effects of the copy are visible to the parent
8993 // context. There is no need to do this for ANGLE because it uses a
8994 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:188995 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:238996 glFlush();
[email protected]0c8c9d22010-06-25 17:36:398997 }
[email protected]6217d392010-03-25 22:08:358998 } else {
[email protected]f62a5ab2011-05-23 20:34:158999 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019000 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569001 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019002 }
[email protected]6217d392010-03-25 22:08:359003 }
[email protected]6217d392010-03-25 22:08:359004}
9005
[email protected]d4239852011-08-12 04:51:229006error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359007 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:189008 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289009 if (!bucket || bucket->size() == 0) {
9010 return error::kInvalidArguments;
9011 }
[email protected]ed9f9cd2013-02-27 21:12:359012 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189013 Result* result = GetSharedMemoryAs<Result*>(
9014 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9015 if (!result) {
9016 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109017 }
[email protected]b1d2dcb2010-05-17 19:24:189018 // Check that the client initialized the result.
9019 if (*result != 0) {
9020 return error::kInvalidArguments;
9021 }
9022 std::string feature_str;
9023 if (!bucket->GetAsString(&feature_str)) {
9024 return error::kInvalidArguments;
9025 }
9026
9027 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229028 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189029 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229030 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409031 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9032 // TODO(gman): decide how to remove the need for this const_cast.
9033 // I could make validators_ non const but that seems bad as this is the only
9034 // place it is needed. I could make some special friend class of validators
9035 // just to allow this to set them. That seems silly. I could refactor this
9036 // code to use the extension mechanism or the initialization attributes to
9037 // turn this feature on. Given that the only real point of this is to make
9038 // the conformance tests pass and given that there is lots of real work that
9039 // needs to be done it seems like refactoring for one to one of those
9040 // methods is a very low priority.
9041 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049042 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9043 force_webgl_glsl_validation_ = true;
9044 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189045 } else {
9046 return error::kNoError;
9047 }
9048
9049 *result = 1; // true.
9050 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109051}
9052
[email protected]c2f8c8402010-12-06 18:07:249053error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9054 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359055 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249056 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359057 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199058 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249059 bucket->SetFromString(info->extensions().c_str());
9060 return error::kNoError;
9061}
9062
9063error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359064 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249065 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289066 if (!bucket || bucket->size() == 0) {
9067 return error::kInvalidArguments;
9068 }
[email protected]c2f8c8402010-12-06 18:07:249069 std::string feature_str;
9070 if (!bucket->GetAsString(&feature_str)) {
9071 return error::kInvalidArguments;
9072 }
9073
[email protected]4b7eba92013-01-08 02:23:569074 bool desire_webgl_glsl_validation =
9075 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9076 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499077 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139078 bool desire_draw_buffers = false;
[email protected]4b7eba92013-01-08 02:23:569079 if (force_webgl_glsl_validation_) {
9080 desire_standard_derivatives =
9081 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499082 desire_frag_depth =
9083 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139084 desire_draw_buffers =
9085 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049086 }
9087
[email protected]4b7eba92013-01-08 02:23:569088 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499089 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139090 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9091 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499092 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9093 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9094 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139095 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]c2f8c8402010-12-06 18:07:249096 InitializeShaderTranslator();
9097 }
9098
[email protected]302ce6d2011-07-07 23:28:119099 UpdateCapabilities();
9100
[email protected]c2f8c8402010-12-06 18:07:249101 return error::kNoError;
9102}
9103
[email protected]372e0412011-06-28 16:08:569104error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359105 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:569106 GLuint count = c.count;
9107 uint32 pnames_size;
9108 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9109 return error::kOutOfBounds;
9110 }
9111 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9112 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9113 if (pnames == NULL) {
9114 return error::kOutOfBounds;
9115 }
9116
9117 // We have to copy them since we use them twice so the client
9118 // can't change them between the time we validate them and the time we use
9119 // them.
[email protected]40d90a22013-04-09 03:39:559120 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:569121 memcpy(enums.get(), pnames, pnames_size);
9122
9123 // Count up the space needed for the result.
9124 uint32 num_results = 0;
9125 for (GLuint ii = 0; ii < count; ++ii) {
9126 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9127 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519128 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9129 "glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569130 return error::kNoError;
9131 }
9132 // Num will never be more than 4.
9133 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479134 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569135 return error::kOutOfBounds;
9136 }
9137 }
9138
9139 uint32 result_size = 0;
9140 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9141 return error::kOutOfBounds;
9142 }
9143
9144 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519145 LOCAL_SET_GL_ERROR(
9146 GL_INVALID_VALUE,
9147 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569148 return error::kNoError;
9149 }
9150
9151 GLint* results = GetSharedMemoryAs<GLint*>(
9152 c.results_shm_id, c.results_shm_offset, result_size);
9153 if (results == NULL) {
9154 return error::kOutOfBounds;
9155 }
9156
9157 // Check the results have been cleared in case the context was lost.
9158 for (uint32 ii = 0; ii < num_results; ++ii) {
9159 if (results[ii]) {
9160 return error::kInvalidArguments;
9161 }
9162 }
9163
9164 // Get each result.
9165 GLint* start = results;
9166 for (GLuint ii = 0; ii < count; ++ii) {
9167 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269168 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539169 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:489170 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:569171 }
9172 results += num_written;
9173 }
9174
9175 // Just to verify. Should this be a DCHECK?
9176 if (static_cast<uint32>(results - start) != num_results) {
9177 return error::kOutOfBounds;
9178 }
9179
9180 return error::kNoError;
9181}
9182
[email protected]2318d342011-07-11 22:27:429183error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359184 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:429185 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429186 uint32 bucket_id = c.bucket_id;
9187 Bucket* bucket = CreateBucket(bucket_id);
9188 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429189 Program* program = NULL;
9190 program = GetProgram(program_id);
9191 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469192 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429193 }
[email protected]df37b9932013-03-08 05:21:429194 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429195 return error::kNoError;
9196}
9197
[email protected]38d139d2011-07-14 00:38:439198error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9199 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439200 case GL_NO_ERROR:
9201 // TODO(kbr): improve the precision of the error code in this case.
9202 // Consider delegating to context for error code if MakeCurrent fails.
9203 return error::kUnknown;
9204 case GL_GUILTY_CONTEXT_RESET_ARB:
9205 return error::kGuilty;
9206 case GL_INNOCENT_CONTEXT_RESET_ARB:
9207 return error::kInnocent;
9208 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9209 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439210 }
9211
9212 NOTREACHED();
9213 return error::kUnknown;
9214}
9215
9216bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099217 if (reset_status_ != GL_NO_ERROR) {
9218 return true;
9219 }
[email protected]706b69f2012-07-27 04:59:309220 if (context_->WasAllocatedUsingRobustnessExtension()) {
9221 GLenum status = GL_NO_ERROR;
9222 if (has_robustness_extension_)
9223 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439224 if (status != GL_NO_ERROR) {
9225 // The graphics card was reset. Signal a lost context to the application.
9226 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229227 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439228 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099229 << " context lost via ARB/EXT_robustness. Reset status = "
9230 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439231 return true;
9232 }
9233 }
9234 return false;
9235}
9236
[email protected]93a7d98f2013-07-11 00:04:229237bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9238 return WasContextLost() && reset_by_robustness_extension_;
9239}
9240
[email protected]c4485aad62012-12-17 10:19:099241void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9242 // Only loses the context once.
9243 if (reset_status_ != GL_NO_ERROR) {
9244 return;
9245 }
9246
9247 // Marks this context as lost.
9248 reset_status_ = reset_status;
9249 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099250}
9251
9252error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359253 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099254 GLenum current = static_cast<GLenum>(c.current);
9255 GLenum other = static_cast<GLenum>(c.other);
9256 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519257 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9258 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099259 }
9260 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519261 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099262 }
9263 group_->LoseContexts(other);
9264 reset_status_ = current;
9265 current_decoder_error_ = error::kLostContext;
9266 return error::kLostContext;
9267}
9268
[email protected]b096d032013-03-08 03:08:019269error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9270 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9271 return error::kUnknownCommand;
9272}
9273
[email protected]840a7e462013-02-27 01:29:519274error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359275 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:519276 if (wait_sync_point_callback_.is_null())
9277 return error::kNoError;
9278
9279 return wait_sync_point_callback_.Run(c.sync_point) ?
9280 error::kNoError : error::kDeferCommandUntilLater;
9281}
9282
[email protected]5dfc457b2013-12-13 11:13:079283error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
9284 uint32 immediate_data_size, const cmds::DiscardBackbufferCHROMIUM& c) {
9285 if (surface_->DeferDraws())
9286 return error::kDeferCommandUntilLater;
9287 if (!surface_->SetBackbufferAllocation(false))
9288 return error::kLostContext;
9289 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9290 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9291 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9292 return error::kNoError;
9293}
9294
[email protected]882ba1e22012-03-08 19:02:539295bool GLES2DecoderImpl::GenQueriesEXTHelper(
9296 GLsizei n, const GLuint* client_ids) {
9297 for (GLsizei ii = 0; ii < n; ++ii) {
9298 if (query_manager_->GetQuery(client_ids[ii])) {
9299 return false;
9300 }
9301 }
[email protected]c45f1972012-03-14 07:27:369302 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539303 return true;
9304}
9305
9306void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9307 GLsizei n, const GLuint* client_ids) {
9308 for (GLsizei ii = 0; ii < n; ++ii) {
9309 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9310 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139311 ContextState::QueryMap::iterator it =
9312 state_.current_queries.find(query->target());
9313 if (it != state_.current_queries.end())
9314 state_.current_queries.erase(it);
9315
[email protected]c45f1972012-03-14 07:27:369316 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539317 query_manager_->RemoveQuery(client_ids[ii]);
9318 }
9319 }
9320}
9321
[email protected]22e3f552012-03-13 01:54:199322bool GLES2DecoderImpl::ProcessPendingQueries() {
9323 if (query_manager_.get() == NULL) {
9324 return false;
9325 }
[email protected]c45f1972012-03-14 07:27:369326 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199327 current_decoder_error_ = error::kOutOfBounds;
9328 }
9329 return query_manager_->HavePendingQueries();
9330}
9331
[email protected]5a36dc132013-07-23 23:17:559332// Note that if there are no pending readpixels right now,
9333// this function will call the callback immediately.
9334void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9335 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9336 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9337 } else {
9338 callback.Run();
9339 }
9340}
9341
9342void GLES2DecoderImpl::ProcessPendingReadPixels() {
9343 while (!pending_readpixel_fences_.empty() &&
9344 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9345 std::vector<base::Closure> callbacks =
9346 pending_readpixel_fences_.front()->callbacks;
9347 pending_readpixel_fences_.pop();
9348 for (size_t i = 0; i < callbacks.size(); i++) {
9349 callbacks[i].Run();
9350 }
9351 }
9352}
9353
[email protected]2b1767cf2013-03-16 09:25:059354bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559355 return !pending_readpixel_fences_.empty() ||
9356 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059357}
9358
9359void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559360 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:489361 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059362 return;
[email protected]b68b100752013-06-05 08:34:489363 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059364 ProcessFinishedAsyncTransfers();
9365}
9366
[email protected]882ba1e22012-03-08 19:02:539367error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359368 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539369 GLenum target = static_cast<GLenum>(c.target);
9370 GLuint client_id = static_cast<GLuint>(c.id);
9371 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9372 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9373
[email protected]c45f1972012-03-14 07:27:369374 switch (target) {
9375 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559376 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:319377 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9378 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009379 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369380 break;
9381 default:
[email protected]62e155e2012-10-23 22:43:159382 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519383 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009384 GL_INVALID_OPERATION, "glBeginQueryEXT",
9385 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369386 return error::kNoError;
9387 }
9388 break;
[email protected]882ba1e22012-03-08 19:02:539389 }
9390
[email protected]8ebd46c2014-01-08 12:06:139391 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519392 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439393 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539394 return error::kNoError;
9395 }
9396
9397 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519398 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539399 return error::kNoError;
9400 }
9401
9402 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9403 if (!query) {
[email protected]c45f1972012-03-14 07:27:369404 // TODO(gman): Decide if we need this check.
9405 //
[email protected]882ba1e22012-03-08 19:02:539406 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369407 //
9408 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9409 // for all Query ids but from the POV of the command buffer service maybe
9410 // you don't.
9411 //
9412 // The client can enforce this. I don't think the service cares.
9413 //
9414 // IdAllocatorInterface* id_allocator =
9415 // group_->GetIdAllocator(id_namespaces::kQueries);
9416 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519417 // LOCAL_SET_GL_ERROR(
9418 // GL_INVALID_OPERATION,
9419 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369420 // return error::kNoError;
9421 // }
9422 query = query_manager_->CreateQuery(
9423 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539424 }
9425
[email protected]c45f1972012-03-14 07:27:369426 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519427 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439428 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539429 return error::kNoError;
9430 } else if (query->shm_id() != sync_shm_id ||
9431 query->shm_offset() != sync_shm_offset) {
9432 DLOG(ERROR) << "Shared memory used by query not the same as before";
9433 return error::kInvalidArguments;
9434 }
9435
[email protected]c45f1972012-03-14 07:27:369436 if (!query_manager_->BeginQuery(query)) {
9437 return error::kOutOfBounds;
9438 }
[email protected]882ba1e22012-03-08 19:02:539439
[email protected]8ebd46c2014-01-08 12:06:139440 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:539441 return error::kNoError;
9442}
9443
9444error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359445 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539446 GLenum target = static_cast<GLenum>(c.target);
9447 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:139448 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:539449
[email protected]8ebd46c2014-01-08 12:06:139450 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519451 LOCAL_SET_GL_ERROR(
9452 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539453 return error::kNoError;
9454 }
[email protected]882ba1e22012-03-08 19:02:539455
[email protected]8ebd46c2014-01-08 12:06:139456 QueryManager::Query* query = it->second.get();
9457 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369458 return error::kOutOfBounds;
9459 }
9460
[email protected]fe8d73c2013-02-16 22:37:329461 query_manager_->ProcessPendingTransferQueries();
9462
[email protected]8ebd46c2014-01-08 12:06:139463 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:539464 return error::kNoError;
9465}
9466
[email protected]944b62f32012-09-27 02:20:469467bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9468 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469469 for (GLsizei ii = 0; ii < n; ++ii) {
9470 if (GetVertexAttribManager(client_ids[ii])) {
9471 return false;
9472 }
9473 }
[email protected]ab4fd7282012-10-12 16:25:579474
[email protected]62e155e2012-10-23 22:43:159475 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579476 // Emulated VAO
9477 for (GLsizei ii = 0; ii < n; ++ii) {
9478 CreateVertexAttribManager(client_ids[ii], 0);
9479 }
9480 } else {
[email protected]40d90a22013-04-09 03:39:559481 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579482
9483 glGenVertexArraysOES(n, service_ids.get());
9484 for (GLsizei ii = 0; ii < n; ++ii) {
9485 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9486 }
[email protected]944b62f32012-09-27 02:20:469487 }
[email protected]ab4fd7282012-10-12 16:25:579488
[email protected]944b62f32012-09-27 02:20:469489 return true;
9490}
9491
9492void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9493 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469494 for (GLsizei ii = 0; ii < n; ++ii) {
9495 VertexAttribManager* vao =
9496 GetVertexAttribManager(client_ids[ii]);
9497 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119498 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]e259eb412012-10-13 05:47:249499 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469500 }
9501 RemoveVertexAttribManager(client_ids[ii]);
9502 }
9503 }
9504}
9505
9506void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469507 VertexAttribManager* vao = NULL;
9508 GLuint service_id = 0;
9509 if (client_id != 0) {
9510 vao = GetVertexAttribManager(client_id);
9511 if (!vao) {
9512 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9513 // only allows names that have been previously generated. As such, we do
9514 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519515 LOCAL_SET_GL_ERROR(
9516 GL_INVALID_OPERATION,
9517 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469518 current_decoder_error_ = error::kNoError;
9519 return;
9520 } else {
9521 service_id = vao->service_id();
9522 }
[email protected]944b62f32012-09-27 02:20:469523 } else {
[email protected]7cd76fd2013-06-02 21:11:119524 vao = default_vertex_attrib_manager_.get();
[email protected]944b62f32012-09-27 02:20:469525 }
9526
[email protected]ab4fd7282012-10-12 16:25:579527 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:119528 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:249529 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159530 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579531 EmulateVertexArrayState();
9532 } else {
9533 glBindVertexArrayOES(service_id);
9534 }
9535 }
9536}
9537
9538// Used when OES_vertex_array_object isn't natively supported
9539void GLES2DecoderImpl::EmulateVertexArrayState() {
9540 // Setup the Vertex attribute state
9541 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9542 RestoreStateForAttrib(vv);
9543 }
9544
9545 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219546 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249547 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579548 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9549 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469550}
9551
9552bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469553 const VertexAttribManager* vao =
9554 GetVertexAttribManager(client_id);
9555 return vao && vao->IsValid() && !vao->IsDeleted();
9556}
9557
[email protected]e51bdf32011-11-23 22:21:469558#if defined(OS_MACOSX)
9559void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9560 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9561 texture_id);
9562 if (it != texture_to_io_surface_map_.end()) {
9563 // Found a previous IOSurface bound to this texture; release it.
9564 CFTypeRef surface = it->second;
9565 CFRelease(surface);
9566 texture_to_io_surface_map_.erase(it);
9567 }
9568}
9569#endif
9570
9571void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9572 GLenum target, GLsizei width, GLsizei height,
9573 GLuint io_surface_id, GLuint plane) {
9574#if defined(OS_MACOSX)
9575 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519576 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439577 GL_INVALID_OPERATION,
9578 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469579 return;
9580 }
9581
9582 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9583 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519584 LOCAL_SET_GL_ERROR(
9585 GL_INVALID_OPERATION,
9586 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469587 return;
9588 }
9589
9590 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9591 // This might be supported in the future, and if we could require
9592 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9593 // could delete a lot of code. For now, perform strict validation so we
9594 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519595 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469596 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439597 "glTexImageIOSurface2DCHROMIUM",
9598 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469599 return;
9600 }
9601
[email protected]09d50362012-10-18 20:54:379602 // Default target might be conceptually valid, but disallow it to avoid
9603 // accidents.
[email protected]c986af502013-08-14 01:04:449604 TextureRef* texture_ref =
9605 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:499606 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519607 LOCAL_SET_GL_ERROR(
9608 GL_INVALID_OPERATION,
9609 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469610 return;
9611 }
[email protected]e51bdf32011-11-23 22:21:469612
9613 // Look up the new IOSurface. Note that because of asynchrony
9614 // between processes this might fail; during live resizing the
9615 // plugin process might allocate and release an IOSurface before
9616 // this process gets a chance to look it up. Hold on to any old
9617 // IOSurface in this case.
9618 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9619 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519620 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439621 GL_INVALID_OPERATION,
9622 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469623 return;
9624 }
9625
9626 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499627 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469628
9629 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9630 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499631 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469632
9633 CGLContextObj context =
9634 static_cast<CGLContextObj>(context_->GetHandle());
9635
9636 CGLError err = surface_support->CGLTexImageIOSurface2D(
9637 context,
9638 target,
9639 GL_RGBA,
9640 width,
9641 height,
9642 GL_BGRA,
9643 GL_UNSIGNED_INT_8_8_8_8_REV,
9644 surface,
9645 plane);
9646
9647 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519648 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469649 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439650 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469651 return;
9652 }
9653
9654 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499655 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469656 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9657
9658#else
[email protected]ab09b612013-03-11 22:11:519659 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439660 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469661#endif
9662}
9663
[email protected]97dc7cbe2011-12-06 17:26:179664static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9665 switch (internalformat) {
9666 case GL_RGB565:
9667 return GL_RGB;
9668 case GL_RGBA4:
9669 return GL_RGBA;
9670 case GL_RGB5_A1:
9671 return GL_RGBA;
9672 case GL_RGB8_OES:
9673 return GL_RGB;
9674 case GL_RGBA8_OES:
9675 return GL_RGBA;
9676 case GL_LUMINANCE8_ALPHA8_EXT:
9677 return GL_LUMINANCE_ALPHA;
9678 case GL_LUMINANCE8_EXT:
9679 return GL_LUMINANCE;
9680 case GL_ALPHA8_EXT:
9681 return GL_ALPHA;
9682 case GL_RGBA32F_EXT:
9683 return GL_RGBA;
9684 case GL_RGB32F_EXT:
9685 return GL_RGB;
9686 case GL_ALPHA32F_EXT:
9687 return GL_ALPHA;
9688 case GL_LUMINANCE32F_EXT:
9689 return GL_LUMINANCE;
9690 case GL_LUMINANCE_ALPHA32F_EXT:
9691 return GL_LUMINANCE_ALPHA;
9692 case GL_RGBA16F_EXT:
9693 return GL_RGBA;
9694 case GL_RGB16F_EXT:
9695 return GL_RGB;
9696 case GL_ALPHA16F_EXT:
9697 return GL_ALPHA;
9698 case GL_LUMINANCE16F_EXT:
9699 return GL_LUMINANCE;
9700 case GL_LUMINANCE_ALPHA16F_EXT:
9701 return GL_LUMINANCE_ALPHA;
9702 case GL_BGRA8_EXT:
9703 return GL_BGRA_EXT;
9704 default:
9705 return GL_NONE;
9706 }
9707}
9708
[email protected]43410e92012-04-20 17:06:289709void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039710 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549711 GLenum internal_format, GLenum dest_type) {
[email protected]370eaf12013-05-18 09:19:499712 TextureRef* dest_texture_ref = GetTexture(dest_id);
9713 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289714
[email protected]370eaf12013-05-18 09:19:499715 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519716 LOCAL_SET_GL_ERROR(
9717 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289718 return;
9719 }
9720
9721 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519722 LOCAL_SET_GL_ERROR(
9723 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289724 return;
9725 }
9726
[email protected]370eaf12013-05-18 09:19:499727 Texture* source_texture = source_texture_ref->texture();
9728 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079729 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259730 (source_texture->target() != GL_TEXTURE_2D &&
9731 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:009732 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9733 "glCopyTextureCHROMIUM",
9734 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039735 return;
9736 }
9737
[email protected]43410e92012-04-20 17:06:289738 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289739
[email protected]7bffe9e12014-01-27 23:02:559740 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9741 gfx::GLImage* image =
9742 source_texture->GetLevelImage(source_texture->target(), 0);
9743 if (!image) {
[email protected]377976552013-05-14 23:32:569744 LOCAL_SET_GL_ERROR(
[email protected]7bffe9e12014-01-27 23:02:559745 GL_INVALID_OPERATION,
9746 "glCopyTextureChromium", "No external image");
[email protected]377976552013-05-14 23:32:569747 return;
9748 }
[email protected]7bffe9e12014-01-27 23:02:559749 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:569750 source_width = size.width();
9751 source_height = size.height();
9752 if (source_width <= 0 || source_height <= 0) {
9753 LOCAL_SET_GL_ERROR(
9754 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:559755 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:569756 return;
9757 }
[email protected]3ecc1052013-09-26 08:59:009758 } else {
9759 if (!source_texture->GetLevelSize(
9760 source_texture->target(), 0, &source_width, &source_height)) {
9761 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9762 "glCopyTextureChromium",
9763 "source texture has no level 0");
9764 return;
9765 }
9766
9767 // Check that this type of texture is allowed.
9768 if (!texture_manager()->ValidForTarget(
9769 source_texture->target(), level, source_width, source_height, 1)) {
9770 LOCAL_SET_GL_ERROR(
9771 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
9772 return;
9773 }
[email protected]377976552013-05-14 23:32:569774 }
9775
[email protected]cf6b8f62012-05-25 21:43:379776 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9777 // needed because it takes 10s of milliseconds to initialize.
9778 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519779 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379780 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279781 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379782 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519783 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379784 return;
9785 }
9786
[email protected]a4a6bdd12013-04-19 20:46:549787 GLenum dest_type_previous;
[email protected]0a1e9ad2012-05-04 21:13:039788 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079789 bool dest_level_defined = dest_texture->GetLevelSize(
9790 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289791
[email protected]0a1e9ad2012-05-04 21:13:039792 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:549793 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:079794 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039795 }
9796
9797 // Resize the destination texture to the dimensions of the source texture.
9798 if (!dest_level_defined || dest_width != source_width ||
9799 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:549800 dest_internal_format != internal_format ||
9801 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:289802 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519803 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079804 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:389805 glTexImage2D(
[email protected]43410e92012-04-20 17:06:289806 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039807 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519808 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039809 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:029810 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:289811 return;
[email protected]0a1e9ad2012-05-04 21:13:039812 }
[email protected]43410e92012-04-20 17:06:289813
9814 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499815 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039816 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259817 } else {
[email protected]02965c22013-03-09 02:40:079818 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:499819 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289820 }
9821
[email protected]91c94eb2013-10-22 10:32:549822 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
9823
[email protected]5394a4102013-04-18 05:41:379824 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9825 // before presenting.
9826 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9827 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9828 // instead of using default matrix crbug.com/226218.
9829 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9830 0.0f, 1.0f, 0.0f, 0.0f,
9831 0.0f, 0.0f, 1.0f, 0.0f,
9832 0.0f, 0.0f, 0.0f, 1.0f};
9833 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9834 this,
9835 source_texture->target(),
9836 dest_texture->target(),
9837 source_texture->service_id(),
9838 dest_texture->service_id(), level,
9839 source_width, source_height,
9840 unpack_flip_y_,
9841 unpack_premultiply_alpha_,
9842 unpack_unpremultiply_alpha_,
9843 default_matrix);
9844 } else {
9845 copy_texture_CHROMIUM_->DoCopyTexture(
9846 this,
9847 source_texture->target(),
9848 dest_texture->target(),
9849 source_texture->service_id(),
9850 dest_texture->service_id(), level,
9851 source_width, source_height,
9852 unpack_flip_y_,
9853 unpack_premultiply_alpha_,
9854 unpack_unpremultiply_alpha_);
9855 }
[email protected]91c94eb2013-10-22 10:32:549856
9857 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:289858}
9859
[email protected]97dc7cbe2011-12-06 17:26:179860static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9861 switch (internalformat) {
9862 case GL_RGB565:
9863 return GL_UNSIGNED_SHORT_5_6_5;
9864 case GL_RGBA4:
9865 return GL_UNSIGNED_SHORT_4_4_4_4;
9866 case GL_RGB5_A1:
9867 return GL_UNSIGNED_SHORT_5_5_5_1;
9868 case GL_RGB8_OES:
9869 return GL_UNSIGNED_BYTE;
9870 case GL_RGBA8_OES:
9871 return GL_UNSIGNED_BYTE;
9872 case GL_LUMINANCE8_ALPHA8_EXT:
9873 return GL_UNSIGNED_BYTE;
9874 case GL_LUMINANCE8_EXT:
9875 return GL_UNSIGNED_BYTE;
9876 case GL_ALPHA8_EXT:
9877 return GL_UNSIGNED_BYTE;
9878 case GL_RGBA32F_EXT:
9879 return GL_FLOAT;
9880 case GL_RGB32F_EXT:
9881 return GL_FLOAT;
9882 case GL_ALPHA32F_EXT:
9883 return GL_FLOAT;
9884 case GL_LUMINANCE32F_EXT:
9885 return GL_FLOAT;
9886 case GL_LUMINANCE_ALPHA32F_EXT:
9887 return GL_FLOAT;
9888 case GL_RGBA16F_EXT:
9889 return GL_HALF_FLOAT_OES;
9890 case GL_RGB16F_EXT:
9891 return GL_HALF_FLOAT_OES;
9892 case GL_ALPHA16F_EXT:
9893 return GL_HALF_FLOAT_OES;
9894 case GL_LUMINANCE16F_EXT:
9895 return GL_HALF_FLOAT_OES;
9896 case GL_LUMINANCE_ALPHA16F_EXT:
9897 return GL_HALF_FLOAT_OES;
9898 case GL_BGRA8_EXT:
9899 return GL_UNSIGNED_BYTE;
9900 default:
9901 return GL_NONE;
9902 }
9903}
9904
9905void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449906 GLenum target,
9907 GLint levels,
9908 GLenum internal_format,
9909 GLsizei width,
9910 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389911 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419912 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:009913 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:519914 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439915 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179916 return;
9917 }
[email protected]c986af502013-08-14 01:04:449918 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9919 &state_, target);
[email protected]370eaf12013-05-18 09:19:499920 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519921 LOCAL_SET_GL_ERROR(
9922 GL_INVALID_OPERATION,
9923 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179924 return;
9925 }
[email protected]370eaf12013-05-18 09:19:499926 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079927 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449928 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:179929 }
[email protected]02965c22013-03-09 02:40:079930 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519931 LOCAL_SET_GL_ERROR(
9932 GL_INVALID_OPERATION,
9933 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179934 return;
9935 }
[email protected]7989c9e2013-01-23 06:39:269936
9937 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9938 GLenum type = ExtractTypeFromStorageFormat(internal_format);
9939
9940 {
9941 GLsizei level_width = width;
9942 GLsizei level_height = height;
9943 uint32 estimated_size = 0;
9944 for (int ii = 0; ii < levels; ++ii) {
9945 uint32 level_size = 0;
9946 if (!GLES2Util::ComputeImageDataSizes(
9947 level_width, level_height, format, type, state_.unpack_alignment,
9948 &estimated_size, NULL, NULL) ||
9949 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519950 LOCAL_SET_GL_ERROR(
9951 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269952 return;
9953 }
9954 level_width = std::max(1, level_width >> 1);
9955 level_height = std::max(1, level_height >> 1);
9956 }
9957 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519958 LOCAL_SET_GL_ERROR(
9959 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269960 return;
9961 }
9962 }
9963
[email protected]ab09b612013-03-11 22:11:519964 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:389965 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:519966 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:179967 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:159968 GLsizei level_width = width;
9969 GLsizei level_height = height;
9970 for (int ii = 0; ii < levels; ++ii) {
9971 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499972 texture_ref, target, ii, format,
9973 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:159974 level_width = std::max(1, level_width >> 1);
9975 level_height = std::max(1, level_height >> 1);
9976 }
[email protected]02965c22013-03-09 02:40:079977 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:179978 }
[email protected]97dc7cbe2011-12-06 17:26:179979}
[email protected]e51bdf32011-11-23 22:21:469980
[email protected]78b514b2012-05-01 21:50:599981error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359982 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]baed42c2013-10-01 05:06:359983 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:599984}
9985
9986void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9987 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029988 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329989 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029990 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9991
[email protected]c986af502013-08-14 01:04:449992 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9993 &state_, target);
[email protected]370eaf12013-05-18 09:19:499994 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519995 LOCAL_SET_GL_ERROR(
9996 GL_INVALID_OPERATION,
9997 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599998 return;
9999 }
10000
[email protected]62e65f02013-05-29 22:28:1010001 Texture* produced = texture_manager()->Produce(texture_ref);
10002 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110003 LOCAL_SET_GL_ERROR(
10004 GL_INVALID_OPERATION,
10005 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:5910006 return;
10007 }
10008
10009 if (!group_->mailbox_manager()->ProduceTexture(
10010 target,
10011 *reinterpret_cast<const MailboxName*>(mailbox),
[email protected]62e65f02013-05-29 22:28:1010012 produced)) {
[email protected]ab09b612013-03-11 22:11:5110013 LOCAL_SET_GL_ERROR(
10014 GL_INVALID_OPERATION,
10015 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910016 return;
10017 }
[email protected]78b514b2012-05-01 21:50:5910018}
10019
10020void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
10021 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:0210022 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210023 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:0210024 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
10025
[email protected]62e65f02013-05-29 22:28:1010026 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410027 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110028 if (!texture_ref.get()) {
10029 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10030 "glConsumeTextureCHROMIUM",
10031 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910032 return;
10033 }
[email protected]62e65f02013-05-29 22:28:1010034 GLuint client_id = texture_ref->client_id();
10035 if (!client_id) {
10036 LOCAL_SET_GL_ERROR(
10037 GL_INVALID_OPERATION,
10038 "glConsumeTextureCHROMIUM", "unknown texture for target");
10039 return;
10040 }
10041 Texture* texture =
[email protected]78b514b2012-05-01 21:50:5910042 group_->mailbox_manager()->ConsumeTexture(
10043 target,
[email protected]62e65f02013-05-29 22:28:1010044 *reinterpret_cast<const MailboxName*>(mailbox));
10045 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110046 LOCAL_SET_GL_ERROR(
10047 GL_INVALID_OPERATION,
10048 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910049 return;
10050 }
[email protected]62e65f02013-05-29 22:28:1010051 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110052 LOCAL_SET_GL_ERROR(
10053 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010054 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910055 return;
10056 }
[email protected]62e65f02013-05-29 22:28:1010057
10058 DeleteTexturesHelper(1, &client_id);
10059 texture_ref = texture_manager()->Consume(client_id, texture);
10060 glBindTexture(target, texture_ref->service_id());
10061
10062 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10063 unit.bind_target = target;
10064 switch (target) {
10065 case GL_TEXTURE_2D:
10066 unit.bound_texture_2d = texture_ref;
10067 break;
10068 case GL_TEXTURE_CUBE_MAP:
10069 unit.bound_texture_cube_map = texture_ref;
10070 break;
10071 case GL_TEXTURE_EXTERNAL_OES:
10072 unit.bound_texture_external_oes = texture_ref;
10073 break;
10074 case GL_TEXTURE_RECTANGLE_ARB:
10075 unit.bound_texture_rectangle_arb = texture_ref;
10076 break;
10077 default:
10078 NOTREACHED(); // Validation should prevent us getting here.
10079 break;
10080 }
[email protected]78b514b2012-05-01 21:50:5910081}
10082
[email protected]d2a0e1a2012-08-12 02:25:0110083void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10084 GLsizei length, const GLchar* marker) {
10085 if (!marker) {
10086 marker = "";
10087 }
10088 debug_marker_manager_.SetMarker(
10089 length ? std::string(marker, length) : std::string(marker));
10090}
10091
10092void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10093 GLsizei length, const GLchar* marker) {
10094 if (!marker) {
10095 marker = "";
10096 }
[email protected]cac16542014-01-15 17:53:5110097 std::string name = length ? std::string(marker, length) : std::string(marker);
10098 debug_marker_manager_.PushGroup(name);
10099 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110100}
10101
10102void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10103 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110104 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110105}
10106
[email protected]09d50362012-10-18 20:54:3710107void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10108 GLenum target, GLint image_id) {
10109 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710110
[email protected]bc26e8d2014-01-29 00:40:3010111 if (target == GL_TEXTURE_CUBE_MAP) {
10112 LOCAL_SET_GL_ERROR(
10113 GL_INVALID_ENUM,
10114 "glBindTexImage2DCHROMIUM", "invalid target");
10115 return;
10116 }
10117
[email protected]09d50362012-10-18 20:54:3710118 // Default target might be conceptually valid, but disallow it to avoid
10119 // accidents.
[email protected]c986af502013-08-14 01:04:4410120 TextureRef* texture_ref =
10121 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910122 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110123 LOCAL_SET_GL_ERROR(
10124 GL_INVALID_OPERATION,
10125 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710126 return;
10127 }
10128
10129 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10130 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110131 LOCAL_SET_GL_ERROR(
10132 GL_INVALID_OPERATION,
10133 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710134 return;
10135 }
10136
[email protected]b8160812013-04-09 00:41:0410137 {
10138 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010139 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610140 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410141 LOCAL_SET_GL_ERROR(
10142 GL_INVALID_OPERATION,
10143 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10144 return;
10145 }
[email protected]09d50362012-10-18 20:54:3710146 }
10147
10148 gfx::Size size = gl_image->GetSize();
10149 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910150 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710151 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910152 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710153}
10154
10155void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10156 GLenum target, GLint image_id) {
10157 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710158
10159 // Default target might be conceptually valid, but disallow it to avoid
10160 // accidents.
[email protected]c986af502013-08-14 01:04:4410161 TextureRef* texture_ref =
10162 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910163 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110164 LOCAL_SET_GL_ERROR(
10165 GL_INVALID_OPERATION,
10166 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710167 return;
10168 }
10169
10170 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10171 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110172 LOCAL_SET_GL_ERROR(
10173 GL_INVALID_OPERATION,
10174 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710175 return;
10176 }
10177
10178 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910179 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710180 return;
10181
[email protected]b8160812013-04-09 00:41:0410182 {
10183 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010184 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610185 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0410186 }
[email protected]09d50362012-10-18 20:54:3710187
10188 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910189 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710190 GL_RGBA, GL_UNSIGNED_BYTE, false);
10191}
[email protected]d2a0e1a2012-08-12 02:25:0110192
[email protected]94307712012-11-16 23:26:1110193error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510194 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110195 Bucket* bucket = GetBucket(c.bucket_id);
10196 if (!bucket || bucket->size() == 0) {
10197 return error::kInvalidArguments;
10198 }
10199 std::string command_name;
10200 if (!bucket->GetAsString(&command_name)) {
10201 return error::kInvalidArguments;
10202 }
[email protected]fb97b662013-02-20 23:02:1410203 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5110204 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5110205 LOCAL_SET_GL_ERROR(
10206 GL_INVALID_OPERATION,
10207 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410208 return error::kNoError;
10209 }
[email protected]94307712012-11-16 23:26:1110210 return error::kNoError;
10211}
10212
10213void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410214 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110215 LOCAL_SET_GL_ERROR(
10216 GL_INVALID_OPERATION,
10217 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110218 return;
10219 }
[email protected]fb97b662013-02-20 23:02:1410220 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5110221 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1110222}
10223
[email protected]2f143d482013-03-14 18:04:4910224void GLES2DecoderImpl::DoDrawBuffersEXT(
10225 GLsizei count, const GLenum* bufs) {
10226 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10227 LOCAL_SET_GL_ERROR(
10228 GL_INVALID_VALUE,
10229 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10230 return;
10231 }
10232
10233 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10234 if (framebuffer) {
10235 for (GLsizei i = 0; i < count; ++i) {
10236 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10237 bufs[i] != GL_NONE) {
10238 LOCAL_SET_GL_ERROR(
10239 GL_INVALID_OPERATION,
10240 "glDrawBuffersEXT",
10241 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10242 return;
10243 }
10244 }
10245 glDrawBuffersARB(count, bufs);
10246 framebuffer->SetDrawBuffers(count, bufs);
10247 } else { // backbuffer
10248 if (count > 1 ||
10249 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10250 LOCAL_SET_GL_ERROR(
10251 GL_INVALID_OPERATION,
10252 "glDrawBuffersEXT",
10253 "more than one buffer or bufs not GL_NONE or GL_BACK");
10254 return;
10255 }
10256 GLenum mapped_buf = bufs[0];
10257 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10258 bufs[0] == GL_BACK) {
10259 mapped_buf = GL_COLOR_ATTACHMENT0;
10260 }
10261 glDrawBuffersARB(count, &mapped_buf);
10262 group_->set_draw_buffer(bufs[0]);
10263 }
10264}
10265
[email protected]32145a92012-12-17 09:01:5910266bool GLES2DecoderImpl::ValidateAsyncTransfer(
10267 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710268 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910269 GLenum target,
10270 GLint level,
10271 const void * data) {
10272 // We only support async uploads to 2D textures for now.
10273 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110274 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910275 return false;
10276 }
10277 // We only support uploads to level zero for now.
10278 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110279 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910280 return false;
10281 }
10282 // A transfer buffer must be bound, even for asyncTexImage2D.
10283 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110284 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910285 return false;
10286 }
10287 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710288 if (!texture_ref ||
10289 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110290 LOCAL_SET_GL_ERROR(
10291 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910292 function_name, "transfer already in progress");
10293 return false;
10294 }
10295 return true;
10296}
10297
[email protected]69023942012-11-30 19:57:1610298error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510299 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610300 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610301 GLenum target = static_cast<GLenum>(c.target);
10302 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4410303 // TODO(kloveless): Change HandleAsyncTexImage2DCHROMIUM command to use
10304 // unsigned integer for internalformat.
10305 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1610306 GLsizei width = static_cast<GLsizei>(c.width);
10307 GLsizei height = static_cast<GLsizei>(c.height);
10308 GLint border = static_cast<GLint>(c.border);
10309 GLenum format = static_cast<GLenum>(c.format);
10310 GLenum type = static_cast<GLenum>(c.type);
10311 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10312 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10313 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910314
10315 // TODO(epenner): Move this and copies of this memory validation
10316 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610317 if (!GLES2Util::ComputeImageDataSizes(
10318 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10319 NULL)) {
10320 return error::kOutOfBounds;
10321 }
10322 const void* pixels = NULL;
10323 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10324 pixels = GetSharedMemoryAs<const void*>(
10325 pixels_shm_id, pixels_shm_offset, pixels_size);
10326 if (!pixels) {
10327 return error::kOutOfBounds;
10328 }
10329 }
10330
[email protected]c986af502013-08-14 01:04:4410331 TextureManager::DoTextImage2DArguments args = {
10332 target, level, internal_format, width, height, border, format, type,
10333 pixels, pixels_size};
10334 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5910335 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4410336 if (!texture_manager()->ValidateTexImage2D(
10337 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5910338 return error::kNoError;
10339 }
10340
10341 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910342 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910343 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710344 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910345 return error::kNoError;
10346
10347 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710348 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110349 LOCAL_SET_GL_ERROR(
10350 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910351 "glAsyncTexImage2DCHROMIUM", "already defined");
10352 return error::kNoError;
10353 }
10354
[email protected]7989c9e2013-01-23 06:39:2610355 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110356 LOCAL_SET_GL_ERROR(
10357 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610358 return error::kNoError;
10359 }
10360
[email protected]32145a92012-12-17 09:01:5910361 // We know the memory/size is safe, so get the real shared memory since
10362 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110363 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910364 base::SharedMemory* shared_memory = buffer.shared_memory;
10365 uint32 shm_size = buffer.size;
10366 uint32 shm_data_offset = c.pixels_shm_offset;
10367 uint32 shm_data_size = pixels_size;
10368
[email protected]5b3a8e02013-03-13 05:36:4410369 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810370 AsyncTexImage2DParams tex_params = {
10371 target, level, static_cast<GLenum>(internal_format),
10372 width, height, border, format, type};
10373 AsyncMemoryParams mem_params = {
10374 shared_memory, shm_size, shm_data_offset, shm_data_size};
[email protected]32145a92012-12-17 09:01:5910375
[email protected]5b3a8e02013-03-13 05:36:4410376 // Set up the async state if needed, and make the texture
10377 // immutable so the async state stays valid. The level info
10378 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1810379 AsyncPixelTransferDelegate* delegate =
10380 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
10381 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4410382 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910383
[email protected]896425e2013-06-12 17:27:1810384 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410385 tex_params,
10386 mem_params,
10387 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910388 // The callback is only invoked if the transfer delegate still
10389 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410390 // ownership that both of these pointers are valid.
10391 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910392 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410393 tex_params));
[email protected]f598f422012-12-07 08:30:0310394 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610395}
10396
10397error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510398 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610399 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610400 GLenum target = static_cast<GLenum>(c.target);
10401 GLint level = static_cast<GLint>(c.level);
10402 GLint xoffset = static_cast<GLint>(c.xoffset);
10403 GLint yoffset = static_cast<GLint>(c.yoffset);
10404 GLsizei width = static_cast<GLsizei>(c.width);
10405 GLsizei height = static_cast<GLsizei>(c.height);
10406 GLenum format = static_cast<GLenum>(c.format);
10407 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910408
10409 // TODO(epenner): Move this and copies of this memory validation
10410 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610411 uint32 data_size;
10412 if (!GLES2Util::ComputeImageDataSizes(
10413 width, height, format, type, state_.unpack_alignment, &data_size,
10414 NULL, NULL)) {
10415 return error::kOutOfBounds;
10416 }
10417 const void* pixels = GetSharedMemoryAs<const void*>(
10418 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910419
10420 // All the normal glTexSubImage2D validation.
10421 error::Error error = error::kNoError;
10422 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10423 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10424 return error;
[email protected]69023942012-11-30 19:57:1610425 }
10426
[email protected]32145a92012-12-17 09:01:5910427 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4410428 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10429 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910430 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910431 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710432 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910433 return error::kNoError;
10434
10435 // Guarantee async textures are always 'cleared' as follows:
10436 // - AsyncTexImage2D can not redefine an existing texture
10437 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10438 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10439 // - Textures become immutable after an async call.
10440 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710441 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910442 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10443 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110444 LOCAL_SET_GL_ERROR(
10445 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510446 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910447 return error::kNoError;
10448 }
10449 }
10450
10451 // We know the memory/size is safe, so get the real shared memory since
10452 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110453 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910454 base::SharedMemory* shared_memory = buffer.shared_memory;
10455 uint32 shm_size = buffer.size;
10456 uint32 shm_data_offset = c.data_shm_offset;
10457 uint32 shm_data_size = data_size;
10458
[email protected]5b3a8e02013-03-13 05:36:4410459 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310460 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910461 width, height, format, type};
[email protected]2a7568a2013-05-09 23:12:0310462 AsyncMemoryParams mem_params = {shared_memory, shm_size,
[email protected]32145a92012-12-17 09:01:5910463 shm_data_offset, shm_data_size};
[email protected]896425e2013-06-12 17:27:1810464 AsyncPixelTransferDelegate* delegate =
10465 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10466 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4410467 // TODO(epenner): We may want to enforce exclusive use
10468 // of async APIs in which case this should become an error,
10469 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310470 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410471 0, 0, 0, 0, 0, 0};
10472 texture->GetLevelSize(target, level, &define_params.width,
10473 &define_params.height);
10474 texture->GetLevelType(target, level, &define_params.type,
10475 &define_params.internal_format);
10476 // Set up the async state if needed, and make the texture
10477 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1810478 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4710479 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4410480 texture->SetImmutable(true);
10481 }
10482
[email protected]896425e2013-06-12 17:27:1810483 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910484 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610485}
10486
[email protected]a00c1f742013-03-05 17:02:1610487error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10488 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10489 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10490 GLenum target = static_cast<GLenum>(c.target);
10491
10492 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110493 LOCAL_SET_GL_ERROR(
10494 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610495 return error::kNoError;
10496 }
[email protected]c986af502013-08-14 01:04:4410497 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10498 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910499 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110500 LOCAL_SET_GL_ERROR(
10501 GL_INVALID_OPERATION,
10502 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610503 return error::kNoError;
10504 }
[email protected]896425e2013-06-12 17:27:1810505 AsyncPixelTransferDelegate* delegate =
10506 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10507 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4910508 LOCAL_SET_GL_ERROR(
10509 GL_INVALID_OPERATION,
10510 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10511 return error::kNoError;
10512 }
[email protected]896425e2013-06-12 17:27:1810513 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0910514 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610515 return error::kNoError;
10516}
10517
[email protected]91c94eb2013-10-22 10:32:5410518void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
10519 TextureRef* texture_ref) {
10520 Texture* texture = texture_ref->texture();
10521 DoDidUseTexImageIfNeeded(texture, texture->target());
10522}
10523
[email protected]96449d2c2009-11-25 00:01:3210524// Include the auto-generated part of this file. We split this because it means
10525// we can easily edit the non-auto generated parts right here in this file
10526// instead of having to edit some template or the code generator.
10527#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10528
10529} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510530} // namespace gpu