blob: c3bdae5d5d94a78b9cfa80d8087581f367118ec0 [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]e3c4a9ab2014-03-31 09:07:0218#include "base/callback_helpers.h"
[email protected]e844ae22012-01-14 03:36:2619#include "base/command_line.h"
[email protected]1078f912011-12-23 13:12:1420#include "base/debug/trace_event.h"
[email protected]b2e92592014-01-10 15:47:1521#include "base/debug/trace_event_synthetic_delay.h"
[email protected]3b63f8f42011-03-28 01:54:1522#include "base/memory/scoped_ptr.h"
[email protected]e3c4a9ab2014-03-31 09:07:0223#include "base/numerics/safe_math.h"
[email protected]f4390962013-06-11 07:29:2224#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1225#include "base/strings/string_split.h"
[email protected]d37231fa2010-04-09 21:16:0226#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3227#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2228#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3229#include "gpu/command_buffer/common/gles2_cmd_format.h"
30#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1031#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5132#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2233#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
34#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5035#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3236#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5037#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2438#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5039#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1140#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5841#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3242#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2843#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4644#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1345#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2646#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1447#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3748#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5949#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2550#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4751#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5352#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5853#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4754#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4555#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0456#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4757#include "gpu/command_buffer/service/texture_manager.h"
[email protected]944b62f32012-09-27 02:20:4658#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2259#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]d8bc3ec2013-03-07 06:28:4060#include "ui/gl/gl_bindings.h"
[email protected]5a36dc132013-07-23 23:17:5561#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3762#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2763#include "ui/gl/gl_implementation.h"
64#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2765
[email protected]e51bdf32011-11-23 22:21:4666#if defined(OS_MACOSX)
[email protected]423e644f2013-06-19 00:48:2767#include "ui/gl/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4668#endif
[email protected]de17df392010-04-23 21:09:4169
[email protected]6eb775352013-08-27 05:57:1670#if defined(OS_WIN)
71#include "base/win/win_util.h"
72#endif
73
[email protected]693ca512012-11-13 18:09:1374// TODO(zmo): we can't include "City.h" due to type def conflicts.
75extern uint64 CityHash64(const char*, size_t);
76
[email protected]a7a27ace2009-12-12 00:11:2577namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3278namespace gles2 {
79
[email protected]f0d74742011-10-03 16:31:0480namespace {
[email protected]693ca512012-11-13 18:09:1381
[email protected]f0d74742011-10-03 16:31:0482static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4983static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1384static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]693ca512012-11-13 18:09:1385
[email protected]3d944a82013-02-12 19:09:0286#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]693ca512012-11-13 18:09:1387khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
88 return static_cast<khronos_uint64_t>(
89 CityHash64(name, static_cast<size_t>(len)));
90}
[email protected]3d944a82013-02-12 19:09:0291#endif
[email protected]693ca512012-11-13 18:09:1392
[email protected]448e459e2013-06-12 17:00:4193static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
94 GLint rangeMax,
95 GLint precision) {
96 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
97}
98
[email protected]8dc1bf92013-03-12 03:58:2199static void GetShaderPrecisionFormatImpl(GLenum shader_type,
100 GLenum precision_type,
101 GLint *range, GLint *precision) {
102 switch (precision_type) {
103 case GL_LOW_INT:
104 case GL_MEDIUM_INT:
105 case GL_HIGH_INT:
106 // These values are for a 32-bit twos-complement integer format.
107 range[0] = 31;
108 range[1] = 30;
109 *precision = 0;
110 break;
111 case GL_LOW_FLOAT:
112 case GL_MEDIUM_FLOAT:
113 case GL_HIGH_FLOAT:
114 // These values are for an IEEE single-precision floating-point format.
115 range[0] = 127;
116 range[1] = 127;
117 *precision = 23;
118 break;
119 default:
120 NOTREACHED();
121 break;
122 }
123
[email protected]8af4d5e2013-03-15 23:55:33124 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
125 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21126 // This function is sometimes defined even though it's really just
127 // a stub, so we need to set range and precision as if it weren't
128 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44129 // On Mac OS with some GPUs, calling this generates a
130 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
131 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21132 glGetShaderPrecisionFormat(shader_type, precision_type,
133 range, precision);
[email protected]448e459e2013-06-12 17:00:41134
135 // TODO(brianderson): Make the following official workarounds.
136
137 // Some drivers have bugs where they report the ranges as a negative number.
138 // Taking the absolute value here shouldn't hurt because negative numbers
139 // aren't expected anyway.
140 range[0] = abs(range[0]);
141 range[1] = abs(range[1]);
142
143 // If the driver reports a precision for highp float that isn't actually
144 // highp, don't pretend like it's supported because shader compilation will
145 // fail anyway.
146 if (precision_type == GL_HIGH_FLOAT &&
147 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
148 range[0] = 0;
149 range[1] = 0;
150 *precision = 0;
151 }
[email protected]8dc1bf92013-03-12 03:58:21152 }
153}
154
[email protected]b04e24c2013-01-08 18:35:25155} // namespace
[email protected]f0d74742011-10-03 16:31:04156
[email protected]6217d392010-03-25 22:08:35157class GLES2DecoderImpl;
158
[email protected]ab09b612013-03-11 22:11:51159// Local versions of the SET_GL_ERROR macros
160#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50161 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51162#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50163 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
164 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51165#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50166 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
167 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51168#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50169 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
170 function_name)
[email protected]ab09b612013-03-11 22:11:51171#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50172 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51173#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50174 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51175#define LOCAL_PERFORMANCE_WARNING(msg) \
176 PerformanceWarning(__FILE__, __LINE__, msg)
177#define LOCAL_RENDER_WARNING(msg) \
178 RenderWarning(__FILE__, __LINE__, msg)
179
[email protected]07f54fcc2009-12-22 02:46:30180// Check that certain assumptions the code makes are true. There are places in
181// the code where shared memory is passed direclty to GL. Example, glUniformiv,
182// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
183// a few others) are 32bits. If they are not 32bits the code will have to change
184// to call those GL functions with service side memory and then copy the results
185// to shared memory, converting the sizes.
186COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
187 GLint_not_same_size_as_uint32);
188COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
189 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37190COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
191 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30192
[email protected]43f28f832010-02-03 02:28:48193// TODO(kbr): the use of this anonymous namespace core dumps the
194// linker on Mac OS X 10.6 when the symbol ordering file is used
195// namespace {
[email protected]96449d2c2009-11-25 00:01:32196
197// Returns the address of the first byte after a struct.
198template <typename T>
199const void* AddressAfterStruct(const T& pod) {
200 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
201}
202
[email protected]07f54fcc2009-12-22 02:46:30203// Returns the address of the frst byte after the struct or NULL if size >
204// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32205template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30206RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
207 uint32 size,
208 uint32 immediate_data_size) {
209 return (size <= immediate_data_size) ?
210 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
211 NULL;
[email protected]96449d2c2009-11-25 00:01:32212}
213
[email protected]07f54fcc2009-12-22 02:46:30214// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18215bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32216 GLuint count,
217 size_t size,
[email protected]a76b0052010-03-05 00:33:18218 unsigned int elements_per_unit,
219 uint32* dst) {
220 uint32 value;
221 if (!SafeMultiplyUint32(count, size, &value)) {
222 return false;
223 }
224 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
225 return false;
226 }
227 *dst = value;
228 return true;
[email protected]96449d2c2009-11-25 00:01:32229}
230
231// A struct to hold info about each command.
232struct CommandInfo {
[email protected]cac16542014-01-15 17:53:51233 uint8 arg_flags; // How to handle the arguments for this command
234 uint8 cmd_flags; // How to handle this command
235 uint16 arg_count; // How many arguments are expected for this command.
[email protected]96449d2c2009-11-25 00:01:32236};
237
[email protected]cac16542014-01-15 17:53:51238// cmds::name::cmd_flags,
[email protected]96449d2c2009-11-25 00:01:32239// A table of CommandInfo for all the commands.
240const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35241 #define GLES2_CMD_OP(name) { \
242 cmds::name::kArgFlags, \
[email protected]cac16542014-01-15 17:53:51243 cmds::name::cmd_flags, \
244 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */
[email protected]96449d2c2009-11-25 00:01:32245
246 GLES2_COMMAND_LIST(GLES2_CMD_OP)
247
248 #undef GLES2_CMD_OP
249};
250
[email protected]258a3313f2011-10-18 20:13:57251// Return true if a character belongs to the ASCII subset as defined in
252// GLSL ES 1.0 spec section 3.1.
253static bool CharacterIsValidForGLES(unsigned char c) {
254 // Printing characters are valid except " $ ` @ \ ' DEL.
255 if (c >= 32 && c <= 126 &&
256 c != '"' &&
257 c != '$' &&
258 c != '`' &&
259 c != '@' &&
260 c != '\\' &&
261 c != '\'') {
262 return true;
263 }
264 // Horizontal tab, line feed, vertical tab, form feed, carriage return
265 // are also valid.
266 if (c >= 9 && c <= 13) {
267 return true;
268 }
269
270 return false;
271}
272
273static bool StringIsValidForGLES(const char* str) {
274 for (; *str; ++str) {
275 if (!CharacterIsValidForGLES(*str)) {
276 return false;
277 }
278 }
279 return true;
280}
281
[email protected]297ca1c2011-06-20 23:08:46282// Wrapper for glEnable/glDisable that doesn't suck.
283static void EnableDisable(GLenum pname, bool enable) {
284 if (enable) {
285 glEnable(pname);
286 } else {
287 glDisable(pname);
288 }
289}
290
[email protected]6217d392010-03-25 22:08:35291// This class prevents any GL errors that occur when it is in scope from
292// being reported to the client.
293class ScopedGLErrorSuppressor {
294 public:
[email protected]ab09b612013-03-11 22:11:51295 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30296 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35297 ~ScopedGLErrorSuppressor();
298 private:
[email protected]ab09b612013-03-11 22:11:51299 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30300 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35301 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
302};
303
[email protected]2b10c02d2014-01-29 16:43:02304// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35305// object goes out of scope. Also temporarily switches to using active texture
306// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02307class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35308 public:
[email protected]00c2cf92014-03-14 00:08:37309 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02310 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35311
312 private:
[email protected]ce296892013-10-24 22:04:36313 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02314 GLenum target_;
315 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35316};
317
318// Temporarily changes a decoder's bound render buffer and restore it when this
319// object goes out of scope.
320class ScopedRenderBufferBinder {
321 public:
[email protected]00c2cf92014-03-14 00:08:37322 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35323 ~ScopedRenderBufferBinder();
324
325 private:
[email protected]18e785a2013-10-09 03:29:41326 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35327 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
328};
329
330// Temporarily changes a decoder's bound frame buffer and restore it when this
331// object goes out of scope.
332class ScopedFrameBufferBinder {
333 public:
[email protected]00c2cf92014-03-14 00:08:37334 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35335 ~ScopedFrameBufferBinder();
336
337 private:
338 GLES2DecoderImpl* decoder_;
339 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
340};
341
[email protected]34ff8b0c2010-10-01 20:06:02342// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52343// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27344// if it is bound or enforce_internal_framebuffer is true. If internal is
345// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02346class ScopedResolvedFrameBufferBinder {
347 public:
[email protected]00c2cf92014-03-14 00:08:37348 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
349 bool enforce_internal_framebuffer,
350 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02351 ~ScopedResolvedFrameBufferBinder();
352
353 private:
354 GLES2DecoderImpl* decoder_;
355 bool resolve_and_bind_;
356 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
357};
358
[email protected]00c2cf92014-03-14 00:08:37359class ScopedModifyPixels {
360 public:
361 explicit ScopedModifyPixels(TextureRef* ref);
362 ~ScopedModifyPixels();
363
364 private:
365 TextureRef* ref_;
366};
367
368ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
369 if (ref_)
370 ref_->texture()->OnWillModifyPixels();
371}
372
373ScopedModifyPixels::~ScopedModifyPixels() {
374 if (ref_)
375 ref_->texture()->OnDidModifyPixels();
376}
377
378class ScopedRenderTo {
379 public:
380 explicit ScopedRenderTo(Framebuffer* framebuffer);
381 ~ScopedRenderTo();
382
383 private:
384 const Framebuffer* framebuffer_;
385};
386
387ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
388 : framebuffer_(framebuffer) {
389 if (framebuffer)
390 framebuffer_->OnWillRenderTo();
391}
392
393ScopedRenderTo::~ScopedRenderTo() {
394 if (framebuffer_)
395 framebuffer_->OnDidRenderTo();
396}
397
[email protected]6217d392010-03-25 22:08:35398// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35399class BackTexture {
[email protected]6217d392010-03-25 22:08:35400 public:
[email protected]ce296892013-10-24 22:04:36401 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35402 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35403
404 // Create a new render texture.
405 void Create();
406
407 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09408 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35409
410 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58411 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35412
413 // Destroy the render texture. This must be explicitly called before
414 // destroying this object.
415 void Destroy();
416
[email protected]97872062010-11-03 19:07:05417 // Invalidate the texture. This can be used when a context is lost and it is
418 // not possible to make it current in order to free the resource.
419 void Invalidate();
420
[email protected]6217d392010-03-25 22:08:35421 GLuint id() const {
422 return id_;
423 }
424
[email protected]d37231fa2010-04-09 21:16:02425 gfx::Size size() const {
426 return size_;
427 }
428
[email protected]6217d392010-03-25 22:08:35429 private:
[email protected]ff6493f2012-07-31 19:52:25430 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36431 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48432 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35433 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02434 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35435 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35436};
437
438// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35439class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35440 public:
[email protected]d5a28e452013-10-10 01:01:40441 explicit BackRenderbuffer(
442 RenderbufferManager* renderbuffer_manager,
443 MemoryTracker* memory_tracker,
444 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35445 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35446
447 // Create a new render buffer.
448 void Create();
449
450 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18451 bool AllocateStorage(const FeatureInfo* feature_info,
452 const gfx::Size& size,
453 GLenum format,
454 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35455
456 // Destroy the render buffer. This must be explicitly called before destroying
457 // this object.
458 void Destroy();
459
[email protected]97872062010-11-03 19:07:05460 // Invalidate the render buffer. This can be used when a context is lost and
461 // it is not possible to make it current in order to free the resource.
462 void Invalidate();
463
[email protected]6217d392010-03-25 22:08:35464 GLuint id() const {
465 return id_;
466 }
467
468 private:
[email protected]d5a28e452013-10-10 01:01:40469 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25470 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40471 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48472 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35473 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35474 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35475};
476
477// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35478class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35479 public:
[email protected]ed9f9cd2013-02-27 21:12:35480 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
481 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35482
483 // Create a new frame buffer.
484 void Create();
485
486 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35487 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35488
[email protected]b9363b22010-06-09 22:06:15489 // Attach a render buffer to a frame buffer. Note that this unbinds any
490 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35491 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35492
[email protected]6217d392010-03-25 22:08:35493 // Destroy the frame buffer. This must be explicitly called before destroying
494 // this object.
495 void Destroy();
496
[email protected]97872062010-11-03 19:07:05497 // Invalidate the frame buffer. This can be used when a context is lost and it
498 // is not possible to make it current in order to free the resource.
499 void Invalidate();
500
[email protected]6217d392010-03-25 22:08:35501 // See glCheckFramebufferStatusEXT.
502 GLenum CheckStatus();
503
504 GLuint id() const {
505 return id_;
506 }
507
508 private:
509 GLES2DecoderImpl* decoder_;
510 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35511 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35512};
[email protected]34ff8b0c2010-10-01 20:06:02513
[email protected]5a36dc132013-07-23 23:17:55514struct FenceCallback {
515 explicit FenceCallback()
516 : fence(gfx::GLFence::Create()) {
517 DCHECK(fence);
518 }
[email protected]5a36dc132013-07-23 23:17:55519 std::vector<base::Closure> callbacks;
520 scoped_ptr<gfx::GLFence> fence;
521};
522
[email protected]e3c4a9ab2014-03-31 09:07:02523class AsyncUploadTokenCompletionObserver
524 : public AsyncPixelTransferCompletionObserver {
525 public:
526 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
527 : async_upload_token_(async_upload_token) {
528 }
529
530 virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE {
531 DCHECK(mem_params.buffer());
532 void* data = mem_params.GetDataAddress();
533 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
534 sync->SetAsyncUploadToken(async_upload_token_);
535 }
536
537 private:
538 virtual ~AsyncUploadTokenCompletionObserver() {
539 }
540
541 uint32 async_upload_token_;
542
543 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
544};
545
[email protected]43f28f832010-02-03 02:28:48546// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32547
[email protected]ddb1e5a2010-12-13 20:10:45548bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
549 uint32* service_texture_id) {
550 return false;
551}
552
[email protected]a3ded6d2010-10-19 06:44:39553GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06554 : initialized_(false),
555 debug_(false),
[email protected]1d82e822013-04-10 21:32:32556 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32557}
558
[email protected]3916c97e2010-02-25 03:20:50559GLES2Decoder::~GLES2Decoder() {
560}
561
[email protected]cac16542014-01-15 17:53:51562void GLES2Decoder::BeginDecoding() {}
563
564void GLES2Decoder::EndDecoding() {}
565
[email protected]f39f4b3f2010-05-12 17:04:08566// This class implements GLES2Decoder so we don't have to expose all the GLES2
567// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54568class GLES2DecoderImpl : public GLES2Decoder,
569 public FramebufferManager::TextureDetachObserver {
[email protected]f39f4b3f2010-05-12 17:04:08570 public:
[email protected]aa7666122011-09-02 19:45:52571 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00572 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08573
[email protected]96449d2c2009-11-25 00:01:32574 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14575 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50576 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00577 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32578
579 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00580 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32581
582 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38583 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
584 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23585 bool offscreen,
[email protected]6217d392010-03-25 22:08:35586 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29587 const DisallowedFeatures& disallowed_features,
[email protected]b8e97b62012-09-30 15:09:00588 const std::vector<int32>& attribs) OVERRIDE;
589 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38590 virtual void SetSurface(
591 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]aba551b2014-02-08 03:38:32592 virtual void ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00593 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39594 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00595 virtual bool MakeCurrent() OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00596 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
597 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
598 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]6d668892013-12-04 21:37:12599 virtual Capabilities GetCapabilities() OVERRIDE;
[email protected]5baa86bc2014-01-16 04:33:16600 virtual void RestoreState(const ContextState* prev_state) const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06601
602 virtual void RestoreActiveTexture() const OVERRIDE {
603 state_.RestoreActiveTexture();
604 }
[email protected]5baa86bc2014-01-16 04:33:16605 virtual void RestoreAllTextureUnitBindings(
606 const ContextState* prev_state) const OVERRIDE {
607 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55608 }
[email protected]4b2d2b262014-03-21 22:05:27609 virtual void RestoreActiveTextureUnitBinding(
610 unsigned int target) const OVERRIDE {
611 state_.RestoreActiveTextureUnitBinding(target);
612 }
[email protected]29a4d902013-02-26 20:18:06613 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
614 state_.RestoreAttribute(index);
615 }
616 virtual void RestoreBufferBindings() const OVERRIDE {
617 state_.RestoreBufferBindings();
618 }
619 virtual void RestoreGlobalState() const OVERRIDE {
620 state_.RestoreGlobalState();
621 }
622 virtual void RestoreProgramBindings() const OVERRIDE {
623 state_.RestoreProgramBindings();
624 }
[email protected]29a4d902013-02-26 20:18:06625 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
[email protected]5baa86bc2014-01-16 04:33:16626 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06627 }
628 virtual void RestoreFramebufferBindings() const OVERRIDE;
629 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
630
[email protected]cd2ef752014-02-12 23:16:03631 virtual void ClearAllAttributes() const OVERRIDE;
632 virtual void RestoreAllAttributes() const OVERRIDE;
633
[email protected]b8e97b62012-09-30 15:09:00634 virtual QueryManager* GetQueryManager() OVERRIDE {
635 return query_manager_.get();
636 }
637 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46638 return vertex_array_manager_.get();
639 }
[email protected]b8e97b62012-09-30 15:09:00640 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05641 virtual bool HasMoreIdleWork() OVERRIDE;
642 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48643
[email protected]5a36dc132013-07-23 23:17:55644 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
645
[email protected]9d37f062011-11-22 01:24:52646 virtual void SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:07647 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00648
[email protected]1d82e822013-04-10 21:32:32649 virtual Logger* GetLogger() OVERRIDE;
[email protected]cac16542014-01-15 17:53:51650
651 virtual void BeginDecoding() OVERRIDE;
652 virtual void EndDecoding() OVERRIDE;
653
[email protected]d3eba342013-04-18 21:11:50654 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]5baa86bc2014-01-16 04:33:16655 virtual const ContextState* GetContextState() OVERRIDE { return &state_; }
[email protected]1d82e822013-04-10 21:32:32656
[email protected]e3932abb2013-03-13 00:01:37657 virtual void SetShaderCacheCallback(
658 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51659 virtual void SetWaitSyncPointCallback(
660 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00661
[email protected]85a4ac22013-05-31 01:58:47662 virtual AsyncPixelTransferManager*
663 GetAsyncPixelTransferManager() OVERRIDE;
664 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]498b5c072013-06-04 19:30:07665 virtual void SetAsyncPixelTransferManagerForTest(
666 AsyncPixelTransferManager* manager) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09667 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59668
[email protected]1318e922010-09-17 22:03:16669 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00670 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48671
[email protected]63b465922012-09-06 02:04:52672 virtual uint32 GetTextureUploadCount() OVERRIDE;
673 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
674 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30675 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52676
[email protected]8e3e0662010-08-23 18:46:30677 // Restores the current state to the user's settings.
678 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30679
[email protected]297ca1c2011-06-20 23:08:46680 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
681 void ApplyDirtyState();
682
683 // These check the state of the currently bound framebuffer or the
684 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54685 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
686 // check with all attached and enabled color attachments.
687 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46688 bool BoundFramebufferHasDepthAttachment();
689 bool BoundFramebufferHasStencilAttachment();
690
[email protected]b8e97b62012-09-30 15:09:00691 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43692
[email protected]91c94eb2013-10-22 10:32:54693 // Overridden from FramebufferManager::TextureDetachObserver:
694 virtual void OnTextureRefDetachedFromFramebuffer(
695 TextureRef* texture) OVERRIDE;
696
[email protected]f42f05b2013-11-15 21:46:18697 // Helpers to facilitate calling into compatible extensions.
698 static void RenderbufferStorageMultisampleHelper(
699 const FeatureInfo* feature_info,
700 GLenum target,
701 GLsizei samples,
702 GLenum internal_format,
703 GLsizei width,
704 GLsizei height);
705
706 void BlitFramebufferHelper(GLint srcX0,
707 GLint srcY0,
708 GLint srcX1,
709 GLint srcY1,
710 GLint dstX0,
711 GLint dstY0,
712 GLint dstX1,
713 GLint dstY1,
714 GLbitfield mask,
715 GLenum filter);
[email protected]345ba902013-11-14 21:39:00716
[email protected]96449d2c2009-11-25 00:01:32717 private:
[email protected]70d34263c2013-01-09 00:27:45718 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02719 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35720 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35721
[email protected]c2f8c8402010-12-06 18:07:24722 // Initialize or re-initialize the shader translator.
723 bool InitializeShaderTranslator();
724
[email protected]302ce6d2011-07-07 23:28:11725 void UpdateCapabilities();
726
[email protected]ae51d192010-04-27 00:48:03727 // Helpers for the glGen and glDelete functions.
728 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
729 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
730 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
731 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
732 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
733 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
734 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
735 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53736 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
737 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46738 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
739 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47740
[email protected]e3c4a9ab2014-03-31 09:07:02741 // Helper for async upload token completion notification callback.
742 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
743 uint32 sync_data_shm_id,
744 uint32 sync_data_shm_offset);
745
746
747
[email protected]70d34263c2013-01-09 00:27:45748 // Workarounds
749 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51750 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45751
[email protected]3916c97e2010-02-25 03:20:50752 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50753 BufferManager* buffer_manager() {
754 return group_->buffer_manager();
755 }
756
[email protected]a25fa872010-03-25 02:57:58757 RenderbufferManager* renderbuffer_manager() {
758 return group_->renderbuffer_manager();
759 }
760
761 FramebufferManager* framebuffer_manager() {
762 return group_->framebuffer_manager();
763 }
764
[email protected]3916c97e2010-02-25 03:20:50765 ProgramManager* program_manager() {
766 return group_->program_manager();
767 }
768
769 ShaderManager* shader_manager() {
770 return group_->shader_manager();
771 }
772
[email protected]29a4d902013-02-26 20:18:06773 const TextureManager* texture_manager() const {
774 return group_->texture_manager();
775 }
776
[email protected]3916c97e2010-02-25 03:20:50777 TextureManager* texture_manager() {
778 return group_->texture_manager();
779 }
780
[email protected]78b514b2012-05-01 21:50:59781 MailboxManager* mailbox_manager() {
782 return group_->mailbox_manager();
783 }
784
[email protected]09d50362012-10-18 20:54:37785 ImageManager* image_manager() {
786 return group_->image_manager();
787 }
788
[email protected]944b62f32012-09-27 02:20:46789 VertexArrayManager* vertex_array_manager() {
790 return vertex_array_manager_.get();
791 }
792
[email protected]7989c9e2013-01-23 06:39:26793 MemoryTracker* memory_tracker() {
794 return group_->memory_tracker();
795 }
796
797 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
798 MemoryTracker* tracker = memory_tracker();
799 if (tracker) {
800 return tracker->EnsureGPUMemoryAvailable(estimated_size);
801 }
802 return true;
803 }
804
[email protected]34ff8b0c2010-10-01 20:06:02805 bool IsOffscreenBufferMultisampled() const {
806 return offscreen_target_samples_ > 1;
807 }
808
[email protected]ed9f9cd2013-02-27 21:12:35809 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49810 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03811 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35812 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47813 }
814
815 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49816 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07817 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47818 }
819
820 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35821 void RemoveTexture(GLuint client_id) {
822 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50823 }
[email protected]a93bb842010-02-16 23:03:47824
[email protected]d37231fa2010-04-09 21:16:02825 // Get the size (in pixels) of the currently bound frame buffer (either FBO
826 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30827 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02828
[email protected]9edc6b22010-12-23 02:00:26829 // Get the format of the currently bound frame buffer (either FBO or regular
830 // back buffer)
[email protected]68586372013-12-11 01:27:59831 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26832 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46833 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26834
[email protected]a93bb842010-02-16 23:03:47835 // Wrapper for CompressedTexImage2D commands.
836 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37837 GLenum target,
838 GLint level,
839 GLenum internal_format,
840 GLsizei width,
841 GLsizei height,
842 GLint border,
843 GLsizei image_size,
844 const void* data);
[email protected]a93bb842010-02-16 23:03:47845
[email protected]cadde4a2010-07-31 17:10:43846 // Wrapper for CompressedTexSubImage2D.
847 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37848 GLenum target,
849 GLint level,
850 GLint xoffset,
851 GLint yoffset,
852 GLsizei width,
853 GLsizei height,
854 GLenum format,
855 GLsizei imageSize,
856 const void * data);
[email protected]cadde4a2010-07-31 17:10:43857
858 // Wrapper for CopyTexImage2D.
859 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37860 GLenum target,
861 GLint level,
862 GLenum internal_format,
863 GLint x,
864 GLint y,
865 GLsizei width,
866 GLsizei height,
867 GLint border);
[email protected]cadde4a2010-07-31 17:10:43868
[email protected]6d792ee12013-05-15 00:40:56869 // Wrapper for SwapBuffers.
870 void DoSwapBuffers();
871
[email protected]cadde4a2010-07-31 17:10:43872 // Wrapper for CopyTexSubImage2D.
873 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37874 GLenum target,
875 GLint level,
876 GLint xoffset,
877 GLint yoffset,
878 GLint x,
879 GLint y,
880 GLsizei width,
881 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43882
[email protected]f598f422012-12-07 08:30:03883 // Validation for TexSubImage2D.
884 bool ValidateTexSubImage2D(
885 error::Error* error,
886 const char* function_name,
887 GLenum target,
888 GLint level,
889 GLint xoffset,
890 GLint yoffset,
891 GLsizei width,
892 GLsizei height,
893 GLenum format,
894 GLenum type,
895 const void * data);
896
[email protected]cadde4a2010-07-31 17:10:43897 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03898 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37899 GLenum target,
900 GLint level,
901 GLint xoffset,
902 GLint yoffset,
903 GLsizei width,
904 GLsizei height,
905 GLenum format,
906 GLenum type,
907 const void * data);
[email protected]cadde4a2010-07-31 17:10:43908
[email protected]32145a92012-12-17 09:01:59909 // Extra validation for async tex(Sub)Image2D.
910 bool ValidateAsyncTransfer(
911 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47912 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59913 GLenum target,
914 GLint level,
915 const void * data);
916
[email protected]e51bdf32011-11-23 22:21:46917 // Wrapper for TexImageIOSurface2DCHROMIUM.
918 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37919 GLenum target,
920 GLsizei width,
921 GLsizei height,
922 GLuint io_surface_id,
923 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46924
[email protected]43410e92012-04-20 17:06:28925 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37926 GLenum target,
927 GLuint source_id,
928 GLuint target_id,
929 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54930 GLenum internal_format,
931 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28932
[email protected]97dc7cbe2011-12-06 17:26:17933 // Wrapper for TexStorage2DEXT.
934 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37935 GLenum target,
936 GLint levels,
937 GLenum internal_format,
938 GLsizei width,
939 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17940
[email protected]78b514b2012-05-01 21:50:59941 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
942 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
943
[email protected]09d50362012-10-18 20:54:37944 void DoBindTexImage2DCHROMIUM(
945 GLenum target,
946 GLint image_id);
947 void DoReleaseTexImage2DCHROMIUM(
948 GLenum target,
949 GLint image_id);
950
[email protected]94307712012-11-16 23:26:11951 void DoTraceEndCHROMIUM(void);
952
[email protected]2f143d482013-03-14 18:04:49953 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
954
[email protected]ed9f9cd2013-02-27 21:12:35955 // Creates a Program for the given program.
956 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57957 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35958 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47959 }
960
[email protected]07f54fcc2009-12-22 02:46:30961 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35962 Program* GetProgram(GLuint client_id) {
963 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46964 }
[email protected]07f54fcc2009-12-22 02:46:30965
[email protected]cae20172012-12-07 00:06:19966#if defined(NDEBUG)
967 void LogClientServiceMapping(
968 const char* /* function_name */,
969 GLuint /* client_id */,
970 GLuint /* service_id */) {
971 }
972 template<typename T>
973 void LogClientServiceForInfo(
974 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
975 }
976#else
977 void LogClientServiceMapping(
978 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26979 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:47980 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
981 << ": client_id = " << client_id
982 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:26983 }
[email protected]cae20172012-12-07 00:06:19984 }
985 template<typename T>
986 void LogClientServiceForInfo(
987 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26988 if (info) {
[email protected]cae20172012-12-07 00:06:19989 LogClientServiceMapping(function_name, client_id, info->service_id());
990 }
991 }
992#endif
993
[email protected]6b8cf1a2010-05-06 16:13:58994 // Gets the program info for the given program. If it's not a program
995 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35996 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58997 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42998 Program* program = GetProgram(client_id);
999 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351000 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511001 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431002 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581003 } else {
[email protected]ab09b612013-03-11 22:11:511004 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581005 }
1006 }
[email protected]df37b9932013-03-08 05:21:421007 LogClientServiceForInfo(program, client_id, function_name);
1008 return program;
[email protected]6b8cf1a2010-05-06 16:13:581009 }
1010
1011
[email protected]ed9f9cd2013-02-27 21:12:351012 // Creates a Shader for the given shader.
1013 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571014 GLuint client_id,
1015 GLuint service_id,
1016 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351017 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571018 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311019 }
1020
1021 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351022 Shader* GetShader(GLuint client_id) {
1023 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311024 }
1025
[email protected]6b8cf1a2010-05-06 16:13:581026 // Gets the shader info for the given shader. If it's not a shader generates a
1027 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351028 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581029 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421030 Shader* shader = GetShader(client_id);
1031 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351032 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511033 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431034 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581035 } else {
[email protected]ab09b612013-03-11 22:11:511036 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431037 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581038 }
1039 }
[email protected]df37b9932013-03-08 05:21:421040 LogClientServiceForInfo(shader, client_id, function_name);
1041 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581042 }
1043
[email protected]a93bb842010-02-16 23:03:471044 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351045 void CreateBuffer(GLuint client_id, GLuint service_id) {
1046 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471047 }
1048
[email protected]07f54fcc2009-12-22 02:46:301049 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211050 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071051 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1052 return buffer;
[email protected]1d32bc82010-01-13 22:06:461053 }
[email protected]07f54fcc2009-12-22 02:46:301054
[email protected]a93bb842010-02-16 23:03:471055 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1056 // on glDeleteBuffers so we can make sure the user does not try to render
1057 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351058 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471059
[email protected]a25fa872010-03-25 02:57:581060 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351061 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1062 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581063 }
1064
1065 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061066 Framebuffer* GetFramebuffer(GLuint client_id) {
1067 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581068 }
1069
1070 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351071 void RemoveFramebuffer(GLuint client_id) {
1072 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581073 }
1074
1075 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351076 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1077 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031078 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581079 }
1080
1081 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271082 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1083 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581084 }
1085
1086 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351087 void RemoveRenderbuffer(GLuint client_id) {
1088 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581089 }
1090
[email protected]944b62f32012-09-27 02:20:461091 // Gets the vertex attrib manager for the given vertex array.
1092 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1093 VertexAttribManager* info =
1094 vertex_array_manager()->GetVertexAttribManager(client_id);
1095 return info;
1096 }
1097
1098 // Removes the vertex attrib manager for the given vertex array.
1099 void RemoveVertexAttribManager(GLuint client_id) {
1100 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1101 }
1102
1103 // Creates a vertex attrib manager for the given vertex array.
1104 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1105 return vertex_array_manager()->CreateVertexAttribManager(
1106 client_id, service_id, group_->max_vertex_attribs());
1107 }
1108
[email protected]258a3313f2011-10-18 20:13:571109 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331110 void DoBindUniformLocationCHROMIUM(
1111 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571112
[email protected]558847a2010-03-24 07:02:541113 error::Error GetAttribLocationHelper(
1114 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1115 const std::string& name_str);
1116
1117 error::Error GetUniformLocationHelper(
1118 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1119 const std::string& name_str);
1120
[email protected]3916c97e2010-02-25 03:20:501121 // Helper for glShaderSource.
1122 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031123 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301124
[email protected]0d6bfdc2011-11-02 01:32:201125 // Clear any textures used by the current program.
1126 bool ClearUnclearedTextures();
1127
[email protected]0d6bfdc2011-11-02 01:32:201128 // Clears any uncleared attachments attached to the given frame buffer.
1129 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061130 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281131
[email protected]0d6bfdc2011-11-02 01:32:201132 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001133 virtual bool ClearLevel(unsigned service_id,
1134 unsigned bind_target,
1135 unsigned target,
1136 int level,
[email protected]d8e6c9242014-02-20 16:56:251137 unsigned internal_format,
[email protected]b8e97b62012-09-30 15:09:001138 unsigned format,
1139 unsigned type,
1140 int width,
1141 int height,
1142 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201143
[email protected]c007aa02010-09-02 22:22:401144 // Restore all GL state that affects clearing.
1145 void RestoreClearState();
1146
[email protected]3a2e7c7b2010-08-06 01:12:281147 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461148 // Returns: true if glEnable/glDisable should actually be called.
1149 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281150
[email protected]0d6bfdc2011-11-02 01:32:201151 // Check that the currently bound framebuffers are valid.
1152 // Generates GL error if not.
1153 bool CheckBoundFramebuffersValid(const char* func_name);
1154
1155 // Check if a framebuffer meets our requirements.
1156 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351157 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201158 GLenum target,
1159 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271160
[email protected]939e7362010-05-13 20:49:101161 // Checks if the current program exists and is valid. If not generates the
1162 // appropriate GL error. Returns true if the current program is in a usable
1163 // state.
1164 bool CheckCurrentProgram(const char* function_name);
1165
1166 // Checks if the current program exists and is valid and that location is not
1167 // -1. If the current program is not valid generates the appropriate GL
1168 // error. Returns true if the current program is in a usable state and
1169 // location is not -1.
1170 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1171
1172 // Gets the type of a uniform for a location in the current program. Sets GL
1173 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361174 // program is valid and the location exists. Adjusts count so it
1175 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131176 bool PrepForSetUniformByLocation(GLint fake_location,
1177 const char* function_name,
1178 Program::UniformApiType api_type,
1179 GLint* real_location,
1180 GLenum* type,
1181 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101182
[email protected]b177ae22011-11-01 03:29:111183 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021184 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111185
[email protected]b273e432010-04-12 17:23:581186 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1187 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1188
[email protected]ac77603c72013-03-08 13:52:061189 // Helper for glGetVertexAttrib
1190 void GetVertexAttribHelper(
1191 const VertexAttrib* attrib, GLenum pname, GLint* param);
1192
[email protected]96449d2c2009-11-25 00:01:321193 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031194 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321195
1196 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031197 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321198
[email protected]3916c97e2010-02-25 03:20:501199 // Wrapper for glActiveTexture
1200 void DoActiveTexture(GLenum texture_unit);
1201
[email protected]ae51d192010-04-27 00:48:031202 // Wrapper for glAttachShader
1203 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1204
[email protected]96449d2c2009-11-25 00:01:321205 // Wrapper for glBindBuffer since we need to track the current targets.
1206 void DoBindBuffer(GLenum target, GLuint buffer);
1207
[email protected]86093972010-03-11 00:13:561208 // Wrapper for glBindFramebuffer since we need to track the current targets.
1209 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1210
1211 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1212 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1213
[email protected]a93bb842010-02-16 23:03:471214 // Wrapper for glBindTexture since we need to track the current targets.
1215 void DoBindTexture(GLenum target, GLuint texture);
1216
[email protected]944b62f32012-09-27 02:20:461217 // Wrapper for glBindVertexArrayOES
1218 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571219 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461220
[email protected]49cabed2013-11-13 18:15:181221 // Wrapper for glBlitFramebufferCHROMIUM.
1222 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301223 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1224 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1225 GLbitfield mask, GLenum filter);
1226
[email protected]36cef8ce2010-03-16 07:34:451227 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111228 void DoBufferSubData(
1229 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1230
[email protected]36cef8ce2010-03-16 07:34:451231 // Wrapper for glCheckFramebufferStatus
1232 GLenum DoCheckFramebufferStatus(GLenum target);
1233
[email protected]3a03a8f2011-03-19 00:51:271234 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081235 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271236
[email protected]88a61bf2012-10-27 13:00:421237 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421238 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251239 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281240
[email protected]45bf5152010-02-12 00:11:311241 // Wrapper for glCompileShader.
1242 void DoCompileShader(GLuint shader);
1243
[email protected]269200b12010-11-18 22:53:061244 // Helper for DeleteSharedIdsCHROMIUM commands.
1245 void DoDeleteSharedIdsCHROMIUM(
1246 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101247
[email protected]ae51d192010-04-27 00:48:031248 // Wrapper for glDetachShader
1249 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1250
[email protected]3a2e7c7b2010-08-06 01:12:281251 // Wrapper for glDisable
1252 void DoDisable(GLenum cap);
1253
[email protected]07f54fcc2009-12-22 02:46:301254 // Wrapper for glDisableVertexAttribArray.
1255 void DoDisableVertexAttribArray(GLuint index);
1256
[email protected]60f22d32012-12-12 00:31:581257 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1258 // attachments.
1259 void DoDiscardFramebufferEXT(GLenum target,
1260 GLsizei numAttachments,
1261 const GLenum* attachments);
1262
[email protected]3a2e7c7b2010-08-06 01:12:281263 // Wrapper for glEnable
1264 void DoEnable(GLenum cap);
1265
[email protected]07f54fcc2009-12-22 02:46:301266 // Wrapper for glEnableVertexAttribArray.
1267 void DoEnableVertexAttribArray(GLuint index);
1268
[email protected]882ba1e22012-03-08 19:02:531269 // Wrapper for glFinish.
1270 void DoFinish();
1271
1272 // Wrapper for glFlush.
1273 void DoFlush();
1274
[email protected]36cef8ce2010-03-16 07:34:451275 // Wrapper for glFramebufferRenderbufffer.
1276 void DoFramebufferRenderbuffer(
1277 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1278 GLuint renderbuffer);
1279
1280 // Wrapper for glFramebufferTexture2D.
1281 void DoFramebufferTexture2D(
1282 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1283 GLint level);
1284
[email protected]7d3c36e2013-07-12 14:13:161285 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1286 void DoFramebufferTexture2DMultisample(
1287 GLenum target, GLenum attachment, GLenum textarget,
1288 GLuint texture, GLint level, GLsizei samples);
1289
1290 // Common implementation for both DoFramebufferTexture2D wrappers.
1291 void DoFramebufferTexture2DCommon(const char* name,
1292 GLenum target, GLenum attachment, GLenum textarget,
1293 GLuint texture, GLint level, GLsizei samples);
1294
[email protected]a93bb842010-02-16 23:03:471295 // Wrapper for glGenerateMipmap
1296 void DoGenerateMipmap(GLenum target);
1297
[email protected]269200b12010-11-18 22:53:061298 // Helper for GenSharedIdsCHROMIUM commands.
1299 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101300 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1301
[email protected]7d3c36e2013-07-12 14:13:161302 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1303 // to account for different pname values defined in different extension
1304 // variants.
1305 GLenum AdjustGetPname(GLenum pname);
1306
[email protected]b273e432010-04-12 17:23:581307 // Wrapper for DoGetBooleanv.
1308 void DoGetBooleanv(GLenum pname, GLboolean* params);
1309
1310 // Wrapper for DoGetFloatv.
1311 void DoGetFloatv(GLenum pname, GLfloat* params);
1312
[email protected]36cef8ce2010-03-16 07:34:451313 // Wrapper for glGetFramebufferAttachmentParameteriv.
1314 void DoGetFramebufferAttachmentParameteriv(
1315 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1316
[email protected]a0c3e972010-04-21 00:49:131317 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581318 void DoGetIntegerv(GLenum pname, GLint* params);
1319
[email protected]29a9eb52010-04-13 09:04:231320 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061321 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231322 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1323
[email protected]17cfbe0e2013-03-07 01:26:081324 // Wrapper for glGetBufferParameteriv.
1325 void DoGetBufferParameteriv(
1326 GLenum target, GLenum pname, GLint* params);
1327
[email protected]a0c3e972010-04-21 00:49:131328 // Wrapper for glGetProgramiv.
1329 void DoGetProgramiv(
1330 GLuint program_id, GLenum pname, GLint* params);
1331
[email protected]36cef8ce2010-03-16 07:34:451332 // Wrapper for glRenderbufferParameteriv.
1333 void DoGetRenderbufferParameteriv(
1334 GLenum target, GLenum pname, GLint* params);
1335
[email protected]ddd968b82010-03-02 00:44:291336 // Wrapper for glGetShaderiv
1337 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1338
[email protected]4c6f5462014-03-05 00:26:561339 // Wrappers for glGetTexParameter.
1340 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1341 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1342 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1343
[email protected]b1122982010-05-17 23:04:241344 // Wrappers for glGetVertexAttrib.
1345 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1346 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1347
[email protected]1958e0e2010-04-22 05:17:151348 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241349 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151350 bool DoIsBuffer(GLuint client_id);
1351 bool DoIsFramebuffer(GLuint client_id);
1352 bool DoIsProgram(GLuint client_id);
1353 bool DoIsRenderbuffer(GLuint client_id);
1354 bool DoIsShader(GLuint client_id);
1355 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461356 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151357
[email protected]07f54fcc2009-12-22 02:46:301358 // Wrapper for glLinkProgram
1359 void DoLinkProgram(GLuint program);
1360
[email protected]269200b12010-11-18 22:53:061361 // Helper for RegisterSharedIdsCHROMIUM.
1362 void DoRegisterSharedIdsCHROMIUM(
1363 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101364
[email protected]36cef8ce2010-03-16 07:34:451365 // Wrapper for glRenderbufferStorage.
1366 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031367 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451368
[email protected]49cabed2013-11-13 18:15:181369 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1370 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301371 GLenum target, GLsizei samples, GLenum internalformat,
1372 GLsizei width, GLsizei height);
1373
[email protected]49cabed2013-11-13 18:15:181374 // Handler for glRenderbufferStorageMultisampleEXT
1375 // (multisampled_render_to_texture).
1376 void DoRenderbufferStorageMultisampleEXT(
1377 GLenum target, GLsizei samples, GLenum internalformat,
1378 GLsizei width, GLsizei height);
1379
1380 // Common validation for multisample extensions.
1381 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1382 GLenum internalformat,
1383 GLsizei width,
1384 GLsizei height);
1385
[email protected]4a4c18b2013-09-13 22:50:101386 // Verifies that the currently bound multisample renderbuffer is valid
1387 // Very slow! Only done on platforms with driver bugs that return invalid
1388 // buffers under memory pressure
1389 bool VerifyMultisampleRenderbufferIntegrity(
1390 GLuint renderbuffer, GLenum format);
1391
[email protected]b273e432010-04-12 17:23:581392 // Wrapper for glReleaseShaderCompiler.
1393 void DoReleaseShaderCompiler() { }
1394
[email protected]3916c97e2010-02-25 03:20:501395 // Wrappers for glTexParameter functions.
1396 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1397 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1398 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1399 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1400
1401 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1402 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121403 void DoUniform1i(GLint fake_location, GLint v0);
1404 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1405 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1406 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1407 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101408
1409 // Wrappers for glUniformfv because some drivers don't correctly accept
1410 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121411 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1412 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1413 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1414 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501415
[email protected]43c2f1f2011-03-25 18:35:361416 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121417 GLint fake_location, GLsizei count, GLboolean transpose,
1418 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361419 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121420 GLint fake_location, GLsizei count, GLboolean transpose,
1421 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361422 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121423 GLint fake_location, GLsizei count, GLboolean transpose,
1424 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361425
[email protected]af6380962012-11-29 23:24:131426 bool SetVertexAttribValue(
1427 const char* function_name, GLuint index, const GLfloat* value);
1428
[email protected]b1122982010-05-17 23:04:241429 // Wrappers for glVertexAttrib??
1430 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1431 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1432 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1433 void DoVertexAttrib4f(
1434 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1435 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1436 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1437 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1438 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1439
[email protected]43410e92012-04-20 17:06:281440 // Wrapper for glViewport
1441 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1442
[email protected]07f54fcc2009-12-22 02:46:301443 // Wrapper for glUseProgram
1444 void DoUseProgram(GLuint program);
1445
[email protected]ae51d192010-04-27 00:48:031446 // Wrapper for glValidateProgram.
1447 void DoValidateProgram(GLuint program_client_id);
1448
[email protected]d2a0e1a2012-08-12 02:25:011449 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1450 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1451 void DoPopGroupMarkerEXT(void);
1452
[email protected]4e8a5b122010-05-08 22:00:101453 // Gets the number of values that will be returned by glGetXXX. Returns
1454 // false if pname is unknown.
1455 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1456
[email protected]07f54fcc2009-12-22 02:46:301457 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431458 bool IsDrawValid(
1459 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301460
[email protected]c13e1da62011-09-09 21:48:301461 // Returns true if successful, simulated will be true if attrib0 was
1462 // simulated.
[email protected]c6aef902012-02-14 03:31:421463 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431464 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281465 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241466
[email protected]91c94eb2013-10-22 10:32:541467 // If an image is bound to texture, this will call Will/DidUseTexImage
1468 // if needed.
1469 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1470 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1471
1472 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111473 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541474 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501475
[email protected]8fbedc02010-11-18 18:43:401476 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421477 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431478 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421479 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401480 void RestoreStateForSimulatedFixedAttribs();
1481
[email protected]c6aef902012-02-14 03:31:421482 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1483 // cases (primcount is 0 for non-instanced).
1484 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431485 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421486 bool instanced, GLenum mode, GLint first, GLsizei count,
1487 GLsizei primcount);
1488 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431489 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421490 bool instanced, GLenum mode, GLsizei count, GLenum type,
1491 int32 offset, GLsizei primcount);
1492
[email protected]61eeb33f2011-07-26 15:30:311493 GLenum GetBindTargetForSamplerType(GLenum type) {
1494 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461495 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1496 switch (type) {
1497 case GL_SAMPLER_2D:
1498 return GL_TEXTURE_2D;
1499 case GL_SAMPLER_CUBE:
1500 return GL_TEXTURE_CUBE_MAP;
1501 case GL_SAMPLER_EXTERNAL_OES:
1502 return GL_TEXTURE_EXTERNAL_OES;
1503 case GL_SAMPLER_2D_RECT_ARB:
1504 return GL_TEXTURE_RECTANGLE_ARB;
1505 }
1506
1507 NOTREACHED();
1508 return 0;
[email protected]61eeb33f2011-07-26 15:30:311509 }
1510
[email protected]8e3e0662010-08-23 18:46:301511 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061512 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1513 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301514 switch (target) {
1515 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451516 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341517 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301518 break;
[email protected]ebfb73c2012-08-15 02:37:451519 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341520 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301521 break;
1522 default:
1523 NOTREACHED();
1524 break;
1525 }
[email protected]4d8f0dd2013-03-09 14:37:061526 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301527 }
1528
[email protected]ed9f9cd2013-02-27 21:12:351529 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201530 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271531 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201532 switch (target) {
1533 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111534 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201535 break;
1536 default:
1537 NOTREACHED();
1538 break;
1539 }
[email protected]ee2a79c32013-03-10 03:50:271540 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201541 }
1542
[email protected]f7b85372010-02-03 01:11:371543 // Validates the program and location for a glGetUniform call and returns
1544 // a SizeResult setup to receive the result. Returns true if glGetUniform
1545 // should be called.
1546 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121547 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371548 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121549 error::Error* error, GLint* real_location, GLuint* service_id,
1550 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371551
[email protected]a10b4a02012-11-26 23:09:501552 virtual bool WasContextLost() OVERRIDE;
[email protected]93a7d98f2013-07-11 00:04:221553 virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091554 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431555
[email protected]e51bdf32011-11-23 22:21:461556#if defined(OS_MACOSX)
1557 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1558#endif
1559
[email protected]ad84a3a2012-06-08 21:42:431560 bool ValidateCompressedTexDimensions(
1561 const char* function_name,
1562 GLint level, GLsizei width, GLsizei height, GLenum format);
1563 bool ValidateCompressedTexFuncData(
1564 const char* function_name,
1565 GLsizei width, GLsizei height, GLenum format, size_t size);
1566 bool ValidateCompressedTexSubDimensions(
1567 const char* function_name,
1568 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1569 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351570 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431571
[email protected]ab09b612013-03-11 22:11:511572 void RenderWarning(const char* filename, int line, const std::string& msg);
1573 void PerformanceWarning(
1574 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011575
[email protected]62e155e2012-10-23 22:43:151576 const FeatureInfo::FeatureFlags& features() const {
1577 return feature_info_->feature_flags();
1578 }
1579
1580 const FeatureInfo::Workarounds& workarounds() const {
1581 return feature_info_->workarounds();
1582 }
1583
[email protected]a7266a92012-06-28 02:11:081584 bool ShouldDeferDraws() {
1585 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341586 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081587 surface_->DeferDraws();
1588 }
1589
[email protected]09e17272012-11-30 10:30:441590 bool ShouldDeferReads() {
1591 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341592 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441593 surface_->DeferDraws();
1594 }
1595
[email protected]c76fe672013-12-13 23:30:221596 error::Error WillAccessBoundFramebufferForDraw() {
1597 if (ShouldDeferDraws())
1598 return error::kDeferCommandUntilLater;
1599 if (!offscreen_target_frame_buffer_.get() &&
1600 !framebuffer_state_.bound_draw_framebuffer.get() &&
1601 !surface_->SetBackbufferAllocation(true))
1602 return error::kLostContext;
1603 return error::kNoError;
1604 }
1605
1606 error::Error WillAccessBoundFramebufferForRead() {
1607 if (ShouldDeferReads())
1608 return error::kDeferCommandUntilLater;
1609 if (!offscreen_target_frame_buffer_.get() &&
1610 !framebuffer_state_.bound_read_framebuffer.get() &&
1611 !surface_->SetBackbufferAllocation(true))
1612 return error::kLostContext;
1613 return error::kNoError;
1614 }
1615
[email protected]5a36dc132013-07-23 23:17:551616 void ProcessPendingReadPixels();
1617 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1618
[email protected]96449d2c2009-11-25 00:01:321619 // Generate a member function prototype for each command in an automated and
1620 // typesafe way.
1621 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141622 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351623 uint32 immediate_data_size, \
1624 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321625
1626 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1627
1628 #undef GLES2_CMD_OP
1629
[email protected]2f2d7042010-04-14 21:45:581630 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381631 scoped_refptr<gfx::GLSurface> surface_;
1632 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021633
[email protected]a3ded6d2010-10-19 06:44:391634 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351635 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391636
[email protected]1d82e822013-04-10 21:32:321637 DebugMarkerManager debug_marker_manager_;
1638 Logger logger_;
1639
[email protected]e259eb412012-10-13 05:47:241640 // All the state for this context.
1641 ContextState state_;
1642
[email protected]34ff8b0c2010-10-01 20:06:021643 // Current width and height of the offscreen frame buffer.
1644 gfx::Size offscreen_size_;
1645
[email protected]96449d2c2009-11-25 00:01:321646 // Util to help with GL.
1647 GLES2Util util_;
1648
[email protected]43410e92012-04-20 17:06:281649 // unpack flip y as last set by glPixelStorei
1650 bool unpack_flip_y_;
1651
[email protected]6c75c712012-06-19 15:43:171652 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281653 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171654 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281655
[email protected]944b62f32012-09-27 02:20:461656 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351657 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301658
[email protected]b1122982010-05-17 23:04:241659 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1660 GLuint attrib_0_buffer_id_;
1661
1662 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131663 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241664
[email protected]fc753442011-02-04 19:49:491665 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1666 bool attrib_0_buffer_matches_value_;
1667
[email protected]b1122982010-05-17 23:04:241668 // The size of attrib 0.
1669 GLsizei attrib_0_size_;
1670
[email protected]8fbedc02010-11-18 18:43:401671 // The buffer used to simulate GL_FIXED attribs.
1672 GLuint fixed_attrib_buffer_id_;
1673
1674 // The size of fiixed attrib buffer.
1675 GLsizei fixed_attrib_buffer_size_;
1676
[email protected]b9363b22010-06-09 22:06:151677 // The offscreen frame buffer that the client renders to. With EGL, the
1678 // depth and stencil buffers are separate. With regular GL there is a single
1679 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1680 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351681 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1682 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1683 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1684 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1685 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021686 GLenum offscreen_target_color_format_;
1687 GLenum offscreen_target_depth_format_;
1688 GLenum offscreen_target_stencil_format_;
1689 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561690 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351691
[email protected]de26b3c2011-08-03 21:54:271692 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351693 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1694 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491695 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351696 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271697
1698 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351699 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1700 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051701 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351702
[email protected]882ba1e22012-03-08 19:02:531703 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531704
[email protected]944b62f32012-09-27 02:20:461705 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1706
[email protected]729c0b42013-05-26 02:05:071707 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001708
[email protected]840a7e462013-02-27 01:29:511709 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481710
[email protected]e3932abb2013-03-13 00:01:371711 ShaderCacheCallback shader_cache_callback_;
1712
[email protected]85a4ac22013-05-31 01:58:471713 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421714
[email protected]32fe9aa2011-01-21 23:47:131715 // The format of the back buffer_
1716 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461717 bool back_buffer_has_depth_;
1718 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131719
[email protected]60f22d32012-12-12 00:31:581720 // Backbuffer attachments that are currently undefined.
1721 uint32 backbuffer_needs_clear_bits_;
1722
[email protected]a3a93e7b2010-08-28 00:48:561723 // The current decoder error.
1724 error::Error current_decoder_error_;
1725
[email protected]b1d2dcb2010-05-17 19:24:181726 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041727 scoped_refptr<ShaderTranslator> vertex_translator_;
1728 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181729
[email protected]e82fb792011-09-22 00:33:291730 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411731
[email protected]915a59a12010-09-30 21:29:111732 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051733 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351734 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051735
[email protected]65225772011-05-12 21:10:241736 int frame_number_;
1737
[email protected]706b69f2012-07-27 04:59:301738 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431739 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221740 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431741 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431742
[email protected]f0d74742011-10-03 16:31:041743 // These flags are used to override the state of the shared feature_info_
1744 // member. Because the same FeatureInfo instance may be shared among many
1745 // contexts, the assumptions on the availablity of extensions in WebGL
1746 // contexts may be broken. These flags override the shared state to preserve
1747 // WebGL semantics.
1748 bool force_webgl_glsl_validation_;
1749 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491750 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131751 bool draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041752
[email protected]062c38b2012-01-18 03:25:101753 bool compile_shader_always_succeeds_;
1754
[email protected]cae20172012-12-07 00:06:191755 // Log extra info.
1756 bool service_logging_;
1757
[email protected]e51bdf32011-11-23 22:21:461758#if defined(OS_MACOSX)
1759 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1760 TextureToIOSurfaceMap texture_to_io_surface_map_;
1761#endif
1762
[email protected]43410e92012-04-20 17:06:281763 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1764
[email protected]1868a342012-11-07 15:56:021765 // Cached values of the currently assigned viewport dimensions.
1766 GLsizei viewport_max_width_;
1767 GLsizei viewport_max_height_;
1768
[email protected]63b465922012-09-06 02:04:521769 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521770 base::TimeDelta total_processing_commands_time_;
1771
[email protected]c986af502013-08-14 01:04:441772 // States related to each manager.
1773 DecoderTextureState texture_state_;
1774 DecoderFramebufferState framebuffer_state_;
1775
[email protected]fb97b662013-02-20 23:02:141776 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131777 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
[email protected]cac16542014-01-15 17:53:511778 int gpu_trace_level_;
1779 bool gpu_trace_commands_;
[email protected]94307712012-11-16 23:26:111780
[email protected]5a36dc132013-07-23 23:17:551781 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1782
[email protected]4a4c18b2013-09-13 22:50:101783 // Used to validate multisample renderbuffers if needed
1784 GLuint validation_texture_;
1785 GLuint validation_fbo_multisample_;
1786 GLuint validation_fbo_;
1787
[email protected]96449d2c2009-11-25 00:01:321788 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1789};
1790
[email protected]ab09b612013-03-11 22:11:511791ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301792 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511793 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301794 error_state_(error_state) {
1795 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351796}
1797
1798ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301799 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351800}
1801
[email protected]2b10c02d2014-01-29 16:43:021802static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361803 TextureUnit& info = state->texture_units[0];
1804 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021805 scoped_refptr<TextureRef> texture_ref;
1806 switch (target) {
1807 case GL_TEXTURE_2D:
1808 texture_ref = info.bound_texture_2d;
1809 break;
1810 case GL_TEXTURE_CUBE_MAP:
1811 texture_ref = info.bound_texture_cube_map;
1812 break;
1813 case GL_TEXTURE_EXTERNAL_OES:
1814 texture_ref = info.bound_texture_external_oes;
1815 break;
1816 case GL_TEXTURE_RECTANGLE_ARB:
1817 texture_ref = info.bound_texture_rectangle_arb;
1818 break;
1819 default:
1820 NOTREACHED();
1821 break;
1822 }
1823 if (texture_ref.get()) {
1824 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361825 } else {
1826 last_id = 0;
1827 }
1828
[email protected]2b10c02d2014-01-29 16:43:021829 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361830 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1831}
1832
[email protected]2b10c02d2014-01-29 16:43:021833ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1834 GLuint id,
1835 GLenum target)
1836 : state_(state),
1837 target_(target) {
[email protected]ab09b612013-03-11 22:11:511838 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021839 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351840
1841 // TODO(apatrick): Check if there are any other states that need to be reset
1842 // before binding a new texture.
1843 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021844 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351845}
1846
[email protected]2b10c02d2014-01-29 16:43:021847ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511848 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021849 "ScopedTextureBinder::dtor", state_->GetErrorState());
1850 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351851}
1852
[email protected]18e785a2013-10-09 03:29:411853ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351854 GLuint id)
[email protected]18e785a2013-10-09 03:29:411855 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511856 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411857 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351858 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1859}
1860
1861ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511862 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411863 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1864 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351865}
1866
1867ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1868 GLuint id)
1869 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511870 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301871 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351872 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451873 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351874}
1875
1876ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511877 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301878 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301879 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351880}
1881
[email protected]34ff8b0c2010-10-01 20:06:021882ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271883 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521884 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341885 resolve_and_bind_ = (
1886 decoder_->offscreen_target_frame_buffer_.get() &&
1887 decoder_->IsOffscreenBufferMultisampled() &&
1888 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1889 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021890 if (!resolve_and_bind_)
1891 return;
1892
[email protected]ab09b612013-03-11 22:11:511893 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301894 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021895 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1896 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271897 GLuint targetid;
1898 if (internal) {
1899 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1900 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351901 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271902 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351903 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:361904 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:271905 decoder_->offscreen_resolved_color_texture_->Create();
1906
1907 DCHECK(decoder_->offscreen_saved_color_format_);
1908 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091909 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1910 false);
[email protected]de26b3c2011-08-03 21:54:271911 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1912 decoder_->offscreen_resolved_color_texture_.get());
1913 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1914 GL_FRAMEBUFFER_COMPLETE) {
1915 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1916 << "because offscreen resolved FBO was incomplete.";
1917 return;
1918 }
1919 }
1920 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1921 } else {
1922 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1923 }
1924 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021925 const int width = decoder_->offscreen_size_.width();
1926 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181927 glDisable(GL_SCISSOR_TEST);
[email protected]f42f05b2013-11-15 21:46:181928 decoder->BlitFramebufferHelper(0,
1929 0,
1930 width,
1931 height,
1932 0,
1933 0,
1934 width,
1935 height,
1936 GL_COLOR_BUFFER_BIT,
1937 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:271938 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021939}
1940
1941ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1942 if (!resolve_and_bind_)
1943 return;
1944
[email protected]ab09b612013-03-11 22:11:511945 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301946 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021947 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221948 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181949 glEnable(GL_SCISSOR_TEST);
1950 }
[email protected]34ff8b0c2010-10-01 20:06:021951}
1952
[email protected]ce296892013-10-24 22:04:361953BackTexture::BackTexture(
1954 MemoryTracker* memory_tracker,
1955 ContextState* state)
1956 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
1957 state_(state),
[email protected]68e81a4a62012-12-13 01:16:481958 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251959 id_(0) {
[email protected]6217d392010-03-25 22:08:351960}
1961
[email protected]ed9f9cd2013-02-27 21:12:351962BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351963 // This does not destroy the render texture because that would require that
1964 // the associated GL context was current. Just check that it was explicitly
1965 // destroyed.
1966 DCHECK_EQ(id_, 0u);
1967}
1968
[email protected]ed9f9cd2013-02-27 21:12:351969void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:301970 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:361971 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351972 Destroy();
1973 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:021974 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]3a4d0c52011-06-29 23:11:581975 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1976 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1977 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1978 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161979
1980 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1981 // never called on an offscreen context, no data will ever be uploaded to the
1982 // saved offscreen color texture (it is deferred until to when SwapBuffers
1983 // is called). My idea is that some nvidia drivers might have a bug where
1984 // deleting a texture that has never been populated might cause a
1985 // crash.
1986 glTexImage2D(
1987 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481988
1989 bytes_allocated_ = 16u * 16u * 4u;
1990 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351991}
1992
[email protected]ed9f9cd2013-02-27 21:12:351993bool BackTexture::AllocateStorage(
1994 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351995 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:301996 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:361997 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:021998 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:091999 uint32 image_size = 0;
2000 GLES2Util::ComputeImageDataSizes(
2001 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
2002 NULL, NULL);
2003
[email protected]7989c9e2013-01-23 06:39:262004 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2005 return false;
2006 }
2007
[email protected]40d90a22013-04-09 03:39:552008 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092009 if (zero) {
2010 zero_data.reset(new char[image_size]);
2011 memset(zero_data.get(), 0, image_size);
2012 }
[email protected]6217d392010-03-25 22:08:352013
[email protected]8f1d2aa2013-05-10 23:45:382014 glTexImage2D(GL_TEXTURE_2D,
2015 0, // mip level
2016 format,
2017 size.width(),
2018 size.height(),
2019 0, // border
2020 format,
2021 GL_UNSIGNED_BYTE,
2022 zero_data.get());
[email protected]6217d392010-03-25 22:08:352023
[email protected]d37231fa2010-04-09 21:16:022024 size_ = size;
2025
[email protected]1078f912011-12-23 13:12:142026 bool success = glGetError() == GL_NO_ERROR;
2027 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482028 memory_tracker_.TrackMemFree(bytes_allocated_);
2029 bytes_allocated_ = image_size;
2030 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142031 }
2032 return success;
[email protected]6217d392010-03-25 22:08:352033}
2034
[email protected]ed9f9cd2013-02-27 21:12:352035void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352036 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302037 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362038 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022039 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352040 glCopyTexImage2D(GL_TEXTURE_2D,
2041 0, // level
[email protected]3a4d0c52011-06-29 23:11:582042 format,
[email protected]6217d392010-03-25 22:08:352043 0, 0,
2044 size.width(),
2045 size.height(),
2046 0); // border
2047}
2048
[email protected]ed9f9cd2013-02-27 21:12:352049void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352050 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302051 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362052 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352053 glDeleteTextures(1, &id_);
2054 id_ = 0;
2055 }
[email protected]68e81a4a62012-12-13 01:16:482056 memory_tracker_.TrackMemFree(bytes_allocated_);
2057 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352058}
2059
[email protected]ed9f9cd2013-02-27 21:12:352060void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052061 id_ = 0;
2062}
2063
[email protected]d5a28e452013-10-10 01:01:402064BackRenderbuffer::BackRenderbuffer(
2065 RenderbufferManager* renderbuffer_manager,
2066 MemoryTracker* memory_tracker,
2067 ContextState* state)
2068 : renderbuffer_manager_(renderbuffer_manager),
2069 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2070 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482071 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252072 id_(0) {
[email protected]6217d392010-03-25 22:08:352073}
2074
[email protected]ed9f9cd2013-02-27 21:12:352075BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352076 // This does not destroy the render buffer because that would require that
2077 // the associated GL context was current. Just check that it was explicitly
2078 // destroyed.
2079 DCHECK_EQ(id_, 0u);
2080}
2081
[email protected]ed9f9cd2013-02-27 21:12:352082void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302083 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402084 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352085 Destroy();
2086 glGenRenderbuffersEXT(1, &id_);
2087}
2088
[email protected]f42f05b2013-11-15 21:46:182089bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2090 const gfx::Size& size,
2091 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352092 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512093 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402094 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2095 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262096
2097 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402098 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232099 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262100 return false;
2101 }
2102
2103 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2104 return false;
2105 }
2106
[email protected]34ff8b0c2010-10-01 20:06:022107 if (samples <= 1) {
2108 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2109 format,
2110 size.width(),
2111 size.height());
2112 } else {
[email protected]f42f05b2013-11-15 21:46:182113 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2114 GL_RENDERBUFFER,
2115 samples,
2116 format,
2117 size.width(),
2118 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022119 }
[email protected]1078f912011-12-23 13:12:142120 bool success = glGetError() == GL_NO_ERROR;
2121 if (success) {
[email protected]d5a28e452013-10-10 01:01:402122 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482123 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262124 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402125 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482126 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142127 }
2128 return success;
[email protected]6217d392010-03-25 22:08:352129}
2130
[email protected]ed9f9cd2013-02-27 21:12:352131void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352132 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302133 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402134 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352135 glDeleteRenderbuffersEXT(1, &id_);
2136 id_ = 0;
2137 }
[email protected]68e81a4a62012-12-13 01:16:482138 memory_tracker_.TrackMemFree(bytes_allocated_);
2139 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352140}
2141
[email protected]ed9f9cd2013-02-27 21:12:352142void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052143 id_ = 0;
2144}
2145
[email protected]ed9f9cd2013-02-27 21:12:352146BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352147 : decoder_(decoder),
2148 id_(0) {
2149}
2150
[email protected]ed9f9cd2013-02-27 21:12:352151BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352152 // This does not destroy the frame buffer because that would require that
2153 // the associated GL context was current. Just check that it was explicitly
2154 // destroyed.
2155 DCHECK_EQ(id_, 0u);
2156}
2157
[email protected]ed9f9cd2013-02-27 21:12:352158void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302159 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2160 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352161 Destroy();
2162 glGenFramebuffersEXT(1, &id_);
2163}
2164
[email protected]ed9f9cd2013-02-27 21:12:352165void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352166 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512167 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302168 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352169 ScopedFrameBufferBinder binder(decoder_, id_);
2170 GLuint attach_id = texture ? texture->id() : 0;
2171 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2172 GL_COLOR_ATTACHMENT0,
2173 GL_TEXTURE_2D,
2174 attach_id,
2175 0);
2176}
2177
[email protected]ed9f9cd2013-02-27 21:12:352178void BackFramebuffer::AttachRenderBuffer(GLenum target,
2179 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352180 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512181 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302182 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352183 ScopedFrameBufferBinder binder(decoder_, id_);
2184 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2185 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152186 target,
[email protected]6217d392010-03-25 22:08:352187 GL_RENDERBUFFER,
2188 attach_id);
2189}
2190
[email protected]ed9f9cd2013-02-27 21:12:352191void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352192 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302193 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2194 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352195 glDeleteFramebuffersEXT(1, &id_);
2196 id_ = 0;
2197 }
2198}
2199
[email protected]ed9f9cd2013-02-27 21:12:352200void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052201 id_ = 0;
2202}
2203
[email protected]ed9f9cd2013-02-27 21:12:352204GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352205 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302206 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2207 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352208 ScopedFrameBufferBinder binder(decoder_, id_);
2209 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2210}
2211
[email protected]aa7666122011-09-02 19:45:522212GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2213 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322214}
2215
[email protected]aa7666122011-09-02 19:45:522216GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392217 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572218 group_(group),
[email protected]1d82e822013-04-10 21:32:322219 logger_(&debug_marker_manager_),
[email protected]d3eba342013-04-18 21:11:502220 state_(group_->feature_info(), &logger_),
[email protected]43410e92012-04-20 17:06:282221 unpack_flip_y_(false),
2222 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172223 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242224 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492225 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242226 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402227 fixed_attrib_buffer_id_(0),
2228 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022229 offscreen_target_color_format_(0),
2230 offscreen_target_depth_format_(0),
2231 offscreen_target_stencil_format_(0),
2232 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562233 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052234 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132235 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462236 back_buffer_has_depth_(false),
2237 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582238 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562239 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052240 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112241 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002242 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432243 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302244 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512245 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222246 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432247 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042248 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102249 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492250 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132251 draw_buffers_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282252 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192253 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2254 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022255 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102256 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002257 texture_state_(group_->feature_info()
2258 ->workarounds()
2259 .texsubimage2d_faster_than_teximage2d),
[email protected]4a4c18b2013-09-13 22:50:102260 validation_texture_(0),
2261 validation_fbo_multisample_(0),
2262 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572263 DCHECK(group);
2264
[email protected]b1122982010-05-17 23:04:242265 attrib_0_value_.v[0] = 0.0f;
2266 attrib_0_value_.v[1] = 0.0f;
2267 attrib_0_value_.v[2] = 0.0f;
2268 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152269
[email protected]c2f8c8402010-12-06 18:07:242270 // The shader translator is used for WebGL even when running on EGL
2271 // because additional restrictions are needed (like only enabling
2272 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562273 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2274 // the empty string to CompileShader and this is not a valid shader.
2275 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002276 CommandLine::ForCurrentProcess()->HasSwitch(
2277 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152278 use_shader_translator_ = false;
2279 }
[email protected]96449d2c2009-11-25 00:01:322280}
2281
[email protected]80eb6b52012-01-19 00:14:412282GLES2DecoderImpl::~GLES2DecoderImpl() {
2283}
2284
[email protected]c410da802011-03-14 19:17:412285bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382286 const scoped_refptr<gfx::GLSurface>& surface,
2287 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232288 bool offscreen,
[email protected]c410da802011-03-14 19:17:412289 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292290 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242291 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322292 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382293 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302294 DCHECK(!context_.get());
2295
[email protected]55e136f2013-04-03 18:50:062296 set_initialized();
[email protected]bccc0f32014-01-10 03:18:082297 gpu_tracer_ = GPUTracer::Create(this);
[email protected]8f9b8dd2013-09-12 18:05:132298 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]cac16542014-01-15 17:53:512299 // TODO(vmiura): Enable changing gpu_trace_level_ at runtime
2300 gpu_trace_level_ = 2;
2301 gpu_trace_commands_ = false;
[email protected]fb97b662013-02-20 23:02:142302
[email protected]e844ae22012-01-14 03:36:262303 if (CommandLine::ForCurrentProcess()->HasSwitch(
2304 switches::kEnableGPUDebugging)) {
2305 set_debug(true);
2306 }
2307
[email protected]39ba4f02012-03-26 01:16:002308 if (CommandLine::ForCurrentProcess()->HasSwitch(
2309 switches::kEnableGPUCommandLogging)) {
2310 set_log_commands(true);
2311 }
2312
[email protected]062c38b2012-01-18 03:25:102313 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2314 switches::kCompileShaderAlwaysSucceeds);
2315
[email protected]f62a5ab2011-05-23 20:34:152316
[email protected]63c9b052012-05-17 18:27:382317 // Take ownership of the context and surface. The surface can be replaced with
2318 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382319 context_ = context;
[email protected]63c9b052012-05-17 18:27:382320 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182321
[email protected]65f7efe2013-11-28 03:11:472322 ContextCreationAttribHelper attrib_parser;
2323 if (!attrib_parser.Parse(attribs))
2324 return false;
2325
2326 // If the failIfMajorPerformanceCaveat context creation attribute was true
2327 // and we are using a software renderer, fail.
2328 if (attrib_parser.fail_if_major_perf_caveat_ &&
2329 feature_info_->feature_flags().is_swiftshader) {
2330 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2331 Destroy(true);
2332 return false;
2333 }
2334
[email protected]956aec52013-09-05 15:41:192335 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222336 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392337 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422338 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382339 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032340 return false;
[email protected]a3ded6d2010-10-19 06:44:392341 }
[email protected]b64c24952012-04-19 03:20:272342 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282343
[email protected]e82fb792011-09-22 00:33:292344 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502345
[email protected]af6380962012-11-29 23:24:132346 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462347 default_vertex_attrib_manager_ = new VertexAttribManager();
[email protected]94ba2e02014-03-12 10:32:002348 default_vertex_attrib_manager_->Initialize(
2349 group_->max_vertex_attribs(),
2350 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462351
[email protected]ab4fd7282012-10-12 16:25:572352 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2353 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322354
[email protected]7cd76fd2013-06-02 21:11:112355 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]944b62f32012-09-27 02:20:462356 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532357
[email protected]302ce6d2011-07-07 23:28:112358 util_.set_num_compressed_texture_formats(
2359 validators_->compressed_texture_format.GetValues().size());
2360
[email protected]1071e572011-02-09 20:00:122361 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2362 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2363 // OpenGL ES 2.0 does not have this issue.
2364 glEnableVertexAttribArray(0);
2365 }
[email protected]b1122982010-05-17 23:04:242366 glGenBuffersARB(1, &attrib_0_buffer_id_);
2367 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2368 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2369 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402370 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082371
[email protected]1868a342012-11-07 15:56:022372 state_.texture_units.resize(group_->max_texture_units());
2373 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492374 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312375 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492376 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152377 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492378 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072379 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492380 state_.texture_units[tt].bound_texture_external_oes = ref;
2381 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id());
[email protected]61eeb33f2011-07-26 15:30:312382 }
[email protected]62e155e2012-10-23 22:43:152383 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492384 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072385 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492386 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2387 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id());
[email protected]e51bdf32011-11-23 22:21:462388 }
[email protected]370eaf12013-05-18 09:19:492389 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2390 state_.texture_units[tt].bound_texture_cube_map = ref;
2391 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id());
2392 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2393 state_.texture_units[tt].bound_texture_2d = ref;
2394 glBindTexture(GL_TEXTURE_2D, ref->service_id());
[email protected]1958e0e2010-04-22 05:17:152395 }
[email protected]00f893d2010-08-24 18:55:492396 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502397 CHECK_GL_ERROR();
2398
[email protected]069944672012-04-25 20:52:232399 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022400 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542401 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022402 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432403 // max_sample_count must be initialized to a sane value. If
2404 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2405 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022406 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2407 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2408 max_sample_count);
2409 } else {
2410 offscreen_target_samples_ = 1;
2411 }
[email protected]8a61d872012-01-20 12:43:562412 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022413
2414 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2415 const bool rgb8_supported =
2416 context_->HasExtension("GL_OES_rgb8_rgba8");
2417 // The only available default render buffer formats in GLES2 have very
2418 // little precision. Don't enable multisampling unless 8-bit render
2419 // buffer formats are available--instead fall back to 8-bit textures.
2420 if (rgb8_supported && offscreen_target_samples_ > 1) {
2421 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2422 GL_RGBA8 : GL_RGB8;
2423 } else {
2424 offscreen_target_samples_ = 1;
2425 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2426 GL_RGBA : GL_RGB;
2427 }
2428
2429 // ANGLE only supports packed depth/stencil formats, so use it if it is
2430 // available.
2431 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182432 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272433 VLOG(1) << "GL_OES_packed_depth_stencil "
2434 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002435 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2436 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022437 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2438 offscreen_target_stencil_format_ = 0;
2439 } else {
2440 // It may be the case that this depth/stencil combination is not
2441 // supported, but this will be checked later by CheckFramebufferStatus.
2442 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2443 GL_DEPTH_COMPONENT16 : 0;
2444 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2445 GL_STENCIL_INDEX8 : 0;
2446 }
2447 } else {
2448 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2449 GL_RGBA : GL_RGB;
2450
2451 // If depth is requested at all, use the packed depth stencil format if
2452 // it's available, as some desktop GL drivers don't support any non-packed
2453 // formats for depth attachments.
2454 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182455 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272456 VLOG(1) << "GL_EXT_packed_depth_stencil "
2457 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022458
[email protected]71ee3642010-10-14 18:08:002459 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2460 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022461 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2462 offscreen_target_stencil_format_ = 0;
2463 } else {
2464 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2465 GL_DEPTH_COMPONENT : 0;
2466 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2467 GL_STENCIL_INDEX : 0;
2468 }
2469 }
2470
[email protected]97872062010-11-03 19:07:052471 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2472 GL_RGBA : GL_RGB;
2473
[email protected]6217d392010-03-25 22:08:352474 // Create the target frame buffer. This is the one that the client renders
2475 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352476 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352477 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022478 // Due to GLES2 format limitations, either the color texture (for
2479 // non-multisampling) or the color render buffer (for multisampling) will be
2480 // attached to the offscreen frame buffer. The render buffer has more
2481 // limited formats available to it, but the texture can't do multisampling.
2482 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402483 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2484 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022485 offscreen_target_color_render_buffer_->Create();
2486 } else {
[email protected]ce296892013-10-24 22:04:362487 offscreen_target_color_texture_.reset(new BackTexture(
2488 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022489 offscreen_target_color_texture_->Create();
2490 }
[email protected]d5a28e452013-10-10 01:01:402491 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2492 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152493 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402494 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2495 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152496 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352497
2498 // Create the saved offscreen texture. The target frame buffer is copied
2499 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352500 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022501 offscreen_saved_frame_buffer_->Create();
2502 //
[email protected]ce296892013-10-24 22:04:362503 offscreen_saved_color_texture_.reset(new BackTexture(
2504 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352505 offscreen_saved_color_texture_->Create();
2506
[email protected]6217d392010-03-25 22:08:352507 // Allocate the render buffers at their initial size and check the status
2508 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592509 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012510 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382511 Destroy(true);
[email protected]6217d392010-03-25 22:08:352512 return false;
2513 }
2514
[email protected]678a73f2012-12-19 19:22:092515 // Allocate the offscreen saved color texture.
2516 DCHECK(offscreen_saved_color_format_);
2517 offscreen_saved_color_texture_->AllocateStorage(
2518 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2519
2520 offscreen_saved_frame_buffer_->AttachRenderTexture(
2521 offscreen_saved_color_texture_.get());
2522 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2523 GL_FRAMEBUFFER_COMPLETE) {
2524 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2525 Destroy(true);
2526 return false;
2527 }
2528
[email protected]6217d392010-03-25 22:08:352529 // Bind to the new default frame buffer (the offscreen target frame buffer).
2530 // This should now be associated with ID zero.
2531 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102532 } else {
2533 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2534 // These are NOT if the back buffer has these proprorties. They are
2535 // if we want the command buffer to enforce them regardless of what
2536 // the real backbuffer is assuming the real back buffer gives us more than
2537 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2538 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2539 // can't do anything about that.
2540
2541 GLint v = 0;
2542 glGetIntegerv(GL_ALPHA_BITS, &v);
2543 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2544 // user requested RGB then RGB. If the user did not specify a preference
2545 // than use whatever we were given. Same for DEPTH and STENCIL.
2546 back_buffer_color_format_ =
2547 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2548 glGetIntegerv(GL_DEPTH_BITS, &v);
2549 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2550 glGetIntegerv(GL_STENCIL_BITS, &v);
2551 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
[email protected]6217d392010-03-25 22:08:352552 }
2553
[email protected]76a0ee102010-04-07 21:03:042554 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2555 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2556 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372557 // mailing list archives. It also implicitly enables the desktop GL
2558 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2559 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152560 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2561 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372562 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152563 }
[email protected]de17df392010-04-23 21:09:412564
[email protected]706b69f2012-07-27 04:59:302565 has_robustness_extension_ =
2566 context->HasExtension("GL_ARB_robustness") ||
2567 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432568
[email protected]c2f8c8402010-12-06 18:07:242569 if (!InitializeShaderTranslator()) {
2570 return false;
[email protected]de17df392010-04-23 21:09:412571 }
[email protected]76a0ee102010-04-07 21:03:042572
[email protected]e259eb412012-10-13 05:47:242573 state_.viewport_width = size.width();
2574 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282575
[email protected]5904806b2012-05-08 18:10:222576 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282577 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022578 viewport_max_width_ = viewport_params[0];
2579 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282580
[email protected]88a61bf2012-10-27 13:00:422581 state_.scissor_width = state_.viewport_width;
2582 state_.scissor_height = state_.viewport_height;
2583
[email protected]11f3e702012-06-19 19:00:012584 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222585 state_.InitCapabilities();
2586 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242587 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012588
2589 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2590 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2591 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2592 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2593
[email protected]88cfd132013-07-11 00:59:002594 bool call_gl_clear = true;
2595#if defined(OS_ANDROID)
2596 // Temporary workaround for Android WebView because this clear ignores the
2597 // clip and corrupts that external UI of the App. Not calling glClear is ok
2598 // because the system already clears the buffer before each draw. Proper
2599 // fix might be setting the scissor clip properly before initialize. See
2600 // crbug.com/259023 for details.
2601 call_gl_clear = surface_->GetHandle();
2602#endif
2603 if (call_gl_clear) {
2604 // Clear the backbuffer.
2605 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2606 }
[email protected]561cc0a62013-05-07 18:34:452607
[email protected]b381ee32014-03-22 02:43:432608 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2609 if (feature_info_->workarounds()
2610 .disable_post_sub_buffers_for_onscreen_surfaces &&
2611 !surface->IsOffscreen())
2612 supports_post_sub_buffer_ = false;
2613
[email protected]62e155e2012-10-23 22:43:152614 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462615 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2616 }
[email protected]dd289a5d62012-06-30 22:05:462617
[email protected]9b753992013-04-27 02:04:412618 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2619 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242620 }
[email protected]85cb4682013-04-20 00:54:242621
[email protected]40245ccf2013-11-13 04:00:492622 if (feature_info_->workarounds().release_image_after_use) {
2623 image_manager()->SetReleaseAfterUse();
2624 }
2625
[email protected]97419c02013-04-10 02:52:382626 // Only compositor contexts are known to use only the subset of GL
2627 // that can be safely migrated between the iGPU and the dGPU. Mark
2628 // those contexts as safe to forcibly transition between the GPUs.
2629 // http://crbug.com/180876, http://crbug.com/227228
2630 if (!offscreen)
2631 context_->SetSafeToForceGpuSwitch();
2632
[email protected]85a4ac22013-05-31 01:58:472633 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072634 AsyncPixelTransferManager::Create(context.get()));
2635 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592636
[email protected]91c94eb2013-10-22 10:32:542637 framebuffer_manager()->AddObserver(this);
2638
[email protected]246a70452010-03-05 21:53:502639 return true;
[email protected]96449d2c2009-11-25 00:01:322640}
2641
[email protected]6d668892013-12-04 21:37:122642Capabilities GLES2DecoderImpl::GetCapabilities() {
2643 DCHECK(initialized());
2644
2645 Capabilities caps;
2646
2647 caps.fast_npot_mo8_textures =
2648 feature_info_->workarounds().enable_chromium_fast_npot_mo8_textures;
2649 caps.egl_image_external =
2650 feature_info_->feature_flags().oes_egl_image_external;
2651 caps.texture_format_bgra8888 =
2652 feature_info_->feature_flags().ext_texture_format_bgra8888;
2653 caps.texture_format_etc1 =
2654 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
2655 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2656 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2657 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2658 caps.discard_framebuffer =
2659 feature_info_->feature_flags().ext_discard_framebuffer;
2660
2661#if defined(OS_MACOSX)
2662 // This is unconditionally true on mac, no need to test for it at runtime.
2663 caps.iosurface = true;
2664#endif
2665
[email protected]b381ee32014-03-22 02:43:432666 caps.post_sub_buffer = supports_post_sub_buffer_;
[email protected]6d668892013-12-04 21:37:122667
2668 return caps;
2669}
2670
[email protected]302ce6d2011-07-07 23:28:112671void GLES2DecoderImpl::UpdateCapabilities() {
2672 util_.set_num_compressed_texture_formats(
2673 validators_->compressed_texture_format.GetValues().size());
2674 util_.set_num_shader_binary_formats(
2675 validators_->shader_binary_format.GetValues().size());
2676}
2677
[email protected]c2f8c8402010-12-06 18:07:242678bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442679 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2680
[email protected]c2f8c8402010-12-06 18:07:242681 if (!use_shader_translator_) {
2682 return true;
2683 }
2684 ShBuiltInResources resources;
2685 ShInitBuiltInResources(&resources);
2686 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2687 resources.MaxVertexUniformVectors =
2688 group_->max_vertex_uniform_vectors();
2689 resources.MaxVaryingVectors = group_->max_varying_vectors();
2690 resources.MaxVertexTextureImageUnits =
2691 group_->max_vertex_texture_image_units();
2692 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2693 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2694 resources.MaxFragmentUniformVectors =
2695 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492696 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242697 resources.MaxExpressionComplexity = 256;
2698 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042699
[email protected]9e98f61b2013-03-05 02:21:142700#if (ANGLE_SH_VERSION >= 110)
[email protected]46c86752013-05-21 05:08:392701 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212702 GLint precision = 0;
2703 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2704 range, &precision);
[email protected]448e459e2013-06-12 17:00:412705 resources.FragmentPrecisionHigh =
2706 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142707#endif
2708
[email protected]f0d74742011-10-03 16:31:042709 if (force_webgl_glsl_validation_) {
2710 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492711 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132712 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442713 if (!draw_buffers_explicitly_enabled_)
2714 resources.MaxDrawBuffers = 1;
[email protected]f0d74742011-10-03 16:31:042715 } else {
2716 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152717 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462718 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152719 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062720 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152721 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492722 resources.EXT_draw_buffers =
2723 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492724 resources.EXT_frag_depth =
2725 features().ext_frag_depth ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042726 }
2727
[email protected]26b61442013-03-17 16:12:012728 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2729 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052730 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022731#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052732 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022733#else
2734 resources.HashFunction = &CityHash64;
2735#endif
[email protected]6aedcdc2013-01-24 01:25:052736 else
2737 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122738 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2739 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2740 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212741 int driver_bug_workarounds = 0;
2742 if (workarounds().needs_glsl_built_in_function_emulation)
2743 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542744 if (workarounds().init_gl_position_in_vertex_shader)
2745 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112746 if (workarounds().unfold_short_circuit_as_ternary_operation)
2747 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052748 if (workarounds().init_varyings_without_static_use)
2749 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062750 if (workarounds().unroll_for_loop_with_sampler_array_index)
2751 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]87fb6ab2012-06-13 22:28:042752
2753 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2754 vertex_translator_ = cache->GetTranslator(
2755 SH_VERTEX_SHADER, shader_spec, &resources,
[email protected]a6739bc2013-09-07 04:45:212756 implementation_type,
2757 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042758 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242759 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382760 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242761 return false;
2762 }
[email protected]87fb6ab2012-06-13 22:28:042763
2764 fragment_translator_ = cache->GetTranslator(
2765 SH_FRAGMENT_SHADER, shader_spec, &resources,
[email protected]a6739bc2013-09-07 04:45:212766 implementation_type,
2767 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042768 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242769 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382770 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242771 return false;
2772 }
2773 return true;
2774}
2775
[email protected]ae51d192010-04-27 00:48:032776bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472777 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352778 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032779 return false;
2780 }
2781 }
[email protected]40d90a22013-04-09 03:39:552782 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032783 glGenBuffersARB(n, service_ids.get());
2784 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352785 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032786 }
2787 return true;
2788}
2789
2790bool GLES2DecoderImpl::GenFramebuffersHelper(
2791 GLsizei n, const GLuint* client_ids) {
2792 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352793 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032794 return false;
2795 }
2796 }
[email protected]40d90a22013-04-09 03:39:552797 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032798 glGenFramebuffersEXT(n, service_ids.get());
2799 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352800 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032801 }
2802 return true;
2803}
2804
2805bool GLES2DecoderImpl::GenRenderbuffersHelper(
2806 GLsizei n, const GLuint* client_ids) {
2807 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352808 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032809 return false;
2810 }
2811 }
[email protected]40d90a22013-04-09 03:39:552812 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032813 glGenRenderbuffersEXT(n, service_ids.get());
2814 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352815 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032816 }
2817 return true;
2818}
2819
2820bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2821 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352822 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032823 return false;
2824 }
2825 }
[email protected]40d90a22013-04-09 03:39:552826 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032827 glGenTextures(n, service_ids.get());
2828 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352829 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032830 }
2831 return true;
2832}
2833
2834void GLES2DecoderImpl::DeleteBuffersHelper(
2835 GLsizei n, const GLuint* client_ids) {
2836 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212837 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102838 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242839 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112840 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242841 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102842 }
[email protected]ed9f9cd2013-02-27 21:12:352843 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032844 }
[email protected]a93bb842010-02-16 23:03:472845 }
[email protected]07f54fcc2009-12-22 02:46:302846}
2847
[email protected]ae51d192010-04-27 00:48:032848void GLES2DecoderImpl::DeleteFramebuffersHelper(
2849 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452850 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152851 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112852
[email protected]a25fa872010-03-25 02:57:582853 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352854 Framebuffer* framebuffer =
2855 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102856 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:342857 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2858 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442859 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452860 GLenum target = supports_separate_framebuffer_binds ?
2861 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112862 glBindFramebufferEXT(target, GetBackbufferServiceId());
2863 }
[email protected]9d3b2e12013-10-02 01:04:342864 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2865 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452866 GLenum target = supports_separate_framebuffer_binds ?
2867 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112868 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462869 }
[email protected]70d34263c2013-01-09 00:27:452870 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352871 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032872 }
[email protected]a25fa872010-03-25 02:57:582873 }
[email protected]07f54fcc2009-12-22 02:46:302874}
2875
[email protected]ae51d192010-04-27 00:48:032876void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2877 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452878 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152879 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582880 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352881 Renderbuffer* renderbuffer =
2882 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102883 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112884 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242885 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102886 }
2887 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452888 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342889 if (framebuffer_state_.bound_read_framebuffer.get()) {
2890 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112891 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102892 }
[email protected]9d3b2e12013-10-02 01:04:342893 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2894 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112895 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102896 }
2897 } else {
[email protected]9d3b2e12013-10-02 01:04:342898 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2899 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112900 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102901 }
2902 }
[email protected]c986af502013-08-14 01:04:442903 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:352904 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032905 }
[email protected]a25fa872010-03-25 02:57:582906 }
[email protected]07f54fcc2009-12-22 02:46:302907}
2908
[email protected]ae51d192010-04-27 00:48:032909void GLES2DecoderImpl::DeleteTexturesHelper(
2910 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452911 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152912 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472913 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492914 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2915 if (texture_ref) {
2916 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102917 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:442918 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462919 }
[email protected]370eaf12013-05-18 09:19:492920 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:022921 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:492922 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102923 }
2924 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452925 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342926 if (framebuffer_state_.bound_read_framebuffer.get()) {
2927 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112928 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102929 }
[email protected]9d3b2e12013-10-02 01:04:342930 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2931 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112932 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102933 }
2934 } else {
[email protected]9d3b2e12013-10-02 01:04:342935 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2936 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112937 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102938 }
2939 }
[email protected]e51bdf32011-11-23 22:21:462940#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:072941 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:462942 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2943 ReleaseIOSurfaceForTexture(service_id);
2944 }
2945#endif
[email protected]ed9f9cd2013-02-27 21:12:352946 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032947 }
[email protected]a93bb842010-02-16 23:03:472948 }
[email protected]07f54fcc2009-12-22 02:46:302949}
2950
[email protected]43f28f832010-02-03 02:28:482951// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322952
[email protected]eb54a562010-01-20 21:55:182953bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:342954 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:382955 return false;
2956
[email protected]177d1342013-12-07 04:20:342957 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432958 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292959
2960 // Some D3D drivers cannot recover from device lost in the GPU process
2961 // sandbox. Allow a new GPU process to launch.
2962 if (workarounds().exit_on_context_lost) {
2963 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2964 << " a D3D device in the Chrome GPU process sandbox.";
[email protected]6eb775352013-08-27 05:57:162965#if defined(OS_WIN)
2966 base::win::SetShouldCrashOnProcessDetach(false);
2967#endif
[email protected]e9f0ca82013-04-01 23:52:292968 exit(0);
2969 }
2970
[email protected]63c9b052012-05-17 18:27:382971 return false;
[email protected]38d139d2011-07-14 00:38:432972 }
2973
[email protected]69a8701e2013-03-07 21:31:092974 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:092975
[email protected]9b753992013-04-27 02:04:412976 // Rebind the FBO if it was unbound by the context.
2977 if (workarounds().unbind_fbo_on_context_switch)
2978 RestoreFramebufferBindings();
2979
[email protected]c986af502013-08-14 01:04:442980 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:492981
[email protected]69a8701e2013-03-07 21:31:092982 return true;
2983}
2984
2985void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:552986 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:322987 if (engine() && query_manager_.get())
2988 query_manager_->ProcessPendingTransferQueries();
2989
[email protected]5b3a8e02013-03-13 05:36:442990 // TODO(epenner): Is there a better place to do this?
2991 // This needs to occur before we execute any batch of commands
2992 // from the client, as the client may have recieved an async
2993 // completion while issuing those commands.
2994 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:482995 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:182996}
2997
[email protected]8e3e0662010-08-23 18:46:302998static void RebindCurrentFramebuffer(
2999 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063000 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243001 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063002 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463003
[email protected]a3783712012-01-20 22:18:243004 if (framebuffer_id == 0) {
3005 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303006 }
[email protected]297ca1c2011-06-20 23:08:463007
[email protected]8e3e0662010-08-23 18:46:303008 glBindFramebufferEXT(target, framebuffer_id);
3009}
3010
3011void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443012 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463013
[email protected]62e155e2012-10-23 22:43:153014 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303015 RebindCurrentFramebuffer(
3016 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343017 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243018 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303019 } else {
3020 RebindCurrentFramebuffer(
3021 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343022 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243023 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303024 RebindCurrentFramebuffer(
3025 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343026 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243027 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303028 }
[email protected]70d34263c2013-01-09 00:27:453029 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303030}
3031
[email protected]0d6bfdc2011-11-02 01:32:203032bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353033 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203034 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103035 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:583036 if (backbuffer_needs_clear_bits_) {
3037 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3038 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3039 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3040 glClearStencil(0);
3041 glStencilMask(-1);
3042 glClearDepth(1.0f);
3043 glDepthMask(true);
3044 glDisable(GL_SCISSOR_TEST);
3045 glClear(backbuffer_needs_clear_bits_);
3046 backbuffer_needs_clear_bits_ = 0;
3047 RestoreClearState();
3048 }
[email protected]0d6bfdc2011-11-02 01:32:203049 return true;
3050 }
3051
[email protected]968351b2011-12-20 08:26:513052 if (framebuffer_manager()->IsComplete(framebuffer)) {
3053 return true;
3054 }
3055
[email protected]0d6bfdc2011-11-02 01:32:203056 GLenum completeness = framebuffer->IsPossiblyComplete();
3057 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513058 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433059 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273060 return false;
3061 }
[email protected]0d6bfdc2011-11-02 01:32:203062
3063 // Are all the attachments cleared?
3064 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3065 texture_manager()->HaveUnclearedMips()) {
3066 if (!framebuffer->IsCleared()) {
3067 // Can we clear them?
[email protected]73276522012-11-09 05:50:203068 if (framebuffer->GetStatus(texture_manager(), target) !=
3069 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513070 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433071 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3072 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203073 return false;
3074 }
3075 ClearUnclearedAttachments(target, framebuffer);
3076 }
3077 }
3078
[email protected]968351b2011-12-20 08:26:513079 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203080 if (framebuffer->GetStatus(texture_manager(), target) !=
3081 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513082 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433083 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3084 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513085 return false;
3086 }
3087 framebuffer_manager()->MarkAsComplete(framebuffer);
3088 }
3089
[email protected]0d6bfdc2011-11-02 01:32:203090 // NOTE: At this point we don't know if the framebuffer is complete but
3091 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273092 return true;
3093}
3094
[email protected]0d6bfdc2011-11-02 01:32:203095bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153096 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513097 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343098 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3099 func_name);
[email protected]28718a92013-04-04 12:12:513100
3101 if (valid)
3102 OnUseFramebuffer();
3103
3104 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203105 }
[email protected]9d3b2e12013-10-02 01:04:343106 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113107 GL_DRAW_FRAMEBUFFER_EXT,
3108 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343109 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113110 GL_READ_FRAMEBUFFER_EXT,
3111 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203112}
3113
[email protected]8e3e0662010-08-23 18:46:303114gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353115 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453116 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203117 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353118 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203119 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263120 if (attachment) {
3121 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503122 }
[email protected]9edc6b22010-12-23 02:00:263123 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023124 } else if (offscreen_target_frame_buffer_.get()) {
3125 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353126 } else {
[email protected]f62a5ab2011-05-23 20:34:153127 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023128 }
[email protected]246a70452010-03-05 21:53:503129}
3130
[email protected]68586372013-12-11 01:27:593131GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3132 Framebuffer* framebuffer =
3133 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3134 if (framebuffer != NULL) {
3135 return framebuffer->GetColorAttachmentTextureType();
3136 } else {
3137 return GL_UNSIGNED_BYTE;
3138 }
3139}
3140
[email protected]9edc6b22010-12-23 02:00:263141GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353142 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453143 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203144 if (framebuffer != NULL) {
3145 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463146 } else if (offscreen_target_frame_buffer_.get()) {
3147 return offscreen_target_color_format_;
3148 } else {
3149 return back_buffer_color_format_;
3150 }
3151}
3152
3153GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353154 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453155 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203156 if (framebuffer != NULL) {
3157 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263158 } else if (offscreen_target_frame_buffer_.get()) {
3159 return offscreen_target_color_format_;
3160 } else {
[email protected]32fe9aa2011-01-21 23:47:133161 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263162 }
3163}
3164
[email protected]9a5afa432011-07-22 18:16:393165void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513166 if (!offscreen_saved_color_texture_info_.get())
3167 return;
3168 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3169 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3170 texture_manager()->SetLevelInfo(
3171 offscreen_saved_color_texture_info_.get(),
3172 GL_TEXTURE_2D,
3173 0, // level
3174 GL_RGBA,
3175 offscreen_size_.width(),
3176 offscreen_size_.height(),
3177 1, // depth
3178 0, // border
3179 GL_RGBA,
3180 GL_UNSIGNED_BYTE,
3181 true);
[email protected]737191ee72014-03-09 08:02:423182 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513183 "UpdateParentTextureInfo",
3184 GetErrorState(),
3185 offscreen_saved_color_texture_info_.get(),
3186 GL_TEXTURE_MAG_FILTER,
3187 GL_NEAREST);
[email protected]737191ee72014-03-09 08:02:423188 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513189 "UpdateParentTextureInfo",
3190 GetErrorState(),
3191 offscreen_saved_color_texture_info_.get(),
3192 GL_TEXTURE_MIN_FILTER,
3193 GL_NEAREST);
[email protected]737191ee72014-03-09 08:02:423194 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513195 "UpdateParentTextureInfo",
3196 GetErrorState(),
3197 offscreen_saved_color_texture_info_.get(),
3198 GL_TEXTURE_WRAP_S,
3199 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423200 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513201 "UpdateParentTextureInfo",
3202 GetErrorState(),
3203 offscreen_saved_color_texture_info_.get(),
3204 GL_TEXTURE_WRAP_T,
3205 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443206 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3207 &state_, target);
[email protected]2ad674132013-06-05 07:48:513208 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353209}
3210
[email protected]799b4b22011-08-22 17:09:593211void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073212 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523213 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003214}
3215
[email protected]1d82e822013-04-10 21:32:323216Logger* GLES2DecoderImpl::GetLogger() {
3217 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523218}
3219
[email protected]cac16542014-01-15 17:53:513220void GLES2DecoderImpl::BeginDecoding() {
3221 gpu_tracer_->BeginDecoding();
3222 gpu_trace_commands_ = gpu_tracer_->IsTracing();
3223}
3224
3225void GLES2DecoderImpl::EndDecoding() {
3226 gpu_tracer_->EndDecoding();
3227}
3228
[email protected]d3eba342013-04-18 21:11:503229ErrorState* GLES2DecoderImpl::GetErrorState() {
3230 return state_.GetErrorState();
3231}
3232
[email protected]e3932abb2013-03-13 00:01:373233void GLES2DecoderImpl::SetShaderCacheCallback(
3234 const ShaderCacheCallback& callback) {
3235 shader_cache_callback_ = callback;
3236}
3237
[email protected]840a7e462013-02-27 01:29:513238void GLES2DecoderImpl::SetWaitSyncPointCallback(
3239 const WaitSyncPointCallback& callback) {
3240 wait_sync_point_callback_ = callback;
3241}
3242
[email protected]85a4ac22013-05-31 01:58:473243AsyncPixelTransferManager*
3244 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3245 return async_pixel_transfer_manager_.get();
3246}
3247
3248void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3249 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593250}
3251
[email protected]498b5c072013-06-04 19:30:073252void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3253 AsyncPixelTransferManager* manager) {
3254 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3255}
3256
[email protected]1318e922010-09-17 22:03:163257bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3258 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493259 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3260 if (texture_ref) {
3261 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163262 return true;
3263 }
3264 return false;
3265}
3266
[email protected]63b465922012-09-06 02:04:523267uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443268 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483269 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523270}
3271
3272base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443273 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483274 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523275}
3276
3277base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3278 return total_processing_commands_time_;
3279}
3280
[email protected]dc25dda2012-09-27 21:36:303281void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3282 total_processing_commands_time_ += time;
3283}
3284
[email protected]63c9b052012-05-17 18:27:383285void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063286 if (!initialized())
3287 return;
3288
[email protected]63c9b052012-05-17 18:27:383289 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053290
[email protected]80eb6b52012-01-19 00:14:413291 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243292 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463293 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023294 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243295 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133296 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343297 framebuffer_state_.bound_read_framebuffer = NULL;
3298 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243299 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413300
[email protected]cadac622013-06-11 16:46:363301 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513302 DCHECK(offscreen_target_color_texture_);
3303 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3304 offscreen_saved_color_texture_->id());
3305 offscreen_saved_color_texture_->Invalidate();
3306 offscreen_saved_color_texture_info_ = NULL;
3307 }
[email protected]eadc96792010-10-27 19:39:393308 if (have_context) {
[email protected]c322e882012-05-23 18:06:183309 if (copy_texture_CHROMIUM_.get()) {
3310 copy_texture_CHROMIUM_->Destroy();
3311 copy_texture_CHROMIUM_.reset();
3312 }
[email protected]43410e92012-04-20 17:06:283313
[email protected]7cd76fd2013-06-02 21:11:113314 if (state_.current_program.get()) {
3315 program_manager()->UnuseProgram(shader_manager(),
3316 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143317 }
3318
[email protected]b1122982010-05-17 23:04:243319 if (attrib_0_buffer_id_) {
3320 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3321 }
[email protected]8fbedc02010-11-18 18:43:403322 if (fixed_attrib_buffer_id_) {
3323 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3324 }
[email protected]b1122982010-05-17 23:04:243325
[email protected]4a4c18b2013-09-13 22:50:103326 if (validation_texture_) {
3327 glDeleteTextures(1, &validation_texture_);
3328 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3329 glDeleteFramebuffersEXT(1, &validation_fbo_);
3330 }
3331
[email protected]97872062010-11-03 19:07:053332 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543333 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053334 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543335 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053336 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023337 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053338 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153339 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053340 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153341 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053342 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023343 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053344 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543345 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273346 if (offscreen_resolved_frame_buffer_.get())
3347 offscreen_resolved_frame_buffer_->Destroy();
3348 if (offscreen_resolved_color_texture_.get())
3349 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053350 } else {
3351 if (offscreen_target_frame_buffer_.get())
3352 offscreen_target_frame_buffer_->Invalidate();
3353 if (offscreen_target_color_texture_.get())
3354 offscreen_target_color_texture_->Invalidate();
3355 if (offscreen_target_color_render_buffer_.get())
3356 offscreen_target_color_render_buffer_->Invalidate();
3357 if (offscreen_target_depth_render_buffer_.get())
3358 offscreen_target_depth_render_buffer_->Invalidate();
3359 if (offscreen_target_stencil_render_buffer_.get())
3360 offscreen_target_stencil_render_buffer_->Invalidate();
3361 if (offscreen_saved_frame_buffer_.get())
3362 offscreen_saved_frame_buffer_->Invalidate();
3363 if (offscreen_saved_color_texture_.get())
3364 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273365 if (offscreen_resolved_frame_buffer_.get())
3366 offscreen_resolved_frame_buffer_->Invalidate();
3367 if (offscreen_resolved_color_texture_.get())
3368 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023369 }
[email protected]83a52d032013-07-24 10:30:373370
3371 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3372 // Otherwise, we can leak objects. http://crbug.com/258772.
3373 // state_.current_program must be reset before group_ is reset because
3374 // the later deletes the ProgramManager object that referred by
3375 // state_.current_program object.
3376 state_.current_program = NULL;
3377
[email protected]43410e92012-04-20 17:06:283378 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053379
[email protected]882ba1e22012-03-08 19:02:533380 if (query_manager_.get()) {
3381 query_manager_->Destroy(have_context);
3382 query_manager_.reset();
3383 }
3384
[email protected]944b62f32012-09-27 02:20:463385 if (vertex_array_manager_ .get()) {
3386 vertex_array_manager_->Destroy(have_context);
3387 vertex_array_manager_.reset();
3388 }
3389
[email protected]97872062010-11-03 19:07:053390 offscreen_target_frame_buffer_.reset();
3391 offscreen_target_color_texture_.reset();
3392 offscreen_target_color_render_buffer_.reset();
3393 offscreen_target_depth_render_buffer_.reset();
3394 offscreen_target_stencil_render_buffer_.reset();
3395 offscreen_saved_frame_buffer_.reset();
3396 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273397 offscreen_resolved_frame_buffer_.reset();
3398 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463399
[email protected]85a4ac22013-05-31 01:58:473400 // Should destroy the transfer manager before the texture manager held
3401 // by the context group.
3402 async_pixel_transfer_manager_.reset();
3403
[email protected]7cd76fd2013-06-02 21:11:113404 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393405 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233406 group_->Destroy(this, have_context);
3407 group_ = NULL;
3408 }
3409
3410 if (context_.get()) {
3411 context_->ReleaseCurrent(NULL);
3412 context_ = NULL;
3413 }
3414
[email protected]e51bdf32011-11-23 22:21:463415#if defined(OS_MACOSX)
3416 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3417 it != texture_to_io_surface_map_.end(); ++it) {
3418 CFRelease(it->second);
3419 }
3420 texture_to_io_surface_map_.clear();
3421#endif
[email protected]96449d2c2009-11-25 00:01:323422}
3423
[email protected]63c9b052012-05-17 18:27:383424void GLES2DecoderImpl::SetSurface(
3425 const scoped_refptr<gfx::GLSurface>& surface) {
3426 DCHECK(context_->IsCurrent(NULL));
3427 DCHECK(surface_.get());
3428 surface_ = surface;
3429 RestoreCurrentFramebufferBindings();
3430}
3431
[email protected]aba551b2014-02-08 03:38:323432void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3433 if (!offscreen_saved_color_texture_.get()) {
3434 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3435 return;
3436 }
[email protected]2ad674132013-06-05 07:48:513437 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243438 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073439 offscreen_saved_color_texture_info_ = TextureRef::Create(
3440 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513441 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3442 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393443 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243444 }
[email protected]aba551b2014-02-08 03:38:323445 mailbox_manager()->ProduceTexture(
3446 GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243447}
3448
[email protected]799b4b22011-08-22 17:09:593449bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3450 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3451 if (!is_offscreen) {
3452 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3453 << " with an onscreen framebuffer.";
3454 return false;
3455 }
3456
3457 if (offscreen_size_ == size)
3458 return true;
3459
3460 offscreen_size_ = size;
3461 int w = offscreen_size_.width();
3462 int h = offscreen_size_.height();
3463 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3464 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3465 << "to allocate storage due to excessive dimensions.";
3466 return false;
3467 }
3468
3469 // Reallocate the offscreen target buffers.
3470 DCHECK(offscreen_target_color_format_);
3471 if (IsOffscreenBufferMultisampled()) {
3472 if (!offscreen_target_color_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183473 feature_info_, offscreen_size_, offscreen_target_color_format_,
[email protected]799b4b22011-08-22 17:09:593474 offscreen_target_samples_)) {
3475 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3476 << "to allocate storage for offscreen target color buffer.";
3477 return false;
3478 }
3479 } else {
3480 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093481 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593482 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3483 << "to allocate storage for offscreen target color texture.";
3484 return false;
3485 }
3486 }
3487 if (offscreen_target_depth_format_ &&
3488 !offscreen_target_depth_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183489 feature_info_, offscreen_size_, offscreen_target_depth_format_,
[email protected]799b4b22011-08-22 17:09:593490 offscreen_target_samples_)) {
3491 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3492 << "to allocate storage for offscreen target depth buffer.";
3493 return false;
3494 }
3495 if (offscreen_target_stencil_format_ &&
3496 !offscreen_target_stencil_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183497 feature_info_, offscreen_size_, offscreen_target_stencil_format_,
[email protected]799b4b22011-08-22 17:09:593498 offscreen_target_samples_)) {
3499 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3500 << "to allocate storage for offscreen target stencil buffer.";
3501 return false;
3502 }
3503
3504 // Attach the offscreen target buffers to the target frame buffer.
3505 if (IsOffscreenBufferMultisampled()) {
3506 offscreen_target_frame_buffer_->AttachRenderBuffer(
3507 GL_COLOR_ATTACHMENT0,
3508 offscreen_target_color_render_buffer_.get());
3509 } else {
3510 offscreen_target_frame_buffer_->AttachRenderTexture(
3511 offscreen_target_color_texture_.get());
3512 }
3513 if (offscreen_target_depth_format_) {
3514 offscreen_target_frame_buffer_->AttachRenderBuffer(
3515 GL_DEPTH_ATTACHMENT,
3516 offscreen_target_depth_render_buffer_.get());
3517 }
3518 const bool packed_depth_stencil =
3519 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3520 if (packed_depth_stencil) {
3521 offscreen_target_frame_buffer_->AttachRenderBuffer(
3522 GL_STENCIL_ATTACHMENT,
3523 offscreen_target_depth_render_buffer_.get());
3524 } else if (offscreen_target_stencil_format_) {
3525 offscreen_target_frame_buffer_->AttachRenderBuffer(
3526 GL_STENCIL_ATTACHMENT,
3527 offscreen_target_stencil_render_buffer_.get());
3528 }
3529
3530 if (offscreen_target_frame_buffer_->CheckStatus() !=
3531 GL_FRAMEBUFFER_COMPLETE) {
3532 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3533 << "because offscreen FBO was incomplete.";
3534 return false;
3535 }
3536
3537 // Clear the target frame buffer.
3538 {
3539 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3540 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3541 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3542 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3543 glClearStencil(0);
3544 glStencilMaskSeparate(GL_FRONT, -1);
3545 glStencilMaskSeparate(GL_BACK, -1);
3546 glClearDepth(0);
3547 glDepthMask(GL_TRUE);
3548 glDisable(GL_SCISSOR_TEST);
3549 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3550 RestoreClearState();
3551 }
[email protected]d85ef76d2011-09-08 22:21:433552
3553 // Destroy the offscreen resolved framebuffers.
3554 if (offscreen_resolved_frame_buffer_.get())
3555 offscreen_resolved_frame_buffer_->Destroy();
3556 if (offscreen_resolved_color_texture_.get())
3557 offscreen_resolved_color_texture_->Destroy();
3558 offscreen_resolved_color_texture_.reset();
3559 offscreen_resolved_frame_buffer_.reset();
3560
[email protected]799b4b22011-08-22 17:09:593561 return true;
[email protected]6217d392010-03-25 22:08:353562}
3563
[email protected]799b4b22011-08-22 17:09:593564error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353565 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443566 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023567 return error::kDeferCommandUntilLater;
3568
[email protected]799b4b22011-08-22 17:09:593569 GLuint width = static_cast<GLuint>(c.width);
3570 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073571 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593572 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413573
3574 width = std::max(1U, width);
3575 height = std::max(1U, height);
3576
[email protected]a0d989162011-11-22 13:15:073577#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3578 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003579 // Make sure that we are done drawing to the back buffer before resizing.
3580 glFinish();
3581#endif
[email protected]799b4b22011-08-22 17:09:593582 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3583 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493584 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3585 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3586 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593587 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493588 }
[email protected]7ff86b92010-11-25 17:50:003589 }
[email protected]799b4b22011-08-22 17:09:593590
[email protected]9d37f062011-11-22 01:24:523591 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073592 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443593 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493594 if (!context_->IsCurrent(surface_.get())) {
3595 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3596 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053597 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493598 }
[email protected]658f7562011-09-09 05:24:053599 }
[email protected]799b4b22011-08-22 17:09:593600
3601 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393602}
3603
[email protected]96449d2c2009-11-25 00:01:323604const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3605 if (command_id > kStartPoint && command_id < kNumCommands) {
3606 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3607 }
3608 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3609}
3610
3611// Decode command with its arguments, and call the corresponding GL function.
3612// Note: args is a pointer to the command buffer. As such, it could be changed
3613// by a (malicious) client at any time, so if validation has to happen, it
3614// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143615error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323616 unsigned int command,
3617 unsigned int arg_count,
3618 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143619 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263620 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003621 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
[email protected]65f7efe2013-11-28 03:11:473622 // VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323623 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013624 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193625 }
[email protected]96449d2c2009-11-25 00:01:323626 unsigned int command_index = command - kStartPoint - 1;
3627 if (command_index < arraysize(g_command_info)) {
3628 const CommandInfo& info = g_command_info[command_index];
3629 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3630 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3631 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]cac16542014-01-15 17:53:513632 bool doing_gpu_trace = false;
3633 if (gpu_trace_commands_) {
3634 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3635 doing_gpu_trace = true;
3636 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3637 }
3638 }
3639
[email protected]b9849abf2009-11-25 19:13:193640 uint32 immediate_data_size =
3641 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323642 switch (command) {
3643 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353644 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193645 result = Handle ## name( \
3646 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353647 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193648 break; \
[email protected]96449d2c2009-11-25 00:01:323649
3650 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323651 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383652 }
[email protected]cac16542014-01-15 17:53:513653
3654 if (doing_gpu_trace)
3655 gpu_tracer_->End(kTraceDecoder);
3656
[email protected]bf0985e2009-12-17 03:04:383657 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303658 GLenum error;
3659 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323660 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003661 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3662 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513663 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193664 }
[email protected]96449d2c2009-11-25 00:01:323665 }
3666 } else {
[email protected]f7a64ee2010-02-01 22:24:143667 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323668 }
[email protected]b9849abf2009-11-25 19:13:193669 } else {
3670 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323671 }
[email protected]a3a93e7b2010-08-28 00:48:563672 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3673 result = current_decoder_error_;
3674 current_decoder_error_ = error::kNoError;
3675 }
[email protected]b9849abf2009-11-25 19:13:193676 return result;
[email protected]96449d2c2009-11-25 00:01:323677}
3678
[email protected]ed9f9cd2013-02-27 21:12:353679void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3680 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503681}
3682
[email protected]ae51d192010-04-27 00:48:033683bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353684 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033685 return false;
3686 }
[email protected]96449d2c2009-11-25 00:01:323687 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033688 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353689 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323690 }
[email protected]ae51d192010-04-27 00:48:033691 return true;
[email protected]96449d2c2009-11-25 00:01:323692}
3693
[email protected]ae51d192010-04-27 00:48:033694bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353695 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033696 return false;
[email protected]96449d2c2009-11-25 00:01:323697 }
[email protected]ae51d192010-04-27 00:48:033698 GLuint service_id = glCreateShader(type);
3699 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353700 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033701 }
3702 return true;
[email protected]96449d2c2009-11-25 00:01:323703}
3704
[email protected]882ba1e22012-03-08 19:02:533705void GLES2DecoderImpl::DoFinish() {
3706 glFinish();
[email protected]5a36dc132013-07-23 23:17:553707 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193708 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533709}
3710
3711void GLES2DecoderImpl::DoFlush() {
3712 glFlush();
[email protected]22e3f552012-03-13 01:54:193713 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533714}
3715
[email protected]3916c97e2010-02-25 03:20:503716void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453717 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023718 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513719 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533720 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503721 return;
3722 }
[email protected]e259eb412012-10-13 05:47:243723 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453724 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503725}
3726
[email protected]051b1372010-04-12 02:42:083727void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073728 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083729 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033730 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073731 buffer = GetBuffer(client_id);
3732 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353733 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223734 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3735 "glBindBuffer",
3736 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:353737 return;
3738 }
3739
[email protected]b10492f2013-03-08 05:24:073740 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033741 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353742 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073743 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573744 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103745 group_->GetIdAllocator(id_namespaces::kBuffers);
3746 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033747 }
[email protected]051b1372010-04-12 02:42:083748 }
[email protected]b10492f2013-03-08 05:24:073749 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3750 if (buffer) {
3751 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513752 LOCAL_SET_GL_ERROR(
3753 GL_INVALID_OPERATION,
3754 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473755 return;
3756 }
[email protected]b10492f2013-03-08 05:24:073757 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473758 }
[email protected]96449d2c2009-11-25 00:01:323759 switch (target) {
3760 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073761 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323762 break;
3763 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073764 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323765 break;
3766 default:
[email protected]a93bb842010-02-16 23:03:473767 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323768 break;
3769 }
[email protected]051b1372010-04-12 02:42:083770 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323771}
3772
[email protected]f3b191b2013-06-19 03:43:543773bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3774 bool all_draw_buffers) {
3775 Framebuffer* framebuffer =
3776 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3777 if (!all_draw_buffers || !framebuffer) {
3778 return (GLES2Util::GetChannelsForFormat(
3779 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3780 }
3781 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463782}
3783
3784bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353785 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453786 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203787 if (framebuffer) {
3788 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463789 }
3790 if (offscreen_target_frame_buffer_.get()) {
3791 return offscreen_target_depth_format_ != 0;
3792 }
3793 return back_buffer_has_depth_;
3794}
3795
3796bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353797 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453798 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203799 if (framebuffer) {
3800 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463801 }
3802 if (offscreen_target_frame_buffer_.get()) {
3803 return offscreen_target_stencil_format_ != 0 ||
3804 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3805 }
3806 return back_buffer_has_stencil_;
3807}
3808
3809void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:443810 if (framebuffer_state_.clear_state_dirty) {
[email protected]297ca1c2011-06-20 23:08:463811 glColorMask(
[email protected]e259eb412012-10-13 05:47:243812 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3813 state_.color_mask_alpha &&
[email protected]f3b191b2013-06-19 03:43:543814 BoundFramebufferHasColorAttachmentWithAlpha(true));
[email protected]297ca1c2011-06-20 23:08:463815 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243816 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223817 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463818 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243819 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423820 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243821 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423822 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223823 EnableDisable(
3824 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3825 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3826 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3827 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]c986af502013-08-14 01:04:443828 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:463829 }
3830}
3831
[email protected]1868a342012-11-07 15:56:023832GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:113833 return (offscreen_target_frame_buffer_.get())
3834 ? offscreen_target_frame_buffer_->id()
3835 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:023836}
3837
[email protected]5baa86bc2014-01-16 04:33:163838void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) const {
[email protected]962bfbe72013-05-24 11:16:143839 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3840 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:063841 // Restore the Framebuffer first because of bugs in Intel drivers.
3842 // Intel drivers incorrectly clip the viewport settings to
3843 // the size of the current framebuffer object.
3844 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:163845 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:063846}
3847
3848void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:343849 GLuint service_id =
3850 framebuffer_state_.bound_draw_framebuffer.get()
3851 ? framebuffer_state_.bound_draw_framebuffer->service_id()
3852 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063853 if (!features().chromium_framebuffer_multisample) {
3854 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3855 } else {
3856 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:343857 service_id = framebuffer_state_.bound_read_framebuffer.get()
3858 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:113859 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063860 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3861 }
[email protected]70d34263c2013-01-09 00:27:453862 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063863}
3864
3865void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:103866 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3867 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:253868 GLenum target = texture->target();
3869 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063870 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253871 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063872 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253873 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063874 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253875 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063876 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253877 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063878 RestoreTextureUnitBindings(state_.active_texture_unit);
3879 }
[email protected]70d34263c2013-01-09 00:27:453880}
3881
[email protected]cd2ef752014-02-12 23:16:033882void GLES2DecoderImpl::ClearAllAttributes() const {
3883 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
3884 if (i != 0) // Never disable attribute 0
3885 glDisableVertexAttribArray(i);
3886 if(features().angle_instanced_arrays)
3887 glVertexAttribDivisorANGLE(i, 0);
3888 }
3889}
3890
3891void GLES2DecoderImpl::RestoreAllAttributes() const {
3892 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i)
3893 RestoreAttribute(i);
3894}
3895
[email protected]70d34263c2013-01-09 00:27:453896void GLES2DecoderImpl::OnFboChanged() const {
3897 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513898 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3899}
3900
3901// Called after the FBO is checked for completeness.
3902void GLES2DecoderImpl::OnUseFramebuffer() const {
3903 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3904 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323905 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513906 glScissor(state_.scissor_x,
3907 state_.scissor_y,
3908 state_.scissor_width,
3909 state_.scissor_height);
3910
3911 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3912 // it's unclear how this bug works.
3913 glFlush();
3914 }
[email protected]b177ae22011-11-01 03:29:113915}
3916
[email protected]051b1372010-04-12 02:42:083917void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063918 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083919 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033920 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063921 framebuffer = GetFramebuffer(client_id);
3922 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353923 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223924 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3925 "glBindFramebuffer",
3926 "id not generated by glGenFramebuffers");
3927 return;
[email protected]bf5a8d132011-08-16 08:39:353928 }
3929
[email protected]4d8f0dd2013-03-09 14:37:063930 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033931 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353932 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063933 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573934 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103935 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3936 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033937 } else {
[email protected]4d8f0dd2013-03-09 14:37:063938 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083939 }
[email protected]4d8f0dd2013-03-09 14:37:063940 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083941 }
[email protected]4d8f0dd2013-03-09 14:37:063942 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303943
3944 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:343945 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303946 }
[email protected]cac16542014-01-15 17:53:513947
3948 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:303949 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:343950 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303951 }
[email protected]6217d392010-03-25 22:08:353952
[email protected]c986af502013-08-14 01:04:443953 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463954
[email protected]b177ae22011-11-01 03:29:113955 // If we are rendering to the backbuffer get the FBO id for any simulated
3956 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063957 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113958 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463959 }
[email protected]6217d392010-03-25 22:08:353960
[email protected]051b1372010-04-12 02:42:083961 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453962 OnFboChanged();
[email protected]86093972010-03-11 00:13:563963}
3964
[email protected]051b1372010-04-12 02:42:083965void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273966 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083967 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033968 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273969 renderbuffer = GetRenderbuffer(client_id);
3970 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353971 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223972 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3973 "glBindRenderbuffer",
3974 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:353975 return;
3976 }
3977
[email protected]ee2a79c32013-03-10 03:50:273978 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033979 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353980 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273981 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573982 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103983 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3984 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033985 } else {
[email protected]ee2a79c32013-03-10 03:50:273986 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083987 }
[email protected]ee2a79c32013-03-10 03:50:273988 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083989 }
[email protected]caa13ed2014-02-17 11:29:203990 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:273991 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083992 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563993}
3994
[email protected]051b1372010-04-12 02:42:083995void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:493996 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:083997 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033998 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:493999 texture_ref = GetTexture(client_id);
4000 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354001 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224002 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4003 "glBindTexture",
4004 "id not generated by glGenTextures");
4005 return;
[email protected]bf5a8d132011-08-16 08:39:354006 }
4007
[email protected]02965c22013-03-09 02:40:074008 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034009 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414010 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354011 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494012 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:574013 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:104014 group_->GetIdAllocator(id_namespaces::kTextures);
4015 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:034016 }
4017 } else {
[email protected]370eaf12013-05-18 09:19:494018 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084019 }
[email protected]370eaf12013-05-18 09:19:494020 Texture* texture = texture_ref->texture();
[email protected]ae51d192010-04-27 00:48:034021
[email protected]1958e0e2010-04-22 05:17:154022 // Check the texture exists
4023 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:074024 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:514025 LOCAL_SET_GL_ERROR(
4026 GL_INVALID_OPERATION,
4027 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:154028 return;
4029 }
[email protected]02965c22013-03-09 02:40:074030 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4031 if (texture->target() == 0) {
[email protected]370eaf12013-05-18 09:19:494032 texture_manager()->SetTarget(texture_ref, target);
[email protected]a93bb842010-02-16 23:03:474033 }
[email protected]02965c22013-03-09 02:40:074034 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:594035
[email protected]e259eb412012-10-13 05:47:244036 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504037 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474038 switch (target) {
4039 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494040 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474041 break;
4042 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494043 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474044 break;
[email protected]61eeb33f2011-07-26 15:30:314045 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494046 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314047 break;
[email protected]e51bdf32011-11-23 22:21:464048 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494049 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464050 break;
[email protected]a93bb842010-02-16 23:03:474051 default:
4052 NOTREACHED(); // Validation should prevent us getting here.
4053 break;
4054 }
4055}
4056
[email protected]07f54fcc2009-12-22 02:46:304057void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244058 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124059 if (index != 0 ||
4060 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244061 glDisableVertexAttribArray(index);
4062 }
[email protected]07f54fcc2009-12-22 02:46:304063 } else {
[email protected]ab09b612013-03-11 22:11:514064 LOCAL_SET_GL_ERROR(
4065 GL_INVALID_VALUE,
4066 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304067 }
4068}
4069
[email protected]60f22d32012-12-12 00:31:584070void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4071 GLsizei numAttachments,
4072 const GLenum* attachments) {
[email protected]680aa412013-10-31 18:08:014073 if (!features().ext_discard_framebuffer) {
4074 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4075 "glDiscardFramebufferEXT",
4076 "function not available");
4077 return;
4078 }
4079
[email protected]ed9f9cd2013-02-27 21:12:354080 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584081 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4082
4083 // Validates the attachments. If one of them fails
4084 // the whole command fails.
4085 for (GLsizei i = 0; i < numAttachments; ++i) {
4086 if ((framebuffer &&
4087 !validators_->attachment.IsValid(attachments[i])) ||
4088 (!framebuffer &&
4089 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514090 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4091 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584092 return;
4093 }
4094 }
4095
4096 // Marks each one of them as not cleared
4097 for (GLsizei i = 0; i < numAttachments; ++i) {
4098 if (framebuffer) {
4099 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4100 texture_manager(),
4101 attachments[i],
4102 false);
4103 } else {
4104 switch (attachments[i]) {
4105 case GL_COLOR_EXT:
4106 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4107 break;
4108 case GL_DEPTH_EXT:
4109 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4110 case GL_STENCIL_EXT:
4111 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4112 break;
4113 default:
4114 NOTREACHED();
4115 break;
4116 }
4117 }
4118 }
4119
[email protected]d49c5402013-09-11 15:39:024120 // If the default framebuffer is bound but we are still rendering to an
4121 // FBO, translate attachment names that refer to default framebuffer
4122 // channels to corresponding framebuffer attachments.
4123 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4124 for (GLsizei i = 0; i < numAttachments; ++i) {
4125 GLenum attachment = attachments[i];
4126 if (!framebuffer && GetBackbufferServiceId()) {
4127 switch (attachment) {
4128 case GL_COLOR_EXT:
4129 attachment = GL_COLOR_ATTACHMENT0;
4130 break;
4131 case GL_DEPTH_EXT:
4132 attachment = GL_DEPTH_ATTACHMENT;
4133 break;
4134 case GL_STENCIL_EXT:
4135 attachment = GL_STENCIL_ATTACHMENT;
4136 break;
4137 default:
4138 NOTREACHED();
4139 return;
4140 }
4141 }
4142 translated_attachments[i] = attachment;
4143 }
4144
4145 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584146}
4147
[email protected]07f54fcc2009-12-22 02:46:304148void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244149 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304150 glEnableVertexAttribArray(index);
4151 } else {
[email protected]ab09b612013-03-11 22:11:514152 LOCAL_SET_GL_ERROR(
4153 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304154 }
4155}
4156
[email protected]a93bb842010-02-16 23:03:474157void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444158 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4159 &state_, target);
[email protected]370eaf12013-05-18 09:19:494160 if (!texture_ref ||
4161 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514162 LOCAL_SET_GL_ERROR(
4163 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474164 return;
4165 }
[email protected]38c0a972012-05-12 00:48:024166
[email protected]12d95352012-12-14 07:23:544167 if (target == GL_TEXTURE_CUBE_MAP) {
4168 for (int i = 0; i < 6; ++i) {
4169 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494170 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514171 LOCAL_SET_GL_ERROR(
4172 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544173 return;
4174 }
4175 }
4176 } else {
[email protected]370eaf12013-05-18 09:19:494177 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514178 LOCAL_SET_GL_ERROR(
4179 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544180 return;
4181 }
[email protected]7687479c2012-05-14 23:54:044182 }
4183
[email protected]ab09b612013-03-11 22:11:514184 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194185 // Workaround for Mac driver bug. In the large scheme of things setting
4186 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564187 // hit so there's probably no need to make this conditional. The bug appears
4188 // to be that if the filtering mode is set to something that doesn't require
4189 // mipmaps for rendering, or is never set to something other than the default,
4190 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154191 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194192 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4193 }
[email protected]a93bb842010-02-16 23:03:474194 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154195 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494196 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4197 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194198 }
[email protected]ab09b612013-03-11 22:11:514199 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024200 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494201 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024202 }
[email protected]a93bb842010-02-16 23:03:474203}
4204
[email protected]b273e432010-04-12 17:23:584205bool GLES2DecoderImpl::GetHelper(
4206 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584207 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154208 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4209 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434210 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4211 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214212 // Return the GL implementation's preferred format and (see below type)
4213 // if we have the GL extension that exposes this. This allows the GPU
4214 // client to use the implementation's preferred format for glReadPixels
4215 // for optimisation.
4216 //
4217 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4218 // case when requested on integer/floating point buffers but which is
4219 // acceptable on GLES2 and with the GL_OES_read_format extension.
4220 //
4221 // Therefore if an error occurs we swallow the error and use the
4222 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434223 if (params) {
[email protected]c959a09a2014-03-27 11:44:214224 if (context_->HasExtension("GL_OES_read_format")) {
4225 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4226 GetErrorState());
4227 glGetIntegerv(pname, params);
4228 if (glGetError() == GL_NO_ERROR)
4229 return true;
4230 }
[email protected]68586372013-12-11 01:27:594231 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4232 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434233 }
4234 return true;
4235 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4236 *num_written = 1;
4237 if (params) {
[email protected]c959a09a2014-03-27 11:44:214238 if (context_->HasExtension("GL_OES_read_format")) {
4239 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4240 GetErrorState());
4241 glGetIntegerv(pname, params);
4242 if (glGetError() == GL_NO_ERROR)
4243 return true;
4244 }
[email protected]68586372013-12-11 01:27:594245 *params = GLES2Util::GetPreferredGLReadPixelsType(
4246 GetBoundReadFrameBufferInternalFormat(),
4247 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434248 }
4249 return true;
4250 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4251 *num_written = 1;
4252 if (params) {
4253 *params = group_->max_fragment_uniform_vectors();
4254 }
4255 return true;
4256 case GL_MAX_VARYING_VECTORS:
4257 *num_written = 1;
4258 if (params) {
4259 *params = group_->max_varying_vectors();
4260 }
4261 return true;
4262 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4263 *num_written = 1;
4264 if (params) {
4265 *params = group_->max_vertex_uniform_vectors();
4266 }
4267 return true;
[email protected]4e8a5b122010-05-08 22:00:104268 }
[email protected]5cb735d2011-10-13 01:37:234269 }
4270 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244271 case GL_MAX_VIEWPORT_DIMS:
4272 if (offscreen_target_frame_buffer_.get()) {
4273 *num_written = 2;
4274 if (params) {
4275 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4276 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4277 }
4278 return true;
4279 }
[email protected]5cb735d2011-10-13 01:37:234280 return false;
[email protected]84afefa2011-10-19 21:45:534281 case GL_MAX_SAMPLES:
4282 *num_written = 1;
4283 if (params) {
4284 params[0] = renderbuffer_manager()->max_samples();
4285 }
4286 return true;
4287 case GL_MAX_RENDERBUFFER_SIZE:
4288 *num_written = 1;
4289 if (params) {
4290 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4291 }
4292 return true;
[email protected]5cb735d2011-10-13 01:37:234293 case GL_MAX_TEXTURE_SIZE:
4294 *num_written = 1;
4295 if (params) {
4296 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4297 }
4298 return true;
4299 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4300 *num_written = 1;
4301 if (params) {
4302 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4303 }
4304 return true;
[email protected]2f143d482013-03-14 18:04:494305 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4306 *num_written = 1;
4307 if (params) {
4308 params[0] = group_->max_color_attachments();
4309 }
4310 return true;
4311 case GL_MAX_DRAW_BUFFERS_ARB:
4312 *num_written = 1;
4313 if (params) {
4314 params[0] = group_->max_draw_buffers();
4315 }
4316 return true;
[email protected]297ca1c2011-06-20 23:08:464317 case GL_ALPHA_BITS:
4318 *num_written = 1;
4319 if (params) {
4320 GLint v = 0;
4321 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544322 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464323 }
4324 return true;
4325 case GL_DEPTH_BITS:
4326 *num_written = 1;
4327 if (params) {
4328 GLint v = 0;
4329 glGetIntegerv(GL_DEPTH_BITS, &v);
4330 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4331 }
4332 return true;
4333 case GL_STENCIL_BITS:
4334 *num_written = 1;
4335 if (params) {
4336 GLint v = 0;
4337 glGetIntegerv(GL_STENCIL_BITS, &v);
4338 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4339 }
4340 return true;
[email protected]656dcaad2010-05-07 17:18:374341 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114342 *num_written = validators_->compressed_texture_format.GetValues().size();
4343 if (params) {
4344 for (GLint ii = 0; ii < *num_written; ++ii) {
4345 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4346 }
4347 }
[email protected]656dcaad2010-05-07 17:18:374348 return true;
[email protected]b273e432010-04-12 17:23:584349 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4350 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104351 if (params) {
[email protected]302ce6d2011-07-07 23:28:114352 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104353 }
[email protected]b273e432010-04-12 17:23:584354 return true;
4355 case GL_NUM_SHADER_BINARY_FORMATS:
4356 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104357 if (params) {
[email protected]302ce6d2011-07-07 23:28:114358 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104359 }
[email protected]b273e432010-04-12 17:23:584360 return true;
4361 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114362 *num_written = validators_->shader_binary_format.GetValues().size();
4363 if (params) {
4364 for (GLint ii = 0; ii < *num_written; ++ii) {
4365 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4366 }
4367 }
4368 return true;
[email protected]b273e432010-04-12 17:23:584369 case GL_SHADER_COMPILER:
4370 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104371 if (params) {
4372 *params = GL_TRUE;
4373 }
[email protected]b273e432010-04-12 17:23:584374 return true;
[email protected]6b8cf1a2010-05-06 16:13:584375 case GL_ARRAY_BUFFER_BINDING:
4376 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104377 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114378 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104379 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244380 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104381 &client_id);
4382 *params = client_id;
4383 } else {
4384 *params = 0;
4385 }
[email protected]6b8cf1a2010-05-06 16:13:584386 }
4387 return true;
4388 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4389 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104390 if (params) {
[email protected]e259eb412012-10-13 05:47:244391 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104392 GLuint client_id = 0;
4393 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254394 state_.vertex_attrib_manager->element_array_buffer()->
4395 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104396 *params = client_id;
4397 } else {
4398 *params = 0;
4399 }
[email protected]6b8cf1a2010-05-06 16:13:584400 }
4401 return true;
4402 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304403 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584404 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104405 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354406 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454407 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204408 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104409 GLuint client_id = 0;
4410 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204411 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304412 *params = client_id;
4413 } else {
4414 *params = 0;
4415 }
4416 }
4417 return true;
[email protected]ebfb73c2012-08-15 02:37:454418 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304419 *num_written = 1;
4420 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354421 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454422 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204423 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304424 GLuint client_id = 0;
4425 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204426 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104427 *params = client_id;
4428 } else {
4429 *params = 0;
4430 }
[email protected]6b8cf1a2010-05-06 16:13:584431 }
4432 return true;
4433 case GL_RENDERBUFFER_BINDING:
4434 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104435 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354436 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204437 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4438 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104439 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104440 } else {
4441 *params = 0;
4442 }
[email protected]6b8cf1a2010-05-06 16:13:584443 }
4444 return true;
4445 case GL_CURRENT_PROGRAM:
4446 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104447 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114448 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104449 GLuint client_id = 0;
4450 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244451 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104452 *params = client_id;
4453 } else {
4454 *params = 0;
4455 }
[email protected]6b8cf1a2010-05-06 16:13:584456 }
4457 return true;
[email protected]bf835842012-11-19 15:21:514458 case GL_VERTEX_ARRAY_BINDING_OES:
4459 *num_written = 1;
4460 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114461 if (state_.vertex_attrib_manager.get() !=
4462 default_vertex_attrib_manager_.get()) {
[email protected]bf835842012-11-19 15:21:514463 GLuint client_id = 0;
4464 vertex_array_manager_->GetClientId(
4465 state_.vertex_attrib_manager->service_id(), &client_id);
4466 *params = client_id;
4467 } else {
4468 *params = 0;
4469 }
4470 }
4471 return true;
[email protected]4e8a5b122010-05-08 22:00:104472 case GL_TEXTURE_BINDING_2D:
4473 *num_written = 1;
4474 if (params) {
[email protected]e259eb412012-10-13 05:47:244475 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114476 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104477 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584478 } else {
4479 *params = 0;
4480 }
[email protected]6b8cf1a2010-05-06 16:13:584481 }
[email protected]4e8a5b122010-05-08 22:00:104482 return true;
4483 case GL_TEXTURE_BINDING_CUBE_MAP:
4484 *num_written = 1;
4485 if (params) {
[email protected]e259eb412012-10-13 05:47:244486 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114487 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104488 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584489 } else {
4490 *params = 0;
4491 }
[email protected]6b8cf1a2010-05-06 16:13:584492 }
[email protected]4e8a5b122010-05-08 22:00:104493 return true;
[email protected]61eeb33f2011-07-26 15:30:314494 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4495 *num_written = 1;
4496 if (params) {
[email protected]e259eb412012-10-13 05:47:244497 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114498 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104499 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314500 } else {
4501 *params = 0;
4502 }
4503 }
4504 return true;
[email protected]e51bdf32011-11-23 22:21:464505 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4506 *num_written = 1;
4507 if (params) {
[email protected]e259eb412012-10-13 05:47:244508 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114509 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104510 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464511 } else {
4512 *params = 0;
4513 }
4514 }
4515 return true;
[email protected]6c75c712012-06-19 15:43:174516 case GL_UNPACK_FLIP_Y_CHROMIUM:
4517 *num_written = 1;
4518 if (params) {
4519 params[0] = unpack_flip_y_;
4520 }
4521 return true;
4522 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4523 *num_written = 1;
4524 if (params) {
4525 params[0] = unpack_premultiply_alpha_;
4526 }
4527 return true;
4528 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4529 *num_written = 1;
4530 if (params) {
4531 params[0] = unpack_unpremultiply_alpha_;
4532 }
4533 return true;
[email protected]b273e432010-04-12 17:23:584534 default:
[email protected]2f143d482013-03-14 18:04:494535 if (pname >= GL_DRAW_BUFFER0_ARB &&
4536 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4537 *num_written = 1;
4538 if (params) {
4539 Framebuffer* framebuffer =
4540 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4541 if (framebuffer) {
4542 params[0] = framebuffer->GetDrawBuffer(pname);
4543 } else { // backbuffer
4544 if (pname == GL_DRAW_BUFFER0_ARB)
4545 params[0] = group_->draw_buffer();
4546 else
4547 params[0] = GL_NONE;
4548 }
4549 }
4550 return true;
4551 }
[email protected]4e8a5b122010-05-08 22:00:104552 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534553 return false;
[email protected]b273e432010-04-12 17:23:584554 }
4555}
4556
[email protected]4e8a5b122010-05-08 22:00:104557bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4558 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264559 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534560 return true;
4561 }
[email protected]4e8a5b122010-05-08 22:00:104562 return GetHelper(pname, NULL, num_values);
4563}
4564
[email protected]7d3c36e2013-07-12 14:13:164565GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4566 if (GL_MAX_SAMPLES == pname &&
4567 features().use_img_for_multisampled_render_to_texture) {
4568 return GL_MAX_SAMPLES_IMG;
4569 }
4570 return pname;
4571}
4572
[email protected]b273e432010-04-12 17:23:584573void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4574 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104575 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534576 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554577 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264578 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534579 GetHelper(pname, values.get(), &num_written);
4580 }
[email protected]b273e432010-04-12 17:23:584581 for (GLsizei ii = 0; ii < num_written; ++ii) {
4582 params[ii] = static_cast<GLboolean>(values[ii]);
4583 }
4584 } else {
[email protected]7d3c36e2013-07-12 14:13:164585 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584586 glGetBooleanv(pname, params);
4587 }
4588}
4589
4590void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4591 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104592 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264593 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534594 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554595 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534596 GetHelper(pname, values.get(), &num_written);
4597 for (GLsizei ii = 0; ii < num_written; ++ii) {
4598 params[ii] = static_cast<GLfloat>(values[ii]);
4599 }
4600 } else {
[email protected]7d3c36e2013-07-12 14:13:164601 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534602 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584603 }
[email protected]b273e432010-04-12 17:23:584604 }
4605}
4606
4607void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4608 DCHECK(params);
4609 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264610 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534611 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164612 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584613 glGetIntegerv(pname, params);
4614 }
4615}
4616
[email protected]a0c3e972010-04-21 00:49:134617void GLES2DecoderImpl::DoGetProgramiv(
4618 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424619 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4620 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134621 return;
4622 }
[email protected]df37b9932013-03-08 05:21:424623 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134624}
4625
[email protected]17cfbe0e2013-03-07 01:26:084626void GLES2DecoderImpl::DoGetBufferParameteriv(
4627 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134628 // Just delegate it. Some validation is actually done before this.
4629 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4630 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084631}
4632
[email protected]258a3313f2011-10-18 20:13:574633void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424634 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574635 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514636 LOCAL_SET_GL_ERROR(
4637 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574638 return;
4639 }
[email protected]68dcb1f2012-04-07 00:14:564640 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514641 LOCAL_SET_GL_ERROR(
4642 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564643 return;
4644 }
4645 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514646 LOCAL_SET_GL_ERROR(
4647 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564648 return;
4649 }
[email protected]df37b9932013-03-08 05:21:424650 Program* program = GetProgramInfoNotShader(
4651 program_id, "glBindAttribLocation");
4652 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574653 return;
[email protected]558847a2010-03-24 07:02:544654 }
[email protected]df37b9932013-03-08 05:21:424655 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4656 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574657}
4658
4659error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354660 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574661 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544662 GLuint index = static_cast<GLuint>(c.index);
4663 uint32 name_size = c.data_size;
4664 const char* name = GetSharedMemoryAs<const char*>(
4665 c.name_shm_id, c.name_shm_offset, name_size);
4666 if (name == NULL) {
4667 return error::kOutOfBounds;
4668 }
4669 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574670 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544671 return error::kNoError;
4672}
4673
[email protected]558847a2010-03-24 07:02:544674error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354675 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584676 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544677 GLuint index = static_cast<GLuint>(c.index);
4678 Bucket* bucket = GetBucket(c.name_bucket_id);
4679 if (!bucket || bucket->size() == 0) {
4680 return error::kInvalidArguments;
4681 }
4682 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184683 if (!bucket->GetAsString(&name_str)) {
4684 return error::kInvalidArguments;
4685 }
[email protected]258a3313f2011-10-18 20:13:574686 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544687 return error::kNoError;
4688}
4689
[email protected]2be6abf32012-06-26 00:28:334690void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424691 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334692 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514693 LOCAL_SET_GL_ERROR(
4694 GL_INVALID_VALUE,
4695 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334696 return;
4697 }
4698 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514699 LOCAL_SET_GL_ERROR(
4700 GL_INVALID_OPERATION,
4701 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334702 return;
4703 }
4704 if (location < 0 || static_cast<uint32>(location) >=
4705 (group_->max_fragment_uniform_vectors() +
4706 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514707 LOCAL_SET_GL_ERROR(
4708 GL_INVALID_VALUE,
4709 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334710 return;
4711 }
[email protected]df37b9932013-03-08 05:21:424712 Program* program = GetProgramInfoNotShader(
4713 program_id, "glBindUniformLocationCHROMIUM");
4714 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334715 return;
4716 }
[email protected]df37b9932013-03-08 05:21:424717 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514718 LOCAL_SET_GL_ERROR(
4719 GL_INVALID_VALUE,
4720 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334721 }
4722}
4723
4724error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354725 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334726 GLuint program = static_cast<GLuint>(c.program);
4727 GLint location = static_cast<GLint>(c.location);
4728 uint32 name_size = c.data_size;
4729 const char* name = GetSharedMemoryAs<const char*>(
4730 c.name_shm_id, c.name_shm_offset, name_size);
4731 if (name == NULL) {
4732 return error::kOutOfBounds;
4733 }
4734 String name_str(name, name_size);
4735 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4736 return error::kNoError;
4737}
4738
[email protected]2be6abf32012-06-26 00:28:334739error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4740 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354741 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334742 GLuint program = static_cast<GLuint>(c.program);
4743 GLint location = static_cast<GLint>(c.location);
4744 Bucket* bucket = GetBucket(c.name_bucket_id);
4745 if (!bucket || bucket->size() == 0) {
4746 return error::kInvalidArguments;
4747 }
4748 std::string name_str;
4749 if (!bucket->GetAsString(&name_str)) {
4750 return error::kInvalidArguments;
4751 }
4752 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4753 return error::kNoError;
4754}
4755
[email protected]f7a64ee2010-02-01 22:24:144756error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354757 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034758 GLuint client_id = c.shader;
4759 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424760 Shader* shader = GetShader(client_id);
4761 if (shader) {
4762 if (!shader->IsDeleted()) {
4763 glDeleteShader(shader->service_id());
4764 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144765 }
[email protected]ae51d192010-04-27 00:48:034766 } else {
[email protected]ab09b612013-03-11 22:11:514767 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034768 }
[email protected]96449d2c2009-11-25 00:01:324769 }
[email protected]f7a64ee2010-02-01 22:24:144770 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324771}
4772
[email protected]f7a64ee2010-02-01 22:24:144773error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354774 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034775 GLuint client_id = c.program;
4776 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424777 Program* program = GetProgram(client_id);
4778 if (program) {
4779 if (!program->IsDeleted()) {
4780 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144781 }
[email protected]ae51d192010-04-27 00:48:034782 } else {
[email protected]ab09b612013-03-11 22:11:514783 LOCAL_SET_GL_ERROR(
4784 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034785 }
[email protected]96449d2c2009-11-25 00:01:324786 }
[email protected]f7a64ee2010-02-01 22:24:144787 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324788}
4789
[email protected]269200b12010-11-18 22:53:064790void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104791 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574792 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104793 for (GLsizei ii = 0; ii < n; ++ii) {
4794 id_allocator->FreeID(ids[ii]);
4795 }
4796}
4797
[email protected]269200b12010-11-18 22:53:064798error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354799 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104800 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4801 GLsizei n = static_cast<GLsizei>(c.n);
4802 uint32 data_size;
4803 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4804 return error::kOutOfBounds;
4805 }
4806 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4807 c.ids_shm_id, c.ids_shm_offset, data_size);
4808 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514809 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104810 return error::kNoError;
4811 }
4812 if (ids == NULL) {
4813 return error::kOutOfBounds;
4814 }
[email protected]269200b12010-11-18 22:53:064815 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104816 return error::kNoError;
4817}
4818
[email protected]269200b12010-11-18 22:53:064819void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104820 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574821 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104822 if (id_offset == 0) {
4823 for (GLsizei ii = 0; ii < n; ++ii) {
4824 ids[ii] = id_allocator->AllocateID();
4825 }
4826 } else {
4827 for (GLsizei ii = 0; ii < n; ++ii) {
4828 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4829 id_offset = ids[ii] + 1;
4830 }
4831 }
4832}
4833
[email protected]269200b12010-11-18 22:53:064834error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354835 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104836 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4837 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4838 GLsizei n = static_cast<GLsizei>(c.n);
4839 uint32 data_size;
4840 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4841 return error::kOutOfBounds;
4842 }
4843 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4844 c.ids_shm_id, c.ids_shm_offset, data_size);
4845 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514846 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104847 return error::kNoError;
4848 }
4849 if (ids == NULL) {
4850 return error::kOutOfBounds;
4851 }
[email protected]269200b12010-11-18 22:53:064852 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104853 return error::kNoError;
4854}
4855
[email protected]269200b12010-11-18 22:53:064856void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104857 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574858 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104859 for (GLsizei ii = 0; ii < n; ++ii) {
4860 if (!id_allocator->MarkAsUsed(ids[ii])) {
4861 for (GLsizei jj = 0; jj < ii; ++jj) {
4862 id_allocator->FreeID(ids[jj]);
4863 }
[email protected]ab09b612013-03-11 22:11:514864 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434865 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4866 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104867 return;
4868 }
4869 }
4870}
4871
[email protected]269200b12010-11-18 22:53:064872error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354873 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104874 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4875 GLsizei n = static_cast<GLsizei>(c.n);
4876 uint32 data_size;
4877 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4878 return error::kOutOfBounds;
4879 }
4880 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4881 c.ids_shm_id, c.ids_shm_offset, data_size);
4882 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514883 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104884 return error::kNoError;
4885 }
4886 if (ids == NULL) {
4887 return error::kOutOfBounds;
4888 }
[email protected]269200b12010-11-18 22:53:064889 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104890 return error::kNoError;
4891}
4892
[email protected]a7266a92012-06-28 02:11:084893error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444894 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204895 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:464896 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274897 glClear(mask);
4898 }
[email protected]a7266a92012-06-28 02:11:084899 return error::kNoError;
4900}
4901
[email protected]36cef8ce2010-03-16 07:34:454902void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4903 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034904 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064905 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4906 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514907 LOCAL_SET_GL_ERROR(
4908 GL_INVALID_OPERATION,
4909 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454910 return;
4911 }
[email protected]ae51d192010-04-27 00:48:034912 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274913 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034914 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274915 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4916 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514917 LOCAL_SET_GL_ERROR(
4918 GL_INVALID_OPERATION,
4919 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034920 return;
4921 }
[email protected]ee2a79c32013-03-10 03:50:274922 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034923 }
[email protected]ab09b612013-03-11 22:11:514924 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034925 glFramebufferRenderbufferEXT(
4926 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514927 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264928 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274929 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284930 }
[email protected]9d3b2e12013-10-02 01:04:344931 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:444932 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464933 }
[email protected]81fc9d02013-03-14 23:53:324934 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284935}
4936
[email protected]3a2e7c7b2010-08-06 01:12:284937void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464938 if (SetCapabilityState(cap, false)) {
4939 glDisable(cap);
4940 }
[email protected]3a2e7c7b2010-08-06 01:12:284941}
4942
4943void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464944 if (SetCapabilityState(cap, true)) {
4945 glEnable(cap);
4946 }
[email protected]3a2e7c7b2010-08-06 01:12:284947}
4948
[email protected]88a61bf2012-10-27 13:00:424949void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4950 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4951 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4952 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284953}
4954
[email protected]b04e24c2013-01-08 18:35:254955void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424956 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4957 state_.sample_coverage_invert = (invert != 0);
4958 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284959}
4960
[email protected]0d6bfdc2011-11-02 01:32:204961// Assumes framebuffer is complete.
4962void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064963 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304964 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204965 // bind this to the DRAW point, clear then bind back to READ
4966 // TODO(gman): I don't think there is any guarantee that an FBO that
4967 // is complete on the READ attachment will be complete as a DRAW
4968 // attachment.
4969 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064970 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304971 }
[email protected]3a2e7c7b2010-08-06 01:12:284972 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064973 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464974 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204975 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464976 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064977 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4978 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284979 glColorMask(true, true, true, true);
4980 clear_bits |= GL_COLOR_BUFFER_BIT;
4981 }
4982
[email protected]4d8f0dd2013-03-09 14:37:064983 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4984 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284985 glClearStencil(0);
4986 glStencilMask(-1);
4987 clear_bits |= GL_STENCIL_BUFFER_BIT;
4988 }
4989
[email protected]4d8f0dd2013-03-09 14:37:064990 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4991 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284992 glClearDepth(1.0f);
4993 glDepthMask(true);
4994 clear_bits |= GL_DEPTH_BUFFER_BIT;
4995 }
4996
4997 glDisable(GL_SCISSOR_TEST);
4998 glClear(clear_bits);
4999
[email protected]968351b2011-12-20 08:26:515000 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065001 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285002
[email protected]c007aa02010-09-02 22:22:405003 RestoreClearState();
5004
5005 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065006 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5007 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485008 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065009 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5010 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485011 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405012 }
5013}
5014
5015void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445016 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245017 glClearColor(
5018 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5019 state_.color_clear_alpha);
5020 glClearStencil(state_.stencil_clear);
5021 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225022 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:285023 glEnable(GL_SCISSOR_TEST);
5024 }
[email protected]36cef8ce2010-03-16 07:34:455025}
5026
5027GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355028 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305029 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205030 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455031 return GL_FRAMEBUFFER_COMPLETE;
5032 }
[email protected]0d6bfdc2011-11-02 01:32:205033 GLenum completeness = framebuffer->IsPossiblyComplete();
5034 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5035 return completeness;
5036 }
[email protected]73276522012-11-09 05:50:205037 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455038}
5039
5040void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035041 GLenum target, GLenum attachment, GLenum textarget,
5042 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165043 DoFramebufferTexture2DCommon(
5044 "glFramebufferTexture2D", target, attachment,
5045 textarget, client_texture_id, level, 0);
5046}
5047
5048void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5049 GLenum target, GLenum attachment, GLenum textarget,
5050 GLuint client_texture_id, GLint level, GLsizei samples) {
5051 if (!features().multisampled_render_to_texture) {
5052 LOCAL_SET_GL_ERROR(
5053 GL_INVALID_OPERATION,
5054 "glFramebufferTexture2DMultisample", "function not available");
5055 return;
5056 }
5057 DoFramebufferTexture2DCommon(
5058 "glFramebufferTexture2DMultisample", target, attachment,
5059 textarget, client_texture_id, level, samples);
5060}
5061
5062void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5063 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5064 GLuint client_texture_id, GLint level, GLsizei samples) {
5065 if (samples > renderbuffer_manager()->max_samples()) {
5066 LOCAL_SET_GL_ERROR(
5067 GL_INVALID_VALUE,
5068 "glFramebufferTexture2DMultisample", "samples too large");
5069 return;
5070 }
[email protected]4d8f0dd2013-03-09 14:37:065071 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5072 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515073 LOCAL_SET_GL_ERROR(
5074 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165075 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455076 return;
5077 }
[email protected]ae51d192010-04-27 00:48:035078 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495079 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035080 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495081 texture_ref = GetTexture(client_texture_id);
5082 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515083 LOCAL_SET_GL_ERROR(
5084 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165085 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035086 return;
5087 }
[email protected]370eaf12013-05-18 09:19:495088 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035089 }
[email protected]0d6bfdc2011-11-02 01:32:205090
[email protected]80eb6b52012-01-19 00:14:415091 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515092 LOCAL_SET_GL_ERROR(
5093 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165094 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205095 return;
5096 }
5097
[email protected]91c94eb2013-10-22 10:32:545098 if (texture_ref)
5099 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5100
[email protected]7d3c36e2013-07-12 14:13:165101 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5102 if (0 == samples) {
5103 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5104 } else {
5105 if (features().use_img_for_multisampled_render_to_texture) {
5106 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5107 service_id, level, samples);
5108 } else {
5109 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5110 service_id, level, samples);
5111 }
5112 }
5113 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265114 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165115 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5116 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285117 }
[email protected]9d3b2e12013-10-02 01:04:345118 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445119 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465120 }
[email protected]91c94eb2013-10-22 10:32:545121
5122 if (texture_ref)
5123 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5124
[email protected]81fc9d02013-03-14 23:53:325125 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455126}
5127
5128void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5129 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065130 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5131 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515132 LOCAL_SET_GL_ERROR(
5133 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205134 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455135 return;
5136 }
[email protected]74c1ec42010-08-12 01:55:575137 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105138 const Framebuffer::Attachment* attachment_object =
5139 framebuffer->GetAttachment(attachment);
5140 *params = attachment_object ? attachment_object->object_name() : 0;
5141 } else {
[email protected]7d3c36e2013-07-12 14:13:165142 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5143 features().use_img_for_multisampled_render_to_texture) {
5144 pname = GL_TEXTURE_SAMPLES_IMG;
5145 }
[email protected]62e65f02013-05-29 22:28:105146 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575147 }
[email protected]36cef8ce2010-03-16 07:34:455148}
5149
5150void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5151 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355152 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205153 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5154 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515155 LOCAL_SET_GL_ERROR(
5156 GL_INVALID_OPERATION,
5157 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455158 return;
5159 }
[email protected]3a03a8f2011-03-19 00:51:275160 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435161 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5162 *params = renderbuffer->internal_format();
5163 break;
5164 case GL_RENDERBUFFER_WIDTH:
5165 *params = renderbuffer->width();
5166 break;
5167 case GL_RENDERBUFFER_HEIGHT:
5168 *params = renderbuffer->height();
5169 break;
[email protected]7d3c36e2013-07-12 14:13:165170 case GL_RENDERBUFFER_SAMPLES_EXT:
5171 if (features().use_img_for_multisampled_render_to_texture) {
5172 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5173 params);
5174 } else {
5175 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5176 params);
5177 }
[email protected]ad84a3a2012-06-08 21:42:435178 default:
5179 glGetRenderbufferParameterivEXT(target, pname, params);
5180 break;
[email protected]b71f52c2010-06-18 22:20:205181 }
[email protected]36cef8ce2010-03-16 07:34:455182}
5183
[email protected]49cabed2013-11-13 18:15:185184void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305185 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5186 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5187 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445188 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:155189 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:515190 LOCAL_SET_GL_ERROR(
5191 GL_INVALID_OPERATION,
[email protected]49cabed2013-11-13 18:15:185192 "glBlitFramebufferCHROMIUM", "function not available");
[email protected]680aa412013-10-31 18:08:015193 return;
[email protected]8e3e0662010-08-23 18:46:305194 }
[email protected]0c16343f2013-03-08 20:40:165195
[email protected]49cabed2013-11-13 18:15:185196 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165197 return;
5198 }
5199
[email protected]d058bca2012-11-26 10:27:265200 glDisable(GL_SCISSOR_TEST);
[email protected]f42f05b2013-11-15 21:46:185201 BlitFramebufferHelper(
5202 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5203 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
5204}
5205
5206void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5207 const FeatureInfo* feature_info,
5208 GLenum target,
5209 GLsizei samples,
5210 GLenum internal_format,
5211 GLsizei width,
5212 GLsizei height) {
5213 // TODO(sievers): This could be resolved at the GL binding level, but the
5214 // binding process is currently a bit too 'brute force'.
5215 if (feature_info->feature_flags().is_angle) {
5216 glRenderbufferStorageMultisampleANGLE(
5217 target, samples, internal_format, width, height);
5218 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5219 glRenderbufferStorageMultisample(
5220 target, samples, internal_format, width, height);
5221 } else {
5222 glRenderbufferStorageMultisampleEXT(
5223 target, samples, internal_format, width, height);
5224 }
5225}
5226
5227void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5228 GLint srcY0,
5229 GLint srcX1,
5230 GLint srcY1,
5231 GLint dstX0,
5232 GLint dstY0,
5233 GLint dstX1,
5234 GLint dstY1,
5235 GLbitfield mask,
5236 GLenum filter) {
5237 // TODO(sievers): This could be resolved at the GL binding level, but the
5238 // binding process is currently a bit too 'brute force'.
5239 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245240 glBlitFramebufferANGLE(
5241 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185242 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5243 glBlitFramebuffer(
5244 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245245 } else {
5246 glBlitFramebufferEXT(
5247 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5248 }
[email protected]8e3e0662010-08-23 18:46:305249}
5250
[email protected]49cabed2013-11-13 18:15:185251bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5252 GLsizei samples,
5253 GLenum internalformat,
5254 GLsizei width,
5255 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535256 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515257 LOCAL_SET_GL_ERROR(
5258 GL_INVALID_VALUE,
5259 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185260 return false;
[email protected]84afefa2011-10-19 21:45:535261 }
5262
5263 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5264 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515265 LOCAL_SET_GL_ERROR(
5266 GL_INVALID_VALUE,
5267 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185268 return false;
[email protected]84afefa2011-10-19 21:45:535269 }
5270
[email protected]7989c9e2013-01-23 06:39:265271 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235272 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5273 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515274 LOCAL_SET_GL_ERROR(
5275 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205276 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185277 return false;
[email protected]8e3e0662010-08-23 18:46:305278 }
5279
[email protected]7989c9e2013-01-23 06:39:265280 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515281 LOCAL_SET_GL_ERROR(
5282 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205283 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185284 return false;
5285 }
5286
5287 return true;
5288}
5289
5290void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5291 GLenum target, GLsizei samples, GLenum internalformat,
5292 GLsizei width, GLsizei height) {
5293 if (!features().chromium_framebuffer_multisample) {
5294 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5295 "glRenderbufferStorageMultisampleCHROMIUM",
5296 "function not available");
5297 return;
5298 }
5299
5300 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5301 if (!renderbuffer) {
5302 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5303 "glRenderbufferStorageMultisampleCHROMIUM",
5304 "no renderbuffer bound");
5305 return;
5306 }
5307
5308 if (!ValidateRenderbufferStorageMultisample(
5309 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265310 return;
5311 }
5312
[email protected]8e102e102013-09-20 22:50:235313 GLenum impl_format =
5314 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5315 internalformat);
[email protected]49cabed2013-11-13 18:15:185316 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5317 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185318 RenderbufferStorageMultisampleHelper(
5319 feature_info_, target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185320 GLenum error =
5321 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265322 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105323
5324 if (workarounds().validate_multisample_buffer_allocation) {
5325 if (!VerifyMultisampleRenderbufferIntegrity(
5326 renderbuffer->service_id(), impl_format)) {
5327 LOCAL_SET_GL_ERROR(
5328 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185329 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105330 return;
5331 }
5332 }
5333
[email protected]968351b2011-12-20 08:26:515334 // TODO(gman): If renderbuffers tracked which framebuffers they were
5335 // attached to we could just mark those framebuffers as not complete.
5336 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205337 renderbuffer_manager()->SetInfo(
5338 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265339 }
[email protected]8e3e0662010-08-23 18:46:305340}
5341
[email protected]49cabed2013-11-13 18:15:185342// This is the handler for multisampled_render_to_texture extensions.
5343void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5344 GLenum target, GLsizei samples, GLenum internalformat,
5345 GLsizei width, GLsizei height) {
5346 if (!features().multisampled_render_to_texture) {
5347 LOCAL_SET_GL_ERROR(
5348 GL_INVALID_OPERATION,
5349 "glRenderbufferStorageMultisampleEXT", "function not available");
5350 return;
5351 }
5352
5353 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5354 if (!renderbuffer) {
5355 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5356 "glRenderbufferStorageMultisampleEXT",
5357 "no renderbuffer bound");
5358 return;
5359 }
5360
5361 if (!ValidateRenderbufferStorageMultisample(
5362 samples, internalformat, width, height)) {
5363 return;
5364 }
5365
5366 GLenum impl_format =
5367 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5368 internalformat);
5369 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5370 if (features().use_img_for_multisampled_render_to_texture) {
5371 glRenderbufferStorageMultisampleIMG(
5372 target, samples, impl_format, width, height);
5373 } else {
5374 glRenderbufferStorageMultisampleEXT(
5375 target, samples, impl_format, width, height);
5376 }
5377 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5378 if (error == GL_NO_ERROR) {
5379 // TODO(gman): If renderbuffers tracked which framebuffers they were
5380 // attached to we could just mark those framebuffers as not complete.
5381 framebuffer_manager()->IncFramebufferStateChangeCount();
5382 renderbuffer_manager()->SetInfo(
5383 renderbuffer, samples, internalformat, width, height);
5384 }
5385}
5386
[email protected]4a4c18b2013-09-13 22:50:105387// This function validates the allocation of a multisampled renderbuffer
5388// by clearing it to a key color, blitting the contents to a texture, and
5389// reading back the color to ensure it matches the key.
5390bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5391 GLuint renderbuffer, GLenum format) {
5392
5393 // Only validate color buffers.
5394 // These formats have been selected because they are very common or are known
5395 // to be used by the WebGL backbuffer. If problems are observed with other
5396 // color formats they can be added here.
5397 switch(format) {
5398 case GL_RGB:
5399 case GL_RGB8:
5400 case GL_RGBA:
5401 case GL_RGBA8:
5402 break;
5403 default:
5404 return true;
5405 }
5406
5407 GLint draw_framebuffer, read_framebuffer;
5408
5409 // Cache framebuffer and texture bindings.
5410 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5411 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5412
5413 if (!validation_texture_) {
5414 GLint bound_texture;
5415 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5416
5417 // Create additional resources needed for the verification.
5418 glGenTextures(1, &validation_texture_);
5419 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5420 glGenFramebuffersEXT(1, &validation_fbo_);
5421
5422 // Texture only needs to be 1x1.
5423 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5424 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5425 GL_UNSIGNED_BYTE, NULL);
5426
5427 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5428 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5429 GL_TEXTURE_2D, validation_texture_, 0);
5430
5431 glBindTexture(GL_TEXTURE_2D, bound_texture);
5432 }
5433
5434 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5435 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5436 GL_RENDERBUFFER, renderbuffer);
5437
5438 // Cache current state and reset it to the values we require.
5439 GLboolean scissor_enabled = false;
5440 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5441 if (scissor_enabled)
5442 glDisable(GL_SCISSOR_TEST);
5443
5444 GLboolean color_mask[4] = {true, true, true, true};
5445 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
5446 glColorMask(true, true, true, true);
5447
5448 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5449 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5450 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5451
5452 // Clear the buffer to the desired key color.
5453 glClear(GL_COLOR_BUFFER_BIT);
5454
5455 // Blit from the multisample buffer to a standard texture.
5456 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5457 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5458
[email protected]f42f05b2013-11-15 21:46:185459 BlitFramebufferHelper(
5460 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105461
5462 // Read a pixel from the buffer.
5463 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5464
5465 unsigned char pixel[3] = {0, 0, 0};
5466 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5467
5468 // Detach the renderbuffer.
5469 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5470 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5471 GL_RENDERBUFFER, 0);
5472
5473 // Restore cached state.
5474 if (scissor_enabled)
5475 glEnable(GL_SCISSOR_TEST);
5476
5477 glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
5478 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5479 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5480 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5481
5482 // Return true if the pixel matched the desired key color.
5483 return (pixel[0] == 0xFF &&
5484 pixel[1] == 0x00 &&
5485 pixel[2] == 0xFF);
5486}
5487
[email protected]36cef8ce2010-03-16 07:34:455488void GLES2DecoderImpl::DoRenderbufferStorage(
5489 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355490 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205491 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5492 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515493 LOCAL_SET_GL_ERROR(
5494 GL_INVALID_OPERATION,
5495 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455496 return;
5497 }
[email protected]876f6fee2010-08-02 23:10:325498
[email protected]84afefa2011-10-19 21:45:535499 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5500 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515501 LOCAL_SET_GL_ERROR(
5502 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535503 return;
5504 }
5505
[email protected]7989c9e2013-01-23 06:39:265506 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235507 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5508 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515509 LOCAL_SET_GL_ERROR(
5510 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265511 return;
5512 }
5513
5514 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515515 LOCAL_SET_GL_ERROR(
5516 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265517 return;
[email protected]b71f52c2010-06-18 22:20:205518 }
[email protected]876f6fee2010-08-02 23:10:325519
[email protected]ab09b612013-03-11 22:11:515520 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265521 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235522 target,
5523 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5524 internalformat),
5525 width,
5526 height);
[email protected]ab09b612013-03-11 22:11:515527 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265528 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515529 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5530 // we could just mark those framebuffers as not complete.
5531 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205532 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265533 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265534 }
[email protected]36cef8ce2010-03-16 07:34:455535}
5536
[email protected]df37b9932013-03-08 05:21:425537void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385538 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425539 Program* program = GetProgramInfoNotShader(
5540 program_id, "glLinkProgram");
5541 if (!program) {
[email protected]a93bb842010-02-16 23:03:475542 return;
5543 }
[email protected]05afda12011-01-20 00:17:345544
[email protected]df37b9932013-03-08 05:21:425545 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395546 ShaderTranslator* vertex_translator = NULL;
5547 ShaderTranslator* fragment_translator = NULL;
5548 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115549 vertex_translator = vertex_translator_.get();
5550 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395551 }
[email protected]df37b9932013-03-08 05:21:425552 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115553 vertex_translator,
5554 fragment_translator,
[email protected]008401532014-02-07 00:10:505555 workarounds().count_all_in_varyings_packing ?
5556 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115557 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425558 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185559 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425560 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185561 if (workarounds().clear_uniforms_before_first_program_use)
5562 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545563 }
5564 }
[email protected]07f54fcc2009-12-22 02:46:305565};
5566
[email protected]3916c97e2010-02-25 03:20:505567void GLES2DecoderImpl::DoTexParameterf(
5568 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445569 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5570 &state_, target);
[email protected]02965c22013-03-09 02:40:075571 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515572 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245573 return;
[email protected]07f54fcc2009-12-22 02:46:305574 }
[email protected]cbb22e42011-05-12 23:36:245575
[email protected]737191ee72014-03-09 08:02:425576 texture_manager()->SetParameterf(
5577 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305578}
5579
[email protected]3916c97e2010-02-25 03:20:505580void GLES2DecoderImpl::DoTexParameteri(
5581 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445582 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5583 &state_, target);
[email protected]02965c22013-03-09 02:40:075584 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515585 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245586 return;
[email protected]3916c97e2010-02-25 03:20:505587 }
[email protected]cbb22e42011-05-12 23:36:245588
[email protected]737191ee72014-03-09 08:02:425589 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505590 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505591}
5592
5593void GLES2DecoderImpl::DoTexParameterfv(
5594 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445595 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5596 &state_, target);
[email protected]02965c22013-03-09 02:40:075597 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515598 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245599 return;
[email protected]3916c97e2010-02-25 03:20:505600 }
[email protected]cbb22e42011-05-12 23:36:245601
[email protected]737191ee72014-03-09 08:02:425602 texture_manager()->SetParameterf(
5603 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505604}
5605
5606void GLES2DecoderImpl::DoTexParameteriv(
5607 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445608 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5609 &state_, target);
[email protected]02965c22013-03-09 02:40:075610 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515611 LOCAL_SET_GL_ERROR(
5612 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245613 return;
[email protected]3916c97e2010-02-25 03:20:505614 }
[email protected]cbb22e42011-05-12 23:36:245615
[email protected]737191ee72014-03-09 08:02:425616 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505617 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505618}
5619
[email protected]939e7362010-05-13 20:49:105620bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115621 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435622 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515623 LOCAL_SET_GL_ERROR(
5624 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435625 return false;
[email protected]939e7362010-05-13 20:49:105626 }
[email protected]e259eb412012-10-13 05:47:245627 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515628 LOCAL_SET_GL_ERROR(
5629 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105630 return false;
5631 }
5632 return true;
5633}
5634
5635bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5636 GLint location, const char* function_name) {
5637 if (!CheckCurrentProgram(function_name)) {
5638 return false;
5639 }
5640 return location != -1;
5641}
5642
[email protected]43c2f1f2011-03-25 18:35:365643bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:135644 GLint fake_location,
5645 const char* function_name,
5646 Program::UniformApiType api_type,
5647 GLint* real_location,
5648 GLenum* type,
5649 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365650 DCHECK(type);
5651 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125652 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525653
[email protected]1b0a6752012-02-22 03:44:125654 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105655 return false;
5656 }
[email protected]43c2f1f2011-03-25 18:35:365657 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355658 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245659 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125660 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365661 if (!info) {
[email protected]ab09b612013-03-11 22:11:515662 LOCAL_SET_GL_ERROR(
5663 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105664 return false;
5665 }
[email protected]9b1f1b52014-03-12 10:40:135666
5667 if ((api_type & info->accepts_api_type) == 0) {
[email protected]ab09b612013-03-11 22:11:515668 LOCAL_SET_GL_ERROR(
5669 GL_INVALID_OPERATION, function_name,
5670 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525671 return false;
5672 }
[email protected]43c2f1f2011-03-25 18:35:365673 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515674 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435675 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365676 return false;
5677 }
5678 *count = std::min(info->size - array_index, *count);
5679 if (*count <= 0) {
5680 return false;
5681 }
5682 *type = info->type;
[email protected]939e7362010-05-13 20:49:105683 return true;
5684}
5685
[email protected]1b0a6752012-02-22 03:44:125686void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5687 GLenum type = 0;
5688 GLsizei count = 1;
5689 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135690 if (!PrepForSetUniformByLocation(fake_location,
5691 "glUniform1i",
5692 Program::kUniform1i,
5693 &real_location,
5694 &type,
5695 &count)) {
[email protected]3916c97e2010-02-25 03:20:505696 return;
5697 }
[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, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515700 LOCAL_SET_GL_ERROR(
5701 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465702 return;
5703 }
[email protected]1b0a6752012-02-22 03:44:125704 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505705}
5706
5707void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125708 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365709 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125710 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135711 if (!PrepForSetUniformByLocation(fake_location,
5712 "glUniform1iv",
5713 Program::kUniform1i,
5714 &real_location,
5715 &type,
5716 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365717 return;
5718 }
[email protected]74727112012-06-13 21:18:085719 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5720 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245721 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025722 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515723 LOCAL_SET_GL_ERROR(
5724 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465725 return;
5726 }
[email protected]43c2f1f2011-03-25 18:35:365727 }
[email protected]1b0a6752012-02-22 03:44:125728 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505729}
5730
[email protected]939e7362010-05-13 20:49:105731void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125732 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365733 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125734 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135735 if (!PrepForSetUniformByLocation(fake_location,
5736 "glUniform1fv",
5737 Program::kUniform1f,
5738 &real_location,
5739 &type,
5740 &count)) {
[email protected]939e7362010-05-13 20:49:105741 return;
5742 }
5743 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555744 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105745 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535746 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105747 }
[email protected]1b0a6752012-02-22 03:44:125748 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105749 } else {
[email protected]1b0a6752012-02-22 03:44:125750 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105751 }
5752}
5753
5754void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125755 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365756 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125757 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135758 if (!PrepForSetUniformByLocation(fake_location,
5759 "glUniform2fv",
5760 Program::kUniform2f,
5761 &real_location,
5762 &type,
5763 &count)) {
[email protected]939e7362010-05-13 20:49:105764 return;
5765 }
5766 if (type == GL_BOOL_VEC2) {
5767 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555768 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105769 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535770 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105771 }
[email protected]1b0a6752012-02-22 03:44:125772 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105773 } else {
[email protected]1b0a6752012-02-22 03:44:125774 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105775 }
5776}
5777
5778void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125779 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365780 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125781 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135782 if (!PrepForSetUniformByLocation(fake_location,
5783 "glUniform3fv",
5784 Program::kUniform3f,
5785 &real_location,
5786 &type,
5787 &count)) {
[email protected]939e7362010-05-13 20:49:105788 return;
5789 }
5790 if (type == GL_BOOL_VEC3) {
5791 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555792 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105793 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535794 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105795 }
[email protected]1b0a6752012-02-22 03:44:125796 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105797 } else {
[email protected]1b0a6752012-02-22 03:44:125798 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105799 }
5800}
5801
5802void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125803 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365804 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125805 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135806 if (!PrepForSetUniformByLocation(fake_location,
5807 "glUniform4fv",
5808 Program::kUniform4f,
5809 &real_location,
5810 &type,
5811 &count)) {
[email protected]939e7362010-05-13 20:49:105812 return;
5813 }
5814 if (type == GL_BOOL_VEC4) {
5815 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555816 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105817 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535818 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105819 }
[email protected]1b0a6752012-02-22 03:44:125820 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105821 } else {
[email protected]1b0a6752012-02-22 03:44:125822 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105823 }
5824}
5825
[email protected]43c2f1f2011-03-25 18:35:365826void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125827 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365828 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125829 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135830 if (!PrepForSetUniformByLocation(fake_location,
5831 "glUniform2iv",
5832 Program::kUniform2i,
5833 &real_location,
5834 &type,
5835 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365836 return;
5837 }
[email protected]1b0a6752012-02-22 03:44:125838 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365839}
5840
5841void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125842 GLint fake_location, GLsizei count, const GLint* 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]9b1f1b52014-03-12 10:40:135845 if (!PrepForSetUniformByLocation(fake_location,
5846 "glUniform3iv",
5847 Program::kUniform3i,
5848 &real_location,
5849 &type,
5850 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365851 return;
5852 }
[email protected]1b0a6752012-02-22 03:44:125853 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365854}
5855
5856void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125857 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365858 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125859 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135860 if (!PrepForSetUniformByLocation(fake_location,
5861 "glUniform4iv",
5862 Program::kUniform4i,
5863 &real_location,
5864 &type,
5865 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365866 return;
5867 }
[email protected]1b0a6752012-02-22 03:44:125868 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365869}
5870
5871void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125872 GLint fake_location, GLsizei count, GLboolean transpose,
5873 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365874 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125875 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135876 if (!PrepForSetUniformByLocation(fake_location,
5877 "glUniformMatrix2fv",
5878 Program::kUniformMatrix2f,
5879 &real_location,
5880 &type,
5881 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365882 return;
5883 }
[email protected]1b0a6752012-02-22 03:44:125884 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365885}
5886
5887void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125888 GLint fake_location, GLsizei count, GLboolean transpose,
5889 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365890 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125891 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135892 if (!PrepForSetUniformByLocation(fake_location,
5893 "glUniformMatrix3fv",
5894 Program::kUniformMatrix3f,
5895 &real_location,
5896 &type,
5897 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365898 return;
5899 }
[email protected]1b0a6752012-02-22 03:44:125900 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365901}
5902
5903void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125904 GLint fake_location, GLsizei count, GLboolean transpose,
5905 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365906 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125907 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135908 if (!PrepForSetUniformByLocation(fake_location,
5909 "glUniformMatrix4fv",
5910 Program::kUniformMatrix4f,
5911 &real_location,
5912 &type,
5913 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365914 return;
5915 }
[email protected]1b0a6752012-02-22 03:44:125916 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365917}
5918
[email protected]df37b9932013-03-08 05:21:425919void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035920 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425921 Program* program = NULL;
5922 if (program_id) {
5923 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5924 if (!program) {
[email protected]ae51d192010-04-27 00:48:035925 return;
5926 }
[email protected]df37b9932013-03-08 05:21:425927 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505928 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515929 LOCAL_SET_GL_ERROR(
5930 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505931 return;
5932 }
[email protected]df37b9932013-03-08 05:21:425933 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505934 }
[email protected]7cd76fd2013-06-02 21:11:115935 if (state_.current_program.get()) {
5936 program_manager()->UnuseProgram(shader_manager(),
5937 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145938 }
[email protected]df37b9932013-03-08 05:21:425939 state_.current_program = program;
5940 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545941 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:115942 if (state_.current_program.get()) {
5943 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:185944 if (workarounds().clear_uniforms_before_first_program_use)
5945 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:145946 }
[email protected]3916c97e2010-02-25 03:20:505947}
5948
[email protected]ab09b612013-03-11 22:11:515949void GLES2DecoderImpl::RenderWarning(
5950 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325951 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015952}
5953
[email protected]ab09b612013-03-11 22:11:515954void GLES2DecoderImpl::PerformanceWarning(
5955 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505956 logger_.LogMessage(filename, line,
5957 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015958}
5959
[email protected]91c94eb2013-10-22 10:32:545960void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
5961 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:545962 // Image is already in use if texture is attached to a framebuffer.
5963 if (texture && !texture->IsAttachedToFramebuffer()) {
5964 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5965 if (image) {
5966 ScopedGLErrorSuppressor suppressor(
5967 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
5968 GetErrorState());
5969 glBindTexture(textarget, texture->service_id());
5970 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:025971 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:545972 }
5973 }
5974}
5975
5976void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
5977 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:545978 // Image is still in use if texture is attached to a framebuffer.
5979 if (texture && !texture->IsAttachedToFramebuffer()) {
5980 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5981 if (image) {
5982 ScopedGLErrorSuppressor suppressor(
5983 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
5984 GetErrorState());
5985 glBindTexture(textarget, texture->service_id());
5986 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:025987 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:545988 }
5989 }
5990}
5991
[email protected]e56131d22013-07-28 16:14:115992bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:115993 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:545994 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:555995 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:115996 return true;
[email protected]ef526492010-06-02 23:12:255997 }
[email protected]e2367b42013-05-31 03:37:215998
[email protected]ef526492010-06-02 23:12:255999 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356000 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246001 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506002 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356003 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246004 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506005 DCHECK(uniform_info);
6006 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6007 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026008 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246009 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546010 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366011 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546012 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6013 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256014 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506015 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6016 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546017 textarget,
[email protected]00f893d2010-08-24 18:55:496018 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:516019 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:016020 std::string("texture bound to texture unit ") +
6021 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:296022 " is not renderable. It maybe non-power-of-2 and have"
6023 " incompatible texture filtering or is not"
6024 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:546025 continue;
[email protected]3916c97e2010-02-25 03:20:506026 }
[email protected]91c94eb2013-10-22 10:32:546027
[email protected]4e7b89202014-01-28 01:44:066028 if (textarget != GL_TEXTURE_CUBE_MAP) {
6029 Texture* texture = texture_ref->texture();
6030 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6031 if (image && !texture->IsAttachedToFramebuffer()) {
6032 ScopedGLErrorSuppressor suppressor(
6033 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6034 textures_set = true;
6035 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6036 image->WillUseTexImage();
6037 continue;
6038 }
[email protected]91c94eb2013-10-22 10:32:546039 }
[email protected]3916c97e2010-02-25 03:20:506040 }
6041 // else: should this be an error?
6042 }
6043 }
[email protected]e56131d22013-07-28 16:14:116044 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506045}
6046
[email protected]91c94eb2013-10-22 10:32:546047void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116048 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356049 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116050 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506051 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356052 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246053 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506054 DCHECK(uniform_info);
6055 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6056 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026057 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246058 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116059 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546060 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496061 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506062 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496063 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116064 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6065 ? texture_unit.bound_texture_2d.get()
6066 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506067 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496068 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546069 continue;
6070 }
6071
[email protected]4e7b89202014-01-28 01:44:066072 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6073 Texture* texture = texture_ref->texture();
6074 gfx::GLImage* image =
6075 texture->GetLevelImage(texture_unit.bind_target, 0);
6076 if (image && !texture->IsAttachedToFramebuffer()) {
6077 ScopedGLErrorSuppressor suppressor(
6078 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6079 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6080 image->DidUseTexImage();
6081 continue;
6082 }
[email protected]3916c97e2010-02-25 03:20:506083 }
6084 }
6085 }
6086 }
6087 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246088 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306089}
6090
[email protected]0d6bfdc2011-11-02 01:32:206091bool GLES2DecoderImpl::ClearUnclearedTextures() {
6092 // Only check if there are some uncleared textures.
6093 if (!texture_manager()->HaveUnsafeTextures()) {
6094 return true;
6095 }
6096
6097 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116098 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356099 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116100 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206101 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356102 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246103 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206104 DCHECK(uniform_info);
6105 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6106 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026107 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246108 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496109 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366110 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496111 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6112 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206113 return false;
6114 }
6115 }
6116 }
6117 }
6118 }
6119 }
6120 return true;
6121}
6122
[email protected]c6aef902012-02-14 03:31:426123bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:436124 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:036125 // NOTE: We specifically do not check current_program->IsValid() because
6126 // it could never be invalid since glUseProgram would have failed. While
6127 // glLinkProgram could later mark the program as invalid the previous
6128 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116129 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506130 // The program does not exist.
6131 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516132 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506133 return false;
6134 }
[email protected]c6aef902012-02-14 03:31:426135
[email protected]7cd76fd2013-06-02 21:11:116136 return state_.vertex_attrib_manager
6137 ->ValidateBindings(function_name,
6138 this,
6139 feature_info_.get(),
6140 state_.current_program.get(),
6141 max_vertex_accessed,
6142 primcount);
[email protected]b1122982010-05-17 23:04:246143}
6144
[email protected]c13e1da62011-09-09 21:48:306145bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436146 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306147 DCHECK(simulated);
6148 *simulated = false;
6149
[email protected]876f6fee2010-08-02 23:10:326150 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306151 return true;
[email protected]876f6fee2010-08-02 23:10:326152
[email protected]ac77603c72013-03-08 13:52:066153 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356154 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246155 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246156 bool attrib_0_used =
6157 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066158 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306159 return true;
[email protected]b1122982010-05-17 23:04:246160 }
6161
[email protected]b1122982010-05-17 23:04:246162 // Make a buffer with a single repeated vec4 value enough to
6163 // simulate the constant value that is supposed to be here.
6164 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306165 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476166 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306167
6168 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476169 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306170 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516171 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306172 return false;
6173 }
6174
[email protected]ab09b612013-03-11 22:11:516175 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016176 "Attribute 0 is disabled. This has signficant performance penalty");
6177
[email protected]ab09b612013-03-11 22:11:516178 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306179 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6180
[email protected]8f0b86c2f2012-04-10 05:48:286181 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6182 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496183 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306184 GLenum error = glGetError();
6185 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516186 LOCAL_SET_GL_ERROR(
6187 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306188 return false;
6189 }
[email protected]fc753442011-02-04 19:49:496190 }
[email protected]af6380962012-11-29 23:24:136191
6192 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286193 if (new_buffer ||
6194 (attrib_0_used &&
6195 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136196 (value.v[0] != attrib_0_value_.v[0] ||
6197 value.v[1] != attrib_0_value_.v[1] ||
6198 value.v[2] != attrib_0_value_.v[2] ||
6199 value.v[3] != attrib_0_value_.v[3])))) {
6200 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496201 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6202 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136203 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246204 attrib_0_size_ = size_needed;
6205 }
6206
6207 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6208
[email protected]ac77603c72013-03-08 13:52:066209 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426210 glVertexAttribDivisorANGLE(0, 0);
6211
[email protected]c13e1da62011-09-09 21:48:306212 *simulated = true;
[email protected]b1122982010-05-17 23:04:246213 return true;
[email protected]b1122982010-05-17 23:04:246214}
6215
[email protected]ac77603c72013-03-08 13:52:066216void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
6217 const VertexAttrib* attrib =
6218 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
6219 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6220 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:076221 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:246222 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066223 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6224 attrib->gl_stride(), ptr);
6225 if (attrib->divisor())
6226 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246227 glBindBuffer(
6228 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116229 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6230 : 0);
[email protected]43410e92012-04-20 17:06:286231
[email protected]265f8992012-07-20 01:03:146232 // Never touch vertex attribute 0's state (in particular, never
6233 // disable it) when running on desktop GL because it will never be
6234 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066235 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146236 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066237 if (attrib->enabled()) {
6238 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146239 } else {
[email protected]ac77603c72013-03-08 13:52:066240 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146241 }
[email protected]43410e92012-04-20 17:06:286242 }
[email protected]b1122982010-05-17 23:04:246243}
[email protected]07f54fcc2009-12-22 02:46:306244
[email protected]8fbedc02010-11-18 18:43:406245bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436246 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426247 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406248 DCHECK(simulated);
6249 *simulated = false;
6250 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6251 return true;
6252
[email protected]e259eb412012-10-13 05:47:246253 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406254 return true;
6255 }
6256
[email protected]ab09b612013-03-11 22:11:516257 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016258 "GL_FIXED attributes have a signficant performance penalty");
6259
[email protected]8fbedc02010-11-18 18:43:406260 // NOTE: we could be smart and try to check if a buffer is used
6261 // twice in 2 different attribs, find the overlapping parts and therefore
6262 // duplicate the minimum amount of data but this whole code path is not meant
6263 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6264 // tests so we just add to the buffer attrib used.
6265
[email protected]c13e1da62011-09-09 21:48:306266 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066267 const VertexAttribManager::VertexAttribList& enabled_attribs =
6268 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6269 for (VertexAttribManager::VertexAttribList::const_iterator it =
6270 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6271 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356272 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066273 state_.current_program->GetAttribInfoByLocation(attrib->index());
6274 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6275 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426276 GLuint num_vertices = max_accessed + 1;
6277 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516278 LOCAL_SET_GL_ERROR(
6279 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426280 return false;
6281 }
[email protected]8fbedc02010-11-18 18:43:406282 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066283 attrib->CanAccess(max_accessed) &&
6284 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476285 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066286 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476287 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516288 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436289 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406290 return false;
6291 }
6292 }
6293 }
6294
[email protected]3aad1a32012-09-07 20:54:476295 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6296 uint32 size_needed = 0;
6297 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306298 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516299 LOCAL_SET_GL_ERROR(
6300 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406301 return false;
6302 }
6303
[email protected]ab09b612013-03-11 22:11:516304 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406305
6306 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306307 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406308 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306309 GLenum error = glGetError();
6310 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516311 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436312 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306313 return false;
6314 }
[email protected]8fbedc02010-11-18 18:43:406315 }
6316
6317 // Copy the elements and convert to float
6318 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066319 for (VertexAttribManager::VertexAttribList::const_iterator it =
6320 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6321 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356322 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066323 state_.current_program->GetAttribInfoByLocation(attrib->index());
6324 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426325 max_vertex_accessed);
6326 GLuint num_vertices = max_accessed + 1;
6327 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516328 LOCAL_SET_GL_ERROR(
6329 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426330 return false;
6331 }
[email protected]8fbedc02010-11-18 18:43:406332 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066333 attrib->CanAccess(max_accessed) &&
6334 attrib->type() == GL_FIXED) {
6335 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406336 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556337 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406338 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066339 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406340 const int32* end = src + num_elements;
6341 float* dst = data.get();
6342 while (src != end) {
6343 *dst++ = static_cast<float>(*src++) / 65536.0f;
6344 }
6345 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6346 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066347 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406348 reinterpret_cast<GLvoid*>(offset));
6349 offset += size;
6350 }
6351 }
6352 *simulated = true;
6353 return true;
6354}
6355
6356void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6357 // There's no need to call glVertexAttribPointer because we shadow all the
6358 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246359 glBindBuffer(
6360 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116361 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6362 : 0);
[email protected]8fbedc02010-11-18 18:43:406363}
6364
[email protected]ad84a3a2012-06-08 21:42:436365error::Error GLES2DecoderImpl::DoDrawArrays(
6366 const char* function_name,
6367 bool instanced,
6368 GLenum mode,
6369 GLint first,
6370 GLsizei count,
6371 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226372 error::Error error = WillAccessBoundFramebufferForDraw();
6373 if (error != error::kNoError)
6374 return error;
[email protected]38d139d2011-07-14 00:38:436375 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516376 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436377 return error::kNoError;
6378 }
6379 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516380 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436381 return error::kNoError;
6382 }
[email protected]c6aef902012-02-14 03:31:426383 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516384 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426385 return error::kNoError;
6386 }
[email protected]ad84a3a2012-06-08 21:42:436387 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436388 return error::kNoError;
6389 }
6390 // We have to check this here because the prototype for glDrawArrays
6391 // is GLint not GLsizei.
6392 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516393 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436394 return error::kNoError;
6395 }
6396
[email protected]c6aef902012-02-14 03:31:426397 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:516398 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436399 return error::kNoError;
6400 }
6401
6402 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:436403 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206404 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516405 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206406 return error::kNoError;
6407 }
[email protected]c13e1da62011-09-09 21:48:306408 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436409 if (!SimulateAttrib0(
6410 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306411 return error::kNoError;
6412 }
[email protected]38d139d2011-07-14 00:38:436413 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436414 if (SimulateFixedAttribs(
6415 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6416 primcount)) {
[email protected]e56131d22013-07-28 16:14:116417 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436418 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376419 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426420 if (!instanced) {
6421 glDrawArrays(mode, first, count);
6422 } else {
6423 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6424 }
[email protected]22e3f552012-03-13 01:54:196425 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:436426 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546427 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436428 }
6429 if (simulated_fixed_attribs) {
6430 RestoreStateForSimulatedFixedAttribs();
6431 }
6432 }
6433 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286434 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436435 }
[email protected]38d139d2011-07-14 00:38:436436 }
6437 return error::kNoError;
6438}
6439
[email protected]c6aef902012-02-14 03:31:426440error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356441 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436442 return DoDrawArrays("glDrawArrays",
6443 false,
[email protected]c6aef902012-02-14 03:31:426444 static_cast<GLenum>(c.mode),
6445 static_cast<GLint>(c.first),
6446 static_cast<GLsizei>(c.count),
6447 0);
6448}
6449
6450error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356451 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156452 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516453 LOCAL_SET_GL_ERROR(
6454 GL_INVALID_OPERATION,
6455 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426456 return error::kNoError;
6457 }
[email protected]ad84a3a2012-06-08 21:42:436458 return DoDrawArrays("glDrawArraysIntancedANGLE",
6459 true,
[email protected]c6aef902012-02-14 03:31:426460 static_cast<GLenum>(c.mode),
6461 static_cast<GLint>(c.first),
6462 static_cast<GLsizei>(c.count),
6463 static_cast<GLsizei>(c.primcount));
6464}
6465
[email protected]ad84a3a2012-06-08 21:42:436466error::Error GLES2DecoderImpl::DoDrawElements(
6467 const char* function_name,
6468 bool instanced,
6469 GLenum mode,
6470 GLsizei count,
6471 GLenum type,
6472 int32 offset,
6473 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226474 error::Error error = WillAccessBoundFramebufferForDraw();
6475 if (error != error::kNoError)
6476 return error;
[email protected]e259eb412012-10-13 05:47:246477 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516478 LOCAL_SET_GL_ERROR(
6479 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296480 return error::kNoError;
6481 }
6482
[email protected]8eee29c2010-04-29 03:38:296483 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516484 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296485 return error::kNoError;
6486 }
6487 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516488 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296489 return error::kNoError;
6490 }
[email protected]9438b012010-06-15 22:55:056491 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516492 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296493 return error::kNoError;
6494 }
[email protected]9438b012010-06-15 22:55:056495 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516496 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296497 return error::kNoError;
6498 }
[email protected]c6aef902012-02-14 03:31:426499 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516500 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426501 return error::kNoError;
6502 }
[email protected]8eee29c2010-04-29 03:38:296503
[email protected]ad84a3a2012-06-08 21:42:436504 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276505 return error::kNoError;
6506 }
6507
[email protected]c6aef902012-02-14 03:31:426508 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316509 return error::kNoError;
6510 }
6511
[email protected]8eee29c2010-04-29 03:38:296512 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086513 Buffer* element_array_buffer =
6514 state_.vertex_attrib_manager->element_array_buffer();
6515
6516 if (!element_array_buffer->GetMaxValueForRange(
6517 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516518 LOCAL_SET_GL_ERROR(
6519 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296520 return error::kNoError;
6521 }
6522
[email protected]ad84a3a2012-06-08 21:42:436523 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206524 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516525 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206526 return error::kNoError;
6527 }
[email protected]c13e1da62011-09-09 21:48:306528 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436529 if (!SimulateAttrib0(
6530 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306531 return error::kNoError;
6532 }
[email protected]8fbedc02010-11-18 18:43:406533 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436534 if (SimulateFixedAttribs(
6535 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6536 primcount)) {
[email protected]e56131d22013-07-28 16:14:116537 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466538 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086539 // TODO(gman): Refactor to hide these details in BufferManager or
6540 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406541 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086542 bool used_client_side_array = false;
6543 if (element_array_buffer->IsClientSideArray()) {
6544 used_client_side_array = true;
6545 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6546 indices = element_array_buffer->GetRange(offset, 0);
6547 }
6548
[email protected]00c2cf92014-03-14 00:08:376549 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426550 if (!instanced) {
6551 glDrawElements(mode, count, type, indices);
6552 } else {
6553 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6554 }
[email protected]17cfbe0e2013-03-07 01:26:086555
6556 if (used_client_side_array) {
6557 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6558 element_array_buffer->service_id());
6559 }
6560
[email protected]22e3f552012-03-13 01:54:196561 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406562 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546563 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406564 }
6565 if (simulated_fixed_attribs) {
6566 RestoreStateForSimulatedFixedAttribs();
6567 }
[email protected]ba3176a2009-12-16 18:19:466568 }
[email protected]b1122982010-05-17 23:04:246569 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286570 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246571 }
[email protected]96449d2c2009-11-25 00:01:326572 }
[email protected]f7a64ee2010-02-01 22:24:146573 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326574}
6575
[email protected]c6aef902012-02-14 03:31:426576error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356577 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436578 return DoDrawElements("glDrawElements",
6579 false,
[email protected]c6aef902012-02-14 03:31:426580 static_cast<GLenum>(c.mode),
6581 static_cast<GLsizei>(c.count),
6582 static_cast<GLenum>(c.type),
6583 static_cast<int32>(c.index_offset),
6584 0);
6585}
6586
6587error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356588 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156589 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516590 LOCAL_SET_GL_ERROR(
6591 GL_INVALID_OPERATION,
6592 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426593 return error::kNoError;
6594 }
[email protected]ad84a3a2012-06-08 21:42:436595 return DoDrawElements("glDrawElementsInstancedANGLE",
6596 true,
[email protected]c6aef902012-02-14 03:31:426597 static_cast<GLenum>(c.mode),
6598 static_cast<GLsizei>(c.count),
6599 static_cast<GLenum>(c.type),
6600 static_cast<int32>(c.index_offset),
6601 static_cast<GLsizei>(c.primcount));
6602}
6603
[email protected]269200b12010-11-18 22:53:066604GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236605 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6606 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076607 Buffer* buffer = GetBuffer(buffer_id);
6608 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036609 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516610 LOCAL_SET_GL_ERROR(
6611 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236612 } else {
[email protected]b10492f2013-03-08 05:24:076613 if (!buffer->GetMaxValueForRange(
6614 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036615 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516616 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066617 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436618 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236619 }
6620 }
6621 return max_vertex_accessed;
6622}
6623
[email protected]96449d2c2009-11-25 00:01:326624// Calls glShaderSource for the various versions of the ShaderSource command.
6625// Assumes that data / data_size points to a piece of memory that is in range
6626// of whatever context it came from (shared memory, immediate memory, bucket
6627// memory.)
[email protected]45bf5152010-02-12 00:11:316628error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036629 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576630 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426631 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6632 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316633 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326634 }
[email protected]45bf5152010-02-12 00:11:316635 // Note: We don't actually call glShaderSource here. We wait until
6636 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426637 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146638 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326639}
6640
[email protected]f7a64ee2010-02-01 22:24:146641error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356642 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326643 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316644 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326645 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466646 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146647 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326648 }
[email protected]ae51d192010-04-27 00:48:036649 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326650}
6651
[email protected]558847a2010-03-24 07:02:546652error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356653 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546654 Bucket* bucket = GetBucket(c.data_bucket_id);
6655 if (!bucket || bucket->size() == 0) {
6656 return error::kInvalidArguments;
6657 }
6658 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036659 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546660 bucket->size() - 1);
6661}
6662
[email protected]ae51d192010-04-27 00:48:036663void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386664 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426665 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6666 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316667 return;
6668 }
[email protected]f57bb282010-11-12 00:51:346669 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186670 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426671 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456672 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416673 }
[email protected]de17df392010-04-23 21:09:416674
[email protected]b05955552014-02-06 18:41:186675 program_manager()->DoCompileShader(
6676 shader,
6677 translator,
6678 feature_info_->feature_flags().angle_translated_shader_source ?
6679 ProgramManager::kANGLE : ProgramManager::kGL);
[email protected]45bf5152010-02-12 00:11:316680};
6681
[email protected]ddd968b82010-03-02 00:44:296682void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426683 GLuint shader_id, GLenum pname, GLint* params) {
6684 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6685 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296686 return;
6687 }
[email protected]8f1ccdac2010-05-19 21:01:486688 switch (pname) {
6689 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426690 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486691 return;
6692 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426693 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416694 return;
[email protected]8f1ccdac2010-05-19 21:01:486695 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426696 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416697 return;
[email protected]d6a53e42011-10-05 00:09:366698 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426699 *params = shader->translated_source() ?
6700 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366701 return;
[email protected]8f1ccdac2010-05-19 21:01:486702 default:
6703 break;
[email protected]ddd968b82010-03-02 00:44:296704 }
[email protected]df37b9932013-03-08 05:21:426705 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296706}
6707
[email protected]ae51d192010-04-27 00:48:036708error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356709 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426710 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036711 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6712 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426713 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6714 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296715 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296716 return error::kNoError;
6717 }
[email protected]df37b9932013-03-08 05:21:426718 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036719 return error::kNoError;
6720}
6721
[email protected]d6a53e42011-10-05 00:09:366722error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6723 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356724 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426725 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366726 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6727 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426728 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:206729 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:426730 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366731 bucket->SetSize(0);
6732 return error::kNoError;
6733 }
6734
[email protected]df37b9932013-03-08 05:21:426735 bucket->SetFromString(shader->translated_source() ?
6736 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366737 return error::kNoError;
6738}
6739
[email protected]ae51d192010-04-27 00:48:036740error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356741 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426742 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586743 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6744 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426745 Program* program = GetProgramInfoNotShader(
6746 program_id, "glGetProgramInfoLog");
6747 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466748 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036749 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316750 }
[email protected]df37b9932013-03-08 05:21:426751 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036752 return error::kNoError;
6753}
6754
6755error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356756 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426757 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586758 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6759 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426760 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6761 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466762 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036763 return error::kNoError;
6764 }
[email protected]df37b9932013-03-08 05:21:426765 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036766 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326767}
6768
[email protected]d058bca2012-11-26 10:27:266769bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6770 return state_.GetEnabled(cap);
6771}
6772
[email protected]1958e0e2010-04-22 05:17:156773bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216774 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106775 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156776}
6777
6778bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356779 const Framebuffer* framebuffer =
6780 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106781 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156782}
6783
6784bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366785 // IsProgram is true for programs as soon as they are created, until they are
6786 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356787 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106788 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156789}
6790
6791bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356792 const Renderbuffer* renderbuffer =
6793 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106794 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156795}
6796
6797bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366798 // IsShader is true for shaders as soon as they are created, until they
6799 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356800 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106801 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156802}
6803
6804bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496805 const TextureRef* texture_ref = GetTexture(client_id);
6806 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036807}
6808
6809void GLES2DecoderImpl::DoAttachShader(
6810 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426811 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586812 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426813 if (!program) {
[email protected]ae51d192010-04-27 00:48:036814 return;
[email protected]1958e0e2010-04-22 05:17:156815 }
[email protected]df37b9932013-03-08 05:21:426816 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6817 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036818 return;
6819 }
[email protected]df37b9932013-03-08 05:21:426820 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516821 LOCAL_SET_GL_ERROR(
6822 GL_INVALID_OPERATION,
6823 "glAttachShader",
6824 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316825 return;
6826 }
[email protected]df37b9932013-03-08 05:21:426827 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036828}
6829
6830void GLES2DecoderImpl::DoDetachShader(
6831 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426832 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586833 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426834 if (!program) {
[email protected]ae51d192010-04-27 00:48:036835 return;
6836 }
[email protected]df37b9932013-03-08 05:21:426837 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6838 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036839 return;
6840 }
[email protected]df37b9932013-03-08 05:21:426841 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516842 LOCAL_SET_GL_ERROR(
6843 GL_INVALID_OPERATION,
6844 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226845 return;
6846 }
[email protected]df37b9932013-03-08 05:21:426847 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036848}
6849
6850void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426851 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586852 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426853 if (!program) {
[email protected]ae51d192010-04-27 00:48:036854 return;
6855 }
[email protected]df37b9932013-03-08 05:21:426856 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156857}
6858
[email protected]ac77603c72013-03-08 13:52:066859void GLES2DecoderImpl::GetVertexAttribHelper(
6860 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246861 switch (pname) {
6862 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066863 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246864 if (buffer && !buffer->IsDeleted()) {
6865 GLuint client_id;
6866 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6867 *params = client_id;
6868 }
6869 break;
6870 }
6871 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066872 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246873 break;
6874 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066875 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246876 break;
6877 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066878 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246879 break;
6880 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066881 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246882 break;
6883 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066884 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246885 break;
[email protected]c6aef902012-02-14 03:31:426886 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066887 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426888 break;
[email protected]ac77603c72013-03-08 13:52:066889 default:
6890 NOTREACHED();
6891 break;
6892 }
6893}
6894
[email protected]4c6f5462014-03-05 00:26:566895void GLES2DecoderImpl::DoGetTexParameterfv(
6896 GLenum target, GLenum pname, GLfloat* params) {
6897 InitTextureMaxAnisotropyIfNeeded(target, pname);
6898 glGetTexParameterfv(target, pname, params);
6899}
6900
6901void GLES2DecoderImpl::DoGetTexParameteriv(
6902 GLenum target, GLenum pname, GLint* params) {
6903 InitTextureMaxAnisotropyIfNeeded(target, pname);
6904 glGetTexParameteriv(target, pname, params);
6905}
6906
6907void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
6908 GLenum target, GLenum pname) {
6909 if (!workarounds().init_texture_max_anisotropy)
6910 return;
6911 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
6912 !validators_->texture_parameter.IsValid(pname)) {
6913 return;
6914 }
6915
6916 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
6917 &state_, target);
6918 if (!texture_ref) {
6919 LOCAL_SET_GL_ERROR(
6920 GL_INVALID_OPERATION,
6921 "glGetTexParamter{fi}v", "unknown texture for target");
6922 return;
6923 }
6924 Texture* texture = texture_ref->texture();
6925 texture->InitTextureMaxAnisotropyIfNeeded(target);
6926}
6927
[email protected]ac77603c72013-03-08 13:52:066928void GLES2DecoderImpl::DoGetVertexAttribfv(
6929 GLuint index, GLenum pname, GLfloat* params) {
6930 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6931 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516932 LOCAL_SET_GL_ERROR(
6933 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066934 return;
6935 }
6936 switch (pname) {
6937 case GL_CURRENT_VERTEX_ATTRIB: {
6938 const Vec4& value = state_.attrib_values[index];
6939 params[0] = value.v[0];
6940 params[1] = value.v[1];
6941 params[2] = value.v[2];
6942 params[3] = value.v[3];
6943 break;
6944 }
6945 default: {
6946 GLint value = 0;
6947 GetVertexAttribHelper(attrib, pname, &value);
6948 *params = static_cast<GLfloat>(value);
6949 break;
6950 }
6951 }
6952}
6953
6954void GLES2DecoderImpl::DoGetVertexAttribiv(
6955 GLuint index, GLenum pname, GLint* params) {
6956 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6957 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516958 LOCAL_SET_GL_ERROR(
6959 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066960 return;
6961 }
6962 switch (pname) {
[email protected]af6380962012-11-29 23:24:136963 case GL_CURRENT_VERTEX_ATTRIB: {
6964 const Vec4& value = state_.attrib_values[index];
6965 params[0] = static_cast<GLint>(value.v[0]);
6966 params[1] = static_cast<GLint>(value.v[1]);
6967 params[2] = static_cast<GLint>(value.v[2]);
6968 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246969 break;
[email protected]af6380962012-11-29 23:24:136970 }
[email protected]b1122982010-05-17 23:04:246971 default:
[email protected]ac77603c72013-03-08 13:52:066972 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246973 break;
6974 }
6975}
6976
[email protected]af6380962012-11-29 23:24:136977bool GLES2DecoderImpl::SetVertexAttribValue(
6978 const char* function_name, GLuint index, const GLfloat* value) {
6979 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516980 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136981 return false;
[email protected]b1122982010-05-17 23:04:246982 }
[email protected]af6380962012-11-29 23:24:136983 Vec4& v = state_.attrib_values[index];
6984 v.v[0] = value[0];
6985 v.v[1] = value[1];
6986 v.v[2] = value[2];
6987 v.v[3] = value[3];
6988 return true;
6989}
6990
6991void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6992 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6993 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6994 glVertexAttrib1f(index, v0);
6995 }
[email protected]b1122982010-05-17 23:04:246996}
6997
6998void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136999 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7000 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7001 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247002 }
[email protected]b1122982010-05-17 23:04:247003}
7004
7005void GLES2DecoderImpl::DoVertexAttrib3f(
7006 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137007 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7008 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7009 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247010 }
[email protected]b1122982010-05-17 23:04:247011}
7012
7013void GLES2DecoderImpl::DoVertexAttrib4f(
7014 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137015 GLfloat v[4] = { v0, v1, v2, v3, };
7016 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7017 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247018 }
[email protected]b1122982010-05-17 23:04:247019}
7020
7021void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137022 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7023 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7024 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247025 }
[email protected]b1122982010-05-17 23:04:247026}
7027
7028void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137029 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7030 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7031 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247032 }
[email protected]b1122982010-05-17 23:04:247033}
7034
7035void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137036 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7037 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7038 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247039 }
[email protected]b1122982010-05-17 23:04:247040}
7041
7042void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137043 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7044 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247045 }
[email protected]b1122982010-05-17 23:04:247046}
7047
[email protected]f7a64ee2010-02-01 22:24:147048error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:357049 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:467050
[email protected]7cd76fd2013-06-02 21:11:117051 if (!state_.bound_array_buffer.get() ||
7052 state_.bound_array_buffer->IsDeleted()) {
7053 if (state_.vertex_attrib_manager.get() ==
7054 default_vertex_attrib_manager_.get()) {
[email protected]ab09b612013-03-11 22:11:517055 LOCAL_SET_GL_ERROR(
7056 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467057 return error::kNoError;
7058 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517059 LOCAL_SET_GL_ERROR(
7060 GL_INVALID_VALUE,
7061 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467062 return error::kNoError;
7063 }
[email protected]96449d2c2009-11-25 00:01:327064 }
[email protected]8eee29c2010-04-29 03:38:297065
7066 GLuint indx = c.indx;
7067 GLint size = c.size;
7068 GLenum type = c.type;
7069 GLboolean normalized = c.normalized;
7070 GLsizei stride = c.stride;
7071 GLsizei offset = c.offset;
7072 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057073 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517074 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297075 return error::kNoError;
7076 }
[email protected]9438b012010-06-15 22:55:057077 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517078 LOCAL_SET_GL_ERROR(
7079 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297080 return error::kNoError;
7081 }
7082 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517083 LOCAL_SET_GL_ERROR(
7084 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297085 return error::kNoError;
7086 }
7087 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517088 LOCAL_SET_GL_ERROR(
7089 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297090 return error::kNoError;
7091 }
7092 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517093 LOCAL_SET_GL_ERROR(
7094 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297095 return error::kNoError;
7096 }
7097 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517098 LOCAL_SET_GL_ERROR(
7099 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297100 return error::kNoError;
7101 }
7102 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317103 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:297104 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:517105 LOCAL_SET_GL_ERROR(
7106 GL_INVALID_OPERATION,
7107 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317108 return error::kNoError;
7109 }
7110 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:517111 LOCAL_SET_GL_ERROR(
7112 GL_INVALID_OPERATION,
7113 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297114 return error::kNoError;
7115 }
[email protected]7cd76fd2013-06-02 21:11:117116 state_.vertex_attrib_manager
7117 ->SetAttribInfo(indx,
7118 state_.bound_array_buffer.get(),
7119 size,
7120 type,
7121 normalized,
7122 stride,
7123 stride != 0 ? stride : component_size * size,
7124 offset);
[email protected]8fbedc02010-11-18 18:43:407125 if (type != GL_FIXED) {
7126 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7127 }
[email protected]f7a64ee2010-02-01 22:24:147128 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327129}
7130
[email protected]43410e92012-04-20 17:06:287131void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7132 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247133 state_.viewport_x = x;
7134 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027135 state_.viewport_width = std::min(width, viewport_max_width_);
7136 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287137 glViewport(x, y, width, height);
7138}
7139
[email protected]c6aef902012-02-14 03:31:427140error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:357141 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:157142 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517143 LOCAL_SET_GL_ERROR(
7144 GL_INVALID_OPERATION,
7145 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427146 }
7147 GLuint index = c.index;
7148 GLuint divisor = c.divisor;
7149 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517150 LOCAL_SET_GL_ERROR(
7151 GL_INVALID_VALUE,
7152 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427153 return error::kNoError;
7154 }
7155
[email protected]e259eb412012-10-13 05:47:247156 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427157 index,
7158 divisor);
7159 glVertexAttribDivisorANGLE(index, divisor);
7160 return error::kNoError;
7161}
7162
[email protected]68586372013-12-11 01:27:597163template <typename pixel_data_type>
7164static void WriteAlphaData(
7165 void *pixels, uint32 row_count, uint32 channel_count,
7166 uint32 alpha_channel_index, uint32 unpadded_row_size,
7167 uint32 padded_row_size, pixel_data_type alpha_value) {
7168 DCHECK_GT(channel_count, 0U);
7169 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7170 uint32 unpadded_row_size_in_elements =
7171 unpadded_row_size / sizeof(pixel_data_type);
7172 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7173 uint32 padded_row_size_in_elements =
7174 padded_row_size / sizeof(pixel_data_type);
7175 pixel_data_type* dst =
7176 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7177 for (uint32 yy = 0; yy < row_count; ++yy) {
7178 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7179 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7180 *d = alpha_value;
7181 }
7182 dst += padded_row_size_in_elements;
7183 }
7184}
7185
[email protected]5a36dc132013-07-23 23:17:557186void GLES2DecoderImpl::FinishReadPixels(
7187 const cmds::ReadPixels& c,
7188 GLuint buffer) {
7189 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7190 GLsizei width = c.width;
7191 GLsizei height = c.height;
7192 GLenum format = c.format;
7193 GLenum type = c.type;
7194 typedef cmds::ReadPixels::Result Result;
7195 uint32 pixels_size;
7196 Result* result = NULL;
7197 if (c.result_shm_id != 0) {
7198 result = GetSharedMemoryAs<Result*>(
7199 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7200 if (!result) {
7201 if (buffer != 0) {
7202 glDeleteBuffersARB(1, &buffer);
7203 }
7204 return;
7205 }
7206 }
7207 GLES2Util::ComputeImageDataSizes(
7208 width, height, format, type, state_.pack_alignment, &pixels_size,
7209 NULL, NULL);
7210 void* pixels = GetSharedMemoryAs<void*>(
7211 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7212 if (!pixels) {
7213 if (buffer != 0) {
7214 glDeleteBuffersARB(1, &buffer);
7215 }
7216 return;
7217 }
7218
7219 if (buffer != 0) {
7220 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337221 void* data;
7222 if (features().map_buffer_range) {
7223 data = glMapBufferRange(
7224 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7225 } else {
7226 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7227 }
[email protected]5a36dc132013-07-23 23:17:557228 memcpy(pixels, data, pixels_size);
7229 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7230 // have to restore the state.
7231 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7232 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7233 glDeleteBuffersARB(1, &buffer);
7234 }
7235
7236 if (result != NULL) {
7237 *result = true;
7238 }
7239
7240 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7241 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7242 if ((channels_exist & 0x0008) == 0 &&
7243 workarounds().clear_alpha_in_readpixels) {
7244 // Set the alpha to 255 because some drivers are buggy in this regard.
7245 uint32 temp_size;
7246
7247 uint32 unpadded_row_size;
7248 uint32 padded_row_size;
7249 if (!GLES2Util::ComputeImageDataSizes(
7250 width, 2, format, type, state_.pack_alignment, &temp_size,
7251 &unpadded_row_size, &padded_row_size)) {
7252 return;
7253 }
[email protected]68586372013-12-11 01:27:597254
7255 uint32 channel_count = 0;
7256 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557257 switch (format) {
7258 case GL_RGBA:
7259 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597260 channel_count = 4;
7261 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557262 break;
[email protected]68586372013-12-11 01:27:597263 case GL_ALPHA:
7264 channel_count = 1;
7265 alpha_channel = 0;
7266 break;
7267 }
7268
7269 if (channel_count > 0) {
7270 switch (type) {
7271 case GL_UNSIGNED_BYTE:
7272 WriteAlphaData<uint8>(
7273 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7274 padded_row_size, 0xFF);
7275 break;
7276 case GL_FLOAT:
7277 WriteAlphaData<float>(
7278 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7279 padded_row_size, 1.0f);
7280 break;
7281 case GL_HALF_FLOAT:
7282 WriteAlphaData<uint16>(
7283 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7284 padded_row_size, 0x3C00);
7285 break;
[email protected]5a36dc132013-07-23 23:17:557286 }
[email protected]5a36dc132013-07-23 23:17:557287 }
7288 }
7289}
7290
7291
[email protected]f7a64ee2010-02-01 22:24:147292error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:357293 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]c959a09a2014-03-27 11:44:217294 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227295 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7296 if (fbo_error != error::kNoError)
7297 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317298 GLint x = c.x;
7299 GLint y = c.y;
7300 GLsizei width = c.width;
7301 GLsizei height = c.height;
7302 GLenum format = c.format;
7303 GLenum type = c.type;
[email protected]5a36dc132013-07-23 23:17:557304 GLboolean async = c.async;
[email protected]57f223832010-03-19 01:57:567305 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517306 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567307 return error::kNoError;
7308 }
[email protected]ed9f9cd2013-02-27 21:12:357309 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187310 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347311 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247312 width, height, format, type, state_.pack_alignment, &pixels_size,
7313 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187314 return error::kOutOfBounds;
7315 }
[email protected]612d2f82009-12-08 20:49:317316 void* pixels = GetSharedMemoryAs<void*>(
7317 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107318 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147319 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467320 }
[email protected]de43f082013-04-02 01:16:107321 Result* result = NULL;
7322 if (c.result_shm_id != 0) {
7323 result = GetSharedMemoryAs<Result*>(
7324 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7325 if (!result) {
7326 return error::kOutOfBounds;
7327 }
7328 }
[email protected]a51788e2010-02-24 21:54:257329
[email protected]9438b012010-06-15 22:55:057330 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517331 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297332 return error::kNoError;
7333 }
[email protected]68586372013-12-11 01:27:597334 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517335 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127336 return error::kNoError;
7337 }
[email protected]68586372013-12-11 01:27:597338 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7339 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7340 // format and type are acceptable enums but not guaranteed to be supported
7341 // for this framebuffer. Have to ask gl if they are valid.
7342 GLint preferred_format = 0;
7343 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7344 GLint preferred_type = 0;
7345 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7346 if (format != static_cast<GLenum>(preferred_format) ||
7347 type != static_cast<GLenum>(preferred_type)) {
7348 LOCAL_SET_GL_ERROR(
7349 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7350 "with the current read framebuffer");
7351 return error::kNoError;
7352 }
7353 }
[email protected]57f223832010-03-19 01:57:567354 if (width == 0 || height == 0) {
7355 return error::kNoError;
7356 }
7357
[email protected]57f223832010-03-19 01:57:567358 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307359 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567360
[email protected]3aad1a32012-09-07 20:54:477361 int32 max_x;
7362 int32 max_y;
7363 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517364 LOCAL_SET_GL_ERROR(
7365 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147366 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317367 }
[email protected]57f223832010-03-19 01:57:567368
[email protected]0d6bfdc2011-11-02 01:32:207369 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7370 return error::kNoError;
7371 }
7372
[email protected]caa13ed2014-02-17 11:29:207373 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107374
7375 ScopedResolvedFrameBufferBinder binder(this, false, true);
7376
[email protected]d37231fa2010-04-09 21:16:027377 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567378 // The user requested an out of range area. Get the results 1 line
7379 // at a time.
7380 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347381 uint32 unpadded_row_size;
7382 uint32 padded_row_size;
7383 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247384 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347385 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517386 LOCAL_SET_GL_ERROR(
7387 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567388 return error::kNoError;
7389 }
7390
7391 GLint dest_x_offset = std::max(-x, 0);
7392 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347393 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247394 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7395 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517396 LOCAL_SET_GL_ERROR(
7397 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567398 return error::kNoError;
7399 }
7400
7401 // Copy each row into the larger dest rect.
7402 int8* dst = static_cast<int8*>(pixels);
7403 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027404 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567405 GLint read_width = read_end_x - read_x;
7406 for (GLint yy = 0; yy < height; ++yy) {
7407 GLint ry = y + yy;
7408
7409 // Clear the row.
7410 memset(dst, 0, unpadded_row_size);
7411
7412 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027413 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567414 glReadPixels(
7415 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7416 }
7417 dst += padded_row_size;
7418 }
7419 } else {
[email protected]5a36dc132013-07-23 23:17:557420 if (async && features().use_async_readpixels) {
7421 GLuint buffer;
7422 glGenBuffersARB(1, &buffer);
7423 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7424 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7425 GLenum error = glGetError();
7426 if (error == GL_NO_ERROR) {
7427 glReadPixels(x, y, width, height, format, type, 0);
7428 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7429 new FenceCallback()));
7430 WaitForReadPixels(base::Bind(
7431 &GLES2DecoderImpl::FinishReadPixels,
7432 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7433 <GLES2DecoderImpl>(this),
7434 c, buffer));
7435 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7436 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597437 } else {
7438 // On error, unbind pack buffer and fall through to sync readpixels
7439 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
[email protected]5a36dc132013-07-23 23:17:557440 }
7441 }
[email protected]57f223832010-03-19 01:57:567442 glReadPixels(x, y, width, height, format, type, pixels);
7443 }
[email protected]ab09b612013-03-11 22:11:517444 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257445 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107446 if (result != NULL) {
7447 *result = true;
7448 }
[email protected]5a36dc132013-07-23 23:17:557449 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257450 }
[email protected]4848b9f82011-03-10 18:37:567451
[email protected]f7a64ee2010-02-01 22:24:147452 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327453}
7454
[email protected]f7a64ee2010-02-01 22:24:147455error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:357456 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:197457 GLenum pname = c.pname;
7458 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057459 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517460 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127461 return error::kNoError;
7462 }
[email protected]222471d2011-11-30 18:06:397463 switch (pname) {
7464 case GL_PACK_ALIGNMENT:
7465 case GL_UNPACK_ALIGNMENT:
7466 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517467 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207468 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397469 return error::kNoError;
7470 }
[email protected]164d6d52012-05-05 00:55:037471 break;
[email protected]0a1e9ad2012-05-04 21:13:037472 case GL_UNPACK_FLIP_Y_CHROMIUM:
7473 unpack_flip_y_ = (param != 0);
7474 return error::kNoError;
7475 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7476 unpack_premultiply_alpha_ = (param != 0);
7477 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177478 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7479 unpack_unpremultiply_alpha_ = (param != 0);
7480 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397481 default:
7482 break;
[email protected]b9849abf2009-11-25 19:13:197483 }
7484 glPixelStorei(pname, param);
7485 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437486 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247487 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437488 break;
7489 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427490 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437491 break;
7492 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247493 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437494 break;
7495 default:
7496 // Validation should have prevented us from getting here.
7497 NOTREACHED();
7498 break;
[email protected]b9849abf2009-11-25 19:13:197499 }
[email protected]f7a64ee2010-02-01 22:24:147500 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197501}
7502
[email protected]1c75a3702011-11-11 14:15:287503error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:357504 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:387505 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]b381ee32014-03-22 02:43:437506 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:517507 LOCAL_SET_GL_ERROR(
7508 GL_INVALID_OPERATION,
7509 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287510 return error::kNoError;
7511 }
[email protected]8f9b8dd2013-09-12 18:05:137512 bool is_tracing;
7513 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7514 &is_tracing);
7515 if (is_tracing) {
7516 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7517 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7518 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7519 is_offscreen ? offscreen_size_ : surface_->GetSize());
7520 }
[email protected]7794d512012-04-17 20:36:497521 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287522 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497523 } else {
7524 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287525 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497526 }
[email protected]1c75a3702011-11-11 14:15:287527}
7528
[email protected]558847a2010-03-24 07:02:547529error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7530 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7531 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577532 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517533 LOCAL_SET_GL_ERROR(
7534 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577535 return error::kNoError;
7536 }
[email protected]df37b9932013-03-08 05:21:427537 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587538 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427539 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147540 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197541 }
[email protected]df37b9932013-03-08 05:21:427542 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517543 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437544 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257545 return error::kNoError;
7546 }
[email protected]b9849abf2009-11-25 19:13:197547 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547548 location_shm_id, location_shm_offset, sizeof(GLint));
7549 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147550 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197551 }
[email protected]558847a2010-03-24 07:02:547552 // Require the client to init this incase the context is lost and we are no
7553 // longer executing commands.
7554 if (*location != -1) {
7555 return error::kGenericError;
7556 }
[email protected]df37b9932013-03-08 05:21:427557 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147558 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197559}
7560
[email protected]558847a2010-03-24 07:02:547561error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357562 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547563 uint32 name_size = c.data_size;
7564 const char* name = GetSharedMemoryAs<const char*>(
7565 c.name_shm_id, c.name_shm_offset, name_size);
7566 if (!name) {
7567 return error::kOutOfBounds;
7568 }
7569 String name_str(name, name_size);
7570 return GetAttribLocationHelper(
7571 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7572}
7573
[email protected]558847a2010-03-24 07:02:547574error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357575 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547576 Bucket* bucket = GetBucket(c.name_bucket_id);
7577 if (!bucket) {
7578 return error::kInvalidArguments;
7579 }
7580 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187581 if (!bucket->GetAsString(&name_str)) {
7582 return error::kInvalidArguments;
7583 }
[email protected]558847a2010-03-24 07:02:547584 return GetAttribLocationHelper(
7585 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7586}
7587
7588error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7589 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7590 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577591 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517592 LOCAL_SET_GL_ERROR(
7593 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577594 return error::kNoError;
7595 }
[email protected]df37b9932013-03-08 05:21:427596 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:207597 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:427598 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147599 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197600 }
[email protected]df37b9932013-03-08 05:21:427601 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517602 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437603 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257604 return error::kNoError;
7605 }
[email protected]b9849abf2009-11-25 19:13:197606 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547607 location_shm_id, location_shm_offset, sizeof(GLint));
7608 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147609 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197610 }
[email protected]558847a2010-03-24 07:02:547611 // Require the client to init this incase the context is lost an we are no
7612 // longer executing commands.
7613 if (*location != -1) {
7614 return error::kGenericError;
7615 }
[email protected]df37b9932013-03-08 05:21:427616 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147617 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197618}
7619
[email protected]f7a64ee2010-02-01 22:24:147620error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357621 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197622 uint32 name_size = c.data_size;
7623 const char* name = GetSharedMemoryAs<const char*>(
7624 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547625 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147626 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197627 }
7628 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547629 return GetUniformLocationHelper(
7630 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197631}
7632
[email protected]558847a2010-03-24 07:02:547633error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357634 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547635 Bucket* bucket = GetBucket(c.name_bucket_id);
7636 if (!bucket) {
7637 return error::kInvalidArguments;
7638 }
7639 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187640 if (!bucket->GetAsString(&name_str)) {
7641 return error::kInvalidArguments;
7642 }
[email protected]558847a2010-03-24 07:02:547643 return GetUniformLocationHelper(
7644 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197645}
7646
[email protected]ddd968b82010-03-02 00:44:297647error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357648 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297649 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057650 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517651 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297652 return error::kNoError;
7653 }
[email protected]959e9072013-09-20 16:58:387654 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:047655 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157656 switch (name) {
7657 case GL_VERSION:
7658 str = "OpenGL ES 2.0 Chromium";
7659 break;
7660 case GL_SHADING_LANGUAGE_VERSION:
7661 str = "OpenGL ES GLSL ES 1.0 Chromium";
7662 break;
[email protected]32939602012-05-09 06:25:167663 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:167664 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:387665 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7666 // They are used by WEBGL_debug_renderer_info.
7667 if (!force_webgl_glsl_validation_)
7668 str = "Chromium";
[email protected]32939602012-05-09 06:25:167669 break;
[email protected]1958e0e2010-04-22 05:17:157670 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047671 {
[email protected]70dc60932013-06-04 03:33:497672 // For WebGL contexts, strip out the OES derivatives and
7673 // EXT frag depth extensions if they have not been enabled.
7674 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047675 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497676 if (!derivatives_explicitly_enabled_) {
7677 size_t offset = extensions.find(kOESDerivativeExtension);
7678 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097679 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497680 std::string());
7681 }
7682 }
7683 if (!frag_depth_explicitly_enabled_) {
7684 size_t offset = extensions.find(kEXTFragDepthExtension);
7685 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097686 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497687 std::string());
7688 }
[email protected]f0d74742011-10-03 16:31:047689 }
[email protected]aff39ac82013-06-08 04:53:137690 if (!draw_buffers_explicitly_enabled_) {
7691 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7692 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097693 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137694 std::string());
7695 }
7696 }
[email protected]f0d74742011-10-03 16:31:047697 } else {
[email protected]6f5fac9d12012-06-26 21:02:457698 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047699 }
[email protected]b381ee32014-03-22 02:43:437700 if (supports_post_sub_buffer_)
7701 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:457702 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047703 }
[email protected]1958e0e2010-04-22 05:17:157704 break;
7705 default:
[email protected]1958e0e2010-04-22 05:17:157706 break;
7707 }
[email protected]ddd968b82010-03-02 00:44:297708 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157709 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297710 return error::kNoError;
7711}
7712
[email protected]0c86dbf2010-03-05 08:14:117713error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357714 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117715 GLenum target = static_cast<GLenum>(c.target);
7716 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7717 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7718 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7719 GLenum usage = static_cast<GLenum>(c.usage);
7720 const void* data = NULL;
7721 if (data_shm_id != 0 || data_shm_offset != 0) {
7722 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7723 if (!data) {
7724 return error::kOutOfBounds;
7725 }
7726 }
[email protected]0fbba3732013-07-17 15:40:137727 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147728 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197729}
7730
[email protected]0c86dbf2010-03-05 08:14:117731void GLES2DecoderImpl::DoBufferSubData(
7732 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137733 // Just delegate it. Some validation is actually done before this.
7734 buffer_manager()->ValidateAndDoBufferSubData(
7735 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197736}
7737
[email protected]0d6bfdc2011-11-02 01:32:207738bool GLES2DecoderImpl::ClearLevel(
7739 unsigned service_id,
7740 unsigned bind_target,
7741 unsigned target,
7742 int level,
[email protected]d8e6c9242014-02-20 16:56:257743 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:207744 unsigned format,
7745 unsigned type,
7746 int width,
[email protected]4502e6492011-12-14 19:39:157747 int height,
7748 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007749 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:007750 if (feature_info_->feature_flags().angle_depth_texture &&
7751 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:007752 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7753 // on depth formats.
7754 GLuint fb = 0;
7755 glGenFramebuffersEXT(1, &fb);
7756 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7757
7758 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7759 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7760 GL_DEPTH_ATTACHMENT;
7761
7762 glFramebufferTexture2DEXT(
7763 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7764 // ANGLE promises a depth only attachment ok.
7765 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7766 GL_FRAMEBUFFER_COMPLETE) {
7767 return false;
7768 }
7769 glClearStencil(0);
7770 glStencilMask(-1);
7771 glClearDepth(1.0f);
7772 glDepthMask(true);
7773 glDisable(GL_SCISSOR_TEST);
7774 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7775
7776 RestoreClearState();
7777
7778 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357779 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007780 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7781 GLuint fb_service_id =
7782 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7783 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7784 return true;
7785 }
7786
[email protected]45d15a62012-04-18 14:33:177787 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7788
7789 uint32 size;
7790 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347791 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247792 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177793 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207794 return false;
7795 }
[email protected]45d15a62012-04-18 14:33:177796
[email protected]a5d3dad2012-05-26 04:34:447797 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7798
[email protected]45d15a62012-04-18 14:33:177799 int tile_height;
7800
7801 if (size > kMaxZeroSize) {
7802 if (kMaxZeroSize < padded_row_size) {
7803 // That'd be an awfully large texture.
7804 return false;
7805 }
7806 // We should never have a large total size with a zero row size.
7807 DCHECK_GT(padded_row_size, 0U);
7808 tile_height = kMaxZeroSize / padded_row_size;
7809 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247810 width, tile_height, format, type, state_.unpack_alignment, &size,
7811 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177812 return false;
7813 }
[email protected]4502e6492011-12-14 19:39:157814 } else {
[email protected]45d15a62012-04-18 14:33:177815 tile_height = height;
7816 }
7817
7818 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557819 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177820 memset(zero.get(), 0, size);
7821 glBindTexture(bind_target, service_id);
7822
7823 GLint y = 0;
7824 while (y < height) {
7825 GLint h = y + tile_height > height ? height - y : tile_height;
7826 if (is_texture_immutable || h != height) {
7827 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7828 } else {
[email protected]8f1d2aa2013-05-10 23:45:387829 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:257830 target, level, internal_format, width, h, 0, format, type,
7831 zero.get());
[email protected]45d15a62012-04-18 14:33:177832 }
7833 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157834 }
[email protected]c986af502013-08-14 01:04:447835 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
7836 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:077837 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207838 return true;
7839}
7840
[email protected]ad84a3a2012-06-08 21:42:437841namespace {
7842
7843const int kS3TCBlockWidth = 4;
7844const int kS3TCBlockHeight = 4;
7845const int kS3TCDXT1BlockSize = 8;
7846const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077847const int kETC1BlockWidth = 4;
7848const int kETC1BlockHeight = 4;
7849const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437850
7851bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517852 return (size == 1) ||
7853 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437854}
7855
7856} // anonymous namespace.
7857
7858bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7859 const char* function_name,
7860 GLsizei width, GLsizei height, GLenum format, size_t size) {
7861 unsigned int bytes_required = 0;
7862
7863 switch (format) {
7864 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7865 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7866 int num_blocks_across =
7867 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7868 int num_blocks_down =
7869 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7870 int num_blocks = num_blocks_across * num_blocks_down;
7871 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7872 break;
7873 }
7874 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7875 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7876 int num_blocks_across =
7877 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7878 int num_blocks_down =
7879 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7880 int num_blocks = num_blocks_across * num_blocks_down;
7881 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7882 break;
7883 }
[email protected]2d3765b2012-10-03 00:31:077884 case GL_ETC1_RGB8_OES: {
7885 int num_blocks_across =
7886 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7887 int num_blocks_down =
7888 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7889 int num_blocks = num_blocks_across * num_blocks_down;
7890 bytes_required = num_blocks * kETC1BlockSize;
7891 break;
7892 }
[email protected]ad84a3a2012-06-08 21:42:437893 default:
[email protected]ab09b612013-03-11 22:11:517894 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437895 return false;
7896 }
7897
7898 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517899 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437900 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7901 return false;
7902 }
7903
7904 return true;
7905}
7906
7907bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7908 const char* function_name,
7909 GLint level, GLsizei width, GLsizei height, GLenum format) {
7910 switch (format) {
7911 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7912 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7913 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7914 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7915 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517916 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437917 GL_INVALID_OPERATION, function_name,
7918 "width or height invalid for level");
7919 return false;
7920 }
7921 return true;
7922 }
[email protected]2d3765b2012-10-03 00:31:077923 case GL_ETC1_RGB8_OES:
7924 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517925 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077926 GL_INVALID_OPERATION, function_name,
7927 "width or height invalid for level");
7928 return false;
7929 }
7930 return true;
[email protected]ad84a3a2012-06-08 21:42:437931 default:
7932 return false;
7933 }
7934}
7935
7936bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7937 const char* function_name,
7938 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7939 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357940 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437941 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517942 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437943 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7944 return false;
7945 }
7946
7947 switch (format) {
7948 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7949 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7950 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7951 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7952 const int kBlockWidth = 4;
7953 const int kBlockHeight = 4;
7954 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517955 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437956 GL_INVALID_OPERATION, function_name,
7957 "xoffset or yoffset not multiple of 4");
7958 return false;
7959 }
7960 GLsizei tex_width = 0;
7961 GLsizei tex_height = 0;
7962 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7963 width - xoffset > tex_width ||
7964 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517965 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437966 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7967 return false;
7968 }
7969 return ValidateCompressedTexDimensions(
7970 function_name, level, width, height, format);
7971 }
[email protected]2d3765b2012-10-03 00:31:077972 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517973 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077974 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:207975 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:077976 return false;
7977 }
[email protected]ad84a3a2012-06-08 21:42:437978 default:
7979 return false;
7980 }
7981}
7982
[email protected]a93bb842010-02-16 23:03:477983error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7984 GLenum target,
7985 GLint level,
7986 GLenum internal_format,
7987 GLsizei width,
7988 GLsizei height,
7989 GLint border,
7990 GLsizei image_size,
7991 const void* data) {
[email protected]a93bb842010-02-16 23:03:477992 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057993 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517994 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7995 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297996 return error::kNoError;
7997 }
[email protected]9438b012010-06-15 22:55:057998 if (!validators_->compressed_texture_format.IsValid(
7999 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518000 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538001 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478002 return error::kNoError;
8003 }
[email protected]80eb6b52012-01-19 00:14:418004 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478005 border != 0) {
[email protected]ab09b612013-03-11 22:11:518006 LOCAL_SET_GL_ERROR(
8007 GL_INVALID_VALUE,
8008 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478009 return error::kNoError;
8010 }
[email protected]c986af502013-08-14 01:04:448011 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8012 &state_, target);
[email protected]370eaf12013-05-18 09:19:498013 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518014 LOCAL_SET_GL_ERROR(
8015 GL_INVALID_VALUE,
8016 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478017 return error::kNoError;
8018 }
[email protected]370eaf12013-05-18 09:19:498019 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078020 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518021 LOCAL_SET_GL_ERROR(
8022 GL_INVALID_OPERATION,
8023 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438024 return error::kNoError;
8025 }
8026
8027 if (!ValidateCompressedTexDimensions(
8028 "glCompressedTexImage2D", level, width, height, internal_format) ||
8029 !ValidateCompressedTexFuncData(
8030 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178031 return error::kNoError;
8032 }
[email protected]968351b2011-12-20 08:26:518033
[email protected]7989c9e2013-01-23 06:39:268034 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518035 LOCAL_SET_GL_ERROR(
8036 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268037 return error::kNoError;
8038 }
8039
[email protected]02965c22013-03-09 02:40:078040 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448041 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518042 }
8043
[email protected]40d90a22013-04-09 03:39:558044 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478045 if (!data) {
8046 zero.reset(new int8[image_size]);
8047 memset(zero.get(), 0, image_size);
8048 data = zero.get();
8049 }
[email protected]ab09b612013-03-11 22:11:518050 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478051 glCompressedTexImage2D(
8052 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518053 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438054 if (error == GL_NO_ERROR) {
8055 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498056 texture_ref, target, level, internal_format,
8057 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438058 }
[email protected]a93bb842010-02-16 23:03:478059 return error::kNoError;
8060}
8061
[email protected]f7a64ee2010-02-01 22:24:148062error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358063 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:198064 GLenum target = static_cast<GLenum>(c.target);
8065 GLint level = static_cast<GLint>(c.level);
8066 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8067 GLsizei width = static_cast<GLsizei>(c.width);
8068 GLsizei height = static_cast<GLsizei>(c.height);
8069 GLint border = static_cast<GLint>(c.border);
8070 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8071 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8072 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8073 const void* data = NULL;
8074 if (data_shm_id != 0 || data_shm_offset != 0) {
8075 data = GetSharedMemoryAs<const void*>(
8076 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468077 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148078 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198079 }
8080 }
[email protected]a93bb842010-02-16 23:03:478081 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198082 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198083}
8084
[email protected]b6140d02010-05-17 14:47:168085error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:358086 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:168087 GLenum target = static_cast<GLenum>(c.target);
8088 GLint level = static_cast<GLint>(c.level);
8089 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8090 GLsizei width = static_cast<GLsizei>(c.width);
8091 GLsizei height = static_cast<GLsizei>(c.height);
8092 GLint border = static_cast<GLint>(c.border);
8093 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288094 if (!bucket) {
8095 return error::kInvalidArguments;
8096 }
8097 uint32 data_size = bucket->size();
8098 GLsizei imageSize = data_size;
8099 const void* data = bucket->GetData(0, data_size);
8100 if (!data) {
8101 return error::kInvalidArguments;
8102 }
[email protected]b6140d02010-05-17 14:47:168103 return DoCompressedTexImage2D(
8104 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288105 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168106}
8107
8108error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8109 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358110 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:168111 GLenum target = static_cast<GLenum>(c.target);
8112 GLint level = static_cast<GLint>(c.level);
8113 GLint xoffset = static_cast<GLint>(c.xoffset);
8114 GLint yoffset = static_cast<GLint>(c.yoffset);
8115 GLsizei width = static_cast<GLsizei>(c.width);
8116 GLsizei height = static_cast<GLsizei>(c.height);
8117 GLenum format = static_cast<GLenum>(c.format);
8118 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288119 if (!bucket) {
8120 return error::kInvalidArguments;
8121 }
[email protected]b6140d02010-05-17 14:47:168122 uint32 data_size = bucket->size();
8123 GLsizei imageSize = data_size;
8124 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288125 if (!data) {
8126 return error::kInvalidArguments;
8127 }
[email protected]9438b012010-06-15 22:55:058128 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518129 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538130 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168131 return error::kNoError;
8132 }
[email protected]9438b012010-06-15 22:55:058133 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518134 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8135 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058136 return error::kNoError;
8137 }
[email protected]b6140d02010-05-17 14:47:168138 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518139 LOCAL_SET_GL_ERROR(
8140 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168141 return error::kNoError;
8142 }
8143 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518144 LOCAL_SET_GL_ERROR(
8145 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168146 return error::kNoError;
8147 }
8148 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518149 LOCAL_SET_GL_ERROR(
8150 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168151 return error::kNoError;
8152 }
[email protected]cadde4a2010-07-31 17:10:438153 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168154 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8155 return error::kNoError;
8156}
8157
[email protected]f7a64ee2010-02-01 22:24:148158error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358159 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388160 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]c986af502013-08-14 01:04:448161 // Set as failed for now, but if it successed, this will be set to not failed.
8162 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198163 GLenum target = static_cast<GLenum>(c.target);
8164 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448165 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8166 // for internalformat.
8167 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198168 GLsizei width = static_cast<GLsizei>(c.width);
8169 GLsizei height = static_cast<GLsizei>(c.height);
8170 GLint border = static_cast<GLint>(c.border);
8171 GLenum format = static_cast<GLenum>(c.format);
8172 GLenum type = static_cast<GLenum>(c.type);
8173 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8174 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188175 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348176 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248177 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348178 NULL)) {
[email protected]a76b0052010-03-05 00:33:188179 return error::kOutOfBounds;
8180 }
[email protected]b9849abf2009-11-25 19:13:198181 const void* pixels = NULL;
8182 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8183 pixels = GetSharedMemoryAs<const void*>(
8184 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468185 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148186 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198187 }
8188 }
[email protected]f598f422012-12-07 08:30:038189
[email protected]c986af502013-08-14 01:04:448190 TextureManager::DoTextImage2DArguments args = {
8191 target, level, internal_format, width, height, border, format, type,
8192 pixels, pixels_size};
8193 texture_manager()->ValidateAndDoTexImage2D(
8194 &texture_state_, &state_, &framebuffer_state_, args);
[email protected]f598f422012-12-07 08:30:038195 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198196}
8197
[email protected]cadde4a2010-07-31 17:10:438198void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8199 GLenum target,
8200 GLint level,
8201 GLint xoffset,
8202 GLint yoffset,
8203 GLsizei width,
8204 GLsizei height,
8205 GLenum format,
8206 GLsizei image_size,
8207 const void * data) {
[email protected]c986af502013-08-14 01:04:448208 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8209 &state_, target);
[email protected]370eaf12013-05-18 09:19:498210 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518211 LOCAL_SET_GL_ERROR(
8212 GL_INVALID_OPERATION,
8213 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438214 return;
8215 }
[email protected]370eaf12013-05-18 09:19:498216 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438217 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528218 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078219 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518220 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528221 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438222 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528223 return;
8224 }
8225 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518226 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528227 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438228 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528229 return;
8230 }
[email protected]02965c22013-03-09 02:40:078231 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528232 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518233 LOCAL_SET_GL_ERROR(
8234 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438235 return;
8236 }
[email protected]ad84a3a2012-06-08 21:42:438237
8238 if (!ValidateCompressedTexFuncData(
8239 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8240 !ValidateCompressedTexSubDimensions(
8241 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078242 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438243 return;
8244 }
8245
8246
[email protected]0d6bfdc2011-11-02 01:32:208247 // Note: There is no need to deal with texture cleared tracking here
8248 // because the validation above means you can only get here if the level
8249 // is already a matching compressed format and in that case
8250 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438251 glCompressedTexSubImage2D(
8252 target, level, xoffset, yoffset, width, height, format, image_size, data);
8253}
8254
[email protected]6e288612010-12-21 20:45:038255static void Clip(
8256 GLint start, GLint range, GLint sourceRange,
8257 GLint* out_start, GLint* out_range) {
8258 DCHECK(out_start);
8259 DCHECK(out_range);
8260 if (start < 0) {
8261 range += start;
8262 start = 0;
8263 }
8264 GLint end = start + range;
8265 if (end > sourceRange) {
8266 range -= end - sourceRange;
8267 }
8268 *out_start = start;
8269 *out_range = range;
8270}
8271
[email protected]cadde4a2010-07-31 17:10:438272void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448273 GLenum target,
8274 GLint level,
8275 GLenum internal_format,
8276 GLint x,
8277 GLint y,
8278 GLsizei width,
8279 GLsizei height,
8280 GLint border) {
[email protected]09e17272012-11-30 10:30:448281 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448282 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8283 &state_, target);
[email protected]370eaf12013-05-18 09:19:498284 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518285 LOCAL_SET_GL_ERROR(
8286 GL_INVALID_OPERATION,
8287 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438288 return;
8289 }
[email protected]370eaf12013-05-18 09:19:498290 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078291 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518292 LOCAL_SET_GL_ERROR(
8293 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:178294 }
[email protected]80eb6b52012-01-19 00:14:418295 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188296 border != 0) {
[email protected]ab09b612013-03-11 22:11:518297 LOCAL_SET_GL_ERROR(
8298 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188299 return;
8300 }
[email protected]17a961192014-02-14 15:20:528301 if (!texture_manager()->ValidateFormatAndTypeCombination(
8302 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8303 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:008304 return;
8305 }
[email protected]f5719fb2010-08-04 18:27:188306
[email protected]9edc6b22010-12-23 02:00:268307 // Check we have compatible formats.
8308 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8309 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8310 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8311
8312 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518313 LOCAL_SET_GL_ERROR(
8314 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268315 return;
8316 }
8317
[email protected]81375742012-06-08 00:04:008318 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518319 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008320 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268321 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8322 return;
8323 }
8324
8325 uint32 estimated_size = 0;
8326 if (!GLES2Util::ComputeImageDataSizes(
8327 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8328 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518329 LOCAL_SET_GL_ERROR(
8330 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268331 return;
8332 }
8333
8334 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518335 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008336 return;
8337 }
8338
[email protected]a0b78dc2011-11-11 10:43:108339 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8340 return;
8341 }
8342
[email protected]ab09b612013-03-11 22:11:518343 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278344 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038345 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268346
[email protected]02965c22013-03-09 02:40:078347 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448348 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468349 }
8350
[email protected]9edc6b22010-12-23 02:00:268351 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038352 GLint copyX = 0;
8353 GLint copyY = 0;
8354 GLint copyWidth = 0;
8355 GLint copyHeight = 0;
8356 Clip(x, width, size.width(), &copyX, &copyWidth);
8357 Clip(y, height, size.height(), &copyY, &copyHeight);
8358
8359 if (copyX != x ||
8360 copyY != y ||
8361 copyWidth != width ||
8362 copyHeight != height) {
8363 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208364 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078365 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:258366 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
8367 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518368 LOCAL_SET_GL_ERROR(
8369 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038370 return;
8371 }
[email protected]6e288612010-12-21 20:45:038372 if (copyHeight > 0 && copyWidth > 0) {
8373 GLint dx = copyX - x;
8374 GLint dy = copyY - y;
8375 GLint destX = dx;
8376 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:378377 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038378 glCopyTexSubImage2D(target, level,
8379 destX, destY, copyX, copyY,
8380 copyWidth, copyHeight);
8381 }
8382 } else {
[email protected]00c2cf92014-03-14 00:08:378383 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038384 glCopyTexImage2D(target, level, internal_format,
8385 copyX, copyY, copyWidth, copyHeight, border);
8386 }
[email protected]ab09b612013-03-11 22:11:518387 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438388 if (error == GL_NO_ERROR) {
8389 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498390 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208391 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438392 }
8393}
8394
8395void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448396 GLenum target,
8397 GLint level,
8398 GLint xoffset,
8399 GLint yoffset,
8400 GLint x,
8401 GLint y,
8402 GLsizei width,
8403 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448404 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448405 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8406 &state_, target);
[email protected]370eaf12013-05-18 09:19:498407 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518408 LOCAL_SET_GL_ERROR(
8409 GL_INVALID_OPERATION,
8410 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438411 return;
8412 }
[email protected]370eaf12013-05-18 09:19:498413 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438414 GLenum type = 0;
8415 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078416 if (!texture->GetLevelType(target, level, &type, &format) ||
8417 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528418 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518419 LOCAL_SET_GL_ERROR(
8420 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438421 return;
8422 }
[email protected]85a4ac22013-05-31 01:58:478423 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518424 LOCAL_SET_GL_ERROR(
8425 GL_INVALID_OPERATION,
8426 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598427 return;
8428 }
[email protected]9edc6b22010-12-23 02:00:268429
8430 // Check we have compatible formats.
8431 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8432 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8433 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8434
[email protected]2d3765b2012-10-03 00:31:078435 if (!channels_needed ||
8436 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518437 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438438 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268439 return;
8440 }
8441
[email protected]81375742012-06-08 00:04:008442 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518443 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008444 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438445 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008446 return;
8447 }
8448
[email protected]a0b78dc2011-11-11 10:43:108449 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8450 return;
8451 }
8452
[email protected]de26b3c2011-08-03 21:54:278453 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038454 gfx::Size size = GetBoundReadFrameBufferSize();
8455 GLint copyX = 0;
8456 GLint copyY = 0;
8457 GLint copyWidth = 0;
8458 GLint copyHeight = 0;
8459 Clip(x, width, size.width(), &copyX, &copyWidth);
8460 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208461
[email protected]370eaf12013-05-18 09:19:498462 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518463 LOCAL_SET_GL_ERROR(
8464 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208465 return;
8466 }
8467
[email protected]6e288612010-12-21 20:45:038468 if (copyX != x ||
8469 copyY != y ||
8470 copyWidth != width ||
8471 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208472 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038473 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348474 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248475 width, height, format, type, state_.unpack_alignment, &pixels_size,
8476 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518477 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438478 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038479 return;
8480 }
[email protected]40d90a22013-04-09 03:39:558481 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038482 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:378483 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038484 glTexSubImage2D(
8485 target, level, xoffset, yoffset, width, height,
8486 format, type, zero.get());
8487 }
[email protected]0d6bfdc2011-11-02 01:32:208488
[email protected]6e288612010-12-21 20:45:038489 if (copyHeight > 0 && copyWidth > 0) {
8490 GLint dx = copyX - x;
8491 GLint dy = copyY - y;
8492 GLint destX = xoffset + dx;
8493 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:378494 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038495 glCopyTexSubImage2D(target, level,
8496 destX, destY, copyX, copyY,
8497 copyWidth, copyHeight);
8498 }
[email protected]cadde4a2010-07-31 17:10:438499}
8500
[email protected]f598f422012-12-07 08:30:038501bool GLES2DecoderImpl::ValidateTexSubImage2D(
8502 error::Error* error,
8503 const char* function_name,
8504 GLenum target,
8505 GLint level,
8506 GLint xoffset,
8507 GLint yoffset,
8508 GLsizei width,
8509 GLsizei height,
8510 GLenum format,
8511 GLenum type,
8512 const void * data) {
8513 (*error) = error::kNoError;
8514 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518515 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038516 return false;
8517 }
8518 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518519 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038520 return false;
8521 }
8522 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518523 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038524 return false;
8525 }
[email protected]c986af502013-08-14 01:04:448526 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8527 &state_, target);
[email protected]370eaf12013-05-18 09:19:498528 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518529 LOCAL_SET_GL_ERROR(
8530 GL_INVALID_OPERATION,
8531 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038532 return false;
[email protected]cadde4a2010-07-31 17:10:438533 }
[email protected]370eaf12013-05-18 09:19:498534 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528535 GLenum current_type = 0;
8536 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078537 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518538 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038539 GL_INVALID_OPERATION, function_name, "level does not exist.");
8540 return false;
[email protected]df6cf1ad2011-01-29 01:20:528541 }
[email protected]17a961192014-02-14 15:20:528542 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
8543 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:038544 return false;
[email protected]df6cf1ad2011-01-29 01:20:528545 }
8546 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518547 LOCAL_SET_GL_ERROR(
8548 GL_INVALID_OPERATION,
8549 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038550 return false;
[email protected]df6cf1ad2011-01-29 01:20:528551 }
[email protected]85a4ac22013-05-31 01:58:478552 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518553 LOCAL_SET_GL_ERROR(
8554 GL_INVALID_OPERATION,
8555 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598556 return false;
8557 }
[email protected]02965c22013-03-09 02:40:078558 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528559 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518560 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038561 return false;
[email protected]cadde4a2010-07-31 17:10:438562 }
[email protected]81375742012-06-08 00:04:008563 if ((GLES2Util::GetChannelsForFormat(format) &
8564 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518565 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008566 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038567 function_name, "can not supply data for depth or stencil textures");
8568 return false;
[email protected]81375742012-06-08 00:04:008569 }
[email protected]f598f422012-12-07 08:30:038570 if (data == NULL) {
8571 (*error) = error::kOutOfBounds;
8572 return false;
8573 }
8574 return true;
8575}
[email protected]81375742012-06-08 00:04:008576
[email protected]f598f422012-12-07 08:30:038577error::Error GLES2DecoderImpl::DoTexSubImage2D(
8578 GLenum target,
8579 GLint level,
8580 GLint xoffset,
8581 GLint yoffset,
8582 GLsizei width,
8583 GLsizei height,
8584 GLenum format,
8585 GLenum type,
8586 const void * data) {
8587 error::Error error = error::kNoError;
8588 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8589 xoffset, yoffset, width, height, format, type, data)) {
8590 return error;
8591 }
[email protected]c986af502013-08-14 01:04:448592 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8593 &state_, target);
[email protected]370eaf12013-05-18 09:19:498594 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158595 GLsizei tex_width = 0;
8596 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078597 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158598 DCHECK(ok);
8599 if (xoffset != 0 || yoffset != 0 ||
8600 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498601 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8602 target, level)) {
[email protected]ab09b612013-03-11 22:11:518603 LOCAL_SET_GL_ERROR(
8604 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038605 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308606 }
[email protected]c986af502013-08-14 01:04:448607 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158608 glTexSubImage2D(
8609 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038610 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208611 }
[email protected]4502e6492011-12-14 19:39:158612
[email protected]345ba902013-11-14 21:39:008613 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:448614 !texture->IsImmutable()) {
8615 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:258616 GLenum internal_format;
8617 GLenum tex_type;
8618 texture->GetLevelType(target, level, &tex_type, &internal_format);
8619 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
8620 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:388621 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258622 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:158623 } else {
[email protected]c986af502013-08-14 01:04:448624 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158625 glTexSubImage2D(
8626 target, level, xoffset, yoffset, width, height, format, type, data);
8627 }
[email protected]370eaf12013-05-18 09:19:498628 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038629 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438630}
8631
[email protected]b493ee622011-04-13 23:52:008632error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358633 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388634 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008635 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448636 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008637 return error::kNoError;
8638
8639 GLenum target = static_cast<GLenum>(c.target);
8640 GLint level = static_cast<GLint>(c.level);
8641 GLint xoffset = static_cast<GLint>(c.xoffset);
8642 GLint yoffset = static_cast<GLint>(c.yoffset);
8643 GLsizei width = static_cast<GLsizei>(c.width);
8644 GLsizei height = static_cast<GLsizei>(c.height);
8645 GLenum format = static_cast<GLenum>(c.format);
8646 GLenum type = static_cast<GLenum>(c.type);
8647 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348648 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248649 width, height, format, type, state_.unpack_alignment, &data_size,
8650 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008651 return error::kOutOfBounds;
8652 }
8653 const void* pixels = GetSharedMemoryAs<const void*>(
8654 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038655 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008656 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008657}
8658
[email protected]f7a64ee2010-02-01 22:24:148659error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358660 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368661 GLuint index = static_cast<GLuint>(c.index);
8662 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358663 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258664 Result* result = GetSharedMemoryAs<Result*>(
8665 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368666 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148667 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368668 }
[email protected]07d0cc82010-02-17 04:51:408669 // Check that the client initialized the result.
8670 if (result->size != 0) {
8671 return error::kInvalidArguments;
8672 }
[email protected]9438b012010-06-15 22:55:058673 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518674 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8675 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148676 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368677 }
[email protected]3916c97e2010-02-25 03:20:508678 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518679 LOCAL_SET_GL_ERROR(
8680 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148681 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368682 }
[email protected]0bfd9882010-02-05 23:02:258683 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088684 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358685 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148686 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328687}
8688
[email protected]f7b85372010-02-03 01:11:378689bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428690 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378691 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128692 error::Error* error, GLint* real_location,
8693 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108694 DCHECK(error);
8695 DCHECK(service_id);
8696 DCHECK(result_pointer);
8697 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128698 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378699 *error = error::kNoError;
8700 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258701 SizedResult<GLint>* result;
8702 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8703 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8704 if (!result) {
[email protected]f7b85372010-02-03 01:11:378705 *error = error::kOutOfBounds;
8706 return false;
8707 }
[email protected]0bfd9882010-02-05 23:02:258708 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378709 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258710 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428711 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8712 if (!program) {
[email protected]ae51d192010-04-27 00:48:038713 return false;
8714 }
[email protected]df37b9932013-03-08 05:21:428715 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378716 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518717 LOCAL_SET_GL_ERROR(
8718 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378719 return false;
8720 }
[email protected]df37b9932013-03-08 05:21:428721 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368722 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358723 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428724 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128725 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368726 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378727 // No such location.
[email protected]ab09b612013-03-11 22:11:518728 LOCAL_SET_GL_ERROR(
8729 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378730 return false;
8731 }
[email protected]43c2f1f2011-03-25 18:35:368732 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508733 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378734 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518735 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378736 return false;
8737 }
[email protected]0bfd9882010-02-05 23:02:258738 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8739 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8740 if (!result) {
[email protected]f7b85372010-02-03 01:11:378741 *error = error::kOutOfBounds;
8742 return false;
8743 }
[email protected]0bfd9882010-02-05 23:02:258744 result->size = size;
[email protected]939e7362010-05-13 20:49:108745 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378746 return true;
8747}
8748
[email protected]f7a64ee2010-02-01 22:24:148749error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358750 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378751 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338752 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378753 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108754 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128755 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378756 Error error;
[email protected]0bfd9882010-02-05 23:02:258757 void* result;
[email protected]f7b85372010-02-03 01:11:378758 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128759 program, fake_location, c.params_shm_id, c.params_shm_offset,
8760 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258761 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128762 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358763 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378764 }
8765 return error;
[email protected]96449d2c2009-11-25 00:01:328766}
8767
[email protected]f7a64ee2010-02-01 22:24:148768error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358769 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378770 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338771 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378772 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128773 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378774 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358775 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108776 Result* result;
8777 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378778 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128779 program, fake_location, c.params_shm_id, c.params_shm_offset,
8780 &error, &real_location, &service_id,
8781 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108782 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8783 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8784 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558785 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128786 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108787 GLfloat* dst = result->GetData();
8788 for (GLsizei ii = 0; ii < num_values; ++ii) {
8789 dst[ii] = (temp[ii] != 0);
8790 }
8791 } else {
[email protected]1b0a6752012-02-22 03:44:128792 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108793 }
[email protected]f7b85372010-02-03 01:11:378794 }
8795 return error;
[email protected]96449d2c2009-11-25 00:01:328796}
8797
[email protected]f7a64ee2010-02-01 22:24:148798error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358799 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258800 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8801 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358802 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258803 Result* result = GetSharedMemoryAs<Result*>(
8804 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8805 if (!result) {
8806 return error::kOutOfBounds;
8807 }
[email protected]07d0cc82010-02-17 04:51:408808 // Check that the client initialized the result.
8809 if (result->success != 0) {
8810 return error::kInvalidArguments;
8811 }
[email protected]9438b012010-06-15 22:55:058812 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518813 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538814 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298815 return error::kNoError;
8816 }
[email protected]9438b012010-06-15 22:55:058817 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518818 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538819 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298820 return error::kNoError;
8821 }
8822
8823 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408824
[email protected]46c86752013-05-21 05:08:398825 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:408826 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218827 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408828
8829 result->min_range = range[0];
8830 result->max_range = range[1];
8831 result->precision = precision;
8832
[email protected]f7a64ee2010-02-01 22:24:148833 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328834}
8835
[email protected]f7a64ee2010-02-01 22:24:148836error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358837 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258838 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428839 GLuint program_id = static_cast<GLuint>(c.program);
8840 Program* program = GetProgramInfoNotShader(
8841 program_id, "glGetAttachedShaders");
8842 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258843 return error::kNoError;
8844 }
[email protected]ed9f9cd2013-02-27 21:12:358845 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258846 uint32 max_count = Result::ComputeMaxResults(result_size);
8847 Result* result = GetSharedMemoryAs<Result*>(
8848 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8849 if (!result) {
8850 return error::kOutOfBounds;
8851 }
[email protected]07d0cc82010-02-17 04:51:408852 // Check that the client initialized the result.
8853 if (result->size != 0) {
8854 return error::kInvalidArguments;
8855 }
[email protected]0bfd9882010-02-05 23:02:258856 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038857 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428858 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258859 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038860 if (!shader_manager()->GetClientId(result->GetData()[ii],
8861 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258862 NOTREACHED();
8863 return error::kGenericError;
8864 }
8865 }
8866 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148867 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328868}
8869
[email protected]f7a64ee2010-02-01 22:24:148870error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358871 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428872 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258873 GLuint index = c.index;
8874 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358875 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258876 Result* result = GetSharedMemoryAs<Result*>(
8877 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8878 if (!result) {
8879 return error::kOutOfBounds;
8880 }
[email protected]07d0cc82010-02-17 04:51:408881 // Check that the client initialized the result.
8882 if (result->success != 0) {
8883 return error::kInvalidArguments;
8884 }
[email protected]df37b9932013-03-08 05:21:428885 Program* program = GetProgramInfoNotShader(
8886 program_id, "glGetActiveUniform");
8887 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258888 return error::kNoError;
8889 }
[email protected]ed9f9cd2013-02-27 21:12:358890 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428891 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258892 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518893 LOCAL_SET_GL_ERROR(
8894 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258895 return error::kNoError;
8896 }
8897 result->success = 1; // true.
8898 result->size = uniform_info->size;
8899 result->type = uniform_info->type;
8900 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298901 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148902 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328903}
8904
[email protected]f7a64ee2010-02-01 22:24:148905error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358906 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428907 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258908 GLuint index = c.index;
8909 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358910 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258911 Result* result = GetSharedMemoryAs<Result*>(
8912 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8913 if (!result) {
8914 return error::kOutOfBounds;
8915 }
[email protected]07d0cc82010-02-17 04:51:408916 // Check that the client initialized the result.
8917 if (result->success != 0) {
8918 return error::kInvalidArguments;
8919 }
[email protected]df37b9932013-03-08 05:21:428920 Program* program = GetProgramInfoNotShader(
8921 program_id, "glGetActiveAttrib");
8922 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258923 return error::kNoError;
8924 }
[email protected]ed9f9cd2013-02-27 21:12:358925 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428926 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258927 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518928 LOCAL_SET_GL_ERROR(
8929 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258930 return error::kNoError;
8931 }
8932 result->success = 1; // true.
8933 result->size = attrib_info->size;
8934 result->type = attrib_info->type;
8935 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298936 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148937 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328938}
8939
[email protected]b273e432010-04-12 17:23:588940error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358941 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588942#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518943 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588944 return error::kNoError;
8945#else
8946 GLsizei n = static_cast<GLsizei>(c.n);
8947 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518948 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588949 return error::kNoError;
8950 }
8951 GLsizei length = static_cast<GLsizei>(c.length);
8952 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518953 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588954 return error::kNoError;
8955 }
8956 uint32 data_size;
8957 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8958 return error::kOutOfBounds;
8959 }
8960 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8961 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8962 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8963 const void* binary = GetSharedMemoryAs<const void*>(
8964 c.binary_shm_id, c.binary_shm_offset, length);
8965 if (shaders == NULL || binary == NULL) {
8966 return error::kOutOfBounds;
8967 }
8968 scoped_array<GLuint> service_ids(new GLuint[n]);
8969 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428970 Shader* shader = GetShader(shaders[ii]);
8971 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518972 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588973 return error::kNoError;
8974 }
[email protected]df37b9932013-03-08 05:21:428975 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588976 }
8977 // TODO(gman): call glShaderBinary
8978 return error::kNoError;
8979#endif
8980}
8981
[email protected]6d792ee12013-05-15 00:40:568982void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:498983 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088984
[email protected]64ace852011-05-19 21:49:498985 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428986 // TRACE_EVENT for gpu tests:
8987 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428988 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428989 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8990 "width", (is_offscreen ? offscreen_size_.width() :
8991 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:568992 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:498993 "offscreen", is_offscreen,
8994 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:158995 {
8996 TRACE_EVENT_SYNTHETIC_DELAY("gpu.SwapBuffers");
8997 }
8998
[email protected]8f9b8dd2013-09-12 18:05:138999 bool is_tracing;
9000 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9001 &is_tracing);
9002 if (is_tracing) {
9003 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9004 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9005 is_offscreen ? offscreen_size_ : surface_->GetSize());
9006 }
9007
[email protected]6217d392010-03-25 22:08:359008 // If offscreen then don't actually SwapBuffers to the display. Just copy
9009 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499010 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319011 TRACE_EVENT2("gpu", "Offscreen",
9012 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539013 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9014 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9015 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9016 // fix this.
[email protected]62e155e2012-10-23 22:43:159017 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539018 offscreen_saved_frame_buffer_->Create();
9019 glFinish();
9020 }
9021
9022 // Allocate the offscreen saved color texture.
9023 DCHECK(offscreen_saved_color_format_);
9024 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099025 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539026
9027 offscreen_saved_frame_buffer_->AttachRenderTexture(
9028 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059029 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9030 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9031 GL_FRAMEBUFFER_COMPLETE) {
9032 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9033 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569034 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9035 return;
[email protected]f0cfe752013-01-14 01:09:059036 }
[email protected]1fb8c482011-08-31 01:01:539037
[email protected]f0cfe752013-01-14 01:09:059038 // Clear the offscreen color texture.
9039 // TODO(piman): Is this still necessary?
9040 {
9041 ScopedFrameBufferBinder binder(this,
9042 offscreen_saved_frame_buffer_->id());
9043 glClearColor(0, 0, 0, 0);
9044 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9045 glDisable(GL_SCISSOR_TEST);
9046 glClear(GL_COLOR_BUFFER_BIT);
9047 RestoreClearState();
9048 }
[email protected]1fb8c482011-08-31 01:01:539049 }
9050
9051 UpdateParentTextureInfo();
9052 }
9053
[email protected]f0cfe752013-01-14 01:09:059054 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:569055 return;
[email protected]ab09b612013-03-11 22:11:519056 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:309057 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:359058
[email protected]34ff8b0c2010-10-01 20:06:029059 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:139060 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:279061 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:489062 } else {
[email protected]069944672012-04-25 20:52:239063 ScopedFrameBufferBinder binder(this,
9064 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:139065
[email protected]069944672012-04-25 20:52:239066 if (offscreen_target_buffer_preserved_) {
9067 // Copy the target frame buffer to the saved offscreen texture.
9068 offscreen_saved_color_texture_->Copy(
9069 offscreen_saved_color_texture_->size(),
9070 offscreen_saved_color_format_);
9071 } else {
9072 // Flip the textures in the parent context via the texture manager.
9073 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499074 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239075 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569076
[email protected]069944672012-04-25 20:52:239077 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9078 offscreen_target_frame_buffer_->AttachRenderTexture(
9079 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489080 }
[email protected]069944672012-04-25 20:52:239081
9082 // Ensure the side effects of the copy are visible to the parent
9083 // context. There is no need to do this for ANGLE because it uses a
9084 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:189085 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:239086 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399087 }
[email protected]6217d392010-03-25 22:08:359088 } else {
[email protected]f62a5ab2011-05-23 20:34:159089 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019090 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569091 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019092 }
[email protected]6217d392010-03-25 22:08:359093 }
[email protected]6217d392010-03-25 22:08:359094}
9095
[email protected]d4239852011-08-12 04:51:229096error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359097 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:189098 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289099 if (!bucket || bucket->size() == 0) {
9100 return error::kInvalidArguments;
9101 }
[email protected]ed9f9cd2013-02-27 21:12:359102 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189103 Result* result = GetSharedMemoryAs<Result*>(
9104 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9105 if (!result) {
9106 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109107 }
[email protected]b1d2dcb2010-05-17 19:24:189108 // Check that the client initialized the result.
9109 if (*result != 0) {
9110 return error::kInvalidArguments;
9111 }
9112 std::string feature_str;
9113 if (!bucket->GetAsString(&feature_str)) {
9114 return error::kInvalidArguments;
9115 }
9116
9117 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229118 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189119 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229120 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409121 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9122 // TODO(gman): decide how to remove the need for this const_cast.
9123 // I could make validators_ non const but that seems bad as this is the only
9124 // place it is needed. I could make some special friend class of validators
9125 // just to allow this to set them. That seems silly. I could refactor this
9126 // code to use the extension mechanism or the initialization attributes to
9127 // turn this feature on. Given that the only real point of this is to make
9128 // the conformance tests pass and given that there is lots of real work that
9129 // needs to be done it seems like refactoring for one to one of those
9130 // methods is a very low priority.
9131 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049132 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9133 force_webgl_glsl_validation_ = true;
9134 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189135 } else {
9136 return error::kNoError;
9137 }
9138
9139 *result = 1; // true.
9140 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109141}
9142
[email protected]c2f8c8402010-12-06 18:07:249143error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9144 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359145 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249146 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359147 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199148 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249149 bucket->SetFromString(info->extensions().c_str());
9150 return error::kNoError;
9151}
9152
9153error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359154 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249155 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289156 if (!bucket || bucket->size() == 0) {
9157 return error::kInvalidArguments;
9158 }
[email protected]c2f8c8402010-12-06 18:07:249159 std::string feature_str;
9160 if (!bucket->GetAsString(&feature_str)) {
9161 return error::kInvalidArguments;
9162 }
9163
[email protected]4b7eba92013-01-08 02:23:569164 bool desire_webgl_glsl_validation =
9165 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9166 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499167 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139168 bool desire_draw_buffers = false;
[email protected]4b7eba92013-01-08 02:23:569169 if (force_webgl_glsl_validation_) {
9170 desire_standard_derivatives =
9171 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499172 desire_frag_depth =
9173 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139174 desire_draw_buffers =
9175 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049176 }
9177
[email protected]4b7eba92013-01-08 02:23:569178 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499179 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139180 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9181 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499182 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9183 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9184 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139185 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]c2f8c8402010-12-06 18:07:249186 InitializeShaderTranslator();
9187 }
9188
[email protected]302ce6d2011-07-07 23:28:119189 UpdateCapabilities();
9190
[email protected]c2f8c8402010-12-06 18:07:249191 return error::kNoError;
9192}
9193
[email protected]372e0412011-06-28 16:08:569194error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359195 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:569196 GLuint count = c.count;
9197 uint32 pnames_size;
9198 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9199 return error::kOutOfBounds;
9200 }
9201 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9202 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9203 if (pnames == NULL) {
9204 return error::kOutOfBounds;
9205 }
9206
9207 // We have to copy them since we use them twice so the client
9208 // can't change them between the time we validate them and the time we use
9209 // them.
[email protected]40d90a22013-04-09 03:39:559210 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:569211 memcpy(enums.get(), pnames, pnames_size);
9212
9213 // Count up the space needed for the result.
9214 uint32 num_results = 0;
9215 for (GLuint ii = 0; ii < count; ++ii) {
9216 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9217 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519218 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]caa13ed2014-02-17 11:29:209219 "glGetMultipleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569220 return error::kNoError;
9221 }
9222 // Num will never be more than 4.
9223 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479224 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569225 return error::kOutOfBounds;
9226 }
9227 }
9228
9229 uint32 result_size = 0;
9230 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9231 return error::kOutOfBounds;
9232 }
9233
9234 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519235 LOCAL_SET_GL_ERROR(
9236 GL_INVALID_VALUE,
[email protected]caa13ed2014-02-17 11:29:209237 "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569238 return error::kNoError;
9239 }
9240
9241 GLint* results = GetSharedMemoryAs<GLint*>(
9242 c.results_shm_id, c.results_shm_offset, result_size);
9243 if (results == NULL) {
9244 return error::kOutOfBounds;
9245 }
9246
9247 // Check the results have been cleared in case the context was lost.
9248 for (uint32 ii = 0; ii < num_results; ++ii) {
9249 if (results[ii]) {
9250 return error::kInvalidArguments;
9251 }
9252 }
9253
9254 // Get each result.
9255 GLint* start = results;
9256 for (GLuint ii = 0; ii < count; ++ii) {
9257 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269258 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539259 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:489260 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:569261 }
9262 results += num_written;
9263 }
9264
9265 // Just to verify. Should this be a DCHECK?
9266 if (static_cast<uint32>(results - start) != num_results) {
9267 return error::kOutOfBounds;
9268 }
9269
9270 return error::kNoError;
9271}
9272
[email protected]2318d342011-07-11 22:27:429273error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359274 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:429275 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429276 uint32 bucket_id = c.bucket_id;
9277 Bucket* bucket = CreateBucket(bucket_id);
9278 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429279 Program* program = NULL;
9280 program = GetProgram(program_id);
9281 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469282 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429283 }
[email protected]df37b9932013-03-08 05:21:429284 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429285 return error::kNoError;
9286}
9287
[email protected]38d139d2011-07-14 00:38:439288error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9289 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439290 case GL_NO_ERROR:
9291 // TODO(kbr): improve the precision of the error code in this case.
9292 // Consider delegating to context for error code if MakeCurrent fails.
9293 return error::kUnknown;
9294 case GL_GUILTY_CONTEXT_RESET_ARB:
9295 return error::kGuilty;
9296 case GL_INNOCENT_CONTEXT_RESET_ARB:
9297 return error::kInnocent;
9298 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9299 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439300 }
9301
9302 NOTREACHED();
9303 return error::kUnknown;
9304}
9305
9306bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099307 if (reset_status_ != GL_NO_ERROR) {
9308 return true;
9309 }
[email protected]706b69f2012-07-27 04:59:309310 if (context_->WasAllocatedUsingRobustnessExtension()) {
9311 GLenum status = GL_NO_ERROR;
9312 if (has_robustness_extension_)
9313 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439314 if (status != GL_NO_ERROR) {
9315 // The graphics card was reset. Signal a lost context to the application.
9316 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229317 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439318 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099319 << " context lost via ARB/EXT_robustness. Reset status = "
9320 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439321 return true;
9322 }
9323 }
9324 return false;
9325}
9326
[email protected]93a7d98f2013-07-11 00:04:229327bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9328 return WasContextLost() && reset_by_robustness_extension_;
9329}
9330
[email protected]c4485aad62012-12-17 10:19:099331void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9332 // Only loses the context once.
9333 if (reset_status_ != GL_NO_ERROR) {
9334 return;
9335 }
9336
9337 // Marks this context as lost.
9338 reset_status_ = reset_status;
9339 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099340}
9341
9342error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359343 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099344 GLenum current = static_cast<GLenum>(c.current);
9345 GLenum other = static_cast<GLenum>(c.other);
9346 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519347 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9348 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099349 }
9350 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519351 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099352 }
9353 group_->LoseContexts(other);
9354 reset_status_ = current;
9355 current_decoder_error_ = error::kLostContext;
9356 return error::kLostContext;
9357}
9358
[email protected]b096d032013-03-08 03:08:019359error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9360 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9361 return error::kUnknownCommand;
9362}
9363
[email protected]840a7e462013-02-27 01:29:519364error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359365 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]00c2cf92014-03-14 00:08:379366 group_->mailbox_manager()->PullTextureUpdates();
[email protected]840a7e462013-02-27 01:29:519367 if (wait_sync_point_callback_.is_null())
9368 return error::kNoError;
9369
9370 return wait_sync_point_callback_.Run(c.sync_point) ?
9371 error::kNoError : error::kDeferCommandUntilLater;
9372}
9373
[email protected]5dfc457b2013-12-13 11:13:079374error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
9375 uint32 immediate_data_size, const cmds::DiscardBackbufferCHROMIUM& c) {
9376 if (surface_->DeferDraws())
9377 return error::kDeferCommandUntilLater;
9378 if (!surface_->SetBackbufferAllocation(false))
9379 return error::kLostContext;
9380 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9381 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9382 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9383 return error::kNoError;
9384}
9385
[email protected]882ba1e22012-03-08 19:02:539386bool GLES2DecoderImpl::GenQueriesEXTHelper(
9387 GLsizei n, const GLuint* client_ids) {
9388 for (GLsizei ii = 0; ii < n; ++ii) {
9389 if (query_manager_->GetQuery(client_ids[ii])) {
9390 return false;
9391 }
9392 }
[email protected]c45f1972012-03-14 07:27:369393 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539394 return true;
9395}
9396
9397void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9398 GLsizei n, const GLuint* client_ids) {
9399 for (GLsizei ii = 0; ii < n; ++ii) {
9400 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9401 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139402 ContextState::QueryMap::iterator it =
9403 state_.current_queries.find(query->target());
9404 if (it != state_.current_queries.end())
9405 state_.current_queries.erase(it);
9406
[email protected]c45f1972012-03-14 07:27:369407 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539408 query_manager_->RemoveQuery(client_ids[ii]);
9409 }
9410 }
9411}
9412
[email protected]22e3f552012-03-13 01:54:199413bool GLES2DecoderImpl::ProcessPendingQueries() {
9414 if (query_manager_.get() == NULL) {
9415 return false;
9416 }
[email protected]c45f1972012-03-14 07:27:369417 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199418 current_decoder_error_ = error::kOutOfBounds;
9419 }
9420 return query_manager_->HavePendingQueries();
9421}
9422
[email protected]5a36dc132013-07-23 23:17:559423// Note that if there are no pending readpixels right now,
9424// this function will call the callback immediately.
9425void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9426 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9427 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9428 } else {
9429 callback.Run();
9430 }
9431}
9432
9433void GLES2DecoderImpl::ProcessPendingReadPixels() {
9434 while (!pending_readpixel_fences_.empty() &&
9435 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9436 std::vector<base::Closure> callbacks =
9437 pending_readpixel_fences_.front()->callbacks;
9438 pending_readpixel_fences_.pop();
9439 for (size_t i = 0; i < callbacks.size(); i++) {
9440 callbacks[i].Run();
9441 }
9442 }
9443}
9444
[email protected]2b1767cf2013-03-16 09:25:059445bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559446 return !pending_readpixel_fences_.empty() ||
9447 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059448}
9449
9450void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559451 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:489452 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059453 return;
[email protected]b68b100752013-06-05 08:34:489454 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059455 ProcessFinishedAsyncTransfers();
9456}
9457
[email protected]882ba1e22012-03-08 19:02:539458error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359459 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539460 GLenum target = static_cast<GLenum>(c.target);
9461 GLuint client_id = static_cast<GLuint>(c.id);
9462 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9463 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9464
[email protected]c45f1972012-03-14 07:27:369465 switch (target) {
9466 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559467 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:319468 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9469 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009470 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369471 break;
9472 default:
[email protected]62e155e2012-10-23 22:43:159473 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519474 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009475 GL_INVALID_OPERATION, "glBeginQueryEXT",
9476 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369477 return error::kNoError;
9478 }
9479 break;
[email protected]882ba1e22012-03-08 19:02:539480 }
9481
[email protected]8ebd46c2014-01-08 12:06:139482 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519483 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439484 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539485 return error::kNoError;
9486 }
9487
9488 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519489 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539490 return error::kNoError;
9491 }
9492
9493 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9494 if (!query) {
[email protected]c45f1972012-03-14 07:27:369495 // TODO(gman): Decide if we need this check.
9496 //
[email protected]882ba1e22012-03-08 19:02:539497 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369498 //
9499 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9500 // for all Query ids but from the POV of the command buffer service maybe
9501 // you don't.
9502 //
9503 // The client can enforce this. I don't think the service cares.
9504 //
9505 // IdAllocatorInterface* id_allocator =
9506 // group_->GetIdAllocator(id_namespaces::kQueries);
9507 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519508 // LOCAL_SET_GL_ERROR(
9509 // GL_INVALID_OPERATION,
9510 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369511 // return error::kNoError;
9512 // }
9513 query = query_manager_->CreateQuery(
9514 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539515 }
9516
[email protected]c45f1972012-03-14 07:27:369517 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519518 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439519 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539520 return error::kNoError;
9521 } else if (query->shm_id() != sync_shm_id ||
9522 query->shm_offset() != sync_shm_offset) {
9523 DLOG(ERROR) << "Shared memory used by query not the same as before";
9524 return error::kInvalidArguments;
9525 }
9526
[email protected]c45f1972012-03-14 07:27:369527 if (!query_manager_->BeginQuery(query)) {
9528 return error::kOutOfBounds;
9529 }
[email protected]882ba1e22012-03-08 19:02:539530
[email protected]8ebd46c2014-01-08 12:06:139531 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:539532 return error::kNoError;
9533}
9534
9535error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359536 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539537 GLenum target = static_cast<GLenum>(c.target);
9538 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:139539 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:539540
[email protected]8ebd46c2014-01-08 12:06:139541 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519542 LOCAL_SET_GL_ERROR(
9543 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539544 return error::kNoError;
9545 }
[email protected]882ba1e22012-03-08 19:02:539546
[email protected]8ebd46c2014-01-08 12:06:139547 QueryManager::Query* query = it->second.get();
9548 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369549 return error::kOutOfBounds;
9550 }
9551
[email protected]fe8d73c2013-02-16 22:37:329552 query_manager_->ProcessPendingTransferQueries();
9553
[email protected]8ebd46c2014-01-08 12:06:139554 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:539555 return error::kNoError;
9556}
9557
[email protected]944b62f32012-09-27 02:20:469558bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9559 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469560 for (GLsizei ii = 0; ii < n; ++ii) {
9561 if (GetVertexAttribManager(client_ids[ii])) {
9562 return false;
9563 }
9564 }
[email protected]ab4fd7282012-10-12 16:25:579565
[email protected]62e155e2012-10-23 22:43:159566 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579567 // Emulated VAO
9568 for (GLsizei ii = 0; ii < n; ++ii) {
9569 CreateVertexAttribManager(client_ids[ii], 0);
9570 }
9571 } else {
[email protected]40d90a22013-04-09 03:39:559572 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579573
9574 glGenVertexArraysOES(n, service_ids.get());
9575 for (GLsizei ii = 0; ii < n; ++ii) {
9576 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9577 }
[email protected]944b62f32012-09-27 02:20:469578 }
[email protected]ab4fd7282012-10-12 16:25:579579
[email protected]944b62f32012-09-27 02:20:469580 return true;
9581}
9582
9583void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9584 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469585 for (GLsizei ii = 0; ii < n; ++ii) {
9586 VertexAttribManager* vao =
9587 GetVertexAttribManager(client_ids[ii]);
9588 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119589 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]e259eb412012-10-13 05:47:249590 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469591 }
9592 RemoveVertexAttribManager(client_ids[ii]);
9593 }
9594 }
9595}
9596
9597void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469598 VertexAttribManager* vao = NULL;
9599 GLuint service_id = 0;
9600 if (client_id != 0) {
9601 vao = GetVertexAttribManager(client_id);
9602 if (!vao) {
9603 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9604 // only allows names that have been previously generated. As such, we do
9605 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519606 LOCAL_SET_GL_ERROR(
9607 GL_INVALID_OPERATION,
9608 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469609 current_decoder_error_ = error::kNoError;
9610 return;
9611 } else {
9612 service_id = vao->service_id();
9613 }
[email protected]944b62f32012-09-27 02:20:469614 } else {
[email protected]7cd76fd2013-06-02 21:11:119615 vao = default_vertex_attrib_manager_.get();
[email protected]944b62f32012-09-27 02:20:469616 }
9617
[email protected]ab4fd7282012-10-12 16:25:579618 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:119619 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:249620 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159621 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579622 EmulateVertexArrayState();
9623 } else {
9624 glBindVertexArrayOES(service_id);
9625 }
9626 }
9627}
9628
9629// Used when OES_vertex_array_object isn't natively supported
9630void GLES2DecoderImpl::EmulateVertexArrayState() {
9631 // Setup the Vertex attribute state
9632 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9633 RestoreStateForAttrib(vv);
9634 }
9635
9636 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219637 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249638 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579639 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9640 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469641}
9642
9643bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469644 const VertexAttribManager* vao =
9645 GetVertexAttribManager(client_id);
9646 return vao && vao->IsValid() && !vao->IsDeleted();
9647}
9648
[email protected]e51bdf32011-11-23 22:21:469649#if defined(OS_MACOSX)
9650void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9651 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9652 texture_id);
9653 if (it != texture_to_io_surface_map_.end()) {
9654 // Found a previous IOSurface bound to this texture; release it.
9655 CFTypeRef surface = it->second;
9656 CFRelease(surface);
9657 texture_to_io_surface_map_.erase(it);
9658 }
9659}
9660#endif
9661
9662void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9663 GLenum target, GLsizei width, GLsizei height,
9664 GLuint io_surface_id, GLuint plane) {
9665#if defined(OS_MACOSX)
9666 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519667 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439668 GL_INVALID_OPERATION,
9669 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469670 return;
9671 }
9672
9673 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9674 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519675 LOCAL_SET_GL_ERROR(
9676 GL_INVALID_OPERATION,
9677 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469678 return;
9679 }
9680
9681 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9682 // This might be supported in the future, and if we could require
9683 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9684 // could delete a lot of code. For now, perform strict validation so we
9685 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519686 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469687 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439688 "glTexImageIOSurface2DCHROMIUM",
9689 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469690 return;
9691 }
9692
[email protected]09d50362012-10-18 20:54:379693 // Default target might be conceptually valid, but disallow it to avoid
9694 // accidents.
[email protected]c986af502013-08-14 01:04:449695 TextureRef* texture_ref =
9696 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:499697 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519698 LOCAL_SET_GL_ERROR(
9699 GL_INVALID_OPERATION,
9700 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469701 return;
9702 }
[email protected]e51bdf32011-11-23 22:21:469703
9704 // Look up the new IOSurface. Note that because of asynchrony
9705 // between processes this might fail; during live resizing the
9706 // plugin process might allocate and release an IOSurface before
9707 // this process gets a chance to look it up. Hold on to any old
9708 // IOSurface in this case.
9709 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9710 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519711 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439712 GL_INVALID_OPERATION,
9713 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469714 return;
9715 }
9716
9717 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499718 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469719
9720 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9721 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499722 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469723
9724 CGLContextObj context =
9725 static_cast<CGLContextObj>(context_->GetHandle());
9726
9727 CGLError err = surface_support->CGLTexImageIOSurface2D(
9728 context,
9729 target,
9730 GL_RGBA,
9731 width,
9732 height,
9733 GL_BGRA,
9734 GL_UNSIGNED_INT_8_8_8_8_REV,
9735 surface,
9736 plane);
9737
9738 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519739 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469740 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439741 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469742 return;
9743 }
9744
9745 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499746 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469747 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9748
9749#else
[email protected]ab09b612013-03-11 22:11:519750 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439751 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469752#endif
9753}
9754
[email protected]97dc7cbe2011-12-06 17:26:179755static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9756 switch (internalformat) {
9757 case GL_RGB565:
9758 return GL_RGB;
9759 case GL_RGBA4:
9760 return GL_RGBA;
9761 case GL_RGB5_A1:
9762 return GL_RGBA;
9763 case GL_RGB8_OES:
9764 return GL_RGB;
9765 case GL_RGBA8_OES:
9766 return GL_RGBA;
9767 case GL_LUMINANCE8_ALPHA8_EXT:
9768 return GL_LUMINANCE_ALPHA;
9769 case GL_LUMINANCE8_EXT:
9770 return GL_LUMINANCE;
9771 case GL_ALPHA8_EXT:
9772 return GL_ALPHA;
9773 case GL_RGBA32F_EXT:
9774 return GL_RGBA;
9775 case GL_RGB32F_EXT:
9776 return GL_RGB;
9777 case GL_ALPHA32F_EXT:
9778 return GL_ALPHA;
9779 case GL_LUMINANCE32F_EXT:
9780 return GL_LUMINANCE;
9781 case GL_LUMINANCE_ALPHA32F_EXT:
9782 return GL_LUMINANCE_ALPHA;
9783 case GL_RGBA16F_EXT:
9784 return GL_RGBA;
9785 case GL_RGB16F_EXT:
9786 return GL_RGB;
9787 case GL_ALPHA16F_EXT:
9788 return GL_ALPHA;
9789 case GL_LUMINANCE16F_EXT:
9790 return GL_LUMINANCE;
9791 case GL_LUMINANCE_ALPHA16F_EXT:
9792 return GL_LUMINANCE_ALPHA;
9793 case GL_BGRA8_EXT:
9794 return GL_BGRA_EXT;
9795 default:
9796 return GL_NONE;
9797 }
9798}
9799
[email protected]43410e92012-04-20 17:06:289800void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039801 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549802 GLenum internal_format, GLenum dest_type) {
[email protected]370eaf12013-05-18 09:19:499803 TextureRef* dest_texture_ref = GetTexture(dest_id);
9804 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289805
[email protected]370eaf12013-05-18 09:19:499806 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519807 LOCAL_SET_GL_ERROR(
9808 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289809 return;
9810 }
9811
9812 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519813 LOCAL_SET_GL_ERROR(
9814 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289815 return;
9816 }
9817
[email protected]370eaf12013-05-18 09:19:499818 Texture* source_texture = source_texture_ref->texture();
9819 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079820 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259821 (source_texture->target() != GL_TEXTURE_2D &&
9822 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:009823 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9824 "glCopyTextureCHROMIUM",
9825 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039826 return;
9827 }
9828
[email protected]43410e92012-04-20 17:06:289829 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289830
[email protected]3e0dfd72014-02-21 06:28:419831 gfx::GLImage* image =
9832 source_texture->GetLevelImage(source_texture->target(), 0);
9833 if (image) {
[email protected]7bffe9e12014-01-27 23:02:559834 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:569835 source_width = size.width();
9836 source_height = size.height();
9837 if (source_width <= 0 || source_height <= 0) {
9838 LOCAL_SET_GL_ERROR(
9839 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:559840 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:569841 return;
9842 }
[email protected]3ecc1052013-09-26 08:59:009843 } else {
9844 if (!source_texture->GetLevelSize(
9845 source_texture->target(), 0, &source_width, &source_height)) {
9846 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9847 "glCopyTextureChromium",
9848 "source texture has no level 0");
9849 return;
9850 }
9851
9852 // Check that this type of texture is allowed.
9853 if (!texture_manager()->ValidForTarget(
9854 source_texture->target(), level, source_width, source_height, 1)) {
9855 LOCAL_SET_GL_ERROR(
9856 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
9857 return;
9858 }
[email protected]377976552013-05-14 23:32:569859 }
9860
[email protected]04b5b37d2014-02-07 02:11:519861 // Clear the source texture if necessary.
9862 if (!texture_manager()->ClearTextureLevel(
9863 this, source_texture_ref, source_texture->target(), 0)) {
9864 LOCAL_SET_GL_ERROR(
9865 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
9866 return;
9867 }
9868
[email protected]cf6b8f62012-05-25 21:43:379869 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9870 // needed because it takes 10s of milliseconds to initialize.
9871 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519872 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379873 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279874 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379875 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519876 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379877 return;
9878 }
9879
[email protected]a4a6bdd12013-04-19 20:46:549880 GLenum dest_type_previous;
[email protected]0a1e9ad2012-05-04 21:13:039881 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079882 bool dest_level_defined = dest_texture->GetLevelSize(
9883 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289884
[email protected]0a1e9ad2012-05-04 21:13:039885 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:549886 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:079887 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039888 }
9889
9890 // Resize the destination texture to the dimensions of the source texture.
9891 if (!dest_level_defined || dest_width != source_width ||
9892 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:549893 dest_internal_format != internal_format ||
9894 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:289895 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519896 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079897 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:389898 glTexImage2D(
[email protected]43410e92012-04-20 17:06:289899 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039900 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519901 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039902 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:029903 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:289904 return;
[email protected]0a1e9ad2012-05-04 21:13:039905 }
[email protected]43410e92012-04-20 17:06:289906
9907 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499908 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039909 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259910 } else {
[email protected]02965c22013-03-09 02:40:079911 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:499912 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289913 }
9914
[email protected]91c94eb2013-10-22 10:32:549915 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]00c2cf92014-03-14 00:08:379916 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:549917
[email protected]5394a4102013-04-18 05:41:379918 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9919 // before presenting.
9920 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9921 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9922 // instead of using default matrix crbug.com/226218.
9923 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9924 0.0f, 1.0f, 0.0f, 0.0f,
9925 0.0f, 0.0f, 1.0f, 0.0f,
9926 0.0f, 0.0f, 0.0f, 1.0f};
9927 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9928 this,
9929 source_texture->target(),
9930 dest_texture->target(),
9931 source_texture->service_id(),
9932 dest_texture->service_id(), level,
9933 source_width, source_height,
9934 unpack_flip_y_,
9935 unpack_premultiply_alpha_,
9936 unpack_unpremultiply_alpha_,
9937 default_matrix);
9938 } else {
9939 copy_texture_CHROMIUM_->DoCopyTexture(
9940 this,
9941 source_texture->target(),
9942 dest_texture->target(),
9943 source_texture->service_id(),
9944 dest_texture->service_id(), level,
9945 source_width, source_height,
9946 unpack_flip_y_,
9947 unpack_premultiply_alpha_,
9948 unpack_unpremultiply_alpha_);
9949 }
[email protected]91c94eb2013-10-22 10:32:549950
9951 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:289952}
9953
[email protected]97dc7cbe2011-12-06 17:26:179954static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9955 switch (internalformat) {
9956 case GL_RGB565:
9957 return GL_UNSIGNED_SHORT_5_6_5;
9958 case GL_RGBA4:
9959 return GL_UNSIGNED_SHORT_4_4_4_4;
9960 case GL_RGB5_A1:
9961 return GL_UNSIGNED_SHORT_5_5_5_1;
9962 case GL_RGB8_OES:
9963 return GL_UNSIGNED_BYTE;
9964 case GL_RGBA8_OES:
9965 return GL_UNSIGNED_BYTE;
9966 case GL_LUMINANCE8_ALPHA8_EXT:
9967 return GL_UNSIGNED_BYTE;
9968 case GL_LUMINANCE8_EXT:
9969 return GL_UNSIGNED_BYTE;
9970 case GL_ALPHA8_EXT:
9971 return GL_UNSIGNED_BYTE;
9972 case GL_RGBA32F_EXT:
9973 return GL_FLOAT;
9974 case GL_RGB32F_EXT:
9975 return GL_FLOAT;
9976 case GL_ALPHA32F_EXT:
9977 return GL_FLOAT;
9978 case GL_LUMINANCE32F_EXT:
9979 return GL_FLOAT;
9980 case GL_LUMINANCE_ALPHA32F_EXT:
9981 return GL_FLOAT;
9982 case GL_RGBA16F_EXT:
9983 return GL_HALF_FLOAT_OES;
9984 case GL_RGB16F_EXT:
9985 return GL_HALF_FLOAT_OES;
9986 case GL_ALPHA16F_EXT:
9987 return GL_HALF_FLOAT_OES;
9988 case GL_LUMINANCE16F_EXT:
9989 return GL_HALF_FLOAT_OES;
9990 case GL_LUMINANCE_ALPHA16F_EXT:
9991 return GL_HALF_FLOAT_OES;
9992 case GL_BGRA8_EXT:
9993 return GL_UNSIGNED_BYTE;
9994 default:
9995 return GL_NONE;
9996 }
9997}
9998
9999void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4410000 GLenum target,
10001 GLint levels,
10002 GLenum internal_format,
10003 GLsizei width,
10004 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:3810005 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:4110006 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0010007 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5110008 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310009 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1710010 return;
10011 }
[email protected]c986af502013-08-14 01:04:4410012 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10013 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910014 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110015 LOCAL_SET_GL_ERROR(
10016 GL_INVALID_OPERATION,
10017 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1710018 return;
10019 }
[email protected]370eaf12013-05-18 09:19:4910020 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710021 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410022 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1710023 }
[email protected]02965c22013-03-09 02:40:0710024 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5110025 LOCAL_SET_GL_ERROR(
10026 GL_INVALID_OPERATION,
10027 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1710028 return;
10029 }
[email protected]7989c9e2013-01-23 06:39:2610030
10031 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10032 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10033
10034 {
10035 GLsizei level_width = width;
10036 GLsizei level_height = height;
10037 uint32 estimated_size = 0;
10038 for (int ii = 0; ii < levels; ++ii) {
10039 uint32 level_size = 0;
10040 if (!GLES2Util::ComputeImageDataSizes(
10041 level_width, level_height, format, type, state_.unpack_alignment,
10042 &estimated_size, NULL, NULL) ||
10043 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110044 LOCAL_SET_GL_ERROR(
10045 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2610046 return;
10047 }
10048 level_width = std::max(1, level_width >> 1);
10049 level_height = std::max(1, level_height >> 1);
10050 }
10051 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110052 LOCAL_SET_GL_ERROR(
10053 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610054 return;
10055 }
10056 }
10057
[email protected]ab09b612013-03-11 22:11:5110058 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3810059 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5110060 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710061 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510062 GLsizei level_width = width;
10063 GLsizei level_height = height;
10064 for (int ii = 0; ii < levels; ++ii) {
10065 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910066 texture_ref, target, ii, format,
10067 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1510068 level_width = std::max(1, level_width >> 1);
10069 level_height = std::max(1, level_height >> 1);
10070 }
[email protected]02965c22013-03-09 02:40:0710071 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710072 }
[email protected]97dc7cbe2011-12-06 17:26:1710073}
[email protected]e51bdf32011-11-23 22:21:4610074
[email protected]78b514b2012-05-01 21:50:5910075error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510076 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]baed42c2013-10-01 05:06:3510077 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910078}
10079
10080void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710081 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210082 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210083 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710084 "mailbox[0]", static_cast<unsigned char>(data[0]));
10085
10086 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10087 DLOG_IF(ERROR, !mailbox.Verify()) << "ProduceTextureCHROMIUM was passed a "
10088 "mailbox that was not generated by "
10089 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210090
[email protected]c986af502013-08-14 01:04:4410091 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10092 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910093 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110094 LOCAL_SET_GL_ERROR(
10095 GL_INVALID_OPERATION,
10096 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910097 return;
10098 }
10099
[email protected]62e65f02013-05-29 22:28:1010100 Texture* produced = texture_manager()->Produce(texture_ref);
10101 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110102 LOCAL_SET_GL_ERROR(
10103 GL_INVALID_OPERATION,
10104 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:5910105 return;
10106 }
10107
[email protected]64ba52f2014-02-15 14:22:3710108 group_->mailbox_manager()->ProduceTexture(target, mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5910109}
10110
10111void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710112 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210113 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210114 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710115 "mailbox[0]", static_cast<unsigned char>(data[0]));
10116 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10117 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10118 "mailbox that was not generated by "
10119 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210120
[email protected]62e65f02013-05-29 22:28:1010121 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410122 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110123 if (!texture_ref.get()) {
10124 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10125 "glConsumeTextureCHROMIUM",
10126 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910127 return;
10128 }
[email protected]62e65f02013-05-29 22:28:1010129 GLuint client_id = texture_ref->client_id();
10130 if (!client_id) {
10131 LOCAL_SET_GL_ERROR(
10132 GL_INVALID_OPERATION,
10133 "glConsumeTextureCHROMIUM", "unknown texture for target");
10134 return;
10135 }
[email protected]64ba52f2014-02-15 14:22:3710136 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
[email protected]62e65f02013-05-29 22:28:1010137 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110138 LOCAL_SET_GL_ERROR(
10139 GL_INVALID_OPERATION,
10140 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910141 return;
10142 }
[email protected]62e65f02013-05-29 22:28:1010143 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110144 LOCAL_SET_GL_ERROR(
10145 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010146 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910147 return;
10148 }
[email protected]62e65f02013-05-29 22:28:1010149
10150 DeleteTexturesHelper(1, &client_id);
10151 texture_ref = texture_manager()->Consume(client_id, texture);
10152 glBindTexture(target, texture_ref->service_id());
10153
10154 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10155 unit.bind_target = target;
10156 switch (target) {
10157 case GL_TEXTURE_2D:
10158 unit.bound_texture_2d = texture_ref;
10159 break;
10160 case GL_TEXTURE_CUBE_MAP:
10161 unit.bound_texture_cube_map = texture_ref;
10162 break;
10163 case GL_TEXTURE_EXTERNAL_OES:
10164 unit.bound_texture_external_oes = texture_ref;
10165 break;
10166 case GL_TEXTURE_RECTANGLE_ARB:
10167 unit.bound_texture_rectangle_arb = texture_ref;
10168 break;
10169 default:
10170 NOTREACHED(); // Validation should prevent us getting here.
10171 break;
10172 }
[email protected]78b514b2012-05-01 21:50:5910173}
10174
[email protected]d2a0e1a2012-08-12 02:25:0110175void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10176 GLsizei length, const GLchar* marker) {
10177 if (!marker) {
10178 marker = "";
10179 }
10180 debug_marker_manager_.SetMarker(
10181 length ? std::string(marker, length) : std::string(marker));
10182}
10183
10184void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10185 GLsizei length, const GLchar* marker) {
10186 if (!marker) {
10187 marker = "";
10188 }
[email protected]cac16542014-01-15 17:53:5110189 std::string name = length ? std::string(marker, length) : std::string(marker);
10190 debug_marker_manager_.PushGroup(name);
10191 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110192}
10193
10194void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10195 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110196 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110197}
10198
[email protected]09d50362012-10-18 20:54:3710199void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10200 GLenum target, GLint image_id) {
10201 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710202
[email protected]bc26e8d2014-01-29 00:40:3010203 if (target == GL_TEXTURE_CUBE_MAP) {
10204 LOCAL_SET_GL_ERROR(
10205 GL_INVALID_ENUM,
10206 "glBindTexImage2DCHROMIUM", "invalid target");
10207 return;
10208 }
10209
[email protected]09d50362012-10-18 20:54:3710210 // Default target might be conceptually valid, but disallow it to avoid
10211 // accidents.
[email protected]c986af502013-08-14 01:04:4410212 TextureRef* texture_ref =
10213 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910214 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110215 LOCAL_SET_GL_ERROR(
10216 GL_INVALID_OPERATION,
10217 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710218 return;
10219 }
10220
10221 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10222 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110223 LOCAL_SET_GL_ERROR(
10224 GL_INVALID_OPERATION,
10225 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710226 return;
10227 }
10228
[email protected]b8160812013-04-09 00:41:0410229 {
10230 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010231 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610232 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410233 LOCAL_SET_GL_ERROR(
10234 GL_INVALID_OPERATION,
10235 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10236 return;
10237 }
[email protected]09d50362012-10-18 20:54:3710238 }
10239
10240 gfx::Size size = gl_image->GetSize();
10241 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910242 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710243 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910244 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710245}
10246
10247void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10248 GLenum target, GLint image_id) {
10249 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710250
10251 // Default target might be conceptually valid, but disallow it to avoid
10252 // accidents.
[email protected]c986af502013-08-14 01:04:4410253 TextureRef* texture_ref =
10254 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910255 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110256 LOCAL_SET_GL_ERROR(
10257 GL_INVALID_OPERATION,
10258 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710259 return;
10260 }
10261
10262 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10263 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110264 LOCAL_SET_GL_ERROR(
10265 GL_INVALID_OPERATION,
10266 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710267 return;
10268 }
10269
10270 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910271 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710272 return;
10273
[email protected]b8160812013-04-09 00:41:0410274 {
10275 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010276 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610277 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0410278 }
[email protected]09d50362012-10-18 20:54:3710279
10280 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910281 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710282 GL_RGBA, GL_UNSIGNED_BYTE, false);
10283}
[email protected]d2a0e1a2012-08-12 02:25:0110284
[email protected]94307712012-11-16 23:26:1110285error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510286 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110287 Bucket* bucket = GetBucket(c.bucket_id);
10288 if (!bucket || bucket->size() == 0) {
10289 return error::kInvalidArguments;
10290 }
10291 std::string command_name;
10292 if (!bucket->GetAsString(&command_name)) {
10293 return error::kInvalidArguments;
10294 }
[email protected]fb97b662013-02-20 23:02:1410295 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5110296 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5110297 LOCAL_SET_GL_ERROR(
10298 GL_INVALID_OPERATION,
10299 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410300 return error::kNoError;
10301 }
[email protected]94307712012-11-16 23:26:1110302 return error::kNoError;
10303}
10304
10305void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410306 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110307 LOCAL_SET_GL_ERROR(
10308 GL_INVALID_OPERATION,
10309 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110310 return;
10311 }
[email protected]fb97b662013-02-20 23:02:1410312 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5110313 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1110314}
10315
[email protected]2f143d482013-03-14 18:04:4910316void GLES2DecoderImpl::DoDrawBuffersEXT(
10317 GLsizei count, const GLenum* bufs) {
10318 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10319 LOCAL_SET_GL_ERROR(
10320 GL_INVALID_VALUE,
10321 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10322 return;
10323 }
10324
10325 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10326 if (framebuffer) {
10327 for (GLsizei i = 0; i < count; ++i) {
10328 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10329 bufs[i] != GL_NONE) {
10330 LOCAL_SET_GL_ERROR(
10331 GL_INVALID_OPERATION,
10332 "glDrawBuffersEXT",
10333 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10334 return;
10335 }
10336 }
10337 glDrawBuffersARB(count, bufs);
10338 framebuffer->SetDrawBuffers(count, bufs);
10339 } else { // backbuffer
10340 if (count > 1 ||
10341 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10342 LOCAL_SET_GL_ERROR(
10343 GL_INVALID_OPERATION,
10344 "glDrawBuffersEXT",
10345 "more than one buffer or bufs not GL_NONE or GL_BACK");
10346 return;
10347 }
10348 GLenum mapped_buf = bufs[0];
10349 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10350 bufs[0] == GL_BACK) {
10351 mapped_buf = GL_COLOR_ATTACHMENT0;
10352 }
10353 glDrawBuffersARB(count, &mapped_buf);
10354 group_->set_draw_buffer(bufs[0]);
10355 }
10356}
10357
[email protected]32145a92012-12-17 09:01:5910358bool GLES2DecoderImpl::ValidateAsyncTransfer(
10359 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710360 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910361 GLenum target,
10362 GLint level,
10363 const void * data) {
10364 // We only support async uploads to 2D textures for now.
10365 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110366 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910367 return false;
10368 }
10369 // We only support uploads to level zero for now.
10370 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110371 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910372 return false;
10373 }
10374 // A transfer buffer must be bound, even for asyncTexImage2D.
10375 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110376 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910377 return false;
10378 }
10379 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710380 if (!texture_ref ||
10381 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110382 LOCAL_SET_GL_ERROR(
10383 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910384 function_name, "transfer already in progress");
10385 return false;
10386 }
10387 return true;
10388}
10389
[email protected]e3c4a9ab2014-03-31 09:07:0210390base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
10391 uint32 async_upload_token,
10392 uint32 sync_data_shm_id,
10393 uint32 sync_data_shm_offset) {
10394 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
10395 if (!buffer || !buffer->GetDataAddress(sync_data_shm_offset,
10396 sizeof(AsyncUploadSync)))
10397 return base::Closure();
10398
10399 AsyncMemoryParams mem_params(buffer,
10400 sync_data_shm_offset,
10401 sizeof(AsyncUploadSync));
10402
10403 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
10404 new AsyncUploadTokenCompletionObserver(async_upload_token));
10405
10406 return base::Bind(
10407 &AsyncPixelTransferManager::AsyncNotifyCompletion,
10408 base::Unretained(GetAsyncPixelTransferManager()),
10409 mem_params,
10410 observer);
10411}
10412
[email protected]69023942012-11-30 19:57:1610413error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510414 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610415 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610416 GLenum target = static_cast<GLenum>(c.target);
10417 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4410418 // TODO(kloveless): Change HandleAsyncTexImage2DCHROMIUM command to use
10419 // unsigned integer for internalformat.
10420 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1610421 GLsizei width = static_cast<GLsizei>(c.width);
10422 GLsizei height = static_cast<GLsizei>(c.height);
10423 GLint border = static_cast<GLint>(c.border);
10424 GLenum format = static_cast<GLenum>(c.format);
10425 GLenum type = static_cast<GLenum>(c.type);
10426 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10427 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10428 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0210429 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
10430 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
10431 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10432
10433 base::ScopedClosureRunner scoped_completion_callback;
10434 if (async_upload_token) {
10435 base::Closure completion_closure =
10436 AsyncUploadTokenCompletionClosure(async_upload_token,
10437 sync_data_shm_id,
10438 sync_data_shm_offset);
10439 if (completion_closure.is_null())
10440 return error::kInvalidArguments;
10441
10442 scoped_completion_callback.Reset(completion_closure);
10443 }
[email protected]32145a92012-12-17 09:01:5910444
10445 // TODO(epenner): Move this and copies of this memory validation
10446 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610447 if (!GLES2Util::ComputeImageDataSizes(
10448 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10449 NULL)) {
10450 return error::kOutOfBounds;
10451 }
10452 const void* pixels = NULL;
10453 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10454 pixels = GetSharedMemoryAs<const void*>(
10455 pixels_shm_id, pixels_shm_offset, pixels_size);
10456 if (!pixels) {
10457 return error::kOutOfBounds;
10458 }
10459 }
10460
[email protected]c986af502013-08-14 01:04:4410461 TextureManager::DoTextImage2DArguments args = {
10462 target, level, internal_format, width, height, border, format, type,
10463 pixels, pixels_size};
10464 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5910465 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4410466 if (!texture_manager()->ValidateTexImage2D(
10467 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5910468 return error::kNoError;
10469 }
10470
10471 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910472 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910473 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710474 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910475 return error::kNoError;
10476
10477 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710478 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110479 LOCAL_SET_GL_ERROR(
10480 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910481 "glAsyncTexImage2DCHROMIUM", "already defined");
10482 return error::kNoError;
10483 }
10484
[email protected]7989c9e2013-01-23 06:39:2610485 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110486 LOCAL_SET_GL_ERROR(
10487 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610488 return error::kNoError;
10489 }
10490
[email protected]5b3a8e02013-03-13 05:36:4410491 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810492 AsyncTexImage2DParams tex_params = {
10493 target, level, static_cast<GLenum>(internal_format),
10494 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1210495 AsyncMemoryParams mem_params(
10496 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5910497
[email protected]5b3a8e02013-03-13 05:36:4410498 // Set up the async state if needed, and make the texture
10499 // immutable so the async state stays valid. The level info
10500 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1810501 AsyncPixelTransferDelegate* delegate =
10502 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
10503 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4410504 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910505
[email protected]896425e2013-06-12 17:27:1810506 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410507 tex_params,
10508 mem_params,
10509 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910510 // The callback is only invoked if the transfer delegate still
10511 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410512 // ownership that both of these pointers are valid.
10513 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910514 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410515 tex_params));
[email protected]f598f422012-12-07 08:30:0310516 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610517}
10518
10519error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510520 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610521 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610522 GLenum target = static_cast<GLenum>(c.target);
10523 GLint level = static_cast<GLint>(c.level);
10524 GLint xoffset = static_cast<GLint>(c.xoffset);
10525 GLint yoffset = static_cast<GLint>(c.yoffset);
10526 GLsizei width = static_cast<GLsizei>(c.width);
10527 GLsizei height = static_cast<GLsizei>(c.height);
10528 GLenum format = static_cast<GLenum>(c.format);
10529 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0210530 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
10531 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
10532 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10533
10534 base::ScopedClosureRunner scoped_completion_callback;
10535 if (async_upload_token) {
10536 base::Closure completion_closure =
10537 AsyncUploadTokenCompletionClosure(async_upload_token,
10538 sync_data_shm_id,
10539 sync_data_shm_offset);
10540 if (completion_closure.is_null())
10541 return error::kInvalidArguments;
10542
10543 scoped_completion_callback.Reset(completion_closure);
10544 }
[email protected]32145a92012-12-17 09:01:5910545
10546 // TODO(epenner): Move this and copies of this memory validation
10547 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610548 uint32 data_size;
10549 if (!GLES2Util::ComputeImageDataSizes(
10550 width, height, format, type, state_.unpack_alignment, &data_size,
10551 NULL, NULL)) {
10552 return error::kOutOfBounds;
10553 }
10554 const void* pixels = GetSharedMemoryAs<const void*>(
10555 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910556
10557 // All the normal glTexSubImage2D validation.
10558 error::Error error = error::kNoError;
10559 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10560 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10561 return error;
[email protected]69023942012-11-30 19:57:1610562 }
10563
[email protected]32145a92012-12-17 09:01:5910564 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4410565 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10566 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910567 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910568 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710569 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910570 return error::kNoError;
10571
10572 // Guarantee async textures are always 'cleared' as follows:
10573 // - AsyncTexImage2D can not redefine an existing texture
10574 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10575 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10576 // - Textures become immutable after an async call.
10577 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710578 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910579 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10580 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110581 LOCAL_SET_GL_ERROR(
10582 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510583 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910584 return error::kNoError;
10585 }
10586 }
10587
[email protected]5b3a8e02013-03-13 05:36:4410588 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310589 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910590 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1210591 AsyncMemoryParams mem_params(
10592 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1810593 AsyncPixelTransferDelegate* delegate =
10594 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10595 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4410596 // TODO(epenner): We may want to enforce exclusive use
10597 // of async APIs in which case this should become an error,
10598 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310599 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410600 0, 0, 0, 0, 0, 0};
10601 texture->GetLevelSize(target, level, &define_params.width,
10602 &define_params.height);
10603 texture->GetLevelType(target, level, &define_params.type,
10604 &define_params.internal_format);
10605 // Set up the async state if needed, and make the texture
10606 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1810607 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4710608 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4410609 texture->SetImmutable(true);
10610 }
10611
[email protected]896425e2013-06-12 17:27:1810612 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910613 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610614}
10615
[email protected]a00c1f742013-03-05 17:02:1610616error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10617 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10618 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10619 GLenum target = static_cast<GLenum>(c.target);
10620
10621 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110622 LOCAL_SET_GL_ERROR(
10623 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610624 return error::kNoError;
10625 }
[email protected]c986af502013-08-14 01:04:4410626 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10627 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910628 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110629 LOCAL_SET_GL_ERROR(
10630 GL_INVALID_OPERATION,
10631 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610632 return error::kNoError;
10633 }
[email protected]896425e2013-06-12 17:27:1810634 AsyncPixelTransferDelegate* delegate =
10635 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10636 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4910637 LOCAL_SET_GL_ERROR(
10638 GL_INVALID_OPERATION,
10639 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10640 return error::kNoError;
10641 }
[email protected]896425e2013-06-12 17:27:1810642 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0910643 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610644 return error::kNoError;
10645}
10646
[email protected]e3c4a9ab2014-03-31 09:07:0210647error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
10648 uint32 immediate_data_size, const cmds::WaitAllAsyncTexImage2DCHROMIUM& c) {
10649 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10650
10651 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
10652 ProcessFinishedAsyncTransfers();
10653 return error::kNoError;
10654}
10655
[email protected]91c94eb2013-10-22 10:32:5410656void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
10657 TextureRef* texture_ref) {
10658 Texture* texture = texture_ref->texture();
10659 DoDidUseTexImageIfNeeded(texture, texture->target());
10660}
10661
[email protected]96449d2c2009-11-25 00:01:3210662// Include the auto-generated part of this file. We split this because it means
10663// we can easily edit the non-auto generated parts right here in this file
10664// instead of having to edit some template or the code generator.
10665#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10666
10667} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510668} // namespace gpu