blob: 7e5f94223651dab84daffc5b04579490d55f3356 [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]6896d7f2014-04-28 20:24:1560#include "third_party/smhasher/src/City.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]c3a6b4a2014-06-04 09:25:5367#include <IOSurface/IOSurfaceAPI.h>
68// Note that this must be included after gl_bindings.h to avoid conflicts.
69#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4670#endif
[email protected]de17df392010-04-23 21:09:4171
[email protected]6eb775352013-08-27 05:57:1672#if defined(OS_WIN)
73#include "base/win/win_util.h"
74#endif
75
[email protected]a7a27ace2009-12-12 00:11:2576namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3277namespace gles2 {
78
[email protected]f0d74742011-10-03 16:31:0479namespace {
[email protected]693ca512012-11-13 18:09:1380
[email protected]f0d74742011-10-03 16:31:0481static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4982static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1383static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]93c2fd82014-04-16 02:46:0684static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
[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]d286ebbc2014-07-03 17:19:10155static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
156 switch (plane_transform) {
157 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
158 return gfx::OVERLAY_TRANSFORM_NONE;
159 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
160 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
161 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
162 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
163 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
164 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
165 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
166 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
167 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
168 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
169 default:
170 return gfx::OVERLAY_TRANSFORM_INVALID;
171 }
172}
173
[email protected]b04e24c2013-01-08 18:35:25174} // namespace
[email protected]f0d74742011-10-03 16:31:04175
[email protected]6217d392010-03-25 22:08:35176class GLES2DecoderImpl;
177
[email protected]ab09b612013-03-11 22:11:51178// Local versions of the SET_GL_ERROR macros
179#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50180 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51181#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50182 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
183 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51184#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50185 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
186 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51187#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50188 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
189 function_name)
[email protected]ab09b612013-03-11 22:11:51190#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50191 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51192#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50193 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51194#define LOCAL_PERFORMANCE_WARNING(msg) \
195 PerformanceWarning(__FILE__, __LINE__, msg)
196#define LOCAL_RENDER_WARNING(msg) \
197 RenderWarning(__FILE__, __LINE__, msg)
198
[email protected]07f54fcc2009-12-22 02:46:30199// Check that certain assumptions the code makes are true. There are places in
200// the code where shared memory is passed direclty to GL. Example, glUniformiv,
201// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
202// a few others) are 32bits. If they are not 32bits the code will have to change
203// to call those GL functions with service side memory and then copy the results
204// to shared memory, converting the sizes.
205COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
206 GLint_not_same_size_as_uint32);
207COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
208 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37209COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
210 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30211
[email protected]43f28f832010-02-03 02:28:48212// TODO(kbr): the use of this anonymous namespace core dumps the
213// linker on Mac OS X 10.6 when the symbol ordering file is used
214// namespace {
[email protected]96449d2c2009-11-25 00:01:32215
216// Returns the address of the first byte after a struct.
217template <typename T>
218const void* AddressAfterStruct(const T& pod) {
219 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
220}
221
[email protected]07f54fcc2009-12-22 02:46:30222// Returns the address of the frst byte after the struct or NULL if size >
223// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32224template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30225RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
226 uint32 size,
227 uint32 immediate_data_size) {
228 return (size <= immediate_data_size) ?
229 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
230 NULL;
[email protected]96449d2c2009-11-25 00:01:32231}
232
[email protected]07f54fcc2009-12-22 02:46:30233// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18234bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32235 GLuint count,
236 size_t size,
[email protected]a76b0052010-03-05 00:33:18237 unsigned int elements_per_unit,
238 uint32* dst) {
239 uint32 value;
240 if (!SafeMultiplyUint32(count, size, &value)) {
241 return false;
242 }
243 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
244 return false;
245 }
246 *dst = value;
247 return true;
[email protected]96449d2c2009-11-25 00:01:32248}
249
250// A struct to hold info about each command.
251struct CommandInfo {
[email protected]cac16542014-01-15 17:53:51252 uint8 arg_flags; // How to handle the arguments for this command
253 uint8 cmd_flags; // How to handle this command
254 uint16 arg_count; // How many arguments are expected for this command.
[email protected]96449d2c2009-11-25 00:01:32255};
256
[email protected]cac16542014-01-15 17:53:51257// cmds::name::cmd_flags,
[email protected]96449d2c2009-11-25 00:01:32258// A table of CommandInfo for all the commands.
259const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35260 #define GLES2_CMD_OP(name) { \
261 cmds::name::kArgFlags, \
[email protected]cac16542014-01-15 17:53:51262 cmds::name::cmd_flags, \
263 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */
[email protected]96449d2c2009-11-25 00:01:32264
265 GLES2_COMMAND_LIST(GLES2_CMD_OP)
266
267 #undef GLES2_CMD_OP
268};
269
[email protected]258a3313f2011-10-18 20:13:57270// Return true if a character belongs to the ASCII subset as defined in
271// GLSL ES 1.0 spec section 3.1.
272static bool CharacterIsValidForGLES(unsigned char c) {
273 // Printing characters are valid except " $ ` @ \ ' DEL.
274 if (c >= 32 && c <= 126 &&
275 c != '"' &&
276 c != '$' &&
277 c != '`' &&
278 c != '@' &&
279 c != '\\' &&
280 c != '\'') {
281 return true;
282 }
283 // Horizontal tab, line feed, vertical tab, form feed, carriage return
284 // are also valid.
285 if (c >= 9 && c <= 13) {
286 return true;
287 }
288
289 return false;
290}
291
292static bool StringIsValidForGLES(const char* str) {
293 for (; *str; ++str) {
294 if (!CharacterIsValidForGLES(*str)) {
295 return false;
296 }
297 }
298 return true;
299}
300
[email protected]6217d392010-03-25 22:08:35301// This class prevents any GL errors that occur when it is in scope from
302// being reported to the client.
303class ScopedGLErrorSuppressor {
304 public:
[email protected]ab09b612013-03-11 22:11:51305 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30306 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35307 ~ScopedGLErrorSuppressor();
308 private:
[email protected]ab09b612013-03-11 22:11:51309 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30310 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35311 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
312};
313
[email protected]2b10c02d2014-01-29 16:43:02314// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35315// object goes out of scope. Also temporarily switches to using active texture
316// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02317class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35318 public:
[email protected]00c2cf92014-03-14 00:08:37319 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02320 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35321
322 private:
[email protected]ce296892013-10-24 22:04:36323 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02324 GLenum target_;
325 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35326};
327
328// Temporarily changes a decoder's bound render buffer and restore it when this
329// object goes out of scope.
330class ScopedRenderBufferBinder {
331 public:
[email protected]00c2cf92014-03-14 00:08:37332 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35333 ~ScopedRenderBufferBinder();
334
335 private:
[email protected]18e785a2013-10-09 03:29:41336 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35337 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
338};
339
340// Temporarily changes a decoder's bound frame buffer and restore it when this
341// object goes out of scope.
342class ScopedFrameBufferBinder {
343 public:
[email protected]00c2cf92014-03-14 00:08:37344 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35345 ~ScopedFrameBufferBinder();
346
347 private:
348 GLES2DecoderImpl* decoder_;
349 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
350};
351
[email protected]34ff8b0c2010-10-01 20:06:02352// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52353// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27354// if it is bound or enforce_internal_framebuffer is true. If internal is
355// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02356class ScopedResolvedFrameBufferBinder {
357 public:
[email protected]00c2cf92014-03-14 00:08:37358 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
359 bool enforce_internal_framebuffer,
360 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02361 ~ScopedResolvedFrameBufferBinder();
362
363 private:
364 GLES2DecoderImpl* decoder_;
365 bool resolve_and_bind_;
366 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
367};
368
[email protected]00c2cf92014-03-14 00:08:37369class ScopedModifyPixels {
370 public:
371 explicit ScopedModifyPixels(TextureRef* ref);
372 ~ScopedModifyPixels();
373
374 private:
375 TextureRef* ref_;
376};
377
378ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
379 if (ref_)
380 ref_->texture()->OnWillModifyPixels();
381}
382
383ScopedModifyPixels::~ScopedModifyPixels() {
384 if (ref_)
385 ref_->texture()->OnDidModifyPixels();
386}
387
388class ScopedRenderTo {
389 public:
390 explicit ScopedRenderTo(Framebuffer* framebuffer);
391 ~ScopedRenderTo();
392
393 private:
394 const Framebuffer* framebuffer_;
395};
396
397ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
398 : framebuffer_(framebuffer) {
399 if (framebuffer)
400 framebuffer_->OnWillRenderTo();
401}
402
403ScopedRenderTo::~ScopedRenderTo() {
404 if (framebuffer_)
405 framebuffer_->OnDidRenderTo();
406}
407
[email protected]6217d392010-03-25 22:08:35408// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35409class BackTexture {
[email protected]6217d392010-03-25 22:08:35410 public:
[email protected]ce296892013-10-24 22:04:36411 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35412 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35413
414 // Create a new render texture.
415 void Create();
416
417 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09418 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35419
420 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58421 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35422
423 // Destroy the render texture. This must be explicitly called before
424 // destroying this object.
425 void Destroy();
426
[email protected]97872062010-11-03 19:07:05427 // Invalidate the texture. This can be used when a context is lost and it is
428 // not possible to make it current in order to free the resource.
429 void Invalidate();
430
[email protected]6217d392010-03-25 22:08:35431 GLuint id() const {
432 return id_;
433 }
434
[email protected]d37231fa2010-04-09 21:16:02435 gfx::Size size() const {
436 return size_;
437 }
438
[email protected]6217d392010-03-25 22:08:35439 private:
[email protected]ff6493f2012-07-31 19:52:25440 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36441 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48442 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35443 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02444 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35445 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35446};
447
448// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35449class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35450 public:
[email protected]d5a28e452013-10-10 01:01:40451 explicit BackRenderbuffer(
452 RenderbufferManager* renderbuffer_manager,
453 MemoryTracker* memory_tracker,
454 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35455 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35456
457 // Create a new render buffer.
458 void Create();
459
460 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18461 bool AllocateStorage(const FeatureInfo* feature_info,
462 const gfx::Size& size,
463 GLenum format,
464 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35465
466 // Destroy the render buffer. This must be explicitly called before destroying
467 // this object.
468 void Destroy();
469
[email protected]97872062010-11-03 19:07:05470 // Invalidate the render buffer. This can be used when a context is lost and
471 // it is not possible to make it current in order to free the resource.
472 void Invalidate();
473
[email protected]6217d392010-03-25 22:08:35474 GLuint id() const {
475 return id_;
476 }
477
478 private:
[email protected]d5a28e452013-10-10 01:01:40479 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25480 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40481 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48482 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35483 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35484 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35485};
486
487// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35488class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35489 public:
[email protected]ed9f9cd2013-02-27 21:12:35490 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
491 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35492
493 // Create a new frame buffer.
494 void Create();
495
496 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35497 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35498
[email protected]b9363b22010-06-09 22:06:15499 // Attach a render buffer to a frame buffer. Note that this unbinds any
500 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35501 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35502
[email protected]6217d392010-03-25 22:08:35503 // Destroy the frame buffer. This must be explicitly called before destroying
504 // this object.
505 void Destroy();
506
[email protected]97872062010-11-03 19:07:05507 // Invalidate the frame buffer. This can be used when a context is lost and it
508 // is not possible to make it current in order to free the resource.
509 void Invalidate();
510
[email protected]6217d392010-03-25 22:08:35511 // See glCheckFramebufferStatusEXT.
512 GLenum CheckStatus();
513
514 GLuint id() const {
515 return id_;
516 }
517
518 private:
519 GLES2DecoderImpl* decoder_;
520 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35521 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35522};
[email protected]34ff8b0c2010-10-01 20:06:02523
[email protected]5a36dc132013-07-23 23:17:55524struct FenceCallback {
525 explicit FenceCallback()
526 : fence(gfx::GLFence::Create()) {
527 DCHECK(fence);
528 }
[email protected]5a36dc132013-07-23 23:17:55529 std::vector<base::Closure> callbacks;
530 scoped_ptr<gfx::GLFence> fence;
531};
532
[email protected]e3c4a9ab2014-03-31 09:07:02533class AsyncUploadTokenCompletionObserver
534 : public AsyncPixelTransferCompletionObserver {
535 public:
536 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
537 : async_upload_token_(async_upload_token) {
538 }
539
540 virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE {
541 DCHECK(mem_params.buffer());
542 void* data = mem_params.GetDataAddress();
543 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
544 sync->SetAsyncUploadToken(async_upload_token_);
545 }
546
547 private:
548 virtual ~AsyncUploadTokenCompletionObserver() {
549 }
550
551 uint32 async_upload_token_;
552
553 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
554};
555
[email protected]43f28f832010-02-03 02:28:48556// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32557
[email protected]efc87712014-07-09 00:22:47558// static
559const unsigned int GLES2Decoder::kDefaultStencilMask =
560 static_cast<unsigned int>(-1);
561
[email protected]ddb1e5a2010-12-13 20:10:45562bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
563 uint32* service_texture_id) {
564 return false;
565}
566
[email protected]a3ded6d2010-10-19 06:44:39567GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06568 : initialized_(false),
569 debug_(false),
[email protected]1d82e822013-04-10 21:32:32570 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32571}
572
[email protected]3916c97e2010-02-25 03:20:50573GLES2Decoder::~GLES2Decoder() {
574}
575
[email protected]cac16542014-01-15 17:53:51576void GLES2Decoder::BeginDecoding() {}
577
578void GLES2Decoder::EndDecoding() {}
579
[email protected]f39f4b3f2010-05-12 17:04:08580// This class implements GLES2Decoder so we don't have to expose all the GLES2
581// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54582class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13583 public FramebufferManager::TextureDetachObserver,
584 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08585 public:
[email protected]aa7666122011-09-02 19:45:52586 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00587 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08588
[email protected]96449d2c2009-11-25 00:01:32589 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14590 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50591 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00592 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32593
594 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00595 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32596
597 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38598 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
599 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23600 bool offscreen,
[email protected]6217d392010-03-25 22:08:35601 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29602 const DisallowedFeatures& disallowed_features,
[email protected]b8e97b62012-09-30 15:09:00603 const std::vector<int32>& attribs) OVERRIDE;
604 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38605 virtual void SetSurface(
606 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]aba551b2014-02-08 03:38:32607 virtual void ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00608 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39609 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00610 virtual bool MakeCurrent() OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00611 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
612 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
613 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]6d668892013-12-04 21:37:12614 virtual Capabilities GetCapabilities() OVERRIDE;
[email protected]8875a5f2014-06-27 08:33:47615 virtual void RestoreState(const ContextState* prev_state) OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06616
617 virtual void RestoreActiveTexture() const OVERRIDE {
618 state_.RestoreActiveTexture();
619 }
[email protected]5baa86bc2014-01-16 04:33:16620 virtual void RestoreAllTextureUnitBindings(
621 const ContextState* prev_state) const OVERRIDE {
622 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55623 }
[email protected]4b2d2b262014-03-21 22:05:27624 virtual void RestoreActiveTextureUnitBinding(
625 unsigned int target) const OVERRIDE {
626 state_.RestoreActiveTextureUnitBinding(target);
627 }
[email protected]29a4d902013-02-26 20:18:06628 virtual void RestoreBufferBindings() const OVERRIDE {
629 state_.RestoreBufferBindings();
630 }
631 virtual void RestoreGlobalState() const OVERRIDE {
[email protected]88ba52f2014-04-09 12:39:34632 state_.RestoreGlobalState(NULL);
[email protected]29a4d902013-02-26 20:18:06633 }
634 virtual void RestoreProgramBindings() const OVERRIDE {
635 state_.RestoreProgramBindings();
636 }
[email protected]29a4d902013-02-26 20:18:06637 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
[email protected]5baa86bc2014-01-16 04:33:16638 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06639 }
640 virtual void RestoreFramebufferBindings() const OVERRIDE;
[email protected]8875a5f2014-06-27 08:33:47641 virtual void RestoreRenderbufferBindings() OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06642 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
643
[email protected]cd2ef752014-02-12 23:16:03644 virtual void ClearAllAttributes() const OVERRIDE;
645 virtual void RestoreAllAttributes() const OVERRIDE;
646
[email protected]b8e97b62012-09-30 15:09:00647 virtual QueryManager* GetQueryManager() OVERRIDE {
648 return query_manager_.get();
649 }
650 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46651 return vertex_array_manager_.get();
652 }
[email protected]b63f1d62014-07-18 15:40:59653 virtual ImageManager* GetImageManager() OVERRIDE {
654 return image_manager_.get();
655 }
[email protected]b8e97b62012-09-30 15:09:00656 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05657 virtual bool HasMoreIdleWork() OVERRIDE;
658 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48659
[email protected]5a36dc132013-07-23 23:17:55660 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
661
[email protected]9d37f062011-11-22 01:24:52662 virtual void SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:07663 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00664
[email protected]1d82e822013-04-10 21:32:32665 virtual Logger* GetLogger() OVERRIDE;
[email protected]cac16542014-01-15 17:53:51666
667 virtual void BeginDecoding() OVERRIDE;
668 virtual void EndDecoding() OVERRIDE;
669
[email protected]d3eba342013-04-18 21:11:50670 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]5baa86bc2014-01-16 04:33:16671 virtual const ContextState* GetContextState() OVERRIDE { return &state_; }
[email protected]1d82e822013-04-10 21:32:32672
[email protected]e3932abb2013-03-13 00:01:37673 virtual void SetShaderCacheCallback(
674 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51675 virtual void SetWaitSyncPointCallback(
676 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00677
[email protected]85a4ac22013-05-31 01:58:47678 virtual AsyncPixelTransferManager*
679 GetAsyncPixelTransferManager() OVERRIDE;
680 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]498b5c072013-06-04 19:30:07681 virtual void SetAsyncPixelTransferManagerForTest(
682 AsyncPixelTransferManager* manager) OVERRIDE;
[email protected]454157e2014-05-03 02:49:45683 virtual void SetIgnoreCachedStateForTest(bool ignore) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09684 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59685
[email protected]1318e922010-09-17 22:03:16686 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00687 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48688
[email protected]63b465922012-09-06 02:04:52689 virtual uint32 GetTextureUploadCount() OVERRIDE;
690 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
691 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30692 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52693
[email protected]8e3e0662010-08-23 18:46:30694 // Restores the current state to the user's settings.
695 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30696
[email protected]297ca1c2011-06-20 23:08:46697 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
698 void ApplyDirtyState();
699
700 // These check the state of the currently bound framebuffer or the
701 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54702 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
703 // check with all attached and enabled color attachments.
704 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46705 bool BoundFramebufferHasDepthAttachment();
706 bool BoundFramebufferHasStencilAttachment();
707
[email protected]b8e97b62012-09-30 15:09:00708 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43709
[email protected]91c94eb2013-10-22 10:32:54710 // Overridden from FramebufferManager::TextureDetachObserver:
711 virtual void OnTextureRefDetachedFromFramebuffer(
712 TextureRef* texture) OVERRIDE;
713
[email protected]828a3932014-04-02 14:43:13714 // Overriden from ErrorStateClient.
715 virtual void OnOutOfMemoryError() OVERRIDE;
716
[email protected]8875a5f2014-06-27 08:33:47717 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
718 void EnsureRenderbufferBound();
719
[email protected]f42f05b2013-11-15 21:46:18720 // Helpers to facilitate calling into compatible extensions.
721 static void RenderbufferStorageMultisampleHelper(
722 const FeatureInfo* feature_info,
723 GLenum target,
724 GLsizei samples,
725 GLenum internal_format,
726 GLsizei width,
727 GLsizei height);
728
729 void BlitFramebufferHelper(GLint srcX0,
730 GLint srcY0,
731 GLint srcX1,
732 GLint srcY1,
733 GLint dstX0,
734 GLint dstY0,
735 GLint dstX1,
736 GLint dstY1,
737 GLbitfield mask,
738 GLenum filter);
[email protected]345ba902013-11-14 21:39:00739
[email protected]96449d2c2009-11-25 00:01:32740 private:
[email protected]70d34263c2013-01-09 00:27:45741 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02742 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35743 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35744
[email protected]c2f8c8402010-12-06 18:07:24745 // Initialize or re-initialize the shader translator.
746 bool InitializeShaderTranslator();
747
[email protected]302ce6d2011-07-07 23:28:11748 void UpdateCapabilities();
749
[email protected]ae51d192010-04-27 00:48:03750 // Helpers for the glGen and glDelete functions.
751 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
752 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
753 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
754 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
755 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
756 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
757 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
758 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53759 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
760 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46761 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
762 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47763
[email protected]e3c4a9ab2014-03-31 09:07:02764 // Helper for async upload token completion notification callback.
765 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
766 uint32 sync_data_shm_id,
767 uint32 sync_data_shm_offset);
768
769
770
[email protected]70d34263c2013-01-09 00:27:45771 // Workarounds
772 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51773 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45774
[email protected]3916c97e2010-02-25 03:20:50775 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50776 BufferManager* buffer_manager() {
777 return group_->buffer_manager();
778 }
779
[email protected]a25fa872010-03-25 02:57:58780 RenderbufferManager* renderbuffer_manager() {
781 return group_->renderbuffer_manager();
782 }
783
784 FramebufferManager* framebuffer_manager() {
785 return group_->framebuffer_manager();
786 }
787
[email protected]3916c97e2010-02-25 03:20:50788 ProgramManager* program_manager() {
789 return group_->program_manager();
790 }
791
792 ShaderManager* shader_manager() {
793 return group_->shader_manager();
794 }
795
[email protected]03cef9b2014-04-03 15:58:14796 ShaderTranslatorCache* shader_translator_cache() {
797 return group_->shader_translator_cache();
798 }
799
[email protected]29a4d902013-02-26 20:18:06800 const TextureManager* texture_manager() const {
801 return group_->texture_manager();
802 }
803
[email protected]3916c97e2010-02-25 03:20:50804 TextureManager* texture_manager() {
805 return group_->texture_manager();
806 }
807
[email protected]78b514b2012-05-01 21:50:59808 MailboxManager* mailbox_manager() {
809 return group_->mailbox_manager();
810 }
811
[email protected]b63f1d62014-07-18 15:40:59812 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37813
[email protected]944b62f32012-09-27 02:20:46814 VertexArrayManager* vertex_array_manager() {
815 return vertex_array_manager_.get();
816 }
817
[email protected]7989c9e2013-01-23 06:39:26818 MemoryTracker* memory_tracker() {
819 return group_->memory_tracker();
820 }
821
822 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
823 MemoryTracker* tracker = memory_tracker();
824 if (tracker) {
825 return tracker->EnsureGPUMemoryAvailable(estimated_size);
826 }
827 return true;
828 }
829
[email protected]34ff8b0c2010-10-01 20:06:02830 bool IsOffscreenBufferMultisampled() const {
831 return offscreen_target_samples_ > 1;
832 }
833
[email protected]ed9f9cd2013-02-27 21:12:35834 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49835 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03836 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35837 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47838 }
839
840 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49841 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07842 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47843 }
844
845 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35846 void RemoveTexture(GLuint client_id) {
847 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50848 }
[email protected]a93bb842010-02-16 23:03:47849
[email protected]d37231fa2010-04-09 21:16:02850 // Get the size (in pixels) of the currently bound frame buffer (either FBO
851 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30852 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02853
[email protected]9edc6b22010-12-23 02:00:26854 // Get the format of the currently bound frame buffer (either FBO or regular
855 // back buffer)
[email protected]68586372013-12-11 01:27:59856 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26857 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46858 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26859
[email protected]a93bb842010-02-16 23:03:47860 // Wrapper for CompressedTexImage2D commands.
861 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37862 GLenum target,
863 GLint level,
864 GLenum internal_format,
865 GLsizei width,
866 GLsizei height,
867 GLint border,
868 GLsizei image_size,
869 const void* data);
[email protected]a93bb842010-02-16 23:03:47870
[email protected]cadde4a2010-07-31 17:10:43871 // Wrapper for CompressedTexSubImage2D.
872 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37873 GLenum target,
874 GLint level,
875 GLint xoffset,
876 GLint yoffset,
877 GLsizei width,
878 GLsizei height,
879 GLenum format,
880 GLsizei imageSize,
881 const void * data);
[email protected]cadde4a2010-07-31 17:10:43882
883 // Wrapper for CopyTexImage2D.
884 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37885 GLenum target,
886 GLint level,
887 GLenum internal_format,
888 GLint x,
889 GLint y,
890 GLsizei width,
891 GLsizei height,
892 GLint border);
[email protected]cadde4a2010-07-31 17:10:43893
[email protected]6d792ee12013-05-15 00:40:56894 // Wrapper for SwapBuffers.
895 void DoSwapBuffers();
896
[email protected]cadde4a2010-07-31 17:10:43897 // Wrapper for CopyTexSubImage2D.
898 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37899 GLenum target,
900 GLint level,
901 GLint xoffset,
902 GLint yoffset,
903 GLint x,
904 GLint y,
905 GLsizei width,
906 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43907
[email protected]f598f422012-12-07 08:30:03908 // Validation for TexSubImage2D.
909 bool ValidateTexSubImage2D(
910 error::Error* error,
911 const char* function_name,
912 GLenum target,
913 GLint level,
914 GLint xoffset,
915 GLint yoffset,
916 GLsizei width,
917 GLsizei height,
918 GLenum format,
919 GLenum type,
920 const void * data);
921
[email protected]cadde4a2010-07-31 17:10:43922 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03923 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37924 GLenum target,
925 GLint level,
926 GLint xoffset,
927 GLint yoffset,
928 GLsizei width,
929 GLsizei height,
930 GLenum format,
931 GLenum type,
932 const void * data);
[email protected]cadde4a2010-07-31 17:10:43933
[email protected]32145a92012-12-17 09:01:59934 // Extra validation for async tex(Sub)Image2D.
935 bool ValidateAsyncTransfer(
936 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47937 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59938 GLenum target,
939 GLint level,
940 const void * data);
941
[email protected]e51bdf32011-11-23 22:21:46942 // Wrapper for TexImageIOSurface2DCHROMIUM.
943 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37944 GLenum target,
945 GLsizei width,
946 GLsizei height,
947 GLuint io_surface_id,
948 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46949
[email protected]43410e92012-04-20 17:06:28950 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37951 GLenum target,
952 GLuint source_id,
953 GLuint target_id,
954 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54955 GLenum internal_format,
956 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28957
[email protected]97dc7cbe2011-12-06 17:26:17958 // Wrapper for TexStorage2DEXT.
959 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37960 GLenum target,
961 GLint levels,
962 GLenum internal_format,
963 GLsizei width,
964 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17965
[email protected]78b514b2012-05-01 21:50:59966 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22967 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
968 const GLbyte* key);
969 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
970 GLenum target, const GLbyte* data);
971
[email protected]78b514b2012-05-01 21:50:59972 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22973 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
974 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59975
[email protected]09d50362012-10-18 20:54:37976 void DoBindTexImage2DCHROMIUM(
977 GLenum target,
978 GLint image_id);
979 void DoReleaseTexImage2DCHROMIUM(
980 GLenum target,
981 GLint image_id);
982
[email protected]94307712012-11-16 23:26:11983 void DoTraceEndCHROMIUM(void);
984
[email protected]2f143d482013-03-14 18:04:49985 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
986
[email protected]a6a09f852014-05-23 13:05:03987 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
988
[email protected]ed9f9cd2013-02-27 21:12:35989 // Creates a Program for the given program.
990 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57991 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35992 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47993 }
994
[email protected]07f54fcc2009-12-22 02:46:30995 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35996 Program* GetProgram(GLuint client_id) {
997 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46998 }
[email protected]07f54fcc2009-12-22 02:46:30999
[email protected]cae20172012-12-07 00:06:191000#if defined(NDEBUG)
1001 void LogClientServiceMapping(
1002 const char* /* function_name */,
1003 GLuint /* client_id */,
1004 GLuint /* service_id */) {
1005 }
1006 template<typename T>
1007 void LogClientServiceForInfo(
1008 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
1009 }
1010#else
1011 void LogClientServiceMapping(
1012 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:261013 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:471014 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1015 << ": client_id = " << client_id
1016 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:261017 }
[email protected]cae20172012-12-07 00:06:191018 }
1019 template<typename T>
1020 void LogClientServiceForInfo(
1021 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:261022 if (info) {
[email protected]cae20172012-12-07 00:06:191023 LogClientServiceMapping(function_name, client_id, info->service_id());
1024 }
1025 }
1026#endif
1027
[email protected]6b8cf1a2010-05-06 16:13:581028 // Gets the program info for the given program. If it's not a program
1029 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351030 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581031 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421032 Program* program = GetProgram(client_id);
1033 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351034 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511035 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431036 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581037 } else {
[email protected]ab09b612013-03-11 22:11:511038 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581039 }
1040 }
[email protected]df37b9932013-03-08 05:21:421041 LogClientServiceForInfo(program, client_id, function_name);
1042 return program;
[email protected]6b8cf1a2010-05-06 16:13:581043 }
1044
1045
[email protected]ed9f9cd2013-02-27 21:12:351046 // Creates a Shader for the given shader.
1047 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571048 GLuint client_id,
1049 GLuint service_id,
1050 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351051 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571052 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311053 }
1054
1055 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351056 Shader* GetShader(GLuint client_id) {
1057 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311058 }
1059
[email protected]6b8cf1a2010-05-06 16:13:581060 // Gets the shader info for the given shader. If it's not a shader generates a
1061 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351062 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581063 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421064 Shader* shader = GetShader(client_id);
1065 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351066 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511067 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431068 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581069 } else {
[email protected]ab09b612013-03-11 22:11:511070 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431071 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581072 }
1073 }
[email protected]df37b9932013-03-08 05:21:421074 LogClientServiceForInfo(shader, client_id, function_name);
1075 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581076 }
1077
[email protected]a93bb842010-02-16 23:03:471078 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351079 void CreateBuffer(GLuint client_id, GLuint service_id) {
1080 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471081 }
1082
[email protected]07f54fcc2009-12-22 02:46:301083 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211084 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071085 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1086 return buffer;
[email protected]1d32bc82010-01-13 22:06:461087 }
[email protected]07f54fcc2009-12-22 02:46:301088
[email protected]a93bb842010-02-16 23:03:471089 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1090 // on glDeleteBuffers so we can make sure the user does not try to render
1091 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351092 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471093
[email protected]a25fa872010-03-25 02:57:581094 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351095 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1096 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581097 }
1098
1099 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061100 Framebuffer* GetFramebuffer(GLuint client_id) {
1101 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581102 }
1103
1104 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351105 void RemoveFramebuffer(GLuint client_id) {
1106 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581107 }
1108
1109 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351110 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1111 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031112 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581113 }
1114
1115 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271116 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1117 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581118 }
1119
1120 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351121 void RemoveRenderbuffer(GLuint client_id) {
1122 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581123 }
1124
[email protected]944b62f32012-09-27 02:20:461125 // Gets the vertex attrib manager for the given vertex array.
1126 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1127 VertexAttribManager* info =
1128 vertex_array_manager()->GetVertexAttribManager(client_id);
1129 return info;
1130 }
1131
1132 // Removes the vertex attrib manager for the given vertex array.
1133 void RemoveVertexAttribManager(GLuint client_id) {
1134 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1135 }
1136
1137 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481138 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1139 GLuint client_id,
1140 GLuint service_id,
1141 bool client_visible) {
1142 return vertex_array_manager()->CreateVertexAttribManager(
1143 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461144 }
1145
[email protected]258a3313f2011-10-18 20:13:571146 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331147 void DoBindUniformLocationCHROMIUM(
1148 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571149
[email protected]558847a2010-03-24 07:02:541150 error::Error GetAttribLocationHelper(
1151 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1152 const std::string& name_str);
1153
1154 error::Error GetUniformLocationHelper(
1155 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1156 const std::string& name_str);
1157
[email protected]3916c97e2010-02-25 03:20:501158 // Helper for glShaderSource.
1159 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031160 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301161
[email protected]0d6bfdc2011-11-02 01:32:201162 // Clear any textures used by the current program.
1163 bool ClearUnclearedTextures();
1164
[email protected]0d6bfdc2011-11-02 01:32:201165 // Clears any uncleared attachments attached to the given frame buffer.
1166 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061167 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281168
[email protected]0d6bfdc2011-11-02 01:32:201169 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001170 virtual bool ClearLevel(unsigned service_id,
1171 unsigned bind_target,
1172 unsigned target,
1173 int level,
[email protected]d8e6c9242014-02-20 16:56:251174 unsigned internal_format,
[email protected]b8e97b62012-09-30 15:09:001175 unsigned format,
1176 unsigned type,
1177 int width,
1178 int height,
1179 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201180
[email protected]c007aa02010-09-02 22:22:401181 // Restore all GL state that affects clearing.
1182 void RestoreClearState();
1183
[email protected]3a2e7c7b2010-08-06 01:12:281184 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461185 // Returns: true if glEnable/glDisable should actually be called.
1186 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281187
[email protected]0d6bfdc2011-11-02 01:32:201188 // Check that the currently bound framebuffers are valid.
1189 // Generates GL error if not.
1190 bool CheckBoundFramebuffersValid(const char* func_name);
1191
[email protected]2ea5950d2014-07-09 18:20:341192 // Check that the currently bound read framebuffer has a color image
1193 // attached. Generates GL error if not.
1194 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1195
[email protected]0d6bfdc2011-11-02 01:32:201196 // Check if a framebuffer meets our requirements.
1197 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351198 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201199 GLenum target,
1200 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271201
[email protected]939e7362010-05-13 20:49:101202 // Checks if the current program exists and is valid. If not generates the
1203 // appropriate GL error. Returns true if the current program is in a usable
1204 // state.
1205 bool CheckCurrentProgram(const char* function_name);
1206
1207 // Checks if the current program exists and is valid and that location is not
1208 // -1. If the current program is not valid generates the appropriate GL
1209 // error. Returns true if the current program is in a usable state and
1210 // location is not -1.
1211 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1212
1213 // Gets the type of a uniform for a location in the current program. Sets GL
1214 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361215 // program is valid and the location exists. Adjusts count so it
1216 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131217 bool PrepForSetUniformByLocation(GLint fake_location,
1218 const char* function_name,
1219 Program::UniformApiType api_type,
1220 GLint* real_location,
1221 GLenum* type,
1222 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101223
[email protected]b177ae22011-11-01 03:29:111224 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021225 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111226
[email protected]b273e432010-04-12 17:23:581227 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1228 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1229
[email protected]ac77603c72013-03-08 13:52:061230 // Helper for glGetVertexAttrib
1231 void GetVertexAttribHelper(
1232 const VertexAttrib* attrib, GLenum pname, GLint* param);
1233
[email protected]96449d2c2009-11-25 00:01:321234 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031235 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321236
1237 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031238 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321239
[email protected]3916c97e2010-02-25 03:20:501240 // Wrapper for glActiveTexture
1241 void DoActiveTexture(GLenum texture_unit);
1242
[email protected]ae51d192010-04-27 00:48:031243 // Wrapper for glAttachShader
1244 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1245
[email protected]96449d2c2009-11-25 00:01:321246 // Wrapper for glBindBuffer since we need to track the current targets.
1247 void DoBindBuffer(GLenum target, GLuint buffer);
1248
[email protected]86093972010-03-11 00:13:561249 // Wrapper for glBindFramebuffer since we need to track the current targets.
1250 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1251
1252 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1253 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1254
[email protected]a93bb842010-02-16 23:03:471255 // Wrapper for glBindTexture since we need to track the current targets.
1256 void DoBindTexture(GLenum target, GLuint texture);
1257
[email protected]944b62f32012-09-27 02:20:461258 // Wrapper for glBindVertexArrayOES
1259 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571260 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461261
[email protected]49cabed2013-11-13 18:15:181262 // Wrapper for glBlitFramebufferCHROMIUM.
1263 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301264 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1265 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1266 GLbitfield mask, GLenum filter);
1267
[email protected]36cef8ce2010-03-16 07:34:451268 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111269 void DoBufferSubData(
1270 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1271
[email protected]36cef8ce2010-03-16 07:34:451272 // Wrapper for glCheckFramebufferStatus
1273 GLenum DoCheckFramebufferStatus(GLenum target);
1274
[email protected]3a03a8f2011-03-19 00:51:271275 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081276 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271277
[email protected]88a61bf2012-10-27 13:00:421278 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421279 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251280 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281281
[email protected]45bf5152010-02-12 00:11:311282 // Wrapper for glCompileShader.
1283 void DoCompileShader(GLuint shader);
1284
[email protected]269200b12010-11-18 22:53:061285 // Helper for DeleteSharedIdsCHROMIUM commands.
1286 void DoDeleteSharedIdsCHROMIUM(
1287 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101288
[email protected]ae51d192010-04-27 00:48:031289 // Wrapper for glDetachShader
1290 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1291
[email protected]3a2e7c7b2010-08-06 01:12:281292 // Wrapper for glDisable
1293 void DoDisable(GLenum cap);
1294
[email protected]07f54fcc2009-12-22 02:46:301295 // Wrapper for glDisableVertexAttribArray.
1296 void DoDisableVertexAttribArray(GLuint index);
1297
[email protected]60f22d32012-12-12 00:31:581298 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1299 // attachments.
1300 void DoDiscardFramebufferEXT(GLenum target,
1301 GLsizei numAttachments,
1302 const GLenum* attachments);
1303
[email protected]3a2e7c7b2010-08-06 01:12:281304 // Wrapper for glEnable
1305 void DoEnable(GLenum cap);
1306
[email protected]07f54fcc2009-12-22 02:46:301307 // Wrapper for glEnableVertexAttribArray.
1308 void DoEnableVertexAttribArray(GLuint index);
1309
[email protected]882ba1e22012-03-08 19:02:531310 // Wrapper for glFinish.
1311 void DoFinish();
1312
1313 // Wrapper for glFlush.
1314 void DoFlush();
1315
[email protected]36cef8ce2010-03-16 07:34:451316 // Wrapper for glFramebufferRenderbufffer.
1317 void DoFramebufferRenderbuffer(
1318 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1319 GLuint renderbuffer);
1320
1321 // Wrapper for glFramebufferTexture2D.
1322 void DoFramebufferTexture2D(
1323 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1324 GLint level);
1325
[email protected]7d3c36e2013-07-12 14:13:161326 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1327 void DoFramebufferTexture2DMultisample(
1328 GLenum target, GLenum attachment, GLenum textarget,
1329 GLuint texture, GLint level, GLsizei samples);
1330
1331 // Common implementation for both DoFramebufferTexture2D wrappers.
1332 void DoFramebufferTexture2DCommon(const char* name,
1333 GLenum target, GLenum attachment, GLenum textarget,
1334 GLuint texture, GLint level, GLsizei samples);
1335
[email protected]a93bb842010-02-16 23:03:471336 // Wrapper for glGenerateMipmap
1337 void DoGenerateMipmap(GLenum target);
1338
[email protected]269200b12010-11-18 22:53:061339 // Helper for GenSharedIdsCHROMIUM commands.
1340 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101341 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1342
[email protected]7d3c36e2013-07-12 14:13:161343 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1344 // to account for different pname values defined in different extension
1345 // variants.
1346 GLenum AdjustGetPname(GLenum pname);
1347
[email protected]b273e432010-04-12 17:23:581348 // Wrapper for DoGetBooleanv.
1349 void DoGetBooleanv(GLenum pname, GLboolean* params);
1350
1351 // Wrapper for DoGetFloatv.
1352 void DoGetFloatv(GLenum pname, GLfloat* params);
1353
[email protected]36cef8ce2010-03-16 07:34:451354 // Wrapper for glGetFramebufferAttachmentParameteriv.
1355 void DoGetFramebufferAttachmentParameteriv(
1356 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1357
[email protected]a0c3e972010-04-21 00:49:131358 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581359 void DoGetIntegerv(GLenum pname, GLint* params);
1360
[email protected]29a9eb52010-04-13 09:04:231361 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061362 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231363 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1364
[email protected]17cfbe0e2013-03-07 01:26:081365 // Wrapper for glGetBufferParameteriv.
1366 void DoGetBufferParameteriv(
1367 GLenum target, GLenum pname, GLint* params);
1368
[email protected]a0c3e972010-04-21 00:49:131369 // Wrapper for glGetProgramiv.
1370 void DoGetProgramiv(
1371 GLuint program_id, GLenum pname, GLint* params);
1372
[email protected]36cef8ce2010-03-16 07:34:451373 // Wrapper for glRenderbufferParameteriv.
1374 void DoGetRenderbufferParameteriv(
1375 GLenum target, GLenum pname, GLint* params);
1376
[email protected]ddd968b82010-03-02 00:44:291377 // Wrapper for glGetShaderiv
1378 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1379
[email protected]4c6f5462014-03-05 00:26:561380 // Wrappers for glGetTexParameter.
1381 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1382 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1383 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1384
[email protected]b1122982010-05-17 23:04:241385 // Wrappers for glGetVertexAttrib.
1386 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1387 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1388
[email protected]1958e0e2010-04-22 05:17:151389 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241390 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151391 bool DoIsBuffer(GLuint client_id);
1392 bool DoIsFramebuffer(GLuint client_id);
1393 bool DoIsProgram(GLuint client_id);
1394 bool DoIsRenderbuffer(GLuint client_id);
1395 bool DoIsShader(GLuint client_id);
1396 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461397 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151398
[email protected]07f54fcc2009-12-22 02:46:301399 // Wrapper for glLinkProgram
1400 void DoLinkProgram(GLuint program);
1401
[email protected]269200b12010-11-18 22:53:061402 // Helper for RegisterSharedIdsCHROMIUM.
1403 void DoRegisterSharedIdsCHROMIUM(
1404 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101405
[email protected]36cef8ce2010-03-16 07:34:451406 // Wrapper for glRenderbufferStorage.
1407 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031408 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451409
[email protected]49cabed2013-11-13 18:15:181410 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1411 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301412 GLenum target, GLsizei samples, GLenum internalformat,
1413 GLsizei width, GLsizei height);
1414
[email protected]49cabed2013-11-13 18:15:181415 // Handler for glRenderbufferStorageMultisampleEXT
1416 // (multisampled_render_to_texture).
1417 void DoRenderbufferStorageMultisampleEXT(
1418 GLenum target, GLsizei samples, GLenum internalformat,
1419 GLsizei width, GLsizei height);
1420
1421 // Common validation for multisample extensions.
1422 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1423 GLenum internalformat,
1424 GLsizei width,
1425 GLsizei height);
1426
[email protected]4a4c18b2013-09-13 22:50:101427 // Verifies that the currently bound multisample renderbuffer is valid
1428 // Very slow! Only done on platforms with driver bugs that return invalid
1429 // buffers under memory pressure
1430 bool VerifyMultisampleRenderbufferIntegrity(
1431 GLuint renderbuffer, GLenum format);
1432
[email protected]b273e432010-04-12 17:23:581433 // Wrapper for glReleaseShaderCompiler.
1434 void DoReleaseShaderCompiler() { }
1435
[email protected]3916c97e2010-02-25 03:20:501436 // Wrappers for glTexParameter functions.
1437 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1438 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1439 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1440 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1441
1442 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1443 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121444 void DoUniform1i(GLint fake_location, GLint v0);
1445 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1446 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1447 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1448 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101449
1450 // Wrappers for glUniformfv because some drivers don't correctly accept
1451 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121452 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1453 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1454 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1455 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501456
[email protected]43c2f1f2011-03-25 18:35:361457 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121458 GLint fake_location, GLsizei count, GLboolean transpose,
1459 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361460 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121461 GLint fake_location, GLsizei count, GLboolean transpose,
1462 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361463 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121464 GLint fake_location, GLsizei count, GLboolean transpose,
1465 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361466
[email protected]af6380962012-11-29 23:24:131467 bool SetVertexAttribValue(
1468 const char* function_name, GLuint index, const GLfloat* value);
1469
[email protected]b1122982010-05-17 23:04:241470 // Wrappers for glVertexAttrib??
1471 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1472 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1473 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1474 void DoVertexAttrib4f(
1475 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1476 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1477 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1478 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1479 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1480
[email protected]43410e92012-04-20 17:06:281481 // Wrapper for glViewport
1482 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1483
[email protected]07f54fcc2009-12-22 02:46:301484 // Wrapper for glUseProgram
1485 void DoUseProgram(GLuint program);
1486
[email protected]ae51d192010-04-27 00:48:031487 // Wrapper for glValidateProgram.
1488 void DoValidateProgram(GLuint program_client_id);
1489
[email protected]d2a0e1a2012-08-12 02:25:011490 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1491 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1492 void DoPopGroupMarkerEXT(void);
1493
[email protected]4e8a5b122010-05-08 22:00:101494 // Gets the number of values that will be returned by glGetXXX. Returns
1495 // false if pname is unknown.
1496 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1497
[email protected]07f54fcc2009-12-22 02:46:301498 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431499 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101500 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1501 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301502
[email protected]c13e1da62011-09-09 21:48:301503 // Returns true if successful, simulated will be true if attrib0 was
1504 // simulated.
[email protected]c6aef902012-02-14 03:31:421505 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431506 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231507 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241508
[email protected]91c94eb2013-10-22 10:32:541509 // If an image is bound to texture, this will call Will/DidUseTexImage
1510 // if needed.
1511 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1512 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1513
1514 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111515 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541516 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501517
[email protected]8fbedc02010-11-18 18:43:401518 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421519 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431520 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421521 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401522 void RestoreStateForSimulatedFixedAttribs();
1523
[email protected]c6aef902012-02-14 03:31:421524 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101525 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421526 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431527 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421528 bool instanced, GLenum mode, GLint first, GLsizei count,
1529 GLsizei primcount);
1530 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431531 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421532 bool instanced, GLenum mode, GLsizei count, GLenum type,
1533 int32 offset, GLsizei primcount);
1534
[email protected]61eeb33f2011-07-26 15:30:311535 GLenum GetBindTargetForSamplerType(GLenum type) {
1536 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461537 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1538 switch (type) {
1539 case GL_SAMPLER_2D:
1540 return GL_TEXTURE_2D;
1541 case GL_SAMPLER_CUBE:
1542 return GL_TEXTURE_CUBE_MAP;
1543 case GL_SAMPLER_EXTERNAL_OES:
1544 return GL_TEXTURE_EXTERNAL_OES;
1545 case GL_SAMPLER_2D_RECT_ARB:
1546 return GL_TEXTURE_RECTANGLE_ARB;
1547 }
1548
1549 NOTREACHED();
1550 return 0;
[email protected]61eeb33f2011-07-26 15:30:311551 }
1552
[email protected]8e3e0662010-08-23 18:46:301553 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061554 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1555 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301556 switch (target) {
1557 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451558 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341559 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301560 break;
[email protected]ebfb73c2012-08-15 02:37:451561 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341562 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301563 break;
1564 default:
1565 NOTREACHED();
1566 break;
1567 }
[email protected]4d8f0dd2013-03-09 14:37:061568 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301569 }
1570
[email protected]ed9f9cd2013-02-27 21:12:351571 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201572 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271573 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201574 switch (target) {
1575 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111576 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201577 break;
1578 default:
1579 NOTREACHED();
1580 break;
1581 }
[email protected]ee2a79c32013-03-10 03:50:271582 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201583 }
1584
[email protected]f7b85372010-02-03 01:11:371585 // Validates the program and location for a glGetUniform call and returns
1586 // a SizeResult setup to receive the result. Returns true if glGetUniform
1587 // should be called.
1588 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121589 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371590 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121591 error::Error* error, GLint* real_location, GLuint* service_id,
1592 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371593
[email protected]a10b4a02012-11-26 23:09:501594 virtual bool WasContextLost() OVERRIDE;
[email protected]93a7d98f2013-07-11 00:04:221595 virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091596 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431597
[email protected]e51bdf32011-11-23 22:21:461598#if defined(OS_MACOSX)
1599 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1600#endif
1601
[email protected]ad84a3a2012-06-08 21:42:431602 bool ValidateCompressedTexDimensions(
1603 const char* function_name,
1604 GLint level, GLsizei width, GLsizei height, GLenum format);
1605 bool ValidateCompressedTexFuncData(
1606 const char* function_name,
1607 GLsizei width, GLsizei height, GLenum format, size_t size);
1608 bool ValidateCompressedTexSubDimensions(
1609 const char* function_name,
1610 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1611 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351612 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431613
[email protected]ab09b612013-03-11 22:11:511614 void RenderWarning(const char* filename, int line, const std::string& msg);
1615 void PerformanceWarning(
1616 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011617
[email protected]62e155e2012-10-23 22:43:151618 const FeatureInfo::FeatureFlags& features() const {
1619 return feature_info_->feature_flags();
1620 }
1621
1622 const FeatureInfo::Workarounds& workarounds() const {
1623 return feature_info_->workarounds();
1624 }
1625
[email protected]a7266a92012-06-28 02:11:081626 bool ShouldDeferDraws() {
1627 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341628 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081629 surface_->DeferDraws();
1630 }
1631
[email protected]09e17272012-11-30 10:30:441632 bool ShouldDeferReads() {
1633 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341634 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441635 surface_->DeferDraws();
1636 }
1637
[email protected]c76fe672013-12-13 23:30:221638 error::Error WillAccessBoundFramebufferForDraw() {
1639 if (ShouldDeferDraws())
1640 return error::kDeferCommandUntilLater;
1641 if (!offscreen_target_frame_buffer_.get() &&
1642 !framebuffer_state_.bound_draw_framebuffer.get() &&
1643 !surface_->SetBackbufferAllocation(true))
1644 return error::kLostContext;
1645 return error::kNoError;
1646 }
1647
1648 error::Error WillAccessBoundFramebufferForRead() {
1649 if (ShouldDeferReads())
1650 return error::kDeferCommandUntilLater;
1651 if (!offscreen_target_frame_buffer_.get() &&
1652 !framebuffer_state_.bound_read_framebuffer.get() &&
1653 !surface_->SetBackbufferAllocation(true))
1654 return error::kLostContext;
1655 return error::kNoError;
1656 }
1657
[email protected]5a36dc132013-07-23 23:17:551658 void ProcessPendingReadPixels();
1659 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1660
[email protected]96449d2c2009-11-25 00:01:321661 // Generate a member function prototype for each command in an automated and
1662 // typesafe way.
1663 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141664 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351665 uint32 immediate_data_size, \
1666 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321667
1668 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1669
1670 #undef GLES2_CMD_OP
1671
[email protected]2f2d7042010-04-14 21:45:581672 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381673 scoped_refptr<gfx::GLSurface> surface_;
1674 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021675
[email protected]a3ded6d2010-10-19 06:44:391676 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351677 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391678
[email protected]1d82e822013-04-10 21:32:321679 DebugMarkerManager debug_marker_manager_;
1680 Logger logger_;
1681
[email protected]e259eb412012-10-13 05:47:241682 // All the state for this context.
1683 ContextState state_;
1684
[email protected]34ff8b0c2010-10-01 20:06:021685 // Current width and height of the offscreen frame buffer.
1686 gfx::Size offscreen_size_;
1687
[email protected]96449d2c2009-11-25 00:01:321688 // Util to help with GL.
1689 GLES2Util util_;
1690
[email protected]43410e92012-04-20 17:06:281691 // unpack flip y as last set by glPixelStorei
1692 bool unpack_flip_y_;
1693
[email protected]6c75c712012-06-19 15:43:171694 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281695 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171696 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281697
[email protected]b1122982010-05-17 23:04:241698 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1699 GLuint attrib_0_buffer_id_;
1700
1701 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131702 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241703
[email protected]fc753442011-02-04 19:49:491704 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1705 bool attrib_0_buffer_matches_value_;
1706
[email protected]b1122982010-05-17 23:04:241707 // The size of attrib 0.
1708 GLsizei attrib_0_size_;
1709
[email protected]8fbedc02010-11-18 18:43:401710 // The buffer used to simulate GL_FIXED attribs.
1711 GLuint fixed_attrib_buffer_id_;
1712
1713 // The size of fiixed attrib buffer.
1714 GLsizei fixed_attrib_buffer_size_;
1715
[email protected]b9363b22010-06-09 22:06:151716 // The offscreen frame buffer that the client renders to. With EGL, the
1717 // depth and stencil buffers are separate. With regular GL there is a single
1718 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1719 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351720 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1721 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1722 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1723 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1724 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021725 GLenum offscreen_target_color_format_;
1726 GLenum offscreen_target_depth_format_;
1727 GLenum offscreen_target_stencil_format_;
1728 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561729 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351730
[email protected]de26b3c2011-08-03 21:54:271731 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351732 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1733 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491734 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351735 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271736
1737 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351738 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1739 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051740 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351741
[email protected]882ba1e22012-03-08 19:02:531742 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531743
[email protected]944b62f32012-09-27 02:20:461744 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1745
[email protected]b63f1d62014-07-18 15:40:591746 scoped_ptr<ImageManager> image_manager_;
1747
[email protected]729c0b42013-05-26 02:05:071748 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001749
[email protected]840a7e462013-02-27 01:29:511750 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481751
[email protected]e3932abb2013-03-13 00:01:371752 ShaderCacheCallback shader_cache_callback_;
1753
[email protected]85a4ac22013-05-31 01:58:471754 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421755
[email protected]32fe9aa2011-01-21 23:47:131756 // The format of the back buffer_
1757 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461758 bool back_buffer_has_depth_;
1759 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131760
[email protected]60f22d32012-12-12 00:31:581761 // Backbuffer attachments that are currently undefined.
1762 uint32 backbuffer_needs_clear_bits_;
1763
[email protected]a6a09f852014-05-23 13:05:031764 // The current decoder error communicates the decoder error through command
1765 // processing functions that do not return the error value. Should be set only
1766 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561767 error::Error current_decoder_error_;
1768
[email protected]b1d2dcb2010-05-17 19:24:181769 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041770 scoped_refptr<ShaderTranslator> vertex_translator_;
1771 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181772
[email protected]e82fb792011-09-22 00:33:291773 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411774
[email protected]915a59a12010-09-30 21:29:111775 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051776 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351777 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051778
[email protected]65225772011-05-12 21:10:241779 int frame_number_;
1780
[email protected]706b69f2012-07-27 04:59:301781 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431782 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221783 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431784 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431785
[email protected]f0d74742011-10-03 16:31:041786 // These flags are used to override the state of the shared feature_info_
1787 // member. Because the same FeatureInfo instance may be shared among many
1788 // contexts, the assumptions on the availablity of extensions in WebGL
1789 // contexts may be broken. These flags override the shared state to preserve
1790 // WebGL semantics.
1791 bool force_webgl_glsl_validation_;
1792 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491793 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131794 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061795 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041796
[email protected]062c38b2012-01-18 03:25:101797 bool compile_shader_always_succeeds_;
1798
[email protected]828a3932014-04-02 14:43:131799 // An optional behaviour to lose the context and group when OOM.
1800 bool lose_context_when_out_of_memory_;
1801
[email protected]cae20172012-12-07 00:06:191802 // Log extra info.
1803 bool service_logging_;
1804
[email protected]e51bdf32011-11-23 22:21:461805#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531806 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461807 TextureToIOSurfaceMap texture_to_io_surface_map_;
1808#endif
1809
[email protected]43410e92012-04-20 17:06:281810 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1811
[email protected]1868a342012-11-07 15:56:021812 // Cached values of the currently assigned viewport dimensions.
1813 GLsizei viewport_max_width_;
1814 GLsizei viewport_max_height_;
1815
[email protected]63b465922012-09-06 02:04:521816 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521817 base::TimeDelta total_processing_commands_time_;
1818
[email protected]c986af502013-08-14 01:04:441819 // States related to each manager.
1820 DecoderTextureState texture_state_;
1821 DecoderFramebufferState framebuffer_state_;
1822
[email protected]fb97b662013-02-20 23:02:141823 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131824 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
[email protected]cac16542014-01-15 17:53:511825 int gpu_trace_level_;
1826 bool gpu_trace_commands_;
[email protected]94307712012-11-16 23:26:111827
[email protected]5a36dc132013-07-23 23:17:551828 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1829
[email protected]4a4c18b2013-09-13 22:50:101830 // Used to validate multisample renderbuffers if needed
1831 GLuint validation_texture_;
1832 GLuint validation_fbo_multisample_;
1833 GLuint validation_fbo_;
1834
[email protected]96449d2c2009-11-25 00:01:321835 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1836};
1837
[email protected]ab09b612013-03-11 22:11:511838ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301839 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511840 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301841 error_state_(error_state) {
1842 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351843}
1844
1845ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301846 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351847}
1848
[email protected]2b10c02d2014-01-29 16:43:021849static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361850 TextureUnit& info = state->texture_units[0];
1851 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021852 scoped_refptr<TextureRef> texture_ref;
1853 switch (target) {
1854 case GL_TEXTURE_2D:
1855 texture_ref = info.bound_texture_2d;
1856 break;
1857 case GL_TEXTURE_CUBE_MAP:
1858 texture_ref = info.bound_texture_cube_map;
1859 break;
1860 case GL_TEXTURE_EXTERNAL_OES:
1861 texture_ref = info.bound_texture_external_oes;
1862 break;
1863 case GL_TEXTURE_RECTANGLE_ARB:
1864 texture_ref = info.bound_texture_rectangle_arb;
1865 break;
1866 default:
1867 NOTREACHED();
1868 break;
1869 }
1870 if (texture_ref.get()) {
1871 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361872 } else {
1873 last_id = 0;
1874 }
1875
[email protected]2b10c02d2014-01-29 16:43:021876 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361877 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1878}
1879
[email protected]2b10c02d2014-01-29 16:43:021880ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1881 GLuint id,
1882 GLenum target)
1883 : state_(state),
1884 target_(target) {
[email protected]ab09b612013-03-11 22:11:511885 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021886 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351887
1888 // TODO(apatrick): Check if there are any other states that need to be reset
1889 // before binding a new texture.
1890 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021891 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351892}
1893
[email protected]2b10c02d2014-01-29 16:43:021894ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511895 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021896 "ScopedTextureBinder::dtor", state_->GetErrorState());
1897 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351898}
1899
[email protected]18e785a2013-10-09 03:29:411900ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351901 GLuint id)
[email protected]18e785a2013-10-09 03:29:411902 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511903 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411904 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351905 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1906}
1907
1908ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511909 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411910 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1911 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351912}
1913
1914ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1915 GLuint id)
1916 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511917 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301918 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351919 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451920 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351921}
1922
1923ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511924 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301925 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301926 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351927}
1928
[email protected]34ff8b0c2010-10-01 20:06:021929ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271930 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521931 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341932 resolve_and_bind_ = (
1933 decoder_->offscreen_target_frame_buffer_.get() &&
1934 decoder_->IsOffscreenBufferMultisampled() &&
1935 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1936 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021937 if (!resolve_and_bind_)
1938 return;
1939
[email protected]ab09b612013-03-11 22:11:511940 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301941 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021942 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1943 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271944 GLuint targetid;
1945 if (internal) {
1946 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1947 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351948 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271949 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351950 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:361951 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:271952 decoder_->offscreen_resolved_color_texture_->Create();
1953
1954 DCHECK(decoder_->offscreen_saved_color_format_);
1955 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091956 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1957 false);
[email protected]de26b3c2011-08-03 21:54:271958 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1959 decoder_->offscreen_resolved_color_texture_.get());
1960 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1961 GL_FRAMEBUFFER_COMPLETE) {
1962 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1963 << "because offscreen resolved FBO was incomplete.";
1964 return;
1965 }
1966 }
1967 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1968 } else {
1969 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1970 }
1971 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021972 const int width = decoder_->offscreen_size_.width();
1973 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:451974 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:181975 decoder->BlitFramebufferHelper(0,
1976 0,
1977 width,
1978 height,
1979 0,
1980 0,
1981 width,
1982 height,
1983 GL_COLOR_BUFFER_BIT,
1984 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:271985 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021986}
1987
1988ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1989 if (!resolve_and_bind_)
1990 return;
1991
[email protected]ab09b612013-03-11 22:11:511992 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301993 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021994 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221995 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:451996 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:181997 }
[email protected]34ff8b0c2010-10-01 20:06:021998}
1999
[email protected]ce296892013-10-24 22:04:362000BackTexture::BackTexture(
2001 MemoryTracker* memory_tracker,
2002 ContextState* state)
2003 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2004 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482005 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252006 id_(0) {
[email protected]6217d392010-03-25 22:08:352007}
2008
[email protected]ed9f9cd2013-02-27 21:12:352009BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352010 // This does not destroy the render texture because that would require that
2011 // the associated GL context was current. Just check that it was explicitly
2012 // destroyed.
2013 DCHECK_EQ(id_, 0u);
2014}
2015
[email protected]ed9f9cd2013-02-27 21:12:352016void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302017 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362018 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352019 Destroy();
2020 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022021 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]3a4d0c52011-06-29 23:11:582022 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2023 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2024 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2025 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162026
2027 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2028 // never called on an offscreen context, no data will ever be uploaded to the
2029 // saved offscreen color texture (it is deferred until to when SwapBuffers
2030 // is called). My idea is that some nvidia drivers might have a bug where
2031 // deleting a texture that has never been populated might cause a
2032 // crash.
2033 glTexImage2D(
2034 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482035
2036 bytes_allocated_ = 16u * 16u * 4u;
2037 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352038}
2039
[email protected]ed9f9cd2013-02-27 21:12:352040bool BackTexture::AllocateStorage(
2041 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352042 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302043 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362044 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022045 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092046 uint32 image_size = 0;
2047 GLES2Util::ComputeImageDataSizes(
2048 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
2049 NULL, NULL);
2050
[email protected]7989c9e2013-01-23 06:39:262051 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2052 return false;
2053 }
2054
[email protected]40d90a22013-04-09 03:39:552055 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092056 if (zero) {
2057 zero_data.reset(new char[image_size]);
2058 memset(zero_data.get(), 0, image_size);
2059 }
[email protected]6217d392010-03-25 22:08:352060
[email protected]8f1d2aa2013-05-10 23:45:382061 glTexImage2D(GL_TEXTURE_2D,
2062 0, // mip level
2063 format,
2064 size.width(),
2065 size.height(),
2066 0, // border
2067 format,
2068 GL_UNSIGNED_BYTE,
2069 zero_data.get());
[email protected]6217d392010-03-25 22:08:352070
[email protected]d37231fa2010-04-09 21:16:022071 size_ = size;
2072
[email protected]1078f912011-12-23 13:12:142073 bool success = glGetError() == GL_NO_ERROR;
2074 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482075 memory_tracker_.TrackMemFree(bytes_allocated_);
2076 bytes_allocated_ = image_size;
2077 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142078 }
2079 return success;
[email protected]6217d392010-03-25 22:08:352080}
2081
[email protected]ed9f9cd2013-02-27 21:12:352082void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352083 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302084 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362085 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022086 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352087 glCopyTexImage2D(GL_TEXTURE_2D,
2088 0, // level
[email protected]3a4d0c52011-06-29 23:11:582089 format,
[email protected]6217d392010-03-25 22:08:352090 0, 0,
2091 size.width(),
2092 size.height(),
2093 0); // border
2094}
2095
[email protected]ed9f9cd2013-02-27 21:12:352096void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352097 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302098 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362099 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352100 glDeleteTextures(1, &id_);
2101 id_ = 0;
2102 }
[email protected]68e81a4a62012-12-13 01:16:482103 memory_tracker_.TrackMemFree(bytes_allocated_);
2104 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352105}
2106
[email protected]ed9f9cd2013-02-27 21:12:352107void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052108 id_ = 0;
2109}
2110
[email protected]d5a28e452013-10-10 01:01:402111BackRenderbuffer::BackRenderbuffer(
2112 RenderbufferManager* renderbuffer_manager,
2113 MemoryTracker* memory_tracker,
2114 ContextState* state)
2115 : renderbuffer_manager_(renderbuffer_manager),
2116 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2117 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482118 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252119 id_(0) {
[email protected]6217d392010-03-25 22:08:352120}
2121
[email protected]ed9f9cd2013-02-27 21:12:352122BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352123 // This does not destroy the render buffer because that would require that
2124 // the associated GL context was current. Just check that it was explicitly
2125 // destroyed.
2126 DCHECK_EQ(id_, 0u);
2127}
2128
[email protected]ed9f9cd2013-02-27 21:12:352129void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302130 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402131 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352132 Destroy();
2133 glGenRenderbuffersEXT(1, &id_);
2134}
2135
[email protected]f42f05b2013-11-15 21:46:182136bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2137 const gfx::Size& size,
2138 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352139 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512140 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402141 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2142 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262143
2144 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402145 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232146 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262147 return false;
2148 }
2149
2150 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2151 return false;
2152 }
2153
[email protected]34ff8b0c2010-10-01 20:06:022154 if (samples <= 1) {
2155 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2156 format,
2157 size.width(),
2158 size.height());
2159 } else {
[email protected]f42f05b2013-11-15 21:46:182160 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2161 GL_RENDERBUFFER,
2162 samples,
2163 format,
2164 size.width(),
2165 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022166 }
[email protected]1078f912011-12-23 13:12:142167 bool success = glGetError() == GL_NO_ERROR;
2168 if (success) {
[email protected]d5a28e452013-10-10 01:01:402169 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482170 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262171 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402172 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482173 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142174 }
2175 return success;
[email protected]6217d392010-03-25 22:08:352176}
2177
[email protected]ed9f9cd2013-02-27 21:12:352178void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352179 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302180 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402181 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352182 glDeleteRenderbuffersEXT(1, &id_);
2183 id_ = 0;
2184 }
[email protected]68e81a4a62012-12-13 01:16:482185 memory_tracker_.TrackMemFree(bytes_allocated_);
2186 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352187}
2188
[email protected]ed9f9cd2013-02-27 21:12:352189void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052190 id_ = 0;
2191}
2192
[email protected]ed9f9cd2013-02-27 21:12:352193BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352194 : decoder_(decoder),
2195 id_(0) {
2196}
2197
[email protected]ed9f9cd2013-02-27 21:12:352198BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352199 // This does not destroy the frame buffer because that would require that
2200 // the associated GL context was current. Just check that it was explicitly
2201 // destroyed.
2202 DCHECK_EQ(id_, 0u);
2203}
2204
[email protected]ed9f9cd2013-02-27 21:12:352205void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302206 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2207 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352208 Destroy();
2209 glGenFramebuffersEXT(1, &id_);
2210}
2211
[email protected]ed9f9cd2013-02-27 21:12:352212void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352213 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512214 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302215 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352216 ScopedFrameBufferBinder binder(decoder_, id_);
2217 GLuint attach_id = texture ? texture->id() : 0;
2218 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2219 GL_COLOR_ATTACHMENT0,
2220 GL_TEXTURE_2D,
2221 attach_id,
2222 0);
2223}
2224
[email protected]ed9f9cd2013-02-27 21:12:352225void BackFramebuffer::AttachRenderBuffer(GLenum target,
2226 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352227 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512228 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302229 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352230 ScopedFrameBufferBinder binder(decoder_, id_);
2231 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2232 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152233 target,
[email protected]6217d392010-03-25 22:08:352234 GL_RENDERBUFFER,
2235 attach_id);
2236}
2237
[email protected]ed9f9cd2013-02-27 21:12:352238void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352239 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302240 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2241 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352242 glDeleteFramebuffersEXT(1, &id_);
2243 id_ = 0;
2244 }
2245}
2246
[email protected]ed9f9cd2013-02-27 21:12:352247void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052248 id_ = 0;
2249}
2250
[email protected]ed9f9cd2013-02-27 21:12:352251GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352252 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302253 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2254 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352255 ScopedFrameBufferBinder binder(decoder_, id_);
2256 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2257}
2258
[email protected]aa7666122011-09-02 19:45:522259GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2260 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322261}
2262
[email protected]aa7666122011-09-02 19:45:522263GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392264 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572265 group_(group),
[email protected]1d82e822013-04-10 21:32:322266 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132267 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282268 unpack_flip_y_(false),
2269 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172270 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242271 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492272 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242273 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402274 fixed_attrib_buffer_id_(0),
2275 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022276 offscreen_target_color_format_(0),
2277 offscreen_target_depth_format_(0),
2278 offscreen_target_stencil_format_(0),
2279 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562280 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052281 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132282 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462283 back_buffer_has_depth_(false),
2284 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582285 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562286 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052287 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112288 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002289 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432290 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302291 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512292 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222293 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432294 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042295 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102296 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492297 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132298 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062299 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282300 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132301 lose_context_when_out_of_memory_(false),
[email protected]cae20172012-12-07 00:06:192302 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2303 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022304 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102305 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002306 texture_state_(group_->feature_info()
2307 ->workarounds()
2308 .texsubimage2d_faster_than_teximage2d),
[email protected]4a4c18b2013-09-13 22:50:102309 validation_texture_(0),
2310 validation_fbo_multisample_(0),
2311 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572312 DCHECK(group);
2313
[email protected]b1122982010-05-17 23:04:242314 attrib_0_value_.v[0] = 0.0f;
2315 attrib_0_value_.v[1] = 0.0f;
2316 attrib_0_value_.v[2] = 0.0f;
2317 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152318
[email protected]c2f8c8402010-12-06 18:07:242319 // The shader translator is used for WebGL even when running on EGL
2320 // because additional restrictions are needed (like only enabling
2321 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562322 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2323 // the empty string to CompileShader and this is not a valid shader.
2324 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002325 CommandLine::ForCurrentProcess()->HasSwitch(
2326 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152327 use_shader_translator_ = false;
2328 }
[email protected]96449d2c2009-11-25 00:01:322329}
2330
[email protected]80eb6b52012-01-19 00:14:412331GLES2DecoderImpl::~GLES2DecoderImpl() {
2332}
2333
[email protected]c410da802011-03-14 19:17:412334bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382335 const scoped_refptr<gfx::GLSurface>& surface,
2336 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232337 bool offscreen,
[email protected]c410da802011-03-14 19:17:412338 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292339 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242340 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322341 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382342 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302343 DCHECK(!context_.get());
2344
[email protected]55e136f2013-04-03 18:50:062345 set_initialized();
[email protected]bccc0f32014-01-10 03:18:082346 gpu_tracer_ = GPUTracer::Create(this);
[email protected]8f9b8dd2013-09-12 18:05:132347 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]cac16542014-01-15 17:53:512348 // TODO(vmiura): Enable changing gpu_trace_level_ at runtime
2349 gpu_trace_level_ = 2;
2350 gpu_trace_commands_ = false;
[email protected]fb97b662013-02-20 23:02:142351
[email protected]e844ae22012-01-14 03:36:262352 if (CommandLine::ForCurrentProcess()->HasSwitch(
2353 switches::kEnableGPUDebugging)) {
2354 set_debug(true);
2355 }
2356
[email protected]39ba4f02012-03-26 01:16:002357 if (CommandLine::ForCurrentProcess()->HasSwitch(
2358 switches::kEnableGPUCommandLogging)) {
2359 set_log_commands(true);
2360 }
2361
[email protected]062c38b2012-01-18 03:25:102362 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2363 switches::kCompileShaderAlwaysSucceeds);
2364
[email protected]f62a5ab2011-05-23 20:34:152365
[email protected]63c9b052012-05-17 18:27:382366 // Take ownership of the context and surface. The surface can be replaced with
2367 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382368 context_ = context;
[email protected]63c9b052012-05-17 18:27:382369 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182370
[email protected]65f7efe2013-11-28 03:11:472371 ContextCreationAttribHelper attrib_parser;
2372 if (!attrib_parser.Parse(attribs))
2373 return false;
2374
[email protected]828a3932014-04-02 14:43:132375 // Save the loseContextWhenOutOfMemory context creation attribute.
2376 lose_context_when_out_of_memory_ =
2377 attrib_parser.lose_context_when_out_of_memory_;
2378
[email protected]65f7efe2013-11-28 03:11:472379 // If the failIfMajorPerformanceCaveat context creation attribute was true
2380 // and we are using a software renderer, fail.
2381 if (attrib_parser.fail_if_major_perf_caveat_ &&
2382 feature_info_->feature_flags().is_swiftshader) {
2383 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2384 Destroy(true);
2385 return false;
2386 }
2387
[email protected]956aec52013-09-05 15:41:192388 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222389 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392390 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422391 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382392 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032393 return false;
[email protected]a3ded6d2010-10-19 06:44:392394 }
[email protected]b64c24952012-04-19 03:20:272395 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282396
[email protected]e82fb792011-09-22 00:33:292397 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502398
[email protected]af6380962012-11-29 23:24:132399 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482400 vertex_array_manager_.reset(new VertexArrayManager());
2401
2402 GLuint default_vertex_attrib_service_id = 0;
2403 if (features().native_vertex_array_object) {
2404 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2405 glBindVertexArrayOES(default_vertex_attrib_service_id);
2406 }
2407
2408 state_.default_vertex_attrib_manager =
2409 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2410
[email protected]81f20a622014-04-18 01:54:522411 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002412 group_->max_vertex_attribs(),
2413 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462414
[email protected]81f20a622014-04-18 01:54:522415 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572416 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322417
[email protected]7cd76fd2013-06-02 21:11:112418 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532419
[email protected]b63f1d62014-07-18 15:40:592420 image_manager_.reset(new ImageManager);
2421
[email protected]302ce6d2011-07-07 23:28:112422 util_.set_num_compressed_texture_formats(
2423 validators_->compressed_texture_format.GetValues().size());
2424
[email protected]1071e572011-02-09 20:00:122425 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2426 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2427 // OpenGL ES 2.0 does not have this issue.
2428 glEnableVertexAttribArray(0);
2429 }
[email protected]b1122982010-05-17 23:04:242430 glGenBuffersARB(1, &attrib_0_buffer_id_);
2431 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2432 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2433 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402434 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082435
[email protected]1868a342012-11-07 15:56:022436 state_.texture_units.resize(group_->max_texture_units());
2437 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492438 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312439 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492440 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152441 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492442 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072443 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492444 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572445 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312446 }
[email protected]62e155e2012-10-23 22:43:152447 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492448 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072449 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492450 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572451 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462452 }
[email protected]370eaf12013-05-18 09:19:492453 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2454 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572455 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492456 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2457 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572458 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152459 }
[email protected]00f893d2010-08-24 18:55:492460 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502461 CHECK_GL_ERROR();
2462
[email protected]069944672012-04-25 20:52:232463 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022464 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542465 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022466 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432467 // max_sample_count must be initialized to a sane value. If
2468 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2469 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022470 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2471 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2472 max_sample_count);
2473 } else {
2474 offscreen_target_samples_ = 1;
2475 }
[email protected]8a61d872012-01-20 12:43:562476 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022477
2478 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2479 const bool rgb8_supported =
2480 context_->HasExtension("GL_OES_rgb8_rgba8");
2481 // The only available default render buffer formats in GLES2 have very
2482 // little precision. Don't enable multisampling unless 8-bit render
2483 // buffer formats are available--instead fall back to 8-bit textures.
2484 if (rgb8_supported && offscreen_target_samples_ > 1) {
2485 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2486 GL_RGBA8 : GL_RGB8;
2487 } else {
2488 offscreen_target_samples_ = 1;
2489 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2490 GL_RGBA : GL_RGB;
2491 }
2492
2493 // ANGLE only supports packed depth/stencil formats, so use it if it is
2494 // available.
2495 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182496 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272497 VLOG(1) << "GL_OES_packed_depth_stencil "
2498 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002499 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2500 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022501 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2502 offscreen_target_stencil_format_ = 0;
2503 } else {
2504 // It may be the case that this depth/stencil combination is not
2505 // supported, but this will be checked later by CheckFramebufferStatus.
2506 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2507 GL_DEPTH_COMPONENT16 : 0;
2508 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2509 GL_STENCIL_INDEX8 : 0;
2510 }
2511 } else {
2512 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2513 GL_RGBA : GL_RGB;
2514
2515 // If depth is requested at all, use the packed depth stencil format if
2516 // it's available, as some desktop GL drivers don't support any non-packed
2517 // formats for depth attachments.
2518 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182519 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272520 VLOG(1) << "GL_EXT_packed_depth_stencil "
2521 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022522
[email protected]71ee3642010-10-14 18:08:002523 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2524 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022525 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2526 offscreen_target_stencil_format_ = 0;
2527 } else {
2528 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2529 GL_DEPTH_COMPONENT : 0;
2530 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2531 GL_STENCIL_INDEX : 0;
2532 }
2533 }
2534
[email protected]97872062010-11-03 19:07:052535 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2536 GL_RGBA : GL_RGB;
2537
[email protected]6217d392010-03-25 22:08:352538 // Create the target frame buffer. This is the one that the client renders
2539 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352540 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352541 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022542 // Due to GLES2 format limitations, either the color texture (for
2543 // non-multisampling) or the color render buffer (for multisampling) will be
2544 // attached to the offscreen frame buffer. The render buffer has more
2545 // limited formats available to it, but the texture can't do multisampling.
2546 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402547 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2548 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022549 offscreen_target_color_render_buffer_->Create();
2550 } else {
[email protected]ce296892013-10-24 22:04:362551 offscreen_target_color_texture_.reset(new BackTexture(
2552 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022553 offscreen_target_color_texture_->Create();
2554 }
[email protected]d5a28e452013-10-10 01:01:402555 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2556 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152557 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402558 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2559 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152560 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352561
2562 // Create the saved offscreen texture. The target frame buffer is copied
2563 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352564 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022565 offscreen_saved_frame_buffer_->Create();
2566 //
[email protected]ce296892013-10-24 22:04:362567 offscreen_saved_color_texture_.reset(new BackTexture(
2568 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352569 offscreen_saved_color_texture_->Create();
2570
[email protected]6217d392010-03-25 22:08:352571 // Allocate the render buffers at their initial size and check the status
2572 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592573 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012574 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382575 Destroy(true);
[email protected]6217d392010-03-25 22:08:352576 return false;
2577 }
2578
[email protected]678a73f2012-12-19 19:22:092579 // Allocate the offscreen saved color texture.
2580 DCHECK(offscreen_saved_color_format_);
2581 offscreen_saved_color_texture_->AllocateStorage(
2582 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2583
2584 offscreen_saved_frame_buffer_->AttachRenderTexture(
2585 offscreen_saved_color_texture_.get());
2586 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2587 GL_FRAMEBUFFER_COMPLETE) {
2588 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2589 Destroy(true);
2590 return false;
2591 }
2592
[email protected]6217d392010-03-25 22:08:352593 // Bind to the new default frame buffer (the offscreen target frame buffer).
2594 // This should now be associated with ID zero.
2595 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102596 } else {
2597 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2598 // These are NOT if the back buffer has these proprorties. They are
2599 // if we want the command buffer to enforce them regardless of what
2600 // the real backbuffer is assuming the real back buffer gives us more than
2601 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2602 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2603 // can't do anything about that.
2604
2605 GLint v = 0;
2606 glGetIntegerv(GL_ALPHA_BITS, &v);
2607 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2608 // user requested RGB then RGB. If the user did not specify a preference
2609 // than use whatever we were given. Same for DEPTH and STENCIL.
2610 back_buffer_color_format_ =
2611 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2612 glGetIntegerv(GL_DEPTH_BITS, &v);
2613 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2614 glGetIntegerv(GL_STENCIL_BITS, &v);
2615 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
[email protected]6217d392010-03-25 22:08:352616 }
2617
[email protected]76a0ee102010-04-07 21:03:042618 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2619 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2620 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372621 // mailing list archives. It also implicitly enables the desktop GL
2622 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2623 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152624 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2625 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372626 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152627 }
[email protected]de17df392010-04-23 21:09:412628
[email protected]706b69f2012-07-27 04:59:302629 has_robustness_extension_ =
2630 context->HasExtension("GL_ARB_robustness") ||
2631 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432632
[email protected]c2f8c8402010-12-06 18:07:242633 if (!InitializeShaderTranslator()) {
2634 return false;
[email protected]de17df392010-04-23 21:09:412635 }
[email protected]76a0ee102010-04-07 21:03:042636
[email protected]e259eb412012-10-13 05:47:242637 state_.viewport_width = size.width();
2638 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282639
[email protected]5904806b2012-05-08 18:10:222640 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282641 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022642 viewport_max_width_ = viewport_params[0];
2643 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282644
[email protected]88a61bf2012-10-27 13:00:422645 state_.scissor_width = state_.viewport_width;
2646 state_.scissor_height = state_.viewport_height;
2647
[email protected]11f3e702012-06-19 19:00:012648 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342649 state_.InitCapabilities(NULL);
2650 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242651 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012652
2653 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2654 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2655 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2656 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2657
[email protected]88cfd132013-07-11 00:59:002658 bool call_gl_clear = true;
2659#if defined(OS_ANDROID)
2660 // Temporary workaround for Android WebView because this clear ignores the
2661 // clip and corrupts that external UI of the App. Not calling glClear is ok
2662 // because the system already clears the buffer before each draw. Proper
2663 // fix might be setting the scissor clip properly before initialize. See
2664 // crbug.com/259023 for details.
2665 call_gl_clear = surface_->GetHandle();
2666#endif
2667 if (call_gl_clear) {
2668 // Clear the backbuffer.
2669 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2670 }
[email protected]561cc0a62013-05-07 18:34:452671
[email protected]b381ee32014-03-22 02:43:432672 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2673 if (feature_info_->workarounds()
2674 .disable_post_sub_buffers_for_onscreen_surfaces &&
2675 !surface->IsOffscreen())
2676 supports_post_sub_buffer_ = false;
2677
[email protected]62e155e2012-10-23 22:43:152678 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462679 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2680 }
[email protected]dd289a5d62012-06-30 22:05:462681
[email protected]9b753992013-04-27 02:04:412682 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2683 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242684 }
[email protected]85cb4682013-04-20 00:54:242685
[email protected]97419c02013-04-10 02:52:382686 // Only compositor contexts are known to use only the subset of GL
2687 // that can be safely migrated between the iGPU and the dGPU. Mark
2688 // those contexts as safe to forcibly transition between the GPUs.
2689 // http://crbug.com/180876, http://crbug.com/227228
2690 if (!offscreen)
2691 context_->SetSafeToForceGpuSwitch();
2692
[email protected]85a4ac22013-05-31 01:58:472693 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072694 AsyncPixelTransferManager::Create(context.get()));
2695 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592696
[email protected]91c94eb2013-10-22 10:32:542697 framebuffer_manager()->AddObserver(this);
2698
[email protected]246a70452010-03-05 21:53:502699 return true;
[email protected]96449d2c2009-11-25 00:01:322700}
2701
[email protected]6d668892013-12-04 21:37:122702Capabilities GLES2DecoderImpl::GetCapabilities() {
2703 DCHECK(initialized());
2704
2705 Capabilities caps;
2706
[email protected]6d668892013-12-04 21:37:122707 caps.egl_image_external =
2708 feature_info_->feature_flags().oes_egl_image_external;
2709 caps.texture_format_bgra8888 =
2710 feature_info_->feature_flags().ext_texture_format_bgra8888;
2711 caps.texture_format_etc1 =
2712 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
2713 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2714 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2715 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2716 caps.discard_framebuffer =
2717 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352718 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122719
2720#if defined(OS_MACOSX)
2721 // This is unconditionally true on mac, no need to test for it at runtime.
2722 caps.iosurface = true;
2723#endif
2724
[email protected]b381ee32014-03-22 02:43:432725 caps.post_sub_buffer = supports_post_sub_buffer_;
[email protected]b63f1d62014-07-18 15:40:592726 caps.map_image = true;
[email protected]6d668892013-12-04 21:37:122727
2728 return caps;
2729}
2730
[email protected]302ce6d2011-07-07 23:28:112731void GLES2DecoderImpl::UpdateCapabilities() {
2732 util_.set_num_compressed_texture_formats(
2733 validators_->compressed_texture_format.GetValues().size());
2734 util_.set_num_shader_binary_formats(
2735 validators_->shader_binary_format.GetValues().size());
2736}
2737
[email protected]c2f8c8402010-12-06 18:07:242738bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442739 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2740
[email protected]c2f8c8402010-12-06 18:07:242741 if (!use_shader_translator_) {
2742 return true;
2743 }
2744 ShBuiltInResources resources;
2745 ShInitBuiltInResources(&resources);
2746 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2747 resources.MaxVertexUniformVectors =
2748 group_->max_vertex_uniform_vectors();
2749 resources.MaxVaryingVectors = group_->max_varying_vectors();
2750 resources.MaxVertexTextureImageUnits =
2751 group_->max_vertex_texture_image_units();
2752 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2753 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2754 resources.MaxFragmentUniformVectors =
2755 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492756 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242757 resources.MaxExpressionComplexity = 256;
2758 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042759
[email protected]9e98f61b2013-03-05 02:21:142760#if (ANGLE_SH_VERSION >= 110)
[email protected]46c86752013-05-21 05:08:392761 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212762 GLint precision = 0;
2763 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2764 range, &precision);
[email protected]448e459e2013-06-12 17:00:412765 resources.FragmentPrecisionHigh =
2766 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142767#endif
2768
[email protected]f0d74742011-10-03 16:31:042769 if (force_webgl_glsl_validation_) {
2770 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492771 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132772 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442773 if (!draw_buffers_explicitly_enabled_)
2774 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062775#if (ANGLE_SH_VERSION >= 123)
2776 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
2777#endif
[email protected]f0d74742011-10-03 16:31:042778 } else {
2779 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152780 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462781 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152782 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062783 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152784 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492785 resources.EXT_draw_buffers =
2786 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492787 resources.EXT_frag_depth =
2788 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062789#if (ANGLE_SH_VERSION >= 123)
2790 resources.EXT_shader_texture_lod =
2791 features().ext_shader_texture_lod ? 1 : 0;
2792#endif
[email protected]f0d74742011-10-03 16:31:042793 }
2794
[email protected]26b61442013-03-17 16:12:012795 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2796 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052797 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022798#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052799 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022800#else
2801 resources.HashFunction = &CityHash64;
2802#endif
[email protected]6aedcdc2013-01-24 01:25:052803 else
2804 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122805 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2806 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2807 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212808 int driver_bug_workarounds = 0;
2809 if (workarounds().needs_glsl_built_in_function_emulation)
2810 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542811 if (workarounds().init_gl_position_in_vertex_shader)
2812 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112813 if (workarounds().unfold_short_circuit_as_ternary_operation)
2814 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052815 if (workarounds().init_varyings_without_static_use)
2816 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062817 if (workarounds().unroll_for_loop_with_sampler_array_index)
2818 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:252819 if (workarounds().scalarize_vec_and_mat_constructor_args)
2820 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]87fb6ab2012-06-13 22:28:042821
[email protected]03cef9b2014-04-03 15:58:142822 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262823#if (ANGLE_SH_VERSION >= 126)
2824 GL_VERTEX_SHADER,
2825#else
[email protected]03cef9b2014-04-03 15:58:142826 SH_VERTEX_SHADER,
[email protected]aeecc6b2014-07-03 17:18:262827#endif
[email protected]03cef9b2014-04-03 15:58:142828 shader_spec,
2829 &resources,
[email protected]a6739bc2013-09-07 04:45:212830 implementation_type,
2831 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042832 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242833 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382834 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242835 return false;
2836 }
[email protected]87fb6ab2012-06-13 22:28:042837
[email protected]03cef9b2014-04-03 15:58:142838 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262839#if (ANGLE_SH_VERSION >= 126)
2840 GL_FRAGMENT_SHADER,
2841#else
[email protected]03cef9b2014-04-03 15:58:142842 SH_FRAGMENT_SHADER,
[email protected]aeecc6b2014-07-03 17:18:262843#endif
[email protected]03cef9b2014-04-03 15:58:142844 shader_spec,
2845 &resources,
[email protected]a6739bc2013-09-07 04:45:212846 implementation_type,
2847 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042848 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242849 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382850 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242851 return false;
2852 }
2853 return true;
2854}
2855
[email protected]ae51d192010-04-27 00:48:032856bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472857 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352858 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032859 return false;
2860 }
2861 }
[email protected]40d90a22013-04-09 03:39:552862 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032863 glGenBuffersARB(n, service_ids.get());
2864 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352865 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032866 }
2867 return true;
2868}
2869
2870bool GLES2DecoderImpl::GenFramebuffersHelper(
2871 GLsizei n, const GLuint* client_ids) {
2872 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352873 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032874 return false;
2875 }
2876 }
[email protected]40d90a22013-04-09 03:39:552877 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032878 glGenFramebuffersEXT(n, service_ids.get());
2879 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352880 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032881 }
2882 return true;
2883}
2884
2885bool GLES2DecoderImpl::GenRenderbuffersHelper(
2886 GLsizei n, const GLuint* client_ids) {
2887 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352888 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032889 return false;
2890 }
2891 }
[email protected]40d90a22013-04-09 03:39:552892 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032893 glGenRenderbuffersEXT(n, service_ids.get());
2894 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352895 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032896 }
2897 return true;
2898}
2899
2900bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2901 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352902 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032903 return false;
2904 }
2905 }
[email protected]40d90a22013-04-09 03:39:552906 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032907 glGenTextures(n, service_ids.get());
2908 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352909 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032910 }
2911 return true;
2912}
2913
2914void GLES2DecoderImpl::DeleteBuffersHelper(
2915 GLsizei n, const GLuint* client_ids) {
2916 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212917 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102918 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242919 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112920 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242921 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102922 }
[email protected]ed9f9cd2013-02-27 21:12:352923 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032924 }
[email protected]a93bb842010-02-16 23:03:472925 }
[email protected]07f54fcc2009-12-22 02:46:302926}
2927
[email protected]ae51d192010-04-27 00:48:032928void GLES2DecoderImpl::DeleteFramebuffersHelper(
2929 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452930 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152931 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112932
[email protected]a25fa872010-03-25 02:57:582933 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352934 Framebuffer* framebuffer =
2935 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102936 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:342937 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2938 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442939 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452940 GLenum target = supports_separate_framebuffer_binds ?
2941 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112942 glBindFramebufferEXT(target, GetBackbufferServiceId());
2943 }
[email protected]9d3b2e12013-10-02 01:04:342944 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2945 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452946 GLenum target = supports_separate_framebuffer_binds ?
2947 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112948 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462949 }
[email protected]70d34263c2013-01-09 00:27:452950 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352951 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032952 }
[email protected]a25fa872010-03-25 02:57:582953 }
[email protected]07f54fcc2009-12-22 02:46:302954}
2955
[email protected]ae51d192010-04-27 00:48:032956void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2957 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452958 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152959 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582960 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352961 Renderbuffer* renderbuffer =
2962 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102963 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112964 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242965 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102966 }
2967 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452968 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342969 if (framebuffer_state_.bound_read_framebuffer.get()) {
2970 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112971 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102972 }
[email protected]9d3b2e12013-10-02 01:04:342973 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2974 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112975 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102976 }
2977 } else {
[email protected]9d3b2e12013-10-02 01:04:342978 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2979 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112980 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102981 }
2982 }
[email protected]c986af502013-08-14 01:04:442983 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:352984 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032985 }
[email protected]a25fa872010-03-25 02:57:582986 }
[email protected]07f54fcc2009-12-22 02:46:302987}
2988
[email protected]ae51d192010-04-27 00:48:032989void GLES2DecoderImpl::DeleteTexturesHelper(
2990 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452991 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152992 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472993 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492994 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2995 if (texture_ref) {
2996 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102997 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:442998 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462999 }
[email protected]370eaf12013-05-18 09:19:493000 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023001 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493002 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103003 }
3004 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453005 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343006 if (framebuffer_state_.bound_read_framebuffer.get()) {
3007 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113008 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103009 }
[email protected]9d3b2e12013-10-02 01:04:343010 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3011 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113012 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103013 }
3014 } else {
[email protected]9d3b2e12013-10-02 01:04:343015 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3016 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113017 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103018 }
3019 }
[email protected]e51bdf32011-11-23 22:21:463020#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073021 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463022 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3023 ReleaseIOSurfaceForTexture(service_id);
3024 }
3025#endif
[email protected]ed9f9cd2013-02-27 21:12:353026 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033027 }
[email protected]a93bb842010-02-16 23:03:473028 }
[email protected]07f54fcc2009-12-22 02:46:303029}
3030
[email protected]43f28f832010-02-03 02:28:483031// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323032
[email protected]eb54a562010-01-20 21:55:183033bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343034 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383035 return false;
3036
[email protected]177d1342013-12-07 04:20:343037 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433038 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293039
3040 // Some D3D drivers cannot recover from device lost in the GPU process
3041 // sandbox. Allow a new GPU process to launch.
3042 if (workarounds().exit_on_context_lost) {
3043 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
3044 << " a D3D device in the Chrome GPU process sandbox.";
[email protected]6eb775352013-08-27 05:57:163045#if defined(OS_WIN)
3046 base::win::SetShouldCrashOnProcessDetach(false);
3047#endif
[email protected]e9f0ca82013-04-01 23:52:293048 exit(0);
3049 }
3050
[email protected]63c9b052012-05-17 18:27:383051 return false;
[email protected]38d139d2011-07-14 00:38:433052 }
3053
[email protected]69a8701e2013-03-07 21:31:093054 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093055
[email protected]9b753992013-04-27 02:04:413056 // Rebind the FBO if it was unbound by the context.
3057 if (workarounds().unbind_fbo_on_context_switch)
3058 RestoreFramebufferBindings();
3059
[email protected]c986af502013-08-14 01:04:443060 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493061
[email protected]69a8701e2013-03-07 21:31:093062 return true;
3063}
3064
3065void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553066 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323067 if (engine() && query_manager_.get())
3068 query_manager_->ProcessPendingTransferQueries();
3069
[email protected]5b3a8e02013-03-13 05:36:443070 // TODO(epenner): Is there a better place to do this?
3071 // This needs to occur before we execute any batch of commands
3072 // from the client, as the client may have recieved an async
3073 // completion while issuing those commands.
3074 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483075 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183076}
3077
[email protected]8e3e0662010-08-23 18:46:303078static void RebindCurrentFramebuffer(
3079 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063080 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243081 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063082 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463083
[email protected]a3783712012-01-20 22:18:243084 if (framebuffer_id == 0) {
3085 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303086 }
[email protected]297ca1c2011-06-20 23:08:463087
[email protected]8e3e0662010-08-23 18:46:303088 glBindFramebufferEXT(target, framebuffer_id);
3089}
3090
3091void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443092 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463093
[email protected]62e155e2012-10-23 22:43:153094 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303095 RebindCurrentFramebuffer(
3096 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343097 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243098 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303099 } else {
3100 RebindCurrentFramebuffer(
3101 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343102 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243103 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303104 RebindCurrentFramebuffer(
3105 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343106 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243107 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303108 }
[email protected]70d34263c2013-01-09 00:27:453109 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303110}
3111
[email protected]0d6bfdc2011-11-02 01:32:203112bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353113 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203114 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103115 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:583116 if (backbuffer_needs_clear_bits_) {
3117 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3118 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
[email protected]454157e2014-05-03 02:49:453119 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583120 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473121 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3122 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583123 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453124 state_.SetDeviceDepthMask(GL_TRUE);
3125 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423126 bool reset_draw_buffer = false;
3127 if ((backbuffer_needs_clear_bits_ | GL_COLOR_BUFFER_BIT) != 0 &&
3128 group_->draw_buffer() == GL_NONE) {
[email protected]ee757922014-06-06 05:21:423129 reset_draw_buffer = true;
3130 GLenum buf = GL_BACK;
3131 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3132 buf = GL_COLOR_ATTACHMENT0;
3133 glDrawBuffersARB(1, &buf);
3134 }
[email protected]60f22d32012-12-12 00:31:583135 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423136 if (reset_draw_buffer) {
3137 GLenum buf = GL_NONE;
3138 glDrawBuffersARB(1, &buf);
3139 }
[email protected]60f22d32012-12-12 00:31:583140 backbuffer_needs_clear_bits_ = 0;
3141 RestoreClearState();
3142 }
[email protected]0d6bfdc2011-11-02 01:32:203143 return true;
3144 }
3145
[email protected]968351b2011-12-20 08:26:513146 if (framebuffer_manager()->IsComplete(framebuffer)) {
3147 return true;
3148 }
3149
[email protected]0d6bfdc2011-11-02 01:32:203150 GLenum completeness = framebuffer->IsPossiblyComplete();
3151 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513152 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433153 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273154 return false;
3155 }
[email protected]0d6bfdc2011-11-02 01:32:203156
3157 // Are all the attachments cleared?
3158 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3159 texture_manager()->HaveUnclearedMips()) {
3160 if (!framebuffer->IsCleared()) {
3161 // Can we clear them?
[email protected]73276522012-11-09 05:50:203162 if (framebuffer->GetStatus(texture_manager(), target) !=
3163 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513164 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433165 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3166 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203167 return false;
3168 }
3169 ClearUnclearedAttachments(target, framebuffer);
3170 }
3171 }
3172
[email protected]968351b2011-12-20 08:26:513173 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203174 if (framebuffer->GetStatus(texture_manager(), target) !=
3175 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513176 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433177 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3178 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513179 return false;
3180 }
3181 framebuffer_manager()->MarkAsComplete(framebuffer);
3182 }
3183
[email protected]0d6bfdc2011-11-02 01:32:203184 // NOTE: At this point we don't know if the framebuffer is complete but
3185 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273186 return true;
3187}
3188
[email protected]0d6bfdc2011-11-02 01:32:203189bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153190 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513191 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343192 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3193 func_name);
[email protected]28718a92013-04-04 12:12:513194
3195 if (valid)
3196 OnUseFramebuffer();
3197
3198 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203199 }
[email protected]9d3b2e12013-10-02 01:04:343200 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113201 GL_DRAW_FRAMEBUFFER_EXT,
3202 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343203 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113204 GL_READ_FRAMEBUFFER_EXT,
3205 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203206}
3207
[email protected]2ea5950d2014-07-09 18:20:343208bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3209 const char* func_name) {
3210 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3211 framebuffer_state_.bound_read_framebuffer.get() :
3212 framebuffer_state_.bound_draw_framebuffer.get();
3213 if (!framebuffer)
3214 return true;
3215 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3216 LOCAL_SET_GL_ERROR(
3217 GL_INVALID_OPERATION, func_name, "no color image attached");
3218 return false;
3219 }
3220 return true;
3221}
3222
[email protected]8e3e0662010-08-23 18:46:303223gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353224 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453225 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203226 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353227 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203228 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263229 if (attachment) {
3230 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503231 }
[email protected]9edc6b22010-12-23 02:00:263232 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023233 } else if (offscreen_target_frame_buffer_.get()) {
3234 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353235 } else {
[email protected]f62a5ab2011-05-23 20:34:153236 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023237 }
[email protected]246a70452010-03-05 21:53:503238}
3239
[email protected]68586372013-12-11 01:27:593240GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3241 Framebuffer* framebuffer =
3242 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3243 if (framebuffer != NULL) {
3244 return framebuffer->GetColorAttachmentTextureType();
3245 } else {
3246 return GL_UNSIGNED_BYTE;
3247 }
3248}
3249
[email protected]9edc6b22010-12-23 02:00:263250GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353251 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453252 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203253 if (framebuffer != NULL) {
3254 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463255 } else if (offscreen_target_frame_buffer_.get()) {
3256 return offscreen_target_color_format_;
3257 } else {
3258 return back_buffer_color_format_;
3259 }
3260}
3261
3262GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353263 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453264 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203265 if (framebuffer != NULL) {
3266 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263267 } else if (offscreen_target_frame_buffer_.get()) {
3268 return offscreen_target_color_format_;
3269 } else {
[email protected]32fe9aa2011-01-21 23:47:133270 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263271 }
3272}
3273
[email protected]9a5afa432011-07-22 18:16:393274void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513275 if (!offscreen_saved_color_texture_info_.get())
3276 return;
3277 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3278 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3279 texture_manager()->SetLevelInfo(
3280 offscreen_saved_color_texture_info_.get(),
3281 GL_TEXTURE_2D,
3282 0, // level
3283 GL_RGBA,
3284 offscreen_size_.width(),
3285 offscreen_size_.height(),
3286 1, // depth
3287 0, // border
3288 GL_RGBA,
3289 GL_UNSIGNED_BYTE,
3290 true);
[email protected]737191ee72014-03-09 08:02:423291 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513292 "UpdateParentTextureInfo",
3293 GetErrorState(),
3294 offscreen_saved_color_texture_info_.get(),
3295 GL_TEXTURE_MAG_FILTER,
3296 GL_NEAREST);
[email protected]737191ee72014-03-09 08:02:423297 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513298 "UpdateParentTextureInfo",
3299 GetErrorState(),
3300 offscreen_saved_color_texture_info_.get(),
3301 GL_TEXTURE_MIN_FILTER,
3302 GL_NEAREST);
[email protected]737191ee72014-03-09 08:02:423303 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513304 "UpdateParentTextureInfo",
3305 GetErrorState(),
3306 offscreen_saved_color_texture_info_.get(),
3307 GL_TEXTURE_WRAP_S,
3308 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423309 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513310 "UpdateParentTextureInfo",
3311 GetErrorState(),
3312 offscreen_saved_color_texture_info_.get(),
3313 GL_TEXTURE_WRAP_T,
3314 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443315 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3316 &state_, target);
[email protected]2ad674132013-06-05 07:48:513317 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353318}
3319
[email protected]799b4b22011-08-22 17:09:593320void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073321 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523322 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003323}
3324
[email protected]1d82e822013-04-10 21:32:323325Logger* GLES2DecoderImpl::GetLogger() {
3326 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523327}
3328
[email protected]cac16542014-01-15 17:53:513329void GLES2DecoderImpl::BeginDecoding() {
3330 gpu_tracer_->BeginDecoding();
3331 gpu_trace_commands_ = gpu_tracer_->IsTracing();
3332}
3333
3334void GLES2DecoderImpl::EndDecoding() {
3335 gpu_tracer_->EndDecoding();
3336}
3337
[email protected]d3eba342013-04-18 21:11:503338ErrorState* GLES2DecoderImpl::GetErrorState() {
3339 return state_.GetErrorState();
3340}
3341
[email protected]e3932abb2013-03-13 00:01:373342void GLES2DecoderImpl::SetShaderCacheCallback(
3343 const ShaderCacheCallback& callback) {
3344 shader_cache_callback_ = callback;
3345}
3346
[email protected]840a7e462013-02-27 01:29:513347void GLES2DecoderImpl::SetWaitSyncPointCallback(
3348 const WaitSyncPointCallback& callback) {
3349 wait_sync_point_callback_ = callback;
3350}
3351
[email protected]85a4ac22013-05-31 01:58:473352AsyncPixelTransferManager*
3353 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3354 return async_pixel_transfer_manager_.get();
3355}
3356
3357void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3358 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593359}
3360
[email protected]498b5c072013-06-04 19:30:073361void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3362 AsyncPixelTransferManager* manager) {
3363 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3364}
3365
[email protected]1318e922010-09-17 22:03:163366bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3367 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493368 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3369 if (texture_ref) {
3370 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163371 return true;
3372 }
3373 return false;
3374}
3375
[email protected]63b465922012-09-06 02:04:523376uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443377 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483378 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523379}
3380
3381base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443382 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483383 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523384}
3385
3386base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3387 return total_processing_commands_time_;
3388}
3389
[email protected]dc25dda2012-09-27 21:36:303390void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3391 total_processing_commands_time_ += time;
3392}
3393
[email protected]63c9b052012-05-17 18:27:383394void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063395 if (!initialized())
3396 return;
3397
[email protected]63c9b052012-05-17 18:27:383398 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053399
[email protected]80eb6b52012-01-19 00:14:413400 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243401 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523402 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023403 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243404 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133405 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343406 framebuffer_state_.bound_read_framebuffer = NULL;
3407 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243408 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413409
[email protected]cadac622013-06-11 16:46:363410 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513411 DCHECK(offscreen_target_color_texture_);
3412 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3413 offscreen_saved_color_texture_->id());
3414 offscreen_saved_color_texture_->Invalidate();
3415 offscreen_saved_color_texture_info_ = NULL;
3416 }
[email protected]eadc96792010-10-27 19:39:393417 if (have_context) {
[email protected]c322e882012-05-23 18:06:183418 if (copy_texture_CHROMIUM_.get()) {
3419 copy_texture_CHROMIUM_->Destroy();
3420 copy_texture_CHROMIUM_.reset();
3421 }
[email protected]43410e92012-04-20 17:06:283422
[email protected]7cd76fd2013-06-02 21:11:113423 if (state_.current_program.get()) {
3424 program_manager()->UnuseProgram(shader_manager(),
3425 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143426 }
3427
[email protected]b1122982010-05-17 23:04:243428 if (attrib_0_buffer_id_) {
3429 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3430 }
[email protected]8fbedc02010-11-18 18:43:403431 if (fixed_attrib_buffer_id_) {
3432 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3433 }
[email protected]b1122982010-05-17 23:04:243434
[email protected]4a4c18b2013-09-13 22:50:103435 if (validation_texture_) {
3436 glDeleteTextures(1, &validation_texture_);
3437 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3438 glDeleteFramebuffersEXT(1, &validation_fbo_);
3439 }
3440
[email protected]97872062010-11-03 19:07:053441 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543442 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053443 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543444 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053445 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023446 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053447 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153448 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053449 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153450 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053451 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023452 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053453 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543454 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273455 if (offscreen_resolved_frame_buffer_.get())
3456 offscreen_resolved_frame_buffer_->Destroy();
3457 if (offscreen_resolved_color_texture_.get())
3458 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053459 } else {
3460 if (offscreen_target_frame_buffer_.get())
3461 offscreen_target_frame_buffer_->Invalidate();
3462 if (offscreen_target_color_texture_.get())
3463 offscreen_target_color_texture_->Invalidate();
3464 if (offscreen_target_color_render_buffer_.get())
3465 offscreen_target_color_render_buffer_->Invalidate();
3466 if (offscreen_target_depth_render_buffer_.get())
3467 offscreen_target_depth_render_buffer_->Invalidate();
3468 if (offscreen_target_stencil_render_buffer_.get())
3469 offscreen_target_stencil_render_buffer_->Invalidate();
3470 if (offscreen_saved_frame_buffer_.get())
3471 offscreen_saved_frame_buffer_->Invalidate();
3472 if (offscreen_saved_color_texture_.get())
3473 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273474 if (offscreen_resolved_frame_buffer_.get())
3475 offscreen_resolved_frame_buffer_->Invalidate();
3476 if (offscreen_resolved_color_texture_.get())
3477 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023478 }
[email protected]83a52d032013-07-24 10:30:373479
3480 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3481 // Otherwise, we can leak objects. http://crbug.com/258772.
3482 // state_.current_program must be reset before group_ is reset because
3483 // the later deletes the ProgramManager object that referred by
3484 // state_.current_program object.
3485 state_.current_program = NULL;
3486
[email protected]43410e92012-04-20 17:06:283487 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053488
[email protected]882ba1e22012-03-08 19:02:533489 if (query_manager_.get()) {
3490 query_manager_->Destroy(have_context);
3491 query_manager_.reset();
3492 }
3493
[email protected]944b62f32012-09-27 02:20:463494 if (vertex_array_manager_ .get()) {
3495 vertex_array_manager_->Destroy(have_context);
3496 vertex_array_manager_.reset();
3497 }
3498
[email protected]d2eaf52f2014-07-31 15:01:243499 if (image_manager_.get()) {
3500 image_manager_->Destroy(have_context);
3501 image_manager_.reset();
3502 }
3503
[email protected]97872062010-11-03 19:07:053504 offscreen_target_frame_buffer_.reset();
3505 offscreen_target_color_texture_.reset();
3506 offscreen_target_color_render_buffer_.reset();
3507 offscreen_target_depth_render_buffer_.reset();
3508 offscreen_target_stencil_render_buffer_.reset();
3509 offscreen_saved_frame_buffer_.reset();
3510 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273511 offscreen_resolved_frame_buffer_.reset();
3512 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463513
[email protected]03cef9b2014-04-03 15:58:143514 // Need to release these before releasing |group_| which may own the
3515 // ShaderTranslatorCache.
3516 fragment_translator_ = NULL;
3517 vertex_translator_ = NULL;
3518
[email protected]85a4ac22013-05-31 01:58:473519 // Should destroy the transfer manager before the texture manager held
3520 // by the context group.
3521 async_pixel_transfer_manager_.reset();
3522
[email protected]7cd76fd2013-06-02 21:11:113523 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393524 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233525 group_->Destroy(this, have_context);
3526 group_ = NULL;
3527 }
3528
3529 if (context_.get()) {
3530 context_->ReleaseCurrent(NULL);
3531 context_ = NULL;
3532 }
3533
[email protected]e51bdf32011-11-23 22:21:463534#if defined(OS_MACOSX)
3535 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3536 it != texture_to_io_surface_map_.end(); ++it) {
3537 CFRelease(it->second);
3538 }
3539 texture_to_io_surface_map_.clear();
3540#endif
[email protected]96449d2c2009-11-25 00:01:323541}
3542
[email protected]63c9b052012-05-17 18:27:383543void GLES2DecoderImpl::SetSurface(
3544 const scoped_refptr<gfx::GLSurface>& surface) {
3545 DCHECK(context_->IsCurrent(NULL));
3546 DCHECK(surface_.get());
3547 surface_ = surface;
3548 RestoreCurrentFramebufferBindings();
3549}
3550
[email protected]aba551b2014-02-08 03:38:323551void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3552 if (!offscreen_saved_color_texture_.get()) {
3553 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3554 return;
3555 }
[email protected]2ad674132013-06-05 07:48:513556 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243557 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073558 offscreen_saved_color_texture_info_ = TextureRef::Create(
3559 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513560 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3561 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393562 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243563 }
[email protected]aba551b2014-02-08 03:38:323564 mailbox_manager()->ProduceTexture(
3565 GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243566}
3567
[email protected]799b4b22011-08-22 17:09:593568bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3569 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3570 if (!is_offscreen) {
3571 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3572 << " with an onscreen framebuffer.";
3573 return false;
3574 }
3575
3576 if (offscreen_size_ == size)
3577 return true;
3578
3579 offscreen_size_ = size;
3580 int w = offscreen_size_.width();
3581 int h = offscreen_size_.height();
3582 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3583 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3584 << "to allocate storage due to excessive dimensions.";
3585 return false;
3586 }
3587
3588 // Reallocate the offscreen target buffers.
3589 DCHECK(offscreen_target_color_format_);
3590 if (IsOffscreenBufferMultisampled()) {
3591 if (!offscreen_target_color_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183592 feature_info_, offscreen_size_, offscreen_target_color_format_,
[email protected]799b4b22011-08-22 17:09:593593 offscreen_target_samples_)) {
3594 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3595 << "to allocate storage for offscreen target color buffer.";
3596 return false;
3597 }
3598 } else {
3599 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093600 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593601 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3602 << "to allocate storage for offscreen target color texture.";
3603 return false;
3604 }
3605 }
3606 if (offscreen_target_depth_format_ &&
3607 !offscreen_target_depth_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183608 feature_info_, offscreen_size_, offscreen_target_depth_format_,
[email protected]799b4b22011-08-22 17:09:593609 offscreen_target_samples_)) {
3610 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3611 << "to allocate storage for offscreen target depth buffer.";
3612 return false;
3613 }
3614 if (offscreen_target_stencil_format_ &&
3615 !offscreen_target_stencil_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183616 feature_info_, offscreen_size_, offscreen_target_stencil_format_,
[email protected]799b4b22011-08-22 17:09:593617 offscreen_target_samples_)) {
3618 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3619 << "to allocate storage for offscreen target stencil buffer.";
3620 return false;
3621 }
3622
3623 // Attach the offscreen target buffers to the target frame buffer.
3624 if (IsOffscreenBufferMultisampled()) {
3625 offscreen_target_frame_buffer_->AttachRenderBuffer(
3626 GL_COLOR_ATTACHMENT0,
3627 offscreen_target_color_render_buffer_.get());
3628 } else {
3629 offscreen_target_frame_buffer_->AttachRenderTexture(
3630 offscreen_target_color_texture_.get());
3631 }
3632 if (offscreen_target_depth_format_) {
3633 offscreen_target_frame_buffer_->AttachRenderBuffer(
3634 GL_DEPTH_ATTACHMENT,
3635 offscreen_target_depth_render_buffer_.get());
3636 }
3637 const bool packed_depth_stencil =
3638 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3639 if (packed_depth_stencil) {
3640 offscreen_target_frame_buffer_->AttachRenderBuffer(
3641 GL_STENCIL_ATTACHMENT,
3642 offscreen_target_depth_render_buffer_.get());
3643 } else if (offscreen_target_stencil_format_) {
3644 offscreen_target_frame_buffer_->AttachRenderBuffer(
3645 GL_STENCIL_ATTACHMENT,
3646 offscreen_target_stencil_render_buffer_.get());
3647 }
3648
3649 if (offscreen_target_frame_buffer_->CheckStatus() !=
3650 GL_FRAMEBUFFER_COMPLETE) {
3651 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3652 << "because offscreen FBO was incomplete.";
3653 return false;
3654 }
3655
3656 // Clear the target frame buffer.
3657 {
3658 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3659 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3660 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
[email protected]454157e2014-05-03 02:49:453661 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593662 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473663 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3664 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593665 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453666 state_.SetDeviceDepthMask(GL_TRUE);
3667 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593668 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3669 RestoreClearState();
3670 }
[email protected]d85ef76d2011-09-08 22:21:433671
3672 // Destroy the offscreen resolved framebuffers.
3673 if (offscreen_resolved_frame_buffer_.get())
3674 offscreen_resolved_frame_buffer_->Destroy();
3675 if (offscreen_resolved_color_texture_.get())
3676 offscreen_resolved_color_texture_->Destroy();
3677 offscreen_resolved_color_texture_.reset();
3678 offscreen_resolved_frame_buffer_.reset();
3679
[email protected]799b4b22011-08-22 17:09:593680 return true;
[email protected]6217d392010-03-25 22:08:353681}
3682
[email protected]799b4b22011-08-22 17:09:593683error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353684 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443685 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023686 return error::kDeferCommandUntilLater;
3687
[email protected]799b4b22011-08-22 17:09:593688 GLuint width = static_cast<GLuint>(c.width);
3689 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073690 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593691 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413692
3693 width = std::max(1U, width);
3694 height = std::max(1U, height);
3695
[email protected]a0d989162011-11-22 13:15:073696#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3697 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003698 // Make sure that we are done drawing to the back buffer before resizing.
3699 glFinish();
3700#endif
[email protected]799b4b22011-08-22 17:09:593701 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3702 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493703 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3704 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3705 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593706 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493707 }
[email protected]7ff86b92010-11-25 17:50:003708 }
[email protected]799b4b22011-08-22 17:09:593709
[email protected]9d37f062011-11-22 01:24:523710 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073711 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443712 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493713 if (!context_->IsCurrent(surface_.get())) {
3714 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3715 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053716 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493717 }
[email protected]658f7562011-09-09 05:24:053718 }
[email protected]799b4b22011-08-22 17:09:593719
3720 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393721}
3722
[email protected]96449d2c2009-11-25 00:01:323723const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3724 if (command_id > kStartPoint && command_id < kNumCommands) {
3725 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3726 }
3727 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3728}
3729
3730// Decode command with its arguments, and call the corresponding GL function.
3731// Note: args is a pointer to the command buffer. As such, it could be changed
3732// by a (malicious) client at any time, so if validation has to happen, it
3733// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143734error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323735 unsigned int command,
3736 unsigned int arg_count,
3737 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143738 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263739 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003740 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
[email protected]65f7efe2013-11-28 03:11:473741 // VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323742 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013743 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193744 }
[email protected]96449d2c2009-11-25 00:01:323745 unsigned int command_index = command - kStartPoint - 1;
3746 if (command_index < arraysize(g_command_info)) {
3747 const CommandInfo& info = g_command_info[command_index];
3748 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3749 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3750 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]cac16542014-01-15 17:53:513751 bool doing_gpu_trace = false;
3752 if (gpu_trace_commands_) {
3753 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3754 doing_gpu_trace = true;
3755 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3756 }
3757 }
3758
[email protected]b9849abf2009-11-25 19:13:193759 uint32 immediate_data_size =
3760 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323761 switch (command) {
3762 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353763 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193764 result = Handle ## name( \
3765 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353766 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193767 break; \
[email protected]96449d2c2009-11-25 00:01:323768
3769 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323770 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383771 }
[email protected]cac16542014-01-15 17:53:513772
3773 if (doing_gpu_trace)
3774 gpu_tracer_->End(kTraceDecoder);
3775
[email protected]bf0985e2009-12-17 03:04:383776 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303777 GLenum error;
3778 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323779 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003780 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3781 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513782 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193783 }
[email protected]96449d2c2009-11-25 00:01:323784 }
3785 } else {
[email protected]f7a64ee2010-02-01 22:24:143786 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323787 }
[email protected]b9849abf2009-11-25 19:13:193788 } else {
3789 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323790 }
[email protected]a3a93e7b2010-08-28 00:48:563791 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3792 result = current_decoder_error_;
3793 current_decoder_error_ = error::kNoError;
3794 }
[email protected]b9849abf2009-11-25 19:13:193795 return result;
[email protected]96449d2c2009-11-25 00:01:323796}
3797
[email protected]ed9f9cd2013-02-27 21:12:353798void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3799 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503800}
3801
[email protected]ae51d192010-04-27 00:48:033802bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353803 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033804 return false;
3805 }
[email protected]96449d2c2009-11-25 00:01:323806 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033807 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353808 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323809 }
[email protected]ae51d192010-04-27 00:48:033810 return true;
[email protected]96449d2c2009-11-25 00:01:323811}
3812
[email protected]ae51d192010-04-27 00:48:033813bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353814 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033815 return false;
[email protected]96449d2c2009-11-25 00:01:323816 }
[email protected]ae51d192010-04-27 00:48:033817 GLuint service_id = glCreateShader(type);
3818 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353819 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033820 }
3821 return true;
[email protected]96449d2c2009-11-25 00:01:323822}
3823
[email protected]882ba1e22012-03-08 19:02:533824void GLES2DecoderImpl::DoFinish() {
3825 glFinish();
[email protected]5a36dc132013-07-23 23:17:553826 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193827 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533828}
3829
3830void GLES2DecoderImpl::DoFlush() {
3831 glFlush();
[email protected]22e3f552012-03-13 01:54:193832 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533833}
3834
[email protected]3916c97e2010-02-25 03:20:503835void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453836 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023837 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513838 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533839 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503840 return;
3841 }
[email protected]e259eb412012-10-13 05:47:243842 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453843 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503844}
3845
[email protected]051b1372010-04-12 02:42:083846void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073847 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083848 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033849 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073850 buffer = GetBuffer(client_id);
3851 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353852 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223853 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3854 "glBindBuffer",
3855 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:353856 return;
3857 }
3858
[email protected]b10492f2013-03-08 05:24:073859 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033860 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353861 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073862 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573863 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103864 group_->GetIdAllocator(id_namespaces::kBuffers);
3865 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033866 }
[email protected]051b1372010-04-12 02:42:083867 }
[email protected]b10492f2013-03-08 05:24:073868 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3869 if (buffer) {
3870 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513871 LOCAL_SET_GL_ERROR(
3872 GL_INVALID_OPERATION,
3873 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473874 return;
3875 }
[email protected]b10492f2013-03-08 05:24:073876 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473877 }
[email protected]96449d2c2009-11-25 00:01:323878 switch (target) {
3879 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073880 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323881 break;
3882 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073883 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323884 break;
3885 default:
[email protected]a93bb842010-02-16 23:03:473886 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323887 break;
3888 }
[email protected]051b1372010-04-12 02:42:083889 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323890}
3891
[email protected]f3b191b2013-06-19 03:43:543892bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3893 bool all_draw_buffers) {
3894 Framebuffer* framebuffer =
3895 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3896 if (!all_draw_buffers || !framebuffer) {
3897 return (GLES2Util::GetChannelsForFormat(
3898 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3899 }
3900 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463901}
3902
3903bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353904 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453905 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203906 if (framebuffer) {
3907 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463908 }
3909 if (offscreen_target_frame_buffer_.get()) {
3910 return offscreen_target_depth_format_ != 0;
3911 }
3912 return back_buffer_has_depth_;
3913}
3914
3915bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353916 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453917 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203918 if (framebuffer) {
3919 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463920 }
3921 if (offscreen_target_frame_buffer_.get()) {
3922 return offscreen_target_stencil_format_ != 0 ||
3923 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3924 }
3925 return back_buffer_has_stencil_;
3926}
3927
3928void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:443929 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:453930 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
3931 state_.SetDeviceColorMask(state_.color_mask_red,
3932 state_.color_mask_green,
3933 state_.color_mask_blue,
3934 state_.color_mask_alpha && have_alpha);
3935
[email protected]297ca1c2011-06-20 23:08:463936 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:453937 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
3938
[email protected]297ca1c2011-06-20 23:08:463939 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:453940 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423941 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:453942 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423943 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:453944
3945 state_.SetDeviceCapabilityState(
3946 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
3947 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:223948 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:443949 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:463950 }
3951}
3952
[email protected]1868a342012-11-07 15:56:023953GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:113954 return (offscreen_target_frame_buffer_.get())
3955 ? offscreen_target_frame_buffer_->id()
3956 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:023957}
3958
[email protected]8875a5f2014-06-27 08:33:473959void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:143960 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3961 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:063962 // Restore the Framebuffer first because of bugs in Intel drivers.
3963 // Intel drivers incorrectly clip the viewport settings to
3964 // the size of the current framebuffer object.
3965 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:163966 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:063967}
3968
3969void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:343970 GLuint service_id =
3971 framebuffer_state_.bound_draw_framebuffer.get()
3972 ? framebuffer_state_.bound_draw_framebuffer->service_id()
3973 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063974 if (!features().chromium_framebuffer_multisample) {
3975 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3976 } else {
3977 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:343978 service_id = framebuffer_state_.bound_read_framebuffer.get()
3979 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:113980 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063981 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3982 }
[email protected]70d34263c2013-01-09 00:27:453983 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063984}
3985
[email protected]8875a5f2014-06-27 08:33:473986void GLES2DecoderImpl::RestoreRenderbufferBindings() {
3987 state_.RestoreRenderbufferBindings();
3988}
3989
[email protected]29a4d902013-02-26 20:18:063990void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:103991 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3992 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:253993 GLenum target = texture->target();
3994 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063995 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253996 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063997 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253998 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063999 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254000 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064001 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254002 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064003 RestoreTextureUnitBindings(state_.active_texture_unit);
4004 }
[email protected]70d34263c2013-01-09 00:27:454005}
4006
[email protected]cd2ef752014-02-12 23:16:034007void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524008 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4009 // other VAOs.
4010 if (feature_info_->feature_flags().native_vertex_array_object)
4011 glBindVertexArrayOES(0);
4012
[email protected]cd2ef752014-02-12 23:16:034013 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4014 if (i != 0) // Never disable attribute 0
4015 glDisableVertexAttribArray(i);
4016 if(features().angle_instanced_arrays)
4017 glVertexAttribDivisorANGLE(i, 0);
4018 }
4019}
4020
4021void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524022 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034023}
4024
[email protected]454157e2014-05-03 02:49:454025void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4026 state_.SetIgnoreCachedStateForTest(ignore);
4027}
4028
[email protected]70d34263c2013-01-09 00:27:454029void GLES2DecoderImpl::OnFboChanged() const {
4030 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514031 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
4032}
4033
4034// Called after the FBO is checked for completeness.
4035void GLES2DecoderImpl::OnUseFramebuffer() const {
4036 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4037 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324038 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514039 glScissor(state_.scissor_x,
4040 state_.scissor_y,
4041 state_.scissor_width,
4042 state_.scissor_height);
4043
4044 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4045 // it's unclear how this bug works.
4046 glFlush();
4047 }
[email protected]b177ae22011-11-01 03:29:114048}
4049
[email protected]051b1372010-04-12 02:42:084050void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064051 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084052 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034053 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064054 framebuffer = GetFramebuffer(client_id);
4055 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354056 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224057 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4058 "glBindFramebuffer",
4059 "id not generated by glGenFramebuffers");
4060 return;
[email protected]bf5a8d132011-08-16 08:39:354061 }
4062
[email protected]4d8f0dd2013-03-09 14:37:064063 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034064 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354065 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064066 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:574067 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:104068 group_->GetIdAllocator(id_namespaces::kFramebuffers);
4069 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:034070 } else {
[email protected]4d8f0dd2013-03-09 14:37:064071 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084072 }
[email protected]4d8f0dd2013-03-09 14:37:064073 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084074 }
[email protected]4d8f0dd2013-03-09 14:37:064075 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304076
4077 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344078 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304079 }
[email protected]cac16542014-01-15 17:53:514080
4081 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304082 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344083 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304084 }
[email protected]6217d392010-03-25 22:08:354085
[email protected]c986af502013-08-14 01:04:444086 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464087
[email protected]b177ae22011-11-01 03:29:114088 // If we are rendering to the backbuffer get the FBO id for any simulated
4089 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064090 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114091 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464092 }
[email protected]6217d392010-03-25 22:08:354093
[email protected]051b1372010-04-12 02:42:084094 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454095 OnFboChanged();
[email protected]86093972010-03-11 00:13:564096}
4097
[email protected]051b1372010-04-12 02:42:084098void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274099 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084100 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034101 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274102 renderbuffer = GetRenderbuffer(client_id);
4103 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354104 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224105 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4106 "glBindRenderbuffer",
4107 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354108 return;
4109 }
4110
[email protected]8875a5f2014-06-27 08:33:474111 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034112 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354113 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274114 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:574115 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:104116 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
4117 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:034118 } else {
[email protected]ee2a79c32013-03-10 03:50:274119 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084120 }
[email protected]ee2a79c32013-03-10 03:50:274121 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084122 }
[email protected]caa13ed2014-02-17 11:29:204123 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274124 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474125 state_.bound_renderbuffer_valid = true;
4126 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564127}
4128
[email protected]051b1372010-04-12 02:42:084129void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494130 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084131 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034132 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494133 texture_ref = GetTexture(client_id);
4134 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354135 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224136 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4137 "glBindTexture",
4138 "id not generated by glGenTextures");
4139 return;
[email protected]bf5a8d132011-08-16 08:39:354140 }
4141
[email protected]02965c22013-03-09 02:40:074142 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034143 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414144 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354145 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494146 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:574147 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:104148 group_->GetIdAllocator(id_namespaces::kTextures);
4149 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:034150 }
4151 } else {
[email protected]370eaf12013-05-18 09:19:494152 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084153 }
[email protected]ae51d192010-04-27 00:48:034154
[email protected]1958e0e2010-04-22 05:17:154155 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574156 if (texture_ref) {
4157 Texture* texture = texture_ref->texture();
4158 // Check that we are not trying to bind it to a different target.
4159 if (texture->target() != 0 && texture->target() != target) {
4160 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4161 "glBindTexture",
4162 "texture bound to more than 1 target.");
4163 return;
4164 }
4165 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4166 if (texture->target() == 0) {
4167 texture_manager()->SetTarget(texture_ref, target);
4168 }
4169 glBindTexture(target, texture->service_id());
4170 } else {
4171 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154172 }
[email protected]32145a92012-12-17 09:01:594173
[email protected]e259eb412012-10-13 05:47:244174 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504175 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474176 switch (target) {
4177 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494178 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474179 break;
4180 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494181 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474182 break;
[email protected]61eeb33f2011-07-26 15:30:314183 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494184 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314185 break;
[email protected]e51bdf32011-11-23 22:21:464186 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494187 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464188 break;
[email protected]a93bb842010-02-16 23:03:474189 default:
4190 NOTREACHED(); // Validation should prevent us getting here.
4191 break;
4192 }
4193}
4194
[email protected]07f54fcc2009-12-22 02:46:304195void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244196 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124197 if (index != 0 ||
4198 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244199 glDisableVertexAttribArray(index);
4200 }
[email protected]07f54fcc2009-12-22 02:46:304201 } else {
[email protected]ab09b612013-03-11 22:11:514202 LOCAL_SET_GL_ERROR(
4203 GL_INVALID_VALUE,
4204 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304205 }
4206}
4207
[email protected]60f22d32012-12-12 00:31:584208void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4209 GLsizei numAttachments,
4210 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354211 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584212 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4213
4214 // Validates the attachments. If one of them fails
4215 // the whole command fails.
4216 for (GLsizei i = 0; i < numAttachments; ++i) {
4217 if ((framebuffer &&
4218 !validators_->attachment.IsValid(attachments[i])) ||
4219 (!framebuffer &&
4220 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514221 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4222 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584223 return;
4224 }
4225 }
4226
4227 // Marks each one of them as not cleared
4228 for (GLsizei i = 0; i < numAttachments; ++i) {
4229 if (framebuffer) {
4230 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4231 texture_manager(),
4232 attachments[i],
4233 false);
4234 } else {
4235 switch (attachments[i]) {
4236 case GL_COLOR_EXT:
4237 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4238 break;
4239 case GL_DEPTH_EXT:
4240 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4241 case GL_STENCIL_EXT:
4242 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4243 break;
4244 default:
4245 NOTREACHED();
4246 break;
4247 }
4248 }
4249 }
4250
[email protected]d49c5402013-09-11 15:39:024251 // If the default framebuffer is bound but we are still rendering to an
4252 // FBO, translate attachment names that refer to default framebuffer
4253 // channels to corresponding framebuffer attachments.
4254 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4255 for (GLsizei i = 0; i < numAttachments; ++i) {
4256 GLenum attachment = attachments[i];
4257 if (!framebuffer && GetBackbufferServiceId()) {
4258 switch (attachment) {
4259 case GL_COLOR_EXT:
4260 attachment = GL_COLOR_ATTACHMENT0;
4261 break;
4262 case GL_DEPTH_EXT:
4263 attachment = GL_DEPTH_ATTACHMENT;
4264 break;
4265 case GL_STENCIL_EXT:
4266 attachment = GL_STENCIL_ATTACHMENT;
4267 break;
4268 default:
4269 NOTREACHED();
4270 return;
4271 }
4272 }
4273 translated_attachments[i] = attachment;
4274 }
4275
4276 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584277}
4278
[email protected]07f54fcc2009-12-22 02:46:304279void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244280 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304281 glEnableVertexAttribArray(index);
4282 } else {
[email protected]ab09b612013-03-11 22:11:514283 LOCAL_SET_GL_ERROR(
4284 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304285 }
4286}
4287
[email protected]a93bb842010-02-16 23:03:474288void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444289 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4290 &state_, target);
[email protected]370eaf12013-05-18 09:19:494291 if (!texture_ref ||
4292 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514293 LOCAL_SET_GL_ERROR(
4294 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474295 return;
4296 }
[email protected]38c0a972012-05-12 00:48:024297
[email protected]12d95352012-12-14 07:23:544298 if (target == GL_TEXTURE_CUBE_MAP) {
4299 for (int i = 0; i < 6; ++i) {
4300 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494301 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514302 LOCAL_SET_GL_ERROR(
4303 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544304 return;
4305 }
4306 }
4307 } else {
[email protected]370eaf12013-05-18 09:19:494308 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514309 LOCAL_SET_GL_ERROR(
4310 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544311 return;
4312 }
[email protected]7687479c2012-05-14 23:54:044313 }
4314
[email protected]ab09b612013-03-11 22:11:514315 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194316 // Workaround for Mac driver bug. In the large scheme of things setting
4317 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564318 // hit so there's probably no need to make this conditional. The bug appears
4319 // to be that if the filtering mode is set to something that doesn't require
4320 // mipmaps for rendering, or is never set to something other than the default,
4321 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154322 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194323 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4324 }
[email protected]a93bb842010-02-16 23:03:474325 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154326 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494327 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4328 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194329 }
[email protected]ab09b612013-03-11 22:11:514330 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024331 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494332 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024333 }
[email protected]a93bb842010-02-16 23:03:474334}
4335
[email protected]b273e432010-04-12 17:23:584336bool GLES2DecoderImpl::GetHelper(
4337 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584338 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154339 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4340 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434341 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4342 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214343 // Return the GL implementation's preferred format and (see below type)
4344 // if we have the GL extension that exposes this. This allows the GPU
4345 // client to use the implementation's preferred format for glReadPixels
4346 // for optimisation.
4347 //
4348 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4349 // case when requested on integer/floating point buffers but which is
4350 // acceptable on GLES2 and with the GL_OES_read_format extension.
4351 //
4352 // Therefore if an error occurs we swallow the error and use the
4353 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434354 if (params) {
[email protected]c959a09a2014-03-27 11:44:214355 if (context_->HasExtension("GL_OES_read_format")) {
4356 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4357 GetErrorState());
4358 glGetIntegerv(pname, params);
4359 if (glGetError() == GL_NO_ERROR)
4360 return true;
4361 }
[email protected]68586372013-12-11 01:27:594362 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4363 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434364 }
4365 return true;
4366 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4367 *num_written = 1;
4368 if (params) {
[email protected]c959a09a2014-03-27 11:44:214369 if (context_->HasExtension("GL_OES_read_format")) {
4370 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4371 GetErrorState());
4372 glGetIntegerv(pname, params);
4373 if (glGetError() == GL_NO_ERROR)
4374 return true;
4375 }
[email protected]68586372013-12-11 01:27:594376 *params = GLES2Util::GetPreferredGLReadPixelsType(
4377 GetBoundReadFrameBufferInternalFormat(),
4378 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434379 }
4380 return true;
4381 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4382 *num_written = 1;
4383 if (params) {
4384 *params = group_->max_fragment_uniform_vectors();
4385 }
4386 return true;
4387 case GL_MAX_VARYING_VECTORS:
4388 *num_written = 1;
4389 if (params) {
4390 *params = group_->max_varying_vectors();
4391 }
4392 return true;
4393 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4394 *num_written = 1;
4395 if (params) {
4396 *params = group_->max_vertex_uniform_vectors();
4397 }
4398 return true;
[email protected]4e8a5b122010-05-08 22:00:104399 }
[email protected]5cb735d2011-10-13 01:37:234400 }
4401 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244402 case GL_MAX_VIEWPORT_DIMS:
4403 if (offscreen_target_frame_buffer_.get()) {
4404 *num_written = 2;
4405 if (params) {
4406 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4407 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4408 }
4409 return true;
4410 }
[email protected]5cb735d2011-10-13 01:37:234411 return false;
[email protected]84afefa2011-10-19 21:45:534412 case GL_MAX_SAMPLES:
4413 *num_written = 1;
4414 if (params) {
4415 params[0] = renderbuffer_manager()->max_samples();
4416 }
4417 return true;
4418 case GL_MAX_RENDERBUFFER_SIZE:
4419 *num_written = 1;
4420 if (params) {
4421 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4422 }
4423 return true;
[email protected]5cb735d2011-10-13 01:37:234424 case GL_MAX_TEXTURE_SIZE:
4425 *num_written = 1;
4426 if (params) {
4427 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4428 }
4429 return true;
4430 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4431 *num_written = 1;
4432 if (params) {
4433 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4434 }
4435 return true;
[email protected]2f143d482013-03-14 18:04:494436 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4437 *num_written = 1;
4438 if (params) {
4439 params[0] = group_->max_color_attachments();
4440 }
4441 return true;
4442 case GL_MAX_DRAW_BUFFERS_ARB:
4443 *num_written = 1;
4444 if (params) {
4445 params[0] = group_->max_draw_buffers();
4446 }
4447 return true;
[email protected]297ca1c2011-06-20 23:08:464448 case GL_ALPHA_BITS:
4449 *num_written = 1;
4450 if (params) {
4451 GLint v = 0;
4452 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544453 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464454 }
4455 return true;
4456 case GL_DEPTH_BITS:
4457 *num_written = 1;
4458 if (params) {
4459 GLint v = 0;
4460 glGetIntegerv(GL_DEPTH_BITS, &v);
4461 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4462 }
4463 return true;
4464 case GL_STENCIL_BITS:
4465 *num_written = 1;
4466 if (params) {
4467 GLint v = 0;
4468 glGetIntegerv(GL_STENCIL_BITS, &v);
4469 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4470 }
4471 return true;
[email protected]656dcaad2010-05-07 17:18:374472 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114473 *num_written = validators_->compressed_texture_format.GetValues().size();
4474 if (params) {
4475 for (GLint ii = 0; ii < *num_written; ++ii) {
4476 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4477 }
4478 }
[email protected]656dcaad2010-05-07 17:18:374479 return true;
[email protected]b273e432010-04-12 17:23:584480 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4481 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104482 if (params) {
[email protected]302ce6d2011-07-07 23:28:114483 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104484 }
[email protected]b273e432010-04-12 17:23:584485 return true;
4486 case GL_NUM_SHADER_BINARY_FORMATS:
4487 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104488 if (params) {
[email protected]302ce6d2011-07-07 23:28:114489 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104490 }
[email protected]b273e432010-04-12 17:23:584491 return true;
4492 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114493 *num_written = validators_->shader_binary_format.GetValues().size();
4494 if (params) {
4495 for (GLint ii = 0; ii < *num_written; ++ii) {
4496 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4497 }
4498 }
4499 return true;
[email protected]b273e432010-04-12 17:23:584500 case GL_SHADER_COMPILER:
4501 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104502 if (params) {
4503 *params = GL_TRUE;
4504 }
[email protected]b273e432010-04-12 17:23:584505 return true;
[email protected]6b8cf1a2010-05-06 16:13:584506 case GL_ARRAY_BUFFER_BINDING:
4507 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104508 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114509 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104510 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244511 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104512 &client_id);
4513 *params = client_id;
4514 } else {
4515 *params = 0;
4516 }
[email protected]6b8cf1a2010-05-06 16:13:584517 }
4518 return true;
4519 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4520 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104521 if (params) {
[email protected]e259eb412012-10-13 05:47:244522 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104523 GLuint client_id = 0;
4524 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254525 state_.vertex_attrib_manager->element_array_buffer()->
4526 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104527 *params = client_id;
4528 } else {
4529 *params = 0;
4530 }
[email protected]6b8cf1a2010-05-06 16:13:584531 }
4532 return true;
4533 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304534 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584535 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104536 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354537 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454538 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204539 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104540 GLuint client_id = 0;
4541 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204542 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304543 *params = client_id;
4544 } else {
4545 *params = 0;
4546 }
4547 }
4548 return true;
[email protected]ebfb73c2012-08-15 02:37:454549 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304550 *num_written = 1;
4551 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354552 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454553 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204554 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304555 GLuint client_id = 0;
4556 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204557 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104558 *params = client_id;
4559 } else {
4560 *params = 0;
4561 }
[email protected]6b8cf1a2010-05-06 16:13:584562 }
4563 return true;
4564 case GL_RENDERBUFFER_BINDING:
4565 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104566 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354567 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204568 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4569 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104570 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104571 } else {
4572 *params = 0;
4573 }
[email protected]6b8cf1a2010-05-06 16:13:584574 }
4575 return true;
4576 case GL_CURRENT_PROGRAM:
4577 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104578 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114579 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104580 GLuint client_id = 0;
4581 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244582 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104583 *params = client_id;
4584 } else {
4585 *params = 0;
4586 }
[email protected]6b8cf1a2010-05-06 16:13:584587 }
4588 return true;
[email protected]bf835842012-11-19 15:21:514589 case GL_VERTEX_ARRAY_BINDING_OES:
4590 *num_written = 1;
4591 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114592 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524593 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514594 GLuint client_id = 0;
4595 vertex_array_manager_->GetClientId(
4596 state_.vertex_attrib_manager->service_id(), &client_id);
4597 *params = client_id;
4598 } else {
4599 *params = 0;
4600 }
4601 }
4602 return true;
[email protected]4e8a5b122010-05-08 22:00:104603 case GL_TEXTURE_BINDING_2D:
4604 *num_written = 1;
4605 if (params) {
[email protected]e259eb412012-10-13 05:47:244606 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114607 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104608 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584609 } else {
4610 *params = 0;
4611 }
[email protected]6b8cf1a2010-05-06 16:13:584612 }
[email protected]4e8a5b122010-05-08 22:00:104613 return true;
4614 case GL_TEXTURE_BINDING_CUBE_MAP:
4615 *num_written = 1;
4616 if (params) {
[email protected]e259eb412012-10-13 05:47:244617 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114618 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104619 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584620 } else {
4621 *params = 0;
4622 }
[email protected]6b8cf1a2010-05-06 16:13:584623 }
[email protected]4e8a5b122010-05-08 22:00:104624 return true;
[email protected]61eeb33f2011-07-26 15:30:314625 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4626 *num_written = 1;
4627 if (params) {
[email protected]e259eb412012-10-13 05:47:244628 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114629 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104630 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314631 } else {
4632 *params = 0;
4633 }
4634 }
4635 return true;
[email protected]e51bdf32011-11-23 22:21:464636 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4637 *num_written = 1;
4638 if (params) {
[email protected]e259eb412012-10-13 05:47:244639 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114640 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104641 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464642 } else {
4643 *params = 0;
4644 }
4645 }
4646 return true;
[email protected]6c75c712012-06-19 15:43:174647 case GL_UNPACK_FLIP_Y_CHROMIUM:
4648 *num_written = 1;
4649 if (params) {
4650 params[0] = unpack_flip_y_;
4651 }
4652 return true;
4653 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4654 *num_written = 1;
4655 if (params) {
4656 params[0] = unpack_premultiply_alpha_;
4657 }
4658 return true;
4659 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4660 *num_written = 1;
4661 if (params) {
4662 params[0] = unpack_unpremultiply_alpha_;
4663 }
4664 return true;
[email protected]6eda6822014-04-03 23:00:504665 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4666 *num_written = 1;
4667 if (params) {
4668 params[0] = group_->bind_generates_resource() ? 1 : 0;
4669 }
4670 return true;
[email protected]b273e432010-04-12 17:23:584671 default:
[email protected]2f143d482013-03-14 18:04:494672 if (pname >= GL_DRAW_BUFFER0_ARB &&
4673 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4674 *num_written = 1;
4675 if (params) {
4676 Framebuffer* framebuffer =
4677 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4678 if (framebuffer) {
4679 params[0] = framebuffer->GetDrawBuffer(pname);
4680 } else { // backbuffer
4681 if (pname == GL_DRAW_BUFFER0_ARB)
4682 params[0] = group_->draw_buffer();
4683 else
4684 params[0] = GL_NONE;
4685 }
4686 }
4687 return true;
4688 }
[email protected]4e8a5b122010-05-08 22:00:104689 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534690 return false;
[email protected]b273e432010-04-12 17:23:584691 }
4692}
4693
[email protected]4e8a5b122010-05-08 22:00:104694bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4695 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264696 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534697 return true;
4698 }
[email protected]4e8a5b122010-05-08 22:00:104699 return GetHelper(pname, NULL, num_values);
4700}
4701
[email protected]7d3c36e2013-07-12 14:13:164702GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4703 if (GL_MAX_SAMPLES == pname &&
4704 features().use_img_for_multisampled_render_to_texture) {
4705 return GL_MAX_SAMPLES_IMG;
4706 }
4707 return pname;
4708}
4709
[email protected]b273e432010-04-12 17:23:584710void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4711 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104712 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534713 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554714 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264715 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534716 GetHelper(pname, values.get(), &num_written);
4717 }
[email protected]b273e432010-04-12 17:23:584718 for (GLsizei ii = 0; ii < num_written; ++ii) {
4719 params[ii] = static_cast<GLboolean>(values[ii]);
4720 }
4721 } else {
[email protected]7d3c36e2013-07-12 14:13:164722 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584723 glGetBooleanv(pname, params);
4724 }
4725}
4726
4727void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4728 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104729 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264730 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534731 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554732 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534733 GetHelper(pname, values.get(), &num_written);
4734 for (GLsizei ii = 0; ii < num_written; ++ii) {
4735 params[ii] = static_cast<GLfloat>(values[ii]);
4736 }
4737 } else {
[email protected]7d3c36e2013-07-12 14:13:164738 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534739 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584740 }
[email protected]b273e432010-04-12 17:23:584741 }
4742}
4743
4744void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4745 DCHECK(params);
4746 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264747 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534748 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164749 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584750 glGetIntegerv(pname, params);
4751 }
4752}
4753
[email protected]a0c3e972010-04-21 00:49:134754void GLES2DecoderImpl::DoGetProgramiv(
4755 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424756 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4757 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134758 return;
4759 }
[email protected]df37b9932013-03-08 05:21:424760 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134761}
4762
[email protected]17cfbe0e2013-03-07 01:26:084763void GLES2DecoderImpl::DoGetBufferParameteriv(
4764 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134765 // Just delegate it. Some validation is actually done before this.
4766 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4767 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084768}
4769
[email protected]258a3313f2011-10-18 20:13:574770void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424771 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574772 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514773 LOCAL_SET_GL_ERROR(
4774 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574775 return;
4776 }
[email protected]68dcb1f2012-04-07 00:14:564777 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514778 LOCAL_SET_GL_ERROR(
4779 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564780 return;
4781 }
4782 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514783 LOCAL_SET_GL_ERROR(
4784 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564785 return;
4786 }
[email protected]df37b9932013-03-08 05:21:424787 Program* program = GetProgramInfoNotShader(
4788 program_id, "glBindAttribLocation");
4789 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574790 return;
[email protected]558847a2010-03-24 07:02:544791 }
[email protected]df37b9932013-03-08 05:21:424792 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4793 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574794}
4795
[email protected]558847a2010-03-24 07:02:544796error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354797 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584798 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544799 GLuint index = static_cast<GLuint>(c.index);
4800 Bucket* bucket = GetBucket(c.name_bucket_id);
4801 if (!bucket || bucket->size() == 0) {
4802 return error::kInvalidArguments;
4803 }
4804 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184805 if (!bucket->GetAsString(&name_str)) {
4806 return error::kInvalidArguments;
4807 }
[email protected]258a3313f2011-10-18 20:13:574808 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544809 return error::kNoError;
4810}
4811
[email protected]2be6abf32012-06-26 00:28:334812void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424813 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334814 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514815 LOCAL_SET_GL_ERROR(
4816 GL_INVALID_VALUE,
4817 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334818 return;
4819 }
4820 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514821 LOCAL_SET_GL_ERROR(
4822 GL_INVALID_OPERATION,
4823 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334824 return;
4825 }
4826 if (location < 0 || static_cast<uint32>(location) >=
4827 (group_->max_fragment_uniform_vectors() +
4828 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514829 LOCAL_SET_GL_ERROR(
4830 GL_INVALID_VALUE,
4831 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334832 return;
4833 }
[email protected]df37b9932013-03-08 05:21:424834 Program* program = GetProgramInfoNotShader(
4835 program_id, "glBindUniformLocationCHROMIUM");
4836 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334837 return;
4838 }
[email protected]df37b9932013-03-08 05:21:424839 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514840 LOCAL_SET_GL_ERROR(
4841 GL_INVALID_VALUE,
4842 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334843 }
4844}
4845
[email protected]2be6abf32012-06-26 00:28:334846error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4847 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354848 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334849 GLuint program = static_cast<GLuint>(c.program);
4850 GLint location = static_cast<GLint>(c.location);
4851 Bucket* bucket = GetBucket(c.name_bucket_id);
4852 if (!bucket || bucket->size() == 0) {
4853 return error::kInvalidArguments;
4854 }
4855 std::string name_str;
4856 if (!bucket->GetAsString(&name_str)) {
4857 return error::kInvalidArguments;
4858 }
4859 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4860 return error::kNoError;
4861}
4862
[email protected]f7a64ee2010-02-01 22:24:144863error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354864 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034865 GLuint client_id = c.shader;
4866 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424867 Shader* shader = GetShader(client_id);
4868 if (shader) {
4869 if (!shader->IsDeleted()) {
4870 glDeleteShader(shader->service_id());
4871 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144872 }
[email protected]ae51d192010-04-27 00:48:034873 } else {
[email protected]ab09b612013-03-11 22:11:514874 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034875 }
[email protected]96449d2c2009-11-25 00:01:324876 }
[email protected]f7a64ee2010-02-01 22:24:144877 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324878}
4879
[email protected]f7a64ee2010-02-01 22:24:144880error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354881 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034882 GLuint client_id = c.program;
4883 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424884 Program* program = GetProgram(client_id);
4885 if (program) {
4886 if (!program->IsDeleted()) {
4887 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144888 }
[email protected]ae51d192010-04-27 00:48:034889 } else {
[email protected]ab09b612013-03-11 22:11:514890 LOCAL_SET_GL_ERROR(
4891 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034892 }
[email protected]96449d2c2009-11-25 00:01:324893 }
[email protected]f7a64ee2010-02-01 22:24:144894 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324895}
4896
[email protected]269200b12010-11-18 22:53:064897void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104898 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574899 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104900 for (GLsizei ii = 0; ii < n; ++ii) {
4901 id_allocator->FreeID(ids[ii]);
4902 }
4903}
4904
[email protected]269200b12010-11-18 22:53:064905error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354906 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104907 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4908 GLsizei n = static_cast<GLsizei>(c.n);
4909 uint32 data_size;
4910 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4911 return error::kOutOfBounds;
4912 }
4913 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4914 c.ids_shm_id, c.ids_shm_offset, data_size);
4915 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514916 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104917 return error::kNoError;
4918 }
4919 if (ids == NULL) {
4920 return error::kOutOfBounds;
4921 }
[email protected]269200b12010-11-18 22:53:064922 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104923 return error::kNoError;
4924}
4925
[email protected]269200b12010-11-18 22:53:064926void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104927 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574928 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104929 if (id_offset == 0) {
4930 for (GLsizei ii = 0; ii < n; ++ii) {
4931 ids[ii] = id_allocator->AllocateID();
4932 }
4933 } else {
4934 for (GLsizei ii = 0; ii < n; ++ii) {
4935 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4936 id_offset = ids[ii] + 1;
4937 }
4938 }
4939}
4940
[email protected]269200b12010-11-18 22:53:064941error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354942 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104943 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4944 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4945 GLsizei n = static_cast<GLsizei>(c.n);
4946 uint32 data_size;
4947 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4948 return error::kOutOfBounds;
4949 }
4950 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4951 c.ids_shm_id, c.ids_shm_offset, data_size);
4952 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514953 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104954 return error::kNoError;
4955 }
4956 if (ids == NULL) {
4957 return error::kOutOfBounds;
4958 }
[email protected]269200b12010-11-18 22:53:064959 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104960 return error::kNoError;
4961}
4962
[email protected]269200b12010-11-18 22:53:064963void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104964 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574965 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104966 for (GLsizei ii = 0; ii < n; ++ii) {
4967 if (!id_allocator->MarkAsUsed(ids[ii])) {
4968 for (GLsizei jj = 0; jj < ii; ++jj) {
4969 id_allocator->FreeID(ids[jj]);
4970 }
[email protected]ab09b612013-03-11 22:11:514971 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434972 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4973 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104974 return;
4975 }
4976 }
4977}
4978
[email protected]269200b12010-11-18 22:53:064979error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354980 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104981 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4982 GLsizei n = static_cast<GLsizei>(c.n);
4983 uint32 data_size;
4984 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4985 return error::kOutOfBounds;
4986 }
4987 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4988 c.ids_shm_id, c.ids_shm_offset, data_size);
4989 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514990 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104991 return error::kNoError;
4992 }
4993 if (ids == NULL) {
4994 return error::kOutOfBounds;
4995 }
[email protected]269200b12010-11-18 22:53:064996 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104997 return error::kNoError;
4998}
4999
[email protected]a7266a92012-06-28 02:11:085000error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445001 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205002 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465003 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:275004 glClear(mask);
5005 }
[email protected]a7266a92012-06-28 02:11:085006 return error::kNoError;
5007}
5008
[email protected]36cef8ce2010-03-16 07:34:455009void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5010 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035011 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065012 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5013 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515014 LOCAL_SET_GL_ERROR(
5015 GL_INVALID_OPERATION,
5016 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455017 return;
5018 }
[email protected]ae51d192010-04-27 00:48:035019 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275020 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035021 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275022 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5023 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515024 LOCAL_SET_GL_ERROR(
5025 GL_INVALID_OPERATION,
5026 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035027 return;
5028 }
[email protected]ee2a79c32013-03-10 03:50:275029 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035030 }
[email protected]ab09b612013-03-11 22:11:515031 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035032 glFramebufferRenderbufferEXT(
5033 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515034 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265035 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275036 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285037 }
[email protected]9d3b2e12013-10-02 01:04:345038 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445039 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465040 }
[email protected]81fc9d02013-03-14 23:53:325041 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285042}
5043
[email protected]3a2e7c7b2010-08-06 01:12:285044void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465045 if (SetCapabilityState(cap, false)) {
5046 glDisable(cap);
5047 }
[email protected]3a2e7c7b2010-08-06 01:12:285048}
5049
5050void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465051 if (SetCapabilityState(cap, true)) {
5052 glEnable(cap);
5053 }
[email protected]3a2e7c7b2010-08-06 01:12:285054}
5055
[email protected]88a61bf2012-10-27 13:00:425056void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5057 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5058 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5059 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285060}
5061
[email protected]b04e24c2013-01-08 18:35:255062void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425063 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5064 state_.sample_coverage_invert = (invert != 0);
5065 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285066}
5067
[email protected]0d6bfdc2011-11-02 01:32:205068// Assumes framebuffer is complete.
5069void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065070 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305071 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205072 // bind this to the DRAW point, clear then bind back to READ
5073 // TODO(gman): I don't think there is any guarantee that an FBO that
5074 // is complete on the READ attachment will be complete as a DRAW
5075 // attachment.
5076 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065077 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305078 }
[email protected]3a2e7c7b2010-08-06 01:12:285079 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425080 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465081 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205082 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465083 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065084 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5085 1.0f);
[email protected]454157e2014-05-03 02:49:455086 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285087 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]ee757922014-06-06 05:21:425088 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285089 }
5090
[email protected]4d8f0dd2013-03-09 14:37:065091 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5092 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285093 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475094 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5095 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285096 clear_bits |= GL_STENCIL_BUFFER_BIT;
5097 }
5098
[email protected]4d8f0dd2013-03-09 14:37:065099 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5100 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285101 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455102 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285103 clear_bits |= GL_DEPTH_BUFFER_BIT;
5104 }
5105
[email protected]454157e2014-05-03 02:49:455106 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285107 glClear(clear_bits);
5108
[email protected]ee757922014-06-06 05:21:425109 if ((clear_bits | GL_COLOR_BUFFER_BIT) != 0)
5110 framebuffer->RestoreDrawBuffersAfterClear();
5111
[email protected]968351b2011-12-20 08:26:515112 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065113 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285114
[email protected]c007aa02010-09-02 22:22:405115 RestoreClearState();
5116
5117 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065118 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5119 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485120 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065121 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5122 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485123 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405124 }
5125}
5126
5127void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445128 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245129 glClearColor(
5130 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5131 state_.color_clear_alpha);
5132 glClearStencil(state_.stencil_clear);
5133 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225134 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455135 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285136 }
[email protected]36cef8ce2010-03-16 07:34:455137}
5138
5139GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355140 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305141 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205142 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455143 return GL_FRAMEBUFFER_COMPLETE;
5144 }
[email protected]0d6bfdc2011-11-02 01:32:205145 GLenum completeness = framebuffer->IsPossiblyComplete();
5146 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5147 return completeness;
5148 }
[email protected]73276522012-11-09 05:50:205149 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455150}
5151
5152void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035153 GLenum target, GLenum attachment, GLenum textarget,
5154 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165155 DoFramebufferTexture2DCommon(
5156 "glFramebufferTexture2D", target, attachment,
5157 textarget, client_texture_id, level, 0);
5158}
5159
5160void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5161 GLenum target, GLenum attachment, GLenum textarget,
5162 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165163 DoFramebufferTexture2DCommon(
5164 "glFramebufferTexture2DMultisample", target, attachment,
5165 textarget, client_texture_id, level, samples);
5166}
5167
5168void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5169 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5170 GLuint client_texture_id, GLint level, GLsizei samples) {
5171 if (samples > renderbuffer_manager()->max_samples()) {
5172 LOCAL_SET_GL_ERROR(
5173 GL_INVALID_VALUE,
5174 "glFramebufferTexture2DMultisample", "samples too large");
5175 return;
5176 }
[email protected]4d8f0dd2013-03-09 14:37:065177 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5178 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515179 LOCAL_SET_GL_ERROR(
5180 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165181 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455182 return;
5183 }
[email protected]ae51d192010-04-27 00:48:035184 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495185 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035186 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495187 texture_ref = GetTexture(client_texture_id);
5188 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515189 LOCAL_SET_GL_ERROR(
5190 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165191 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035192 return;
5193 }
[email protected]370eaf12013-05-18 09:19:495194 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035195 }
[email protected]0d6bfdc2011-11-02 01:32:205196
[email protected]80eb6b52012-01-19 00:14:415197 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515198 LOCAL_SET_GL_ERROR(
5199 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165200 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205201 return;
5202 }
5203
[email protected]91c94eb2013-10-22 10:32:545204 if (texture_ref)
5205 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5206
[email protected]7d3c36e2013-07-12 14:13:165207 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5208 if (0 == samples) {
5209 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5210 } else {
5211 if (features().use_img_for_multisampled_render_to_texture) {
5212 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5213 service_id, level, samples);
5214 } else {
5215 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5216 service_id, level, samples);
5217 }
5218 }
5219 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265220 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165221 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5222 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285223 }
[email protected]9d3b2e12013-10-02 01:04:345224 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445225 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465226 }
[email protected]91c94eb2013-10-22 10:32:545227
5228 if (texture_ref)
5229 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5230
[email protected]81fc9d02013-03-14 23:53:325231 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455232}
5233
5234void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5235 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065236 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5237 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515238 LOCAL_SET_GL_ERROR(
5239 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205240 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455241 return;
5242 }
[email protected]74c1ec42010-08-12 01:55:575243 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105244 const Framebuffer::Attachment* attachment_object =
5245 framebuffer->GetAttachment(attachment);
5246 *params = attachment_object ? attachment_object->object_name() : 0;
5247 } else {
[email protected]7d3c36e2013-07-12 14:13:165248 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5249 features().use_img_for_multisampled_render_to_texture) {
5250 pname = GL_TEXTURE_SAMPLES_IMG;
5251 }
[email protected]62e65f02013-05-29 22:28:105252 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575253 }
[email protected]36cef8ce2010-03-16 07:34:455254}
5255
5256void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5257 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355258 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205259 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5260 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515261 LOCAL_SET_GL_ERROR(
5262 GL_INVALID_OPERATION,
5263 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455264 return;
5265 }
[email protected]8875a5f2014-06-27 08:33:475266
5267 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275268 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435269 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5270 *params = renderbuffer->internal_format();
5271 break;
5272 case GL_RENDERBUFFER_WIDTH:
5273 *params = renderbuffer->width();
5274 break;
5275 case GL_RENDERBUFFER_HEIGHT:
5276 *params = renderbuffer->height();
5277 break;
[email protected]7d3c36e2013-07-12 14:13:165278 case GL_RENDERBUFFER_SAMPLES_EXT:
5279 if (features().use_img_for_multisampled_render_to_texture) {
5280 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5281 params);
5282 } else {
5283 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5284 params);
5285 }
[email protected]ad84a3a2012-06-08 21:42:435286 default:
5287 glGetRenderbufferParameterivEXT(target, pname, params);
5288 break;
[email protected]b71f52c2010-06-18 22:20:205289 }
[email protected]36cef8ce2010-03-16 07:34:455290}
5291
[email protected]49cabed2013-11-13 18:15:185292void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305293 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5294 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5295 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445296 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165297
[email protected]49cabed2013-11-13 18:15:185298 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165299 return;
5300 }
5301
[email protected]454157e2014-05-03 02:49:455302 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:185303 BlitFramebufferHelper(
5304 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455305 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5306 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185307}
5308
[email protected]8875a5f2014-06-27 08:33:475309void GLES2DecoderImpl::EnsureRenderbufferBound() {
5310 if (!state_.bound_renderbuffer_valid) {
5311 state_.bound_renderbuffer_valid = true;
5312 glBindRenderbufferEXT(GL_RENDERBUFFER,
5313 state_.bound_renderbuffer.get()
5314 ? state_.bound_renderbuffer->service_id()
5315 : 0);
5316 }
5317}
5318
[email protected]f42f05b2013-11-15 21:46:185319void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5320 const FeatureInfo* feature_info,
5321 GLenum target,
5322 GLsizei samples,
5323 GLenum internal_format,
5324 GLsizei width,
5325 GLsizei height) {
5326 // TODO(sievers): This could be resolved at the GL binding level, but the
5327 // binding process is currently a bit too 'brute force'.
5328 if (feature_info->feature_flags().is_angle) {
5329 glRenderbufferStorageMultisampleANGLE(
5330 target, samples, internal_format, width, height);
5331 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5332 glRenderbufferStorageMultisample(
5333 target, samples, internal_format, width, height);
5334 } else {
5335 glRenderbufferStorageMultisampleEXT(
5336 target, samples, internal_format, width, height);
5337 }
5338}
5339
5340void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5341 GLint srcY0,
5342 GLint srcX1,
5343 GLint srcY1,
5344 GLint dstX0,
5345 GLint dstY0,
5346 GLint dstX1,
5347 GLint dstY1,
5348 GLbitfield mask,
5349 GLenum filter) {
5350 // TODO(sievers): This could be resolved at the GL binding level, but the
5351 // binding process is currently a bit too 'brute force'.
5352 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245353 glBlitFramebufferANGLE(
5354 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185355 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5356 glBlitFramebuffer(
5357 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245358 } else {
5359 glBlitFramebufferEXT(
5360 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5361 }
[email protected]8e3e0662010-08-23 18:46:305362}
5363
[email protected]49cabed2013-11-13 18:15:185364bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5365 GLsizei samples,
5366 GLenum internalformat,
5367 GLsizei width,
5368 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535369 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515370 LOCAL_SET_GL_ERROR(
5371 GL_INVALID_VALUE,
5372 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185373 return false;
[email protected]84afefa2011-10-19 21:45:535374 }
5375
5376 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5377 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515378 LOCAL_SET_GL_ERROR(
5379 GL_INVALID_VALUE,
5380 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185381 return false;
[email protected]84afefa2011-10-19 21:45:535382 }
5383
[email protected]7989c9e2013-01-23 06:39:265384 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235385 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5386 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515387 LOCAL_SET_GL_ERROR(
5388 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205389 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185390 return false;
[email protected]8e3e0662010-08-23 18:46:305391 }
5392
[email protected]7989c9e2013-01-23 06:39:265393 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515394 LOCAL_SET_GL_ERROR(
5395 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205396 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185397 return false;
5398 }
5399
5400 return true;
5401}
5402
5403void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5404 GLenum target, GLsizei samples, GLenum internalformat,
5405 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185406 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5407 if (!renderbuffer) {
5408 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5409 "glRenderbufferStorageMultisampleCHROMIUM",
5410 "no renderbuffer bound");
5411 return;
5412 }
5413
5414 if (!ValidateRenderbufferStorageMultisample(
5415 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265416 return;
5417 }
5418
[email protected]8875a5f2014-06-27 08:33:475419 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235420 GLenum impl_format =
5421 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5422 internalformat);
[email protected]49cabed2013-11-13 18:15:185423 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5424 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185425 RenderbufferStorageMultisampleHelper(
5426 feature_info_, target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185427 GLenum error =
5428 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265429 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105430
5431 if (workarounds().validate_multisample_buffer_allocation) {
5432 if (!VerifyMultisampleRenderbufferIntegrity(
5433 renderbuffer->service_id(), impl_format)) {
5434 LOCAL_SET_GL_ERROR(
5435 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185436 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105437 return;
5438 }
5439 }
5440
[email protected]968351b2011-12-20 08:26:515441 // TODO(gman): If renderbuffers tracked which framebuffers they were
5442 // attached to we could just mark those framebuffers as not complete.
5443 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205444 renderbuffer_manager()->SetInfo(
5445 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265446 }
[email protected]8e3e0662010-08-23 18:46:305447}
5448
[email protected]49cabed2013-11-13 18:15:185449// This is the handler for multisampled_render_to_texture extensions.
5450void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5451 GLenum target, GLsizei samples, GLenum internalformat,
5452 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185453 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5454 if (!renderbuffer) {
5455 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5456 "glRenderbufferStorageMultisampleEXT",
5457 "no renderbuffer bound");
5458 return;
5459 }
5460
5461 if (!ValidateRenderbufferStorageMultisample(
5462 samples, internalformat, width, height)) {
5463 return;
5464 }
5465
[email protected]8875a5f2014-06-27 08:33:475466 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185467 GLenum impl_format =
5468 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5469 internalformat);
5470 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5471 if (features().use_img_for_multisampled_render_to_texture) {
5472 glRenderbufferStorageMultisampleIMG(
5473 target, samples, impl_format, width, height);
5474 } else {
5475 glRenderbufferStorageMultisampleEXT(
5476 target, samples, impl_format, width, height);
5477 }
5478 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5479 if (error == GL_NO_ERROR) {
5480 // TODO(gman): If renderbuffers tracked which framebuffers they were
5481 // attached to we could just mark those framebuffers as not complete.
5482 framebuffer_manager()->IncFramebufferStateChangeCount();
5483 renderbuffer_manager()->SetInfo(
5484 renderbuffer, samples, internalformat, width, height);
5485 }
5486}
5487
[email protected]4a4c18b2013-09-13 22:50:105488// This function validates the allocation of a multisampled renderbuffer
5489// by clearing it to a key color, blitting the contents to a texture, and
5490// reading back the color to ensure it matches the key.
5491bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5492 GLuint renderbuffer, GLenum format) {
5493
5494 // Only validate color buffers.
5495 // These formats have been selected because they are very common or are known
5496 // to be used by the WebGL backbuffer. If problems are observed with other
5497 // color formats they can be added here.
5498 switch(format) {
5499 case GL_RGB:
5500 case GL_RGB8:
5501 case GL_RGBA:
5502 case GL_RGBA8:
5503 break;
5504 default:
5505 return true;
5506 }
5507
5508 GLint draw_framebuffer, read_framebuffer;
5509
5510 // Cache framebuffer and texture bindings.
5511 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5512 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5513
5514 if (!validation_texture_) {
5515 GLint bound_texture;
5516 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5517
5518 // Create additional resources needed for the verification.
5519 glGenTextures(1, &validation_texture_);
5520 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5521 glGenFramebuffersEXT(1, &validation_fbo_);
5522
5523 // Texture only needs to be 1x1.
5524 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5525 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5526 GL_UNSIGNED_BYTE, NULL);
5527
5528 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5529 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5530 GL_TEXTURE_2D, validation_texture_, 0);
5531
5532 glBindTexture(GL_TEXTURE_2D, bound_texture);
5533 }
5534
5535 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5536 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5537 GL_RENDERBUFFER, renderbuffer);
5538
5539 // Cache current state and reset it to the values we require.
5540 GLboolean scissor_enabled = false;
5541 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5542 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455543 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105544
[email protected]454157e2014-05-03 02:49:455545 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105546 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455547 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105548
5549 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5550 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5551 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5552
5553 // Clear the buffer to the desired key color.
5554 glClear(GL_COLOR_BUFFER_BIT);
5555
5556 // Blit from the multisample buffer to a standard texture.
5557 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5558 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5559
[email protected]f42f05b2013-11-15 21:46:185560 BlitFramebufferHelper(
5561 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105562
5563 // Read a pixel from the buffer.
5564 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5565
5566 unsigned char pixel[3] = {0, 0, 0};
5567 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5568
5569 // Detach the renderbuffer.
5570 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5571 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5572 GL_RENDERBUFFER, 0);
5573
5574 // Restore cached state.
5575 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455576 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105577
[email protected]454157e2014-05-03 02:49:455578 state_.SetDeviceColorMask(
5579 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105580 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5581 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5582 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5583
5584 // Return true if the pixel matched the desired key color.
5585 return (pixel[0] == 0xFF &&
5586 pixel[1] == 0x00 &&
5587 pixel[2] == 0xFF);
5588}
5589
[email protected]36cef8ce2010-03-16 07:34:455590void GLES2DecoderImpl::DoRenderbufferStorage(
5591 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355592 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205593 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5594 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515595 LOCAL_SET_GL_ERROR(
5596 GL_INVALID_OPERATION,
5597 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455598 return;
5599 }
[email protected]876f6fee2010-08-02 23:10:325600
[email protected]84afefa2011-10-19 21:45:535601 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5602 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515603 LOCAL_SET_GL_ERROR(
5604 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535605 return;
5606 }
5607
[email protected]7989c9e2013-01-23 06:39:265608 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235609 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5610 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515611 LOCAL_SET_GL_ERROR(
5612 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265613 return;
5614 }
5615
5616 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515617 LOCAL_SET_GL_ERROR(
5618 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265619 return;
[email protected]b71f52c2010-06-18 22:20:205620 }
[email protected]876f6fee2010-08-02 23:10:325621
[email protected]8875a5f2014-06-27 08:33:475622 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515623 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265624 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235625 target,
5626 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5627 internalformat),
5628 width,
5629 height);
[email protected]ab09b612013-03-11 22:11:515630 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265631 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515632 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5633 // we could just mark those framebuffers as not complete.
5634 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205635 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265636 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265637 }
[email protected]36cef8ce2010-03-16 07:34:455638}
5639
[email protected]df37b9932013-03-08 05:21:425640void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385641 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425642 Program* program = GetProgramInfoNotShader(
5643 program_id, "glLinkProgram");
5644 if (!program) {
[email protected]a93bb842010-02-16 23:03:475645 return;
5646 }
[email protected]05afda12011-01-20 00:17:345647
[email protected]df37b9932013-03-08 05:21:425648 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395649 ShaderTranslator* vertex_translator = NULL;
5650 ShaderTranslator* fragment_translator = NULL;
5651 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115652 vertex_translator = vertex_translator_.get();
5653 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395654 }
[email protected]df37b9932013-03-08 05:21:425655 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115656 vertex_translator,
5657 fragment_translator,
[email protected]008401532014-02-07 00:10:505658 workarounds().count_all_in_varyings_packing ?
5659 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115660 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425661 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185662 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425663 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185664 if (workarounds().clear_uniforms_before_first_program_use)
5665 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545666 }
5667 }
[email protected]07f54fcc2009-12-22 02:46:305668};
5669
[email protected]3916c97e2010-02-25 03:20:505670void GLES2DecoderImpl::DoTexParameterf(
5671 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445672 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5673 &state_, target);
[email protected]02965c22013-03-09 02:40:075674 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515675 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245676 return;
[email protected]07f54fcc2009-12-22 02:46:305677 }
[email protected]cbb22e42011-05-12 23:36:245678
[email protected]737191ee72014-03-09 08:02:425679 texture_manager()->SetParameterf(
5680 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305681}
5682
[email protected]3916c97e2010-02-25 03:20:505683void GLES2DecoderImpl::DoTexParameteri(
5684 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445685 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5686 &state_, target);
[email protected]02965c22013-03-09 02:40:075687 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515688 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245689 return;
[email protected]3916c97e2010-02-25 03:20:505690 }
[email protected]cbb22e42011-05-12 23:36:245691
[email protected]737191ee72014-03-09 08:02:425692 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505693 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505694}
5695
5696void GLES2DecoderImpl::DoTexParameterfv(
5697 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445698 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5699 &state_, target);
[email protected]02965c22013-03-09 02:40:075700 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515701 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245702 return;
[email protected]3916c97e2010-02-25 03:20:505703 }
[email protected]cbb22e42011-05-12 23:36:245704
[email protected]737191ee72014-03-09 08:02:425705 texture_manager()->SetParameterf(
5706 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505707}
5708
5709void GLES2DecoderImpl::DoTexParameteriv(
5710 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445711 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5712 &state_, target);
[email protected]02965c22013-03-09 02:40:075713 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515714 LOCAL_SET_GL_ERROR(
5715 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245716 return;
[email protected]3916c97e2010-02-25 03:20:505717 }
[email protected]cbb22e42011-05-12 23:36:245718
[email protected]737191ee72014-03-09 08:02:425719 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505720 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505721}
5722
[email protected]939e7362010-05-13 20:49:105723bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115724 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435725 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515726 LOCAL_SET_GL_ERROR(
5727 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435728 return false;
[email protected]939e7362010-05-13 20:49:105729 }
[email protected]e259eb412012-10-13 05:47:245730 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515731 LOCAL_SET_GL_ERROR(
5732 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105733 return false;
5734 }
5735 return true;
5736}
5737
5738bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5739 GLint location, const char* function_name) {
5740 if (!CheckCurrentProgram(function_name)) {
5741 return false;
5742 }
5743 return location != -1;
5744}
5745
[email protected]43c2f1f2011-03-25 18:35:365746bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:135747 GLint fake_location,
5748 const char* function_name,
5749 Program::UniformApiType api_type,
5750 GLint* real_location,
5751 GLenum* type,
5752 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365753 DCHECK(type);
5754 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125755 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525756
[email protected]1b0a6752012-02-22 03:44:125757 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105758 return false;
5759 }
[email protected]43c2f1f2011-03-25 18:35:365760 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355761 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245762 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125763 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365764 if (!info) {
[email protected]ab09b612013-03-11 22:11:515765 LOCAL_SET_GL_ERROR(
5766 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105767 return false;
5768 }
[email protected]9b1f1b52014-03-12 10:40:135769
5770 if ((api_type & info->accepts_api_type) == 0) {
[email protected]ab09b612013-03-11 22:11:515771 LOCAL_SET_GL_ERROR(
5772 GL_INVALID_OPERATION, function_name,
5773 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525774 return false;
5775 }
[email protected]43c2f1f2011-03-25 18:35:365776 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515777 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435778 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365779 return false;
5780 }
5781 *count = std::min(info->size - array_index, *count);
5782 if (*count <= 0) {
5783 return false;
5784 }
5785 *type = info->type;
[email protected]939e7362010-05-13 20:49:105786 return true;
5787}
5788
[email protected]1b0a6752012-02-22 03:44:125789void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5790 GLenum type = 0;
5791 GLsizei count = 1;
5792 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135793 if (!PrepForSetUniformByLocation(fake_location,
5794 "glUniform1i",
5795 Program::kUniform1i,
5796 &real_location,
5797 &type,
5798 &count)) {
[email protected]3916c97e2010-02-25 03:20:505799 return;
5800 }
[email protected]e259eb412012-10-13 05:47:245801 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025802 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515803 LOCAL_SET_GL_ERROR(
5804 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465805 return;
5806 }
[email protected]1b0a6752012-02-22 03:44:125807 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505808}
5809
5810void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125811 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365812 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125813 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135814 if (!PrepForSetUniformByLocation(fake_location,
5815 "glUniform1iv",
5816 Program::kUniform1i,
5817 &real_location,
5818 &type,
5819 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365820 return;
5821 }
[email protected]74727112012-06-13 21:18:085822 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5823 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245824 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025825 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515826 LOCAL_SET_GL_ERROR(
5827 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465828 return;
5829 }
[email protected]43c2f1f2011-03-25 18:35:365830 }
[email protected]1b0a6752012-02-22 03:44:125831 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505832}
5833
[email protected]939e7362010-05-13 20:49:105834void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125835 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365836 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125837 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135838 if (!PrepForSetUniformByLocation(fake_location,
5839 "glUniform1fv",
5840 Program::kUniform1f,
5841 &real_location,
5842 &type,
5843 &count)) {
[email protected]939e7362010-05-13 20:49:105844 return;
5845 }
5846 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555847 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105848 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535849 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105850 }
[email protected]1b0a6752012-02-22 03:44:125851 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105852 } else {
[email protected]1b0a6752012-02-22 03:44:125853 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105854 }
5855}
5856
5857void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125858 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365859 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125860 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135861 if (!PrepForSetUniformByLocation(fake_location,
5862 "glUniform2fv",
5863 Program::kUniform2f,
5864 &real_location,
5865 &type,
5866 &count)) {
[email protected]939e7362010-05-13 20:49:105867 return;
5868 }
5869 if (type == GL_BOOL_VEC2) {
5870 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555871 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105872 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535873 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105874 }
[email protected]1b0a6752012-02-22 03:44:125875 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105876 } else {
[email protected]1b0a6752012-02-22 03:44:125877 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105878 }
5879}
5880
5881void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125882 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365883 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125884 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135885 if (!PrepForSetUniformByLocation(fake_location,
5886 "glUniform3fv",
5887 Program::kUniform3f,
5888 &real_location,
5889 &type,
5890 &count)) {
[email protected]939e7362010-05-13 20:49:105891 return;
5892 }
5893 if (type == GL_BOOL_VEC3) {
5894 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555895 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105896 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535897 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105898 }
[email protected]1b0a6752012-02-22 03:44:125899 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105900 } else {
[email protected]1b0a6752012-02-22 03:44:125901 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105902 }
5903}
5904
5905void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125906 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365907 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125908 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135909 if (!PrepForSetUniformByLocation(fake_location,
5910 "glUniform4fv",
5911 Program::kUniform4f,
5912 &real_location,
5913 &type,
5914 &count)) {
[email protected]939e7362010-05-13 20:49:105915 return;
5916 }
5917 if (type == GL_BOOL_VEC4) {
5918 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555919 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105920 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535921 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105922 }
[email protected]1b0a6752012-02-22 03:44:125923 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105924 } else {
[email protected]1b0a6752012-02-22 03:44:125925 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105926 }
5927}
5928
[email protected]43c2f1f2011-03-25 18:35:365929void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125930 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365931 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125932 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135933 if (!PrepForSetUniformByLocation(fake_location,
5934 "glUniform2iv",
5935 Program::kUniform2i,
5936 &real_location,
5937 &type,
5938 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365939 return;
5940 }
[email protected]1b0a6752012-02-22 03:44:125941 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365942}
5943
5944void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125945 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365946 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125947 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135948 if (!PrepForSetUniformByLocation(fake_location,
5949 "glUniform3iv",
5950 Program::kUniform3i,
5951 &real_location,
5952 &type,
5953 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365954 return;
5955 }
[email protected]1b0a6752012-02-22 03:44:125956 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365957}
5958
5959void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125960 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365961 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125962 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135963 if (!PrepForSetUniformByLocation(fake_location,
5964 "glUniform4iv",
5965 Program::kUniform4i,
5966 &real_location,
5967 &type,
5968 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365969 return;
5970 }
[email protected]1b0a6752012-02-22 03:44:125971 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365972}
5973
5974void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125975 GLint fake_location, GLsizei count, GLboolean transpose,
5976 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365977 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125978 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135979 if (!PrepForSetUniformByLocation(fake_location,
5980 "glUniformMatrix2fv",
5981 Program::kUniformMatrix2f,
5982 &real_location,
5983 &type,
5984 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365985 return;
5986 }
[email protected]1b0a6752012-02-22 03:44:125987 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365988}
5989
5990void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125991 GLint fake_location, GLsizei count, GLboolean transpose,
5992 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365993 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125994 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135995 if (!PrepForSetUniformByLocation(fake_location,
5996 "glUniformMatrix3fv",
5997 Program::kUniformMatrix3f,
5998 &real_location,
5999 &type,
6000 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366001 return;
6002 }
[email protected]1b0a6752012-02-22 03:44:126003 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366004}
6005
6006void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126007 GLint fake_location, GLsizei count, GLboolean transpose,
6008 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366009 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126010 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136011 if (!PrepForSetUniformByLocation(fake_location,
6012 "glUniformMatrix4fv",
6013 Program::kUniformMatrix4f,
6014 &real_location,
6015 &type,
6016 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366017 return;
6018 }
[email protected]1b0a6752012-02-22 03:44:126019 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366020}
6021
[email protected]df37b9932013-03-08 05:21:426022void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036023 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426024 Program* program = NULL;
6025 if (program_id) {
6026 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6027 if (!program) {
[email protected]ae51d192010-04-27 00:48:036028 return;
6029 }
[email protected]df37b9932013-03-08 05:21:426030 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506031 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516032 LOCAL_SET_GL_ERROR(
6033 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506034 return;
6035 }
[email protected]df37b9932013-03-08 05:21:426036 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506037 }
[email protected]7cd76fd2013-06-02 21:11:116038 if (state_.current_program.get()) {
6039 program_manager()->UnuseProgram(shader_manager(),
6040 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146041 }
[email protected]df37b9932013-03-08 05:21:426042 state_.current_program = program;
6043 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546044 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116045 if (state_.current_program.get()) {
6046 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186047 if (workarounds().clear_uniforms_before_first_program_use)
6048 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146049 }
[email protected]3916c97e2010-02-25 03:20:506050}
6051
[email protected]ab09b612013-03-11 22:11:516052void GLES2DecoderImpl::RenderWarning(
6053 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326054 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016055}
6056
[email protected]ab09b612013-03-11 22:11:516057void GLES2DecoderImpl::PerformanceWarning(
6058 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506059 logger_.LogMessage(filename, line,
6060 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016061}
6062
[email protected]91c94eb2013-10-22 10:32:546063void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6064 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546065 // Image is already in use if texture is attached to a framebuffer.
6066 if (texture && !texture->IsAttachedToFramebuffer()) {
6067 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6068 if (image) {
6069 ScopedGLErrorSuppressor suppressor(
6070 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6071 GetErrorState());
6072 glBindTexture(textarget, texture->service_id());
6073 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026074 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546075 }
6076 }
6077}
6078
6079void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6080 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546081 // Image is still in use if texture is attached to a framebuffer.
6082 if (texture && !texture->IsAttachedToFramebuffer()) {
6083 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6084 if (image) {
6085 ScopedGLErrorSuppressor suppressor(
6086 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6087 GetErrorState());
6088 glBindTexture(textarget, texture->service_id());
6089 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026090 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546091 }
6092 }
6093}
6094
[email protected]e56131d22013-07-28 16:14:116095bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116096 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546097 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556098 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116099 return true;
[email protected]ef526492010-06-02 23:12:256100 }
[email protected]e2367b42013-05-31 03:37:216101
[email protected]ef526492010-06-02 23:12:256102 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356103 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246104 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506105 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356106 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246107 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506108 DCHECK(uniform_info);
6109 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6110 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026111 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246112 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546113 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366114 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546115 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6116 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256117 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506118 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6119 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546120 textarget,
[email protected]00f893d2010-08-24 18:55:496121 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:516122 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:016123 std::string("texture bound to texture unit ") +
6124 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:296125 " is not renderable. It maybe non-power-of-2 and have"
6126 " incompatible texture filtering or is not"
6127 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:546128 continue;
[email protected]3916c97e2010-02-25 03:20:506129 }
[email protected]91c94eb2013-10-22 10:32:546130
[email protected]4e7b89202014-01-28 01:44:066131 if (textarget != GL_TEXTURE_CUBE_MAP) {
6132 Texture* texture = texture_ref->texture();
6133 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6134 if (image && !texture->IsAttachedToFramebuffer()) {
6135 ScopedGLErrorSuppressor suppressor(
6136 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6137 textures_set = true;
6138 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6139 image->WillUseTexImage();
6140 continue;
6141 }
[email protected]91c94eb2013-10-22 10:32:546142 }
[email protected]3916c97e2010-02-25 03:20:506143 }
6144 // else: should this be an error?
6145 }
6146 }
[email protected]e56131d22013-07-28 16:14:116147 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506148}
6149
[email protected]91c94eb2013-10-22 10:32:546150void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116151 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356152 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116153 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506154 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356155 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246156 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506157 DCHECK(uniform_info);
6158 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6159 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026160 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246161 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116162 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546163 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496164 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506165 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496166 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116167 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6168 ? texture_unit.bound_texture_2d.get()
6169 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506170 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496171 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546172 continue;
6173 }
6174
[email protected]4e7b89202014-01-28 01:44:066175 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6176 Texture* texture = texture_ref->texture();
6177 gfx::GLImage* image =
6178 texture->GetLevelImage(texture_unit.bind_target, 0);
6179 if (image && !texture->IsAttachedToFramebuffer()) {
6180 ScopedGLErrorSuppressor suppressor(
6181 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6182 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6183 image->DidUseTexImage();
6184 continue;
6185 }
[email protected]3916c97e2010-02-25 03:20:506186 }
6187 }
6188 }
6189 }
6190 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246191 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306192}
6193
[email protected]0d6bfdc2011-11-02 01:32:206194bool GLES2DecoderImpl::ClearUnclearedTextures() {
6195 // Only check if there are some uncleared textures.
6196 if (!texture_manager()->HaveUnsafeTextures()) {
6197 return true;
6198 }
6199
6200 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116201 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356202 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116203 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206204 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356205 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246206 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206207 DCHECK(uniform_info);
6208 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6209 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026210 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246211 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496212 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366213 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496214 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6215 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206216 return false;
6217 }
6218 }
6219 }
6220 }
6221 }
6222 }
6223 return true;
6224}
6225
[email protected]c6aef902012-02-14 03:31:426226bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106227 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6228 GLsizei primcount) {
6229 DCHECK(instanced || primcount == 1);
6230
[email protected]689fa1c52010-06-09 18:35:036231 // NOTE: We specifically do not check current_program->IsValid() because
6232 // it could never be invalid since glUseProgram would have failed. While
6233 // glLinkProgram could later mark the program as invalid the previous
6234 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116235 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506236 // The program does not exist.
6237 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516238 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506239 return false;
6240 }
[email protected]c6aef902012-02-14 03:31:426241
[email protected]7cd76fd2013-06-02 21:11:116242 return state_.vertex_attrib_manager
6243 ->ValidateBindings(function_name,
6244 this,
6245 feature_info_.get(),
6246 state_.current_program.get(),
6247 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106248 instanced,
[email protected]7cd76fd2013-06-02 21:11:116249 primcount);
[email protected]b1122982010-05-17 23:04:246250}
6251
[email protected]c13e1da62011-09-09 21:48:306252bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436253 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306254 DCHECK(simulated);
6255 *simulated = false;
6256
[email protected]876f6fee2010-08-02 23:10:326257 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306258 return true;
[email protected]876f6fee2010-08-02 23:10:326259
[email protected]ac77603c72013-03-08 13:52:066260 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356261 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246262 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246263 bool attrib_0_used =
6264 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066265 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306266 return true;
[email protected]b1122982010-05-17 23:04:246267 }
6268
[email protected]b1122982010-05-17 23:04:246269 // Make a buffer with a single repeated vec4 value enough to
6270 // simulate the constant value that is supposed to be here.
6271 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306272 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476273 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306274
6275 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476276 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306277 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516278 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306279 return false;
6280 }
6281
[email protected]ab09b612013-03-11 22:11:516282 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016283 "Attribute 0 is disabled. This has signficant performance penalty");
6284
[email protected]ab09b612013-03-11 22:11:516285 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306286 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6287
[email protected]8f0b86c2f2012-04-10 05:48:286288 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6289 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496290 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306291 GLenum error = glGetError();
6292 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516293 LOCAL_SET_GL_ERROR(
6294 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306295 return false;
6296 }
[email protected]fc753442011-02-04 19:49:496297 }
[email protected]af6380962012-11-29 23:24:136298
6299 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286300 if (new_buffer ||
6301 (attrib_0_used &&
6302 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136303 (value.v[0] != attrib_0_value_.v[0] ||
6304 value.v[1] != attrib_0_value_.v[1] ||
6305 value.v[2] != attrib_0_value_.v[2] ||
6306 value.v[3] != attrib_0_value_.v[3])))) {
6307 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496308 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6309 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136310 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246311 attrib_0_size_ = size_needed;
6312 }
6313
6314 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6315
[email protected]ac77603c72013-03-08 13:52:066316 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426317 glVertexAttribDivisorANGLE(0, 0);
6318
[email protected]c13e1da62011-09-09 21:48:306319 *simulated = true;
[email protected]b1122982010-05-17 23:04:246320 return true;
[email protected]b1122982010-05-17 23:04:246321}
6322
[email protected]3fc38e22014-05-30 00:13:236323void GLES2DecoderImpl::RestoreStateForAttrib(
6324 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066325 const VertexAttrib* attrib =
6326 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236327 if (restore_array_binding) {
6328 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6329 Buffer* buffer = attrib->buffer();
6330 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6331 glVertexAttribPointer(
6332 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6333 attrib->gl_stride(), ptr);
6334 }
[email protected]ac77603c72013-03-08 13:52:066335 if (attrib->divisor())
6336 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246337 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236338 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6339 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286340
[email protected]265f8992012-07-20 01:03:146341 // Never touch vertex attribute 0's state (in particular, never
6342 // disable it) when running on desktop GL because it will never be
6343 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066344 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146345 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066346 if (attrib->enabled()) {
6347 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146348 } else {
[email protected]ac77603c72013-03-08 13:52:066349 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146350 }
[email protected]43410e92012-04-20 17:06:286351 }
[email protected]b1122982010-05-17 23:04:246352}
[email protected]07f54fcc2009-12-22 02:46:306353
[email protected]8fbedc02010-11-18 18:43:406354bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436355 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426356 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406357 DCHECK(simulated);
6358 *simulated = false;
6359 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6360 return true;
6361
[email protected]e259eb412012-10-13 05:47:246362 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406363 return true;
6364 }
6365
[email protected]ab09b612013-03-11 22:11:516366 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016367 "GL_FIXED attributes have a signficant performance penalty");
6368
[email protected]8fbedc02010-11-18 18:43:406369 // NOTE: we could be smart and try to check if a buffer is used
6370 // twice in 2 different attribs, find the overlapping parts and therefore
6371 // duplicate the minimum amount of data but this whole code path is not meant
6372 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6373 // tests so we just add to the buffer attrib used.
6374
[email protected]c13e1da62011-09-09 21:48:306375 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066376 const VertexAttribManager::VertexAttribList& enabled_attribs =
6377 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6378 for (VertexAttribManager::VertexAttribList::const_iterator it =
6379 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6380 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356381 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066382 state_.current_program->GetAttribInfoByLocation(attrib->index());
6383 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6384 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426385 GLuint num_vertices = max_accessed + 1;
6386 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516387 LOCAL_SET_GL_ERROR(
6388 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426389 return false;
6390 }
[email protected]8fbedc02010-11-18 18:43:406391 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066392 attrib->CanAccess(max_accessed) &&
6393 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476394 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066395 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476396 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516397 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436398 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406399 return false;
6400 }
6401 }
6402 }
6403
[email protected]3aad1a32012-09-07 20:54:476404 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6405 uint32 size_needed = 0;
6406 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306407 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516408 LOCAL_SET_GL_ERROR(
6409 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406410 return false;
6411 }
6412
[email protected]ab09b612013-03-11 22:11:516413 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406414
6415 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306416 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406417 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306418 GLenum error = glGetError();
6419 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516420 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436421 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306422 return false;
6423 }
[email protected]8fbedc02010-11-18 18:43:406424 }
6425
6426 // Copy the elements and convert to float
6427 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066428 for (VertexAttribManager::VertexAttribList::const_iterator it =
6429 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6430 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356431 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066432 state_.current_program->GetAttribInfoByLocation(attrib->index());
6433 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426434 max_vertex_accessed);
6435 GLuint num_vertices = max_accessed + 1;
6436 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516437 LOCAL_SET_GL_ERROR(
6438 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426439 return false;
6440 }
[email protected]8fbedc02010-11-18 18:43:406441 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066442 attrib->CanAccess(max_accessed) &&
6443 attrib->type() == GL_FIXED) {
6444 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406445 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556446 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406447 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066448 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406449 const int32* end = src + num_elements;
6450 float* dst = data.get();
6451 while (src != end) {
6452 *dst++ = static_cast<float>(*src++) / 65536.0f;
6453 }
6454 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6455 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066456 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406457 reinterpret_cast<GLvoid*>(offset));
6458 offset += size;
6459 }
6460 }
6461 *simulated = true;
6462 return true;
6463}
6464
6465void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6466 // There's no need to call glVertexAttribPointer because we shadow all the
6467 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246468 glBindBuffer(
6469 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116470 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6471 : 0);
[email protected]8fbedc02010-11-18 18:43:406472}
6473
[email protected]ad84a3a2012-06-08 21:42:436474error::Error GLES2DecoderImpl::DoDrawArrays(
6475 const char* function_name,
6476 bool instanced,
6477 GLenum mode,
6478 GLint first,
6479 GLsizei count,
6480 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226481 error::Error error = WillAccessBoundFramebufferForDraw();
6482 if (error != error::kNoError)
6483 return error;
[email protected]38d139d2011-07-14 00:38:436484 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516485 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436486 return error::kNoError;
6487 }
6488 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516489 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436490 return error::kNoError;
6491 }
[email protected]c6aef902012-02-14 03:31:426492 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516493 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426494 return error::kNoError;
6495 }
[email protected]ad84a3a2012-06-08 21:42:436496 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436497 return error::kNoError;
6498 }
6499 // We have to check this here because the prototype for glDrawArrays
6500 // is GLint not GLsizei.
6501 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516502 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436503 return error::kNoError;
6504 }
6505
[email protected]ac6904d62014-07-30 12:00:106506 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516507 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436508 return error::kNoError;
6509 }
6510
6511 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106512 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206513 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516514 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206515 return error::kNoError;
6516 }
[email protected]c13e1da62011-09-09 21:48:306517 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436518 if (!SimulateAttrib0(
6519 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306520 return error::kNoError;
6521 }
[email protected]38d139d2011-07-14 00:38:436522 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436523 if (SimulateFixedAttribs(
6524 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6525 primcount)) {
[email protected]e56131d22013-07-28 16:14:116526 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436527 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376528 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426529 if (!instanced) {
6530 glDrawArrays(mode, first, count);
6531 } else {
6532 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6533 }
[email protected]38d139d2011-07-14 00:38:436534 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546535 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436536 }
6537 if (simulated_fixed_attribs) {
6538 RestoreStateForSimulatedFixedAttribs();
6539 }
6540 }
6541 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236542 // We don't have to restore attrib 0 generic data at the end of this
6543 // function even if it is simulated. This is because we will simulate
6544 // it in each draw call, and attrib 0 generic data queries use cached
6545 // values instead of passing down to the underlying driver.
6546 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436547 }
[email protected]38d139d2011-07-14 00:38:436548 }
6549 return error::kNoError;
6550}
6551
[email protected]c6aef902012-02-14 03:31:426552error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356553 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436554 return DoDrawArrays("glDrawArrays",
6555 false,
[email protected]c6aef902012-02-14 03:31:426556 static_cast<GLenum>(c.mode),
6557 static_cast<GLint>(c.first),
6558 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106559 1);
[email protected]c6aef902012-02-14 03:31:426560}
6561
6562error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356563 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156564 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516565 LOCAL_SET_GL_ERROR(
6566 GL_INVALID_OPERATION,
6567 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426568 return error::kNoError;
6569 }
[email protected]ad84a3a2012-06-08 21:42:436570 return DoDrawArrays("glDrawArraysIntancedANGLE",
6571 true,
[email protected]c6aef902012-02-14 03:31:426572 static_cast<GLenum>(c.mode),
6573 static_cast<GLint>(c.first),
6574 static_cast<GLsizei>(c.count),
6575 static_cast<GLsizei>(c.primcount));
6576}
6577
[email protected]ad84a3a2012-06-08 21:42:436578error::Error GLES2DecoderImpl::DoDrawElements(
6579 const char* function_name,
6580 bool instanced,
6581 GLenum mode,
6582 GLsizei count,
6583 GLenum type,
6584 int32 offset,
6585 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226586 error::Error error = WillAccessBoundFramebufferForDraw();
6587 if (error != error::kNoError)
6588 return error;
[email protected]e259eb412012-10-13 05:47:246589 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516590 LOCAL_SET_GL_ERROR(
6591 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296592 return error::kNoError;
6593 }
6594
[email protected]8eee29c2010-04-29 03:38:296595 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516596 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296597 return error::kNoError;
6598 }
6599 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516600 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296601 return error::kNoError;
6602 }
[email protected]9438b012010-06-15 22:55:056603 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516604 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296605 return error::kNoError;
6606 }
[email protected]9438b012010-06-15 22:55:056607 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516608 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296609 return error::kNoError;
6610 }
[email protected]c6aef902012-02-14 03:31:426611 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516612 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426613 return error::kNoError;
6614 }
[email protected]8eee29c2010-04-29 03:38:296615
[email protected]ad84a3a2012-06-08 21:42:436616 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276617 return error::kNoError;
6618 }
6619
[email protected]ac6904d62014-07-30 12:00:106620 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316621 return error::kNoError;
6622 }
6623
[email protected]8eee29c2010-04-29 03:38:296624 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086625 Buffer* element_array_buffer =
6626 state_.vertex_attrib_manager->element_array_buffer();
6627
6628 if (!element_array_buffer->GetMaxValueForRange(
6629 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516630 LOCAL_SET_GL_ERROR(
6631 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296632 return error::kNoError;
6633 }
6634
[email protected]ac6904d62014-07-30 12:00:106635 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206636 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516637 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206638 return error::kNoError;
6639 }
[email protected]c13e1da62011-09-09 21:48:306640 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436641 if (!SimulateAttrib0(
6642 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306643 return error::kNoError;
6644 }
[email protected]8fbedc02010-11-18 18:43:406645 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436646 if (SimulateFixedAttribs(
6647 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6648 primcount)) {
[email protected]e56131d22013-07-28 16:14:116649 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466650 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086651 // TODO(gman): Refactor to hide these details in BufferManager or
6652 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406653 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086654 bool used_client_side_array = false;
6655 if (element_array_buffer->IsClientSideArray()) {
6656 used_client_side_array = true;
6657 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6658 indices = element_array_buffer->GetRange(offset, 0);
6659 }
6660
[email protected]00c2cf92014-03-14 00:08:376661 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426662 if (!instanced) {
6663 glDrawElements(mode, count, type, indices);
6664 } else {
6665 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6666 }
[email protected]17cfbe0e2013-03-07 01:26:086667
6668 if (used_client_side_array) {
6669 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6670 element_array_buffer->service_id());
6671 }
6672
[email protected]8fbedc02010-11-18 18:43:406673 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546674 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406675 }
6676 if (simulated_fixed_attribs) {
6677 RestoreStateForSimulatedFixedAttribs();
6678 }
[email protected]ba3176a2009-12-16 18:19:466679 }
[email protected]b1122982010-05-17 23:04:246680 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236681 // We don't have to restore attrib 0 generic data at the end of this
6682 // function even if it is simulated. This is because we will simulate
6683 // it in each draw call, and attrib 0 generic data queries use cached
6684 // values instead of passing down to the underlying driver.
6685 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:246686 }
[email protected]96449d2c2009-11-25 00:01:326687 }
[email protected]f7a64ee2010-02-01 22:24:146688 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326689}
6690
[email protected]c6aef902012-02-14 03:31:426691error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356692 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436693 return DoDrawElements("glDrawElements",
6694 false,
[email protected]c6aef902012-02-14 03:31:426695 static_cast<GLenum>(c.mode),
6696 static_cast<GLsizei>(c.count),
6697 static_cast<GLenum>(c.type),
6698 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:106699 1);
[email protected]c6aef902012-02-14 03:31:426700}
6701
6702error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356703 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156704 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516705 LOCAL_SET_GL_ERROR(
6706 GL_INVALID_OPERATION,
6707 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426708 return error::kNoError;
6709 }
[email protected]ad84a3a2012-06-08 21:42:436710 return DoDrawElements("glDrawElementsInstancedANGLE",
6711 true,
[email protected]c6aef902012-02-14 03:31:426712 static_cast<GLenum>(c.mode),
6713 static_cast<GLsizei>(c.count),
6714 static_cast<GLenum>(c.type),
6715 static_cast<int32>(c.index_offset),
6716 static_cast<GLsizei>(c.primcount));
6717}
6718
[email protected]269200b12010-11-18 22:53:066719GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236720 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6721 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076722 Buffer* buffer = GetBuffer(buffer_id);
6723 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036724 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516725 LOCAL_SET_GL_ERROR(
6726 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236727 } else {
[email protected]b10492f2013-03-08 05:24:076728 if (!buffer->GetMaxValueForRange(
6729 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036730 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516731 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066732 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436733 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236734 }
6735 }
6736 return max_vertex_accessed;
6737}
6738
[email protected]96449d2c2009-11-25 00:01:326739// Calls glShaderSource for the various versions of the ShaderSource command.
6740// Assumes that data / data_size points to a piece of memory that is in range
6741// of whatever context it came from (shared memory, immediate memory, bucket
6742// memory.)
[email protected]45bf5152010-02-12 00:11:316743error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036744 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576745 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426746 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6747 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316748 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326749 }
[email protected]45bf5152010-02-12 00:11:316750 // Note: We don't actually call glShaderSource here. We wait until
6751 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426752 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146753 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326754}
6755
[email protected]558847a2010-03-24 07:02:546756error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356757 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546758 Bucket* bucket = GetBucket(c.data_bucket_id);
6759 if (!bucket || bucket->size() == 0) {
6760 return error::kInvalidArguments;
6761 }
6762 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036763 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546764 bucket->size() - 1);
6765}
6766
[email protected]ae51d192010-04-27 00:48:036767void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386768 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426769 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6770 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316771 return;
6772 }
[email protected]f57bb282010-11-12 00:51:346773 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186774 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426775 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456776 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416777 }
[email protected]de17df392010-04-23 21:09:416778
[email protected]b05955552014-02-06 18:41:186779 program_manager()->DoCompileShader(
6780 shader,
6781 translator,
6782 feature_info_->feature_flags().angle_translated_shader_source ?
6783 ProgramManager::kANGLE : ProgramManager::kGL);
[email protected]45bf5152010-02-12 00:11:316784};
6785
[email protected]ddd968b82010-03-02 00:44:296786void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426787 GLuint shader_id, GLenum pname, GLint* params) {
6788 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6789 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296790 return;
6791 }
[email protected]8f1ccdac2010-05-19 21:01:486792 switch (pname) {
6793 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426794 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486795 return;
6796 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426797 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416798 return;
[email protected]8f1ccdac2010-05-19 21:01:486799 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426800 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416801 return;
[email protected]d6a53e42011-10-05 00:09:366802 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426803 *params = shader->translated_source() ?
6804 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366805 return;
[email protected]8f1ccdac2010-05-19 21:01:486806 default:
6807 break;
[email protected]ddd968b82010-03-02 00:44:296808 }
[email protected]df37b9932013-03-08 05:21:426809 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296810}
6811
[email protected]ae51d192010-04-27 00:48:036812error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356813 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426814 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036815 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6816 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426817 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6818 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296819 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296820 return error::kNoError;
6821 }
[email protected]df37b9932013-03-08 05:21:426822 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036823 return error::kNoError;
6824}
6825
[email protected]d6a53e42011-10-05 00:09:366826error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6827 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356828 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426829 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366830 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6831 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426832 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:206833 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:426834 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366835 bucket->SetSize(0);
6836 return error::kNoError;
6837 }
6838
[email protected]df37b9932013-03-08 05:21:426839 bucket->SetFromString(shader->translated_source() ?
6840 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366841 return error::kNoError;
6842}
6843
[email protected]ae51d192010-04-27 00:48:036844error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356845 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426846 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586847 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6848 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426849 Program* program = GetProgramInfoNotShader(
6850 program_id, "glGetProgramInfoLog");
6851 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466852 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036853 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316854 }
[email protected]df37b9932013-03-08 05:21:426855 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036856 return error::kNoError;
6857}
6858
6859error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356860 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426861 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586862 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6863 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426864 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6865 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466866 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036867 return error::kNoError;
6868 }
[email protected]df37b9932013-03-08 05:21:426869 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036870 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326871}
6872
[email protected]d058bca2012-11-26 10:27:266873bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6874 return state_.GetEnabled(cap);
6875}
6876
[email protected]1958e0e2010-04-22 05:17:156877bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216878 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106879 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156880}
6881
6882bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356883 const Framebuffer* framebuffer =
6884 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106885 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156886}
6887
6888bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366889 // IsProgram is true for programs as soon as they are created, until they are
6890 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356891 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106892 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156893}
6894
6895bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356896 const Renderbuffer* renderbuffer =
6897 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106898 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156899}
6900
6901bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366902 // IsShader is true for shaders as soon as they are created, until they
6903 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356904 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106905 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156906}
6907
6908bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496909 const TextureRef* texture_ref = GetTexture(client_id);
6910 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036911}
6912
6913void GLES2DecoderImpl::DoAttachShader(
6914 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426915 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586916 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426917 if (!program) {
[email protected]ae51d192010-04-27 00:48:036918 return;
[email protected]1958e0e2010-04-22 05:17:156919 }
[email protected]df37b9932013-03-08 05:21:426920 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6921 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036922 return;
6923 }
[email protected]df37b9932013-03-08 05:21:426924 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516925 LOCAL_SET_GL_ERROR(
6926 GL_INVALID_OPERATION,
6927 "glAttachShader",
6928 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316929 return;
6930 }
[email protected]df37b9932013-03-08 05:21:426931 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036932}
6933
6934void GLES2DecoderImpl::DoDetachShader(
6935 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426936 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586937 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426938 if (!program) {
[email protected]ae51d192010-04-27 00:48:036939 return;
6940 }
[email protected]df37b9932013-03-08 05:21:426941 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6942 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036943 return;
6944 }
[email protected]df37b9932013-03-08 05:21:426945 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516946 LOCAL_SET_GL_ERROR(
6947 GL_INVALID_OPERATION,
6948 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226949 return;
6950 }
[email protected]df37b9932013-03-08 05:21:426951 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036952}
6953
6954void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426955 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586956 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426957 if (!program) {
[email protected]ae51d192010-04-27 00:48:036958 return;
6959 }
[email protected]df37b9932013-03-08 05:21:426960 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156961}
6962
[email protected]ac77603c72013-03-08 13:52:066963void GLES2DecoderImpl::GetVertexAttribHelper(
6964 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246965 switch (pname) {
6966 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066967 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246968 if (buffer && !buffer->IsDeleted()) {
6969 GLuint client_id;
6970 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6971 *params = client_id;
6972 }
6973 break;
6974 }
6975 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066976 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246977 break;
6978 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066979 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246980 break;
6981 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066982 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246983 break;
6984 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066985 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246986 break;
6987 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066988 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246989 break;
[email protected]c6aef902012-02-14 03:31:426990 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066991 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426992 break;
[email protected]ac77603c72013-03-08 13:52:066993 default:
6994 NOTREACHED();
6995 break;
6996 }
6997}
6998
[email protected]4c6f5462014-03-05 00:26:566999void GLES2DecoderImpl::DoGetTexParameterfv(
7000 GLenum target, GLenum pname, GLfloat* params) {
7001 InitTextureMaxAnisotropyIfNeeded(target, pname);
7002 glGetTexParameterfv(target, pname, params);
7003}
7004
7005void GLES2DecoderImpl::DoGetTexParameteriv(
7006 GLenum target, GLenum pname, GLint* params) {
7007 InitTextureMaxAnisotropyIfNeeded(target, pname);
7008 glGetTexParameteriv(target, pname, params);
7009}
7010
7011void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7012 GLenum target, GLenum pname) {
7013 if (!workarounds().init_texture_max_anisotropy)
7014 return;
7015 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7016 !validators_->texture_parameter.IsValid(pname)) {
7017 return;
7018 }
7019
7020 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7021 &state_, target);
7022 if (!texture_ref) {
7023 LOCAL_SET_GL_ERROR(
7024 GL_INVALID_OPERATION,
7025 "glGetTexParamter{fi}v", "unknown texture for target");
7026 return;
7027 }
7028 Texture* texture = texture_ref->texture();
7029 texture->InitTextureMaxAnisotropyIfNeeded(target);
7030}
7031
[email protected]ac77603c72013-03-08 13:52:067032void GLES2DecoderImpl::DoGetVertexAttribfv(
7033 GLuint index, GLenum pname, GLfloat* params) {
7034 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7035 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517036 LOCAL_SET_GL_ERROR(
7037 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067038 return;
7039 }
7040 switch (pname) {
7041 case GL_CURRENT_VERTEX_ATTRIB: {
7042 const Vec4& value = state_.attrib_values[index];
7043 params[0] = value.v[0];
7044 params[1] = value.v[1];
7045 params[2] = value.v[2];
7046 params[3] = value.v[3];
7047 break;
7048 }
7049 default: {
7050 GLint value = 0;
7051 GetVertexAttribHelper(attrib, pname, &value);
7052 *params = static_cast<GLfloat>(value);
7053 break;
7054 }
7055 }
7056}
7057
7058void GLES2DecoderImpl::DoGetVertexAttribiv(
7059 GLuint index, GLenum pname, GLint* params) {
7060 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7061 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517062 LOCAL_SET_GL_ERROR(
7063 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067064 return;
7065 }
7066 switch (pname) {
[email protected]af6380962012-11-29 23:24:137067 case GL_CURRENT_VERTEX_ATTRIB: {
7068 const Vec4& value = state_.attrib_values[index];
7069 params[0] = static_cast<GLint>(value.v[0]);
7070 params[1] = static_cast<GLint>(value.v[1]);
7071 params[2] = static_cast<GLint>(value.v[2]);
7072 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247073 break;
[email protected]af6380962012-11-29 23:24:137074 }
[email protected]b1122982010-05-17 23:04:247075 default:
[email protected]ac77603c72013-03-08 13:52:067076 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247077 break;
7078 }
7079}
7080
[email protected]af6380962012-11-29 23:24:137081bool GLES2DecoderImpl::SetVertexAttribValue(
7082 const char* function_name, GLuint index, const GLfloat* value) {
7083 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517084 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137085 return false;
[email protected]b1122982010-05-17 23:04:247086 }
[email protected]af6380962012-11-29 23:24:137087 Vec4& v = state_.attrib_values[index];
7088 v.v[0] = value[0];
7089 v.v[1] = value[1];
7090 v.v[2] = value[2];
7091 v.v[3] = value[3];
7092 return true;
7093}
7094
7095void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7096 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7097 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7098 glVertexAttrib1f(index, v0);
7099 }
[email protected]b1122982010-05-17 23:04:247100}
7101
7102void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137103 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7104 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7105 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247106 }
[email protected]b1122982010-05-17 23:04:247107}
7108
7109void GLES2DecoderImpl::DoVertexAttrib3f(
7110 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137111 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7112 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7113 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247114 }
[email protected]b1122982010-05-17 23:04:247115}
7116
7117void GLES2DecoderImpl::DoVertexAttrib4f(
7118 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137119 GLfloat v[4] = { v0, v1, v2, v3, };
7120 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7121 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247122 }
[email protected]b1122982010-05-17 23:04:247123}
7124
7125void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137126 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7127 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7128 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247129 }
[email protected]b1122982010-05-17 23:04:247130}
7131
7132void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137133 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7134 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7135 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247136 }
[email protected]b1122982010-05-17 23:04:247137}
7138
7139void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137140 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7141 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7142 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247143 }
[email protected]b1122982010-05-17 23:04:247144}
7145
7146void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137147 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7148 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247149 }
[email protected]b1122982010-05-17 23:04:247150}
7151
[email protected]f7a64ee2010-02-01 22:24:147152error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:357153 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:467154
[email protected]7cd76fd2013-06-02 21:11:117155 if (!state_.bound_array_buffer.get() ||
7156 state_.bound_array_buffer->IsDeleted()) {
7157 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527158 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517159 LOCAL_SET_GL_ERROR(
7160 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467161 return error::kNoError;
7162 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517163 LOCAL_SET_GL_ERROR(
7164 GL_INVALID_VALUE,
7165 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467166 return error::kNoError;
7167 }
[email protected]96449d2c2009-11-25 00:01:327168 }
[email protected]8eee29c2010-04-29 03:38:297169
7170 GLuint indx = c.indx;
7171 GLint size = c.size;
7172 GLenum type = c.type;
7173 GLboolean normalized = c.normalized;
7174 GLsizei stride = c.stride;
7175 GLsizei offset = c.offset;
7176 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057177 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517178 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297179 return error::kNoError;
7180 }
[email protected]9438b012010-06-15 22:55:057181 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517182 LOCAL_SET_GL_ERROR(
7183 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297184 return error::kNoError;
7185 }
7186 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517187 LOCAL_SET_GL_ERROR(
7188 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297189 return error::kNoError;
7190 }
7191 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517192 LOCAL_SET_GL_ERROR(
7193 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297194 return error::kNoError;
7195 }
7196 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517197 LOCAL_SET_GL_ERROR(
7198 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297199 return error::kNoError;
7200 }
7201 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517202 LOCAL_SET_GL_ERROR(
7203 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297204 return error::kNoError;
7205 }
7206 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317207 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127208 // component_size must be a power of two to use & as optimized modulo.
7209 DCHECK(GLES2Util::IsPOT(component_size));
7210 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517211 LOCAL_SET_GL_ERROR(
7212 GL_INVALID_OPERATION,
7213 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317214 return error::kNoError;
7215 }
[email protected]a07a23602014-08-05 11:36:127216 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517217 LOCAL_SET_GL_ERROR(
7218 GL_INVALID_OPERATION,
7219 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297220 return error::kNoError;
7221 }
[email protected]7cd76fd2013-06-02 21:11:117222 state_.vertex_attrib_manager
7223 ->SetAttribInfo(indx,
7224 state_.bound_array_buffer.get(),
7225 size,
7226 type,
7227 normalized,
7228 stride,
7229 stride != 0 ? stride : component_size * size,
7230 offset);
[email protected]8fbedc02010-11-18 18:43:407231 if (type != GL_FIXED) {
7232 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7233 }
[email protected]f7a64ee2010-02-01 22:24:147234 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327235}
7236
[email protected]43410e92012-04-20 17:06:287237void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7238 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247239 state_.viewport_x = x;
7240 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027241 state_.viewport_width = std::min(width, viewport_max_width_);
7242 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287243 glViewport(x, y, width, height);
7244}
7245
[email protected]c6aef902012-02-14 03:31:427246error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:357247 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:157248 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517249 LOCAL_SET_GL_ERROR(
7250 GL_INVALID_OPERATION,
7251 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537252 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427253 }
7254 GLuint index = c.index;
7255 GLuint divisor = c.divisor;
7256 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517257 LOCAL_SET_GL_ERROR(
7258 GL_INVALID_VALUE,
7259 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427260 return error::kNoError;
7261 }
7262
[email protected]e259eb412012-10-13 05:47:247263 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427264 index,
7265 divisor);
7266 glVertexAttribDivisorANGLE(index, divisor);
7267 return error::kNoError;
7268}
7269
[email protected]68586372013-12-11 01:27:597270template <typename pixel_data_type>
7271static void WriteAlphaData(
7272 void *pixels, uint32 row_count, uint32 channel_count,
7273 uint32 alpha_channel_index, uint32 unpadded_row_size,
7274 uint32 padded_row_size, pixel_data_type alpha_value) {
7275 DCHECK_GT(channel_count, 0U);
7276 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7277 uint32 unpadded_row_size_in_elements =
7278 unpadded_row_size / sizeof(pixel_data_type);
7279 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7280 uint32 padded_row_size_in_elements =
7281 padded_row_size / sizeof(pixel_data_type);
7282 pixel_data_type* dst =
7283 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7284 for (uint32 yy = 0; yy < row_count; ++yy) {
7285 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7286 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7287 *d = alpha_value;
7288 }
7289 dst += padded_row_size_in_elements;
7290 }
7291}
7292
[email protected]5a36dc132013-07-23 23:17:557293void GLES2DecoderImpl::FinishReadPixels(
7294 const cmds::ReadPixels& c,
7295 GLuint buffer) {
7296 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7297 GLsizei width = c.width;
7298 GLsizei height = c.height;
7299 GLenum format = c.format;
7300 GLenum type = c.type;
7301 typedef cmds::ReadPixels::Result Result;
7302 uint32 pixels_size;
7303 Result* result = NULL;
7304 if (c.result_shm_id != 0) {
7305 result = GetSharedMemoryAs<Result*>(
7306 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7307 if (!result) {
7308 if (buffer != 0) {
7309 glDeleteBuffersARB(1, &buffer);
7310 }
7311 return;
7312 }
7313 }
7314 GLES2Util::ComputeImageDataSizes(
7315 width, height, format, type, state_.pack_alignment, &pixels_size,
7316 NULL, NULL);
7317 void* pixels = GetSharedMemoryAs<void*>(
7318 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7319 if (!pixels) {
7320 if (buffer != 0) {
7321 glDeleteBuffersARB(1, &buffer);
7322 }
7323 return;
7324 }
7325
7326 if (buffer != 0) {
7327 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337328 void* data;
7329 if (features().map_buffer_range) {
7330 data = glMapBufferRange(
7331 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7332 } else {
7333 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7334 }
[email protected]5a36dc132013-07-23 23:17:557335 memcpy(pixels, data, pixels_size);
7336 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7337 // have to restore the state.
7338 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7339 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7340 glDeleteBuffersARB(1, &buffer);
7341 }
7342
7343 if (result != NULL) {
7344 *result = true;
7345 }
7346
7347 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7348 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7349 if ((channels_exist & 0x0008) == 0 &&
7350 workarounds().clear_alpha_in_readpixels) {
7351 // Set the alpha to 255 because some drivers are buggy in this regard.
7352 uint32 temp_size;
7353
7354 uint32 unpadded_row_size;
7355 uint32 padded_row_size;
7356 if (!GLES2Util::ComputeImageDataSizes(
7357 width, 2, format, type, state_.pack_alignment, &temp_size,
7358 &unpadded_row_size, &padded_row_size)) {
7359 return;
7360 }
[email protected]68586372013-12-11 01:27:597361
7362 uint32 channel_count = 0;
7363 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557364 switch (format) {
7365 case GL_RGBA:
7366 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597367 channel_count = 4;
7368 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557369 break;
[email protected]68586372013-12-11 01:27:597370 case GL_ALPHA:
7371 channel_count = 1;
7372 alpha_channel = 0;
7373 break;
7374 }
7375
7376 if (channel_count > 0) {
7377 switch (type) {
7378 case GL_UNSIGNED_BYTE:
7379 WriteAlphaData<uint8>(
7380 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7381 padded_row_size, 0xFF);
7382 break;
7383 case GL_FLOAT:
7384 WriteAlphaData<float>(
7385 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7386 padded_row_size, 1.0f);
7387 break;
7388 case GL_HALF_FLOAT:
7389 WriteAlphaData<uint16>(
7390 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7391 padded_row_size, 0x3C00);
7392 break;
[email protected]5a36dc132013-07-23 23:17:557393 }
[email protected]5a36dc132013-07-23 23:17:557394 }
7395 }
7396}
7397
7398
[email protected]f7a64ee2010-02-01 22:24:147399error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:357400 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]c959a09a2014-03-27 11:44:217401 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227402 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7403 if (fbo_error != error::kNoError)
7404 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317405 GLint x = c.x;
7406 GLint y = c.y;
7407 GLsizei width = c.width;
7408 GLsizei height = c.height;
7409 GLenum format = c.format;
7410 GLenum type = c.type;
[email protected]5a36dc132013-07-23 23:17:557411 GLboolean async = c.async;
[email protected]57f223832010-03-19 01:57:567412 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517413 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567414 return error::kNoError;
7415 }
[email protected]ed9f9cd2013-02-27 21:12:357416 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187417 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347418 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247419 width, height, format, type, state_.pack_alignment, &pixels_size,
7420 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187421 return error::kOutOfBounds;
7422 }
[email protected]612d2f82009-12-08 20:49:317423 void* pixels = GetSharedMemoryAs<void*>(
7424 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107425 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147426 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467427 }
[email protected]de43f082013-04-02 01:16:107428 Result* result = NULL;
7429 if (c.result_shm_id != 0) {
7430 result = GetSharedMemoryAs<Result*>(
7431 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7432 if (!result) {
7433 return error::kOutOfBounds;
7434 }
7435 }
[email protected]a51788e2010-02-24 21:54:257436
[email protected]9438b012010-06-15 22:55:057437 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517438 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297439 return error::kNoError;
7440 }
[email protected]68586372013-12-11 01:27:597441 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517442 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127443 return error::kNoError;
7444 }
[email protected]68586372013-12-11 01:27:597445 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7446 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7447 // format and type are acceptable enums but not guaranteed to be supported
7448 // for this framebuffer. Have to ask gl if they are valid.
7449 GLint preferred_format = 0;
7450 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7451 GLint preferred_type = 0;
7452 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7453 if (format != static_cast<GLenum>(preferred_format) ||
7454 type != static_cast<GLenum>(preferred_type)) {
7455 LOCAL_SET_GL_ERROR(
7456 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7457 "with the current read framebuffer");
7458 return error::kNoError;
7459 }
7460 }
[email protected]57f223832010-03-19 01:57:567461 if (width == 0 || height == 0) {
7462 return error::kNoError;
7463 }
7464
[email protected]57f223832010-03-19 01:57:567465 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307466 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567467
[email protected]3aad1a32012-09-07 20:54:477468 int32 max_x;
7469 int32 max_y;
7470 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517471 LOCAL_SET_GL_ERROR(
7472 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147473 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317474 }
[email protected]57f223832010-03-19 01:57:567475
[email protected]2ea5950d2014-07-09 18:20:347476 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7477 return error::kNoError;
7478 }
7479
[email protected]0d6bfdc2011-11-02 01:32:207480 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7481 return error::kNoError;
7482 }
7483
[email protected]caa13ed2014-02-17 11:29:207484 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107485
7486 ScopedResolvedFrameBufferBinder binder(this, false, true);
7487
[email protected]d37231fa2010-04-09 21:16:027488 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567489 // The user requested an out of range area. Get the results 1 line
7490 // at a time.
7491 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347492 uint32 unpadded_row_size;
7493 uint32 padded_row_size;
7494 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247495 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347496 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517497 LOCAL_SET_GL_ERROR(
7498 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567499 return error::kNoError;
7500 }
7501
7502 GLint dest_x_offset = std::max(-x, 0);
7503 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347504 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247505 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7506 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517507 LOCAL_SET_GL_ERROR(
7508 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567509 return error::kNoError;
7510 }
7511
7512 // Copy each row into the larger dest rect.
7513 int8* dst = static_cast<int8*>(pixels);
7514 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027515 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567516 GLint read_width = read_end_x - read_x;
7517 for (GLint yy = 0; yy < height; ++yy) {
7518 GLint ry = y + yy;
7519
7520 // Clear the row.
7521 memset(dst, 0, unpadded_row_size);
7522
7523 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027524 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567525 glReadPixels(
7526 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7527 }
7528 dst += padded_row_size;
7529 }
7530 } else {
[email protected]5a36dc132013-07-23 23:17:557531 if (async && features().use_async_readpixels) {
7532 GLuint buffer;
7533 glGenBuffersARB(1, &buffer);
7534 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7535 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7536 GLenum error = glGetError();
7537 if (error == GL_NO_ERROR) {
7538 glReadPixels(x, y, width, height, format, type, 0);
7539 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7540 new FenceCallback()));
7541 WaitForReadPixels(base::Bind(
7542 &GLES2DecoderImpl::FinishReadPixels,
7543 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7544 <GLES2DecoderImpl>(this),
7545 c, buffer));
7546 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7547 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597548 } else {
7549 // On error, unbind pack buffer and fall through to sync readpixels
7550 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
[email protected]5a36dc132013-07-23 23:17:557551 }
7552 }
[email protected]57f223832010-03-19 01:57:567553 glReadPixels(x, y, width, height, format, type, pixels);
7554 }
[email protected]ab09b612013-03-11 22:11:517555 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257556 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107557 if (result != NULL) {
7558 *result = true;
7559 }
[email protected]5a36dc132013-07-23 23:17:557560 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257561 }
[email protected]4848b9f82011-03-10 18:37:567562
[email protected]f7a64ee2010-02-01 22:24:147563 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327564}
7565
[email protected]f7a64ee2010-02-01 22:24:147566error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:357567 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:197568 GLenum pname = c.pname;
7569 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057570 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517571 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127572 return error::kNoError;
7573 }
[email protected]222471d2011-11-30 18:06:397574 switch (pname) {
7575 case GL_PACK_ALIGNMENT:
7576 case GL_UNPACK_ALIGNMENT:
7577 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517578 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207579 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397580 return error::kNoError;
7581 }
[email protected]164d6d52012-05-05 00:55:037582 break;
[email protected]0a1e9ad2012-05-04 21:13:037583 case GL_UNPACK_FLIP_Y_CHROMIUM:
7584 unpack_flip_y_ = (param != 0);
7585 return error::kNoError;
7586 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7587 unpack_premultiply_alpha_ = (param != 0);
7588 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177589 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7590 unpack_unpremultiply_alpha_ = (param != 0);
7591 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397592 default:
7593 break;
[email protected]b9849abf2009-11-25 19:13:197594 }
7595 glPixelStorei(pname, param);
7596 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437597 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247598 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437599 break;
7600 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427601 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437602 break;
7603 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247604 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437605 break;
7606 default:
7607 // Validation should have prevented us from getting here.
7608 NOTREACHED();
7609 break;
[email protected]b9849abf2009-11-25 19:13:197610 }
[email protected]f7a64ee2010-02-01 22:24:147611 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197612}
7613
[email protected]1c75a3702011-11-11 14:15:287614error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:357615 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:387616 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:277617 {
7618 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
7619 }
[email protected]b381ee32014-03-22 02:43:437620 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:517621 LOCAL_SET_GL_ERROR(
7622 GL_INVALID_OPERATION,
7623 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287624 return error::kNoError;
7625 }
[email protected]8f9b8dd2013-09-12 18:05:137626 bool is_tracing;
7627 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7628 &is_tracing);
7629 if (is_tracing) {
7630 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7631 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7632 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7633 is_offscreen ? offscreen_size_ : surface_->GetSize());
7634 }
[email protected]7794d512012-04-17 20:36:497635 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287636 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497637 } else {
7638 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287639 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497640 }
[email protected]1c75a3702011-11-11 14:15:287641}
7642
[email protected]957f0642014-04-09 16:50:017643error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
7644 uint32 immediate_data_size,
7645 const cmds::ScheduleOverlayPlaneCHROMIUM& c) {
[email protected]d286ebbc2014-07-03 17:19:107646 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
7647 if (!ref) {
7648 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7649 "glScheduleOverlayPlaneCHROMIUM",
7650 "unknown texture");
7651 return error::kNoError;
7652 }
7653 gfx::GLImage* image =
7654 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
7655 if (!image) {
7656 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7657 "glScheduleOverlayPlaneCHROMIUM",
7658 "unsupported texture format");
7659 return error::kNoError;
7660 }
7661 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
7662 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
7663 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
7664 "glScheduleOverlayPlaneCHROMIUM",
7665 "invalid transform enum");
7666 return error::kNoError;
7667 }
7668 if (!surface_->ScheduleOverlayPlane(
7669 c.plane_z_order,
7670 transform,
7671 image,
7672 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
7673 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
7674 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
7675 "glScheduleOverlayPlaneCHROMIUM",
7676 "failed to schedule overlay");
7677 }
[email protected]957f0642014-04-09 16:50:017678 return error::kNoError;
7679}
7680
[email protected]558847a2010-03-24 07:02:547681error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7682 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7683 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577684 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517685 LOCAL_SET_GL_ERROR(
7686 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577687 return error::kNoError;
7688 }
[email protected]df37b9932013-03-08 05:21:427689 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587690 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427691 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147692 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197693 }
[email protected]df37b9932013-03-08 05:21:427694 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517695 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437696 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257697 return error::kNoError;
7698 }
[email protected]b9849abf2009-11-25 19:13:197699 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547700 location_shm_id, location_shm_offset, sizeof(GLint));
7701 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147702 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197703 }
[email protected]558847a2010-03-24 07:02:547704 // Require the client to init this incase the context is lost and we are no
7705 // longer executing commands.
7706 if (*location != -1) {
7707 return error::kGenericError;
7708 }
[email protected]df37b9932013-03-08 05:21:427709 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147710 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197711}
7712
[email protected]558847a2010-03-24 07:02:547713error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357714 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547715 Bucket* bucket = GetBucket(c.name_bucket_id);
7716 if (!bucket) {
7717 return error::kInvalidArguments;
7718 }
7719 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187720 if (!bucket->GetAsString(&name_str)) {
7721 return error::kInvalidArguments;
7722 }
[email protected]558847a2010-03-24 07:02:547723 return GetAttribLocationHelper(
7724 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7725}
7726
7727error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7728 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7729 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577730 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517731 LOCAL_SET_GL_ERROR(
7732 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577733 return error::kNoError;
7734 }
[email protected]df37b9932013-03-08 05:21:427735 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:207736 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:427737 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147738 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197739 }
[email protected]df37b9932013-03-08 05:21:427740 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517741 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437742 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257743 return error::kNoError;
7744 }
[email protected]b9849abf2009-11-25 19:13:197745 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547746 location_shm_id, location_shm_offset, sizeof(GLint));
7747 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147748 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197749 }
[email protected]558847a2010-03-24 07:02:547750 // Require the client to init this incase the context is lost an we are no
7751 // longer executing commands.
7752 if (*location != -1) {
7753 return error::kGenericError;
7754 }
[email protected]df37b9932013-03-08 05:21:427755 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147756 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197757}
7758
[email protected]f7a64ee2010-02-01 22:24:147759error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357760 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]558847a2010-03-24 07:02:547761 Bucket* bucket = GetBucket(c.name_bucket_id);
7762 if (!bucket) {
7763 return error::kInvalidArguments;
7764 }
7765 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187766 if (!bucket->GetAsString(&name_str)) {
7767 return error::kInvalidArguments;
7768 }
[email protected]558847a2010-03-24 07:02:547769 return GetUniformLocationHelper(
7770 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197771}
7772
[email protected]ddd968b82010-03-02 00:44:297773error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357774 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297775 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057776 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517777 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297778 return error::kNoError;
7779 }
[email protected]959e9072013-09-20 16:58:387780 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:047781 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157782 switch (name) {
7783 case GL_VERSION:
7784 str = "OpenGL ES 2.0 Chromium";
7785 break;
7786 case GL_SHADING_LANGUAGE_VERSION:
7787 str = "OpenGL ES GLSL ES 1.0 Chromium";
7788 break;
[email protected]32939602012-05-09 06:25:167789 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:167790 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:387791 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7792 // They are used by WEBGL_debug_renderer_info.
7793 if (!force_webgl_glsl_validation_)
7794 str = "Chromium";
[email protected]32939602012-05-09 06:25:167795 break;
[email protected]1958e0e2010-04-22 05:17:157796 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047797 {
[email protected]70dc60932013-06-04 03:33:497798 // For WebGL contexts, strip out the OES derivatives and
7799 // EXT frag depth extensions if they have not been enabled.
7800 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047801 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497802 if (!derivatives_explicitly_enabled_) {
7803 size_t offset = extensions.find(kOESDerivativeExtension);
7804 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097805 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497806 std::string());
7807 }
7808 }
7809 if (!frag_depth_explicitly_enabled_) {
7810 size_t offset = extensions.find(kEXTFragDepthExtension);
7811 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097812 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497813 std::string());
7814 }
[email protected]f0d74742011-10-03 16:31:047815 }
[email protected]aff39ac82013-06-08 04:53:137816 if (!draw_buffers_explicitly_enabled_) {
7817 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7818 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097819 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137820 std::string());
7821 }
7822 }
[email protected]93c2fd82014-04-16 02:46:067823 if (!shader_texture_lod_explicitly_enabled_) {
7824 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
7825 if (std::string::npos != offset) {
7826 extensions.replace(offset,
7827 arraysize(kEXTShaderTextureLodExtension),
7828 std::string());
7829 }
7830 }
[email protected]f0d74742011-10-03 16:31:047831 } else {
[email protected]6f5fac9d12012-06-26 21:02:457832 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047833 }
[email protected]b381ee32014-03-22 02:43:437834 if (supports_post_sub_buffer_)
7835 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:457836 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047837 }
[email protected]1958e0e2010-04-22 05:17:157838 break;
7839 default:
[email protected]1958e0e2010-04-22 05:17:157840 break;
7841 }
[email protected]ddd968b82010-03-02 00:44:297842 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157843 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297844 return error::kNoError;
7845}
7846
[email protected]0c86dbf2010-03-05 08:14:117847error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357848 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117849 GLenum target = static_cast<GLenum>(c.target);
7850 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7851 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7852 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7853 GLenum usage = static_cast<GLenum>(c.usage);
7854 const void* data = NULL;
7855 if (data_shm_id != 0 || data_shm_offset != 0) {
7856 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7857 if (!data) {
7858 return error::kOutOfBounds;
7859 }
7860 }
[email protected]0fbba3732013-07-17 15:40:137861 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147862 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197863}
7864
[email protected]0c86dbf2010-03-05 08:14:117865void GLES2DecoderImpl::DoBufferSubData(
7866 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137867 // Just delegate it. Some validation is actually done before this.
7868 buffer_manager()->ValidateAndDoBufferSubData(
7869 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197870}
7871
[email protected]0d6bfdc2011-11-02 01:32:207872bool GLES2DecoderImpl::ClearLevel(
7873 unsigned service_id,
7874 unsigned bind_target,
7875 unsigned target,
7876 int level,
[email protected]d8e6c9242014-02-20 16:56:257877 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:207878 unsigned format,
7879 unsigned type,
7880 int width,
[email protected]4502e6492011-12-14 19:39:157881 int height,
7882 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007883 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:007884 if (feature_info_->feature_flags().angle_depth_texture &&
7885 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:007886 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7887 // on depth formats.
7888 GLuint fb = 0;
7889 glGenFramebuffersEXT(1, &fb);
7890 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7891
7892 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7893 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7894 GL_DEPTH_ATTACHMENT;
7895
7896 glFramebufferTexture2DEXT(
7897 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7898 // ANGLE promises a depth only attachment ok.
7899 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7900 GL_FRAMEBUFFER_COMPLETE) {
7901 return false;
7902 }
7903 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:477904 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
7905 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:007906 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:457907 state_.SetDeviceDepthMask(GL_TRUE);
7908 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:007909 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7910
7911 RestoreClearState();
7912
7913 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357914 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007915 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7916 GLuint fb_service_id =
7917 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7918 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7919 return true;
7920 }
7921
[email protected]45d15a62012-04-18 14:33:177922 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7923
7924 uint32 size;
7925 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347926 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247927 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177928 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207929 return false;
7930 }
[email protected]45d15a62012-04-18 14:33:177931
[email protected]a5d3dad2012-05-26 04:34:447932 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7933
[email protected]45d15a62012-04-18 14:33:177934 int tile_height;
7935
7936 if (size > kMaxZeroSize) {
7937 if (kMaxZeroSize < padded_row_size) {
7938 // That'd be an awfully large texture.
7939 return false;
7940 }
7941 // We should never have a large total size with a zero row size.
7942 DCHECK_GT(padded_row_size, 0U);
7943 tile_height = kMaxZeroSize / padded_row_size;
7944 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247945 width, tile_height, format, type, state_.unpack_alignment, &size,
7946 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177947 return false;
7948 }
[email protected]4502e6492011-12-14 19:39:157949 } else {
[email protected]45d15a62012-04-18 14:33:177950 tile_height = height;
7951 }
7952
7953 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557954 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177955 memset(zero.get(), 0, size);
7956 glBindTexture(bind_target, service_id);
7957
7958 GLint y = 0;
7959 while (y < height) {
7960 GLint h = y + tile_height > height ? height - y : tile_height;
7961 if (is_texture_immutable || h != height) {
7962 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7963 } else {
[email protected]8f1d2aa2013-05-10 23:45:387964 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:257965 target, level, internal_format, width, h, 0, format, type,
7966 zero.get());
[email protected]45d15a62012-04-18 14:33:177967 }
7968 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157969 }
[email protected]c986af502013-08-14 01:04:447970 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
7971 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:077972 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207973 return true;
7974}
7975
[email protected]ad84a3a2012-06-08 21:42:437976namespace {
7977
7978const int kS3TCBlockWidth = 4;
7979const int kS3TCBlockHeight = 4;
7980const int kS3TCDXT1BlockSize = 8;
7981const int kS3TCDXT3AndDXT5BlockSize = 16;
7982
7983bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517984 return (size == 1) ||
7985 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437986}
7987
[email protected]8aec81ec2014-04-29 01:04:517988bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:127989 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:517990}
7991
[email protected]ad84a3a2012-06-08 21:42:437992} // anonymous namespace.
7993
7994bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7995 const char* function_name,
7996 GLsizei width, GLsizei height, GLenum format, size_t size) {
7997 unsigned int bytes_required = 0;
7998
7999 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518000 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438001 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518002 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8003 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438004 int num_blocks_across =
8005 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8006 int num_blocks_down =
8007 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8008 int num_blocks = num_blocks_across * num_blocks_down;
8009 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8010 break;
8011 }
[email protected]8aec81ec2014-04-29 01:04:518012 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8013 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438014 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8015 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8016 int num_blocks_across =
8017 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8018 int num_blocks_down =
8019 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8020 int num_blocks = num_blocks_across * num_blocks_down;
8021 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8022 break;
8023 }
[email protected]8aec81ec2014-04-29 01:04:518024 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8025 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8026 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8027 break;
8028 }
8029 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8030 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8031 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078032 break;
8033 }
[email protected]ad84a3a2012-06-08 21:42:438034 default:
[email protected]ab09b612013-03-11 22:11:518035 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438036 return false;
8037 }
8038
8039 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518040 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438041 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8042 return false;
8043 }
8044
8045 return true;
8046}
8047
8048bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8049 const char* function_name,
8050 GLint level, GLsizei width, GLsizei height, GLenum format) {
8051 switch (format) {
8052 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8053 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8054 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8055 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8056 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518057 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438058 GL_INVALID_OPERATION, function_name,
8059 "width or height invalid for level");
8060 return false;
8061 }
8062 return true;
8063 }
[email protected]8aec81ec2014-04-29 01:04:518064 case GL_ATC_RGB_AMD:
8065 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8066 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8067 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078068 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518069 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078070 GL_INVALID_OPERATION, function_name,
8071 "width or height invalid for level");
8072 return false;
8073 }
8074 return true;
[email protected]8aec81ec2014-04-29 01:04:518075 }
8076 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8077 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8078 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8079 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8080 if (!IsValidPVRTCSize(level, width) ||
8081 !IsValidPVRTCSize(level, height)) {
8082 LOCAL_SET_GL_ERROR(
8083 GL_INVALID_OPERATION, function_name,
8084 "width or height invalid for level");
8085 return false;
8086 }
8087 return true;
8088 }
[email protected]ad84a3a2012-06-08 21:42:438089 default:
8090 return false;
8091 }
8092}
8093
8094bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8095 const char* function_name,
8096 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8097 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358098 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438099 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518100 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438101 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8102 return false;
8103 }
8104
8105 switch (format) {
8106 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8107 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8108 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8109 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8110 const int kBlockWidth = 4;
8111 const int kBlockHeight = 4;
8112 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518113 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438114 GL_INVALID_OPERATION, function_name,
8115 "xoffset or yoffset not multiple of 4");
8116 return false;
8117 }
8118 GLsizei tex_width = 0;
8119 GLsizei tex_height = 0;
8120 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8121 width - xoffset > tex_width ||
8122 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518123 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438124 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8125 return false;
8126 }
8127 return ValidateCompressedTexDimensions(
8128 function_name, level, width, height, format);
8129 }
[email protected]8aec81ec2014-04-29 01:04:518130 case GL_ATC_RGB_AMD:
8131 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8132 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8133 LOCAL_SET_GL_ERROR(
8134 GL_INVALID_OPERATION, function_name,
8135 "not supported for ATC textures");
8136 return false;
8137 }
[email protected]2d3765b2012-10-03 00:31:078138 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518139 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078140 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208141 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078142 return false;
8143 }
[email protected]8aec81ec2014-04-29 01:04:518144 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8145 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8146 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8147 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8148 if ((xoffset != 0) || (yoffset != 0)) {
8149 LOCAL_SET_GL_ERROR(
8150 GL_INVALID_OPERATION, function_name,
8151 "xoffset and yoffset must be zero");
8152 return false;
8153 }
8154 GLsizei tex_width = 0;
8155 GLsizei tex_height = 0;
8156 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8157 width != tex_width ||
8158 height != tex_height) {
8159 LOCAL_SET_GL_ERROR(
8160 GL_INVALID_OPERATION, function_name,
8161 "dimensions must match existing texture level dimensions");
8162 return false;
8163 }
8164 return ValidateCompressedTexDimensions(
8165 function_name, level, width, height, format);
8166 }
[email protected]ad84a3a2012-06-08 21:42:438167 default:
8168 return false;
8169 }
8170}
8171
[email protected]a93bb842010-02-16 23:03:478172error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8173 GLenum target,
8174 GLint level,
8175 GLenum internal_format,
8176 GLsizei width,
8177 GLsizei height,
8178 GLint border,
8179 GLsizei image_size,
8180 const void* data) {
[email protected]a93bb842010-02-16 23:03:478181 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058182 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518183 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8184 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298185 return error::kNoError;
8186 }
[email protected]9438b012010-06-15 22:55:058187 if (!validators_->compressed_texture_format.IsValid(
8188 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518189 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538190 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478191 return error::kNoError;
8192 }
[email protected]80eb6b52012-01-19 00:14:418193 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478194 border != 0) {
[email protected]ab09b612013-03-11 22:11:518195 LOCAL_SET_GL_ERROR(
8196 GL_INVALID_VALUE,
8197 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478198 return error::kNoError;
8199 }
[email protected]c986af502013-08-14 01:04:448200 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8201 &state_, target);
[email protected]370eaf12013-05-18 09:19:498202 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518203 LOCAL_SET_GL_ERROR(
8204 GL_INVALID_VALUE,
8205 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478206 return error::kNoError;
8207 }
[email protected]370eaf12013-05-18 09:19:498208 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078209 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518210 LOCAL_SET_GL_ERROR(
8211 GL_INVALID_OPERATION,
8212 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438213 return error::kNoError;
8214 }
8215
8216 if (!ValidateCompressedTexDimensions(
8217 "glCompressedTexImage2D", level, width, height, internal_format) ||
8218 !ValidateCompressedTexFuncData(
8219 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178220 return error::kNoError;
8221 }
[email protected]968351b2011-12-20 08:26:518222
[email protected]7989c9e2013-01-23 06:39:268223 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518224 LOCAL_SET_GL_ERROR(
8225 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268226 return error::kNoError;
8227 }
8228
[email protected]02965c22013-03-09 02:40:078229 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448230 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518231 }
8232
[email protected]40d90a22013-04-09 03:39:558233 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478234 if (!data) {
8235 zero.reset(new int8[image_size]);
8236 memset(zero.get(), 0, image_size);
8237 data = zero.get();
8238 }
[email protected]ab09b612013-03-11 22:11:518239 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478240 glCompressedTexImage2D(
8241 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518242 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438243 if (error == GL_NO_ERROR) {
8244 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498245 texture_ref, target, level, internal_format,
8246 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438247 }
[email protected]a93bb842010-02-16 23:03:478248 return error::kNoError;
8249}
8250
[email protected]f7a64ee2010-02-01 22:24:148251error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358252 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:198253 GLenum target = static_cast<GLenum>(c.target);
8254 GLint level = static_cast<GLint>(c.level);
8255 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8256 GLsizei width = static_cast<GLsizei>(c.width);
8257 GLsizei height = static_cast<GLsizei>(c.height);
8258 GLint border = static_cast<GLint>(c.border);
8259 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8260 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8261 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8262 const void* data = NULL;
8263 if (data_shm_id != 0 || data_shm_offset != 0) {
8264 data = GetSharedMemoryAs<const void*>(
8265 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468266 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148267 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198268 }
8269 }
[email protected]a93bb842010-02-16 23:03:478270 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198271 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198272}
8273
[email protected]b6140d02010-05-17 14:47:168274error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:358275 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:168276 GLenum target = static_cast<GLenum>(c.target);
8277 GLint level = static_cast<GLint>(c.level);
8278 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8279 GLsizei width = static_cast<GLsizei>(c.width);
8280 GLsizei height = static_cast<GLsizei>(c.height);
8281 GLint border = static_cast<GLint>(c.border);
8282 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288283 if (!bucket) {
8284 return error::kInvalidArguments;
8285 }
8286 uint32 data_size = bucket->size();
8287 GLsizei imageSize = data_size;
8288 const void* data = bucket->GetData(0, data_size);
8289 if (!data) {
8290 return error::kInvalidArguments;
8291 }
[email protected]b6140d02010-05-17 14:47:168292 return DoCompressedTexImage2D(
8293 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288294 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168295}
8296
8297error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8298 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358299 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:168300 GLenum target = static_cast<GLenum>(c.target);
8301 GLint level = static_cast<GLint>(c.level);
8302 GLint xoffset = static_cast<GLint>(c.xoffset);
8303 GLint yoffset = static_cast<GLint>(c.yoffset);
8304 GLsizei width = static_cast<GLsizei>(c.width);
8305 GLsizei height = static_cast<GLsizei>(c.height);
8306 GLenum format = static_cast<GLenum>(c.format);
8307 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288308 if (!bucket) {
8309 return error::kInvalidArguments;
8310 }
[email protected]b6140d02010-05-17 14:47:168311 uint32 data_size = bucket->size();
8312 GLsizei imageSize = data_size;
8313 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288314 if (!data) {
8315 return error::kInvalidArguments;
8316 }
[email protected]9438b012010-06-15 22:55:058317 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518318 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538319 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168320 return error::kNoError;
8321 }
[email protected]9438b012010-06-15 22:55:058322 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518323 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8324 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058325 return error::kNoError;
8326 }
[email protected]b6140d02010-05-17 14:47:168327 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518328 LOCAL_SET_GL_ERROR(
8329 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168330 return error::kNoError;
8331 }
8332 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518333 LOCAL_SET_GL_ERROR(
8334 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168335 return error::kNoError;
8336 }
8337 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518338 LOCAL_SET_GL_ERROR(
8339 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168340 return error::kNoError;
8341 }
[email protected]cadde4a2010-07-31 17:10:438342 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168343 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8344 return error::kNoError;
8345}
8346
[email protected]f7a64ee2010-02-01 22:24:148347error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358348 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]67f929422014-05-17 15:33:138349 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8350 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448351 // Set as failed for now, but if it successed, this will be set to not failed.
8352 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198353 GLenum target = static_cast<GLenum>(c.target);
8354 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448355 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8356 // for internalformat.
8357 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198358 GLsizei width = static_cast<GLsizei>(c.width);
8359 GLsizei height = static_cast<GLsizei>(c.height);
8360 GLint border = static_cast<GLint>(c.border);
8361 GLenum format = static_cast<GLenum>(c.format);
8362 GLenum type = static_cast<GLenum>(c.type);
8363 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8364 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188365 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348366 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248367 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348368 NULL)) {
[email protected]a76b0052010-03-05 00:33:188369 return error::kOutOfBounds;
8370 }
[email protected]b9849abf2009-11-25 19:13:198371 const void* pixels = NULL;
8372 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8373 pixels = GetSharedMemoryAs<const void*>(
8374 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468375 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148376 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198377 }
8378 }
[email protected]f598f422012-12-07 08:30:038379
[email protected]c986af502013-08-14 01:04:448380 TextureManager::DoTextImage2DArguments args = {
8381 target, level, internal_format, width, height, border, format, type,
8382 pixels, pixels_size};
8383 texture_manager()->ValidateAndDoTexImage2D(
8384 &texture_state_, &state_, &framebuffer_state_, args);
[email protected]f598f422012-12-07 08:30:038385 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198386}
8387
[email protected]cadde4a2010-07-31 17:10:438388void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8389 GLenum target,
8390 GLint level,
8391 GLint xoffset,
8392 GLint yoffset,
8393 GLsizei width,
8394 GLsizei height,
8395 GLenum format,
8396 GLsizei image_size,
8397 const void * data) {
[email protected]c986af502013-08-14 01:04:448398 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8399 &state_, target);
[email protected]370eaf12013-05-18 09:19:498400 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518401 LOCAL_SET_GL_ERROR(
8402 GL_INVALID_OPERATION,
8403 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438404 return;
8405 }
[email protected]370eaf12013-05-18 09:19:498406 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438407 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528408 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078409 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518410 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528411 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438412 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528413 return;
8414 }
8415 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518416 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528417 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438418 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528419 return;
8420 }
[email protected]02965c22013-03-09 02:40:078421 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528422 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518423 LOCAL_SET_GL_ERROR(
8424 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438425 return;
8426 }
[email protected]ad84a3a2012-06-08 21:42:438427
8428 if (!ValidateCompressedTexFuncData(
8429 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8430 !ValidateCompressedTexSubDimensions(
8431 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078432 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438433 return;
8434 }
8435
8436
[email protected]0d6bfdc2011-11-02 01:32:208437 // Note: There is no need to deal with texture cleared tracking here
8438 // because the validation above means you can only get here if the level
8439 // is already a matching compressed format and in that case
8440 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438441 glCompressedTexSubImage2D(
8442 target, level, xoffset, yoffset, width, height, format, image_size, data);
8443}
8444
[email protected]6e288612010-12-21 20:45:038445static void Clip(
8446 GLint start, GLint range, GLint sourceRange,
8447 GLint* out_start, GLint* out_range) {
8448 DCHECK(out_start);
8449 DCHECK(out_range);
8450 if (start < 0) {
8451 range += start;
8452 start = 0;
8453 }
8454 GLint end = start + range;
8455 if (end > sourceRange) {
8456 range -= end - sourceRange;
8457 }
8458 *out_start = start;
8459 *out_range = range;
8460}
8461
[email protected]cadde4a2010-07-31 17:10:438462void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448463 GLenum target,
8464 GLint level,
8465 GLenum internal_format,
8466 GLint x,
8467 GLint y,
8468 GLsizei width,
8469 GLsizei height,
8470 GLint border) {
[email protected]09e17272012-11-30 10:30:448471 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448472 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8473 &state_, target);
[email protected]370eaf12013-05-18 09:19:498474 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518475 LOCAL_SET_GL_ERROR(
8476 GL_INVALID_OPERATION,
8477 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438478 return;
8479 }
[email protected]370eaf12013-05-18 09:19:498480 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078481 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518482 LOCAL_SET_GL_ERROR(
8483 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:538484 return;
[email protected]97dc7cbe2011-12-06 17:26:178485 }
[email protected]80eb6b52012-01-19 00:14:418486 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188487 border != 0) {
[email protected]ab09b612013-03-11 22:11:518488 LOCAL_SET_GL_ERROR(
8489 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188490 return;
8491 }
[email protected]17a961192014-02-14 15:20:528492 if (!texture_manager()->ValidateFormatAndTypeCombination(
8493 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8494 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:008495 return;
8496 }
[email protected]f5719fb2010-08-04 18:27:188497
[email protected]9edc6b22010-12-23 02:00:268498 // Check we have compatible formats.
8499 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8500 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8501 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8502
8503 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518504 LOCAL_SET_GL_ERROR(
8505 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268506 return;
8507 }
8508
[email protected]81375742012-06-08 00:04:008509 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518510 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008511 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268512 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8513 return;
8514 }
8515
8516 uint32 estimated_size = 0;
8517 if (!GLES2Util::ComputeImageDataSizes(
8518 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8519 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518520 LOCAL_SET_GL_ERROR(
8521 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268522 return;
8523 }
8524
8525 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518526 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008527 return;
8528 }
8529
[email protected]2ea5950d2014-07-09 18:20:348530 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
8531 return;
8532 }
8533
[email protected]a0b78dc2011-11-11 10:43:108534 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8535 return;
8536 }
8537
[email protected]ab09b612013-03-11 22:11:518538 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278539 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038540 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268541
[email protected]02965c22013-03-09 02:40:078542 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448543 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468544 }
8545
[email protected]9edc6b22010-12-23 02:00:268546 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038547 GLint copyX = 0;
8548 GLint copyY = 0;
8549 GLint copyWidth = 0;
8550 GLint copyHeight = 0;
8551 Clip(x, width, size.width(), &copyX, &copyWidth);
8552 Clip(y, height, size.height(), &copyY, &copyHeight);
8553
8554 if (copyX != x ||
8555 copyY != y ||
8556 copyWidth != width ||
8557 copyHeight != height) {
8558 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208559 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078560 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:258561 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
8562 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518563 LOCAL_SET_GL_ERROR(
8564 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038565 return;
8566 }
[email protected]6e288612010-12-21 20:45:038567 if (copyHeight > 0 && copyWidth > 0) {
8568 GLint dx = copyX - x;
8569 GLint dy = copyY - y;
8570 GLint destX = dx;
8571 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:378572 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038573 glCopyTexSubImage2D(target, level,
8574 destX, destY, copyX, copyY,
8575 copyWidth, copyHeight);
8576 }
8577 } else {
[email protected]00c2cf92014-03-14 00:08:378578 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038579 glCopyTexImage2D(target, level, internal_format,
8580 copyX, copyY, copyWidth, copyHeight, border);
8581 }
[email protected]ab09b612013-03-11 22:11:518582 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438583 if (error == GL_NO_ERROR) {
8584 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498585 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208586 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438587 }
8588}
8589
8590void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448591 GLenum target,
8592 GLint level,
8593 GLint xoffset,
8594 GLint yoffset,
8595 GLint x,
8596 GLint y,
8597 GLsizei width,
8598 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448599 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448600 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8601 &state_, target);
[email protected]370eaf12013-05-18 09:19:498602 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518603 LOCAL_SET_GL_ERROR(
8604 GL_INVALID_OPERATION,
8605 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438606 return;
8607 }
[email protected]370eaf12013-05-18 09:19:498608 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438609 GLenum type = 0;
8610 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078611 if (!texture->GetLevelType(target, level, &type, &format) ||
8612 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528613 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518614 LOCAL_SET_GL_ERROR(
8615 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438616 return;
8617 }
[email protected]85a4ac22013-05-31 01:58:478618 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518619 LOCAL_SET_GL_ERROR(
8620 GL_INVALID_OPERATION,
8621 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598622 return;
8623 }
[email protected]9edc6b22010-12-23 02:00:268624
8625 // Check we have compatible formats.
8626 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8627 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8628 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8629
[email protected]2d3765b2012-10-03 00:31:078630 if (!channels_needed ||
8631 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518632 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438633 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268634 return;
8635 }
8636
[email protected]81375742012-06-08 00:04:008637 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518638 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008639 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438640 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008641 return;
8642 }
8643
[email protected]2ea5950d2014-07-09 18:20:348644 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
8645 return;
8646 }
8647
[email protected]a0b78dc2011-11-11 10:43:108648 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8649 return;
8650 }
8651
[email protected]de26b3c2011-08-03 21:54:278652 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038653 gfx::Size size = GetBoundReadFrameBufferSize();
8654 GLint copyX = 0;
8655 GLint copyY = 0;
8656 GLint copyWidth = 0;
8657 GLint copyHeight = 0;
8658 Clip(x, width, size.width(), &copyX, &copyWidth);
8659 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208660
[email protected]370eaf12013-05-18 09:19:498661 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518662 LOCAL_SET_GL_ERROR(
8663 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208664 return;
8665 }
8666
[email protected]6e288612010-12-21 20:45:038667 if (copyX != x ||
8668 copyY != y ||
8669 copyWidth != width ||
8670 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208671 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038672 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348673 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248674 width, height, format, type, state_.unpack_alignment, &pixels_size,
8675 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518676 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438677 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038678 return;
8679 }
[email protected]40d90a22013-04-09 03:39:558680 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038681 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:378682 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038683 glTexSubImage2D(
8684 target, level, xoffset, yoffset, width, height,
8685 format, type, zero.get());
8686 }
[email protected]0d6bfdc2011-11-02 01:32:208687
[email protected]6e288612010-12-21 20:45:038688 if (copyHeight > 0 && copyWidth > 0) {
8689 GLint dx = copyX - x;
8690 GLint dy = copyY - y;
8691 GLint destX = xoffset + dx;
8692 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:378693 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038694 glCopyTexSubImage2D(target, level,
8695 destX, destY, copyX, copyY,
8696 copyWidth, copyHeight);
8697 }
[email protected]cadde4a2010-07-31 17:10:438698}
8699
[email protected]f598f422012-12-07 08:30:038700bool GLES2DecoderImpl::ValidateTexSubImage2D(
8701 error::Error* error,
8702 const char* function_name,
8703 GLenum target,
8704 GLint level,
8705 GLint xoffset,
8706 GLint yoffset,
8707 GLsizei width,
8708 GLsizei height,
8709 GLenum format,
8710 GLenum type,
8711 const void * data) {
8712 (*error) = error::kNoError;
8713 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518714 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038715 return false;
8716 }
8717 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518718 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038719 return false;
8720 }
8721 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518722 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038723 return false;
8724 }
[email protected]c986af502013-08-14 01:04:448725 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8726 &state_, target);
[email protected]370eaf12013-05-18 09:19:498727 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518728 LOCAL_SET_GL_ERROR(
8729 GL_INVALID_OPERATION,
8730 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038731 return false;
[email protected]cadde4a2010-07-31 17:10:438732 }
[email protected]370eaf12013-05-18 09:19:498733 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528734 GLenum current_type = 0;
8735 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078736 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518737 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038738 GL_INVALID_OPERATION, function_name, "level does not exist.");
8739 return false;
[email protected]df6cf1ad2011-01-29 01:20:528740 }
[email protected]17a961192014-02-14 15:20:528741 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
8742 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:038743 return false;
[email protected]df6cf1ad2011-01-29 01:20:528744 }
8745 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518746 LOCAL_SET_GL_ERROR(
8747 GL_INVALID_OPERATION,
8748 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038749 return false;
[email protected]df6cf1ad2011-01-29 01:20:528750 }
[email protected]85a4ac22013-05-31 01:58:478751 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518752 LOCAL_SET_GL_ERROR(
8753 GL_INVALID_OPERATION,
8754 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598755 return false;
8756 }
[email protected]02965c22013-03-09 02:40:078757 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528758 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518759 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038760 return false;
[email protected]cadde4a2010-07-31 17:10:438761 }
[email protected]81375742012-06-08 00:04:008762 if ((GLES2Util::GetChannelsForFormat(format) &
8763 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518764 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008765 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038766 function_name, "can not supply data for depth or stencil textures");
8767 return false;
[email protected]81375742012-06-08 00:04:008768 }
[email protected]f598f422012-12-07 08:30:038769 if (data == NULL) {
8770 (*error) = error::kOutOfBounds;
8771 return false;
8772 }
8773 return true;
8774}
[email protected]81375742012-06-08 00:04:008775
[email protected]f598f422012-12-07 08:30:038776error::Error GLES2DecoderImpl::DoTexSubImage2D(
8777 GLenum target,
8778 GLint level,
8779 GLint xoffset,
8780 GLint yoffset,
8781 GLsizei width,
8782 GLsizei height,
8783 GLenum format,
8784 GLenum type,
8785 const void * data) {
8786 error::Error error = error::kNoError;
8787 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8788 xoffset, yoffset, width, height, format, type, data)) {
8789 return error;
8790 }
[email protected]c986af502013-08-14 01:04:448791 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8792 &state_, target);
[email protected]370eaf12013-05-18 09:19:498793 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158794 GLsizei tex_width = 0;
8795 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078796 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158797 DCHECK(ok);
8798 if (xoffset != 0 || yoffset != 0 ||
8799 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498800 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8801 target, level)) {
[email protected]ab09b612013-03-11 22:11:518802 LOCAL_SET_GL_ERROR(
8803 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038804 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308805 }
[email protected]c986af502013-08-14 01:04:448806 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158807 glTexSubImage2D(
8808 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038809 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208810 }
[email protected]4502e6492011-12-14 19:39:158811
[email protected]345ba902013-11-14 21:39:008812 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:448813 !texture->IsImmutable()) {
8814 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:258815 GLenum internal_format;
8816 GLenum tex_type;
8817 texture->GetLevelType(target, level, &tex_type, &internal_format);
8818 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
8819 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:388820 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258821 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:158822 } else {
[email protected]c986af502013-08-14 01:04:448823 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158824 glTexSubImage2D(
8825 target, level, xoffset, yoffset, width, height, format, type, data);
8826 }
[email protected]370eaf12013-05-18 09:19:498827 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038828 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438829}
8830
[email protected]b493ee622011-04-13 23:52:008831error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358832 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]67f929422014-05-17 15:33:138833 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
8834 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:008835 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448836 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008837 return error::kNoError;
8838
8839 GLenum target = static_cast<GLenum>(c.target);
8840 GLint level = static_cast<GLint>(c.level);
8841 GLint xoffset = static_cast<GLint>(c.xoffset);
8842 GLint yoffset = static_cast<GLint>(c.yoffset);
8843 GLsizei width = static_cast<GLsizei>(c.width);
8844 GLsizei height = static_cast<GLsizei>(c.height);
8845 GLenum format = static_cast<GLenum>(c.format);
8846 GLenum type = static_cast<GLenum>(c.type);
8847 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348848 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248849 width, height, format, type, state_.unpack_alignment, &data_size,
8850 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008851 return error::kOutOfBounds;
8852 }
8853 const void* pixels = GetSharedMemoryAs<const void*>(
8854 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038855 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008856 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008857}
8858
[email protected]f7a64ee2010-02-01 22:24:148859error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358860 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368861 GLuint index = static_cast<GLuint>(c.index);
8862 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358863 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258864 Result* result = GetSharedMemoryAs<Result*>(
8865 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368866 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148867 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368868 }
[email protected]07d0cc82010-02-17 04:51:408869 // Check that the client initialized the result.
8870 if (result->size != 0) {
8871 return error::kInvalidArguments;
8872 }
[email protected]9438b012010-06-15 22:55:058873 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518874 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8875 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148876 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368877 }
[email protected]3916c97e2010-02-25 03:20:508878 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518879 LOCAL_SET_GL_ERROR(
8880 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148881 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368882 }
[email protected]0bfd9882010-02-05 23:02:258883 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088884 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358885 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148886 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328887}
8888
[email protected]f7b85372010-02-03 01:11:378889bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428890 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378891 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128892 error::Error* error, GLint* real_location,
8893 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108894 DCHECK(error);
8895 DCHECK(service_id);
8896 DCHECK(result_pointer);
8897 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128898 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378899 *error = error::kNoError;
8900 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258901 SizedResult<GLint>* result;
8902 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8903 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8904 if (!result) {
[email protected]f7b85372010-02-03 01:11:378905 *error = error::kOutOfBounds;
8906 return false;
8907 }
[email protected]0bfd9882010-02-05 23:02:258908 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378909 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258910 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428911 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8912 if (!program) {
[email protected]ae51d192010-04-27 00:48:038913 return false;
8914 }
[email protected]df37b9932013-03-08 05:21:428915 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378916 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518917 LOCAL_SET_GL_ERROR(
8918 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378919 return false;
8920 }
[email protected]df37b9932013-03-08 05:21:428921 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368922 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358923 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428924 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128925 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368926 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378927 // No such location.
[email protected]ab09b612013-03-11 22:11:518928 LOCAL_SET_GL_ERROR(
8929 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378930 return false;
8931 }
[email protected]43c2f1f2011-03-25 18:35:368932 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508933 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378934 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518935 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378936 return false;
8937 }
[email protected]0bfd9882010-02-05 23:02:258938 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8939 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8940 if (!result) {
[email protected]f7b85372010-02-03 01:11:378941 *error = error::kOutOfBounds;
8942 return false;
8943 }
[email protected]0bfd9882010-02-05 23:02:258944 result->size = size;
[email protected]939e7362010-05-13 20:49:108945 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378946 return true;
8947}
8948
[email protected]f7a64ee2010-02-01 22:24:148949error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358950 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378951 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338952 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378953 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108954 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128955 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378956 Error error;
[email protected]0bfd9882010-02-05 23:02:258957 void* result;
[email protected]f7b85372010-02-03 01:11:378958 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128959 program, fake_location, c.params_shm_id, c.params_shm_offset,
8960 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258961 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128962 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358963 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378964 }
8965 return error;
[email protected]96449d2c2009-11-25 00:01:328966}
8967
[email protected]f7a64ee2010-02-01 22:24:148968error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358969 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378970 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338971 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378972 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128973 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378974 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358975 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108976 Result* result;
8977 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378978 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128979 program, fake_location, c.params_shm_id, c.params_shm_offset,
8980 &error, &real_location, &service_id,
8981 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108982 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8983 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8984 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558985 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128986 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108987 GLfloat* dst = result->GetData();
8988 for (GLsizei ii = 0; ii < num_values; ++ii) {
8989 dst[ii] = (temp[ii] != 0);
8990 }
8991 } else {
[email protected]1b0a6752012-02-22 03:44:128992 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108993 }
[email protected]f7b85372010-02-03 01:11:378994 }
8995 return error;
[email protected]96449d2c2009-11-25 00:01:328996}
8997
[email protected]f7a64ee2010-02-01 22:24:148998error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358999 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:259000 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9001 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359002 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259003 Result* result = GetSharedMemoryAs<Result*>(
9004 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9005 if (!result) {
9006 return error::kOutOfBounds;
9007 }
[email protected]07d0cc82010-02-17 04:51:409008 // Check that the client initialized the result.
9009 if (result->success != 0) {
9010 return error::kInvalidArguments;
9011 }
[email protected]9438b012010-06-15 22:55:059012 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519013 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539014 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299015 return error::kNoError;
9016 }
[email protected]9438b012010-06-15 22:55:059017 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519018 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539019 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299020 return error::kNoError;
9021 }
9022
9023 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409024
[email protected]46c86752013-05-21 05:08:399025 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409026 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219027 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409028
9029 result->min_range = range[0];
9030 result->max_range = range[1];
9031 result->precision = precision;
9032
[email protected]f7a64ee2010-02-01 22:24:149033 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329034}
9035
[email protected]f7a64ee2010-02-01 22:24:149036error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:359037 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:259038 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429039 GLuint program_id = static_cast<GLuint>(c.program);
9040 Program* program = GetProgramInfoNotShader(
9041 program_id, "glGetAttachedShaders");
9042 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259043 return error::kNoError;
9044 }
[email protected]ed9f9cd2013-02-27 21:12:359045 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259046 uint32 max_count = Result::ComputeMaxResults(result_size);
9047 Result* result = GetSharedMemoryAs<Result*>(
9048 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9049 if (!result) {
9050 return error::kOutOfBounds;
9051 }
[email protected]07d0cc82010-02-17 04:51:409052 // Check that the client initialized the result.
9053 if (result->size != 0) {
9054 return error::kInvalidArguments;
9055 }
[email protected]0bfd9882010-02-05 23:02:259056 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039057 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429058 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259059 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039060 if (!shader_manager()->GetClientId(result->GetData()[ii],
9061 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259062 NOTREACHED();
9063 return error::kGenericError;
9064 }
9065 }
9066 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149067 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329068}
9069
[email protected]f7a64ee2010-02-01 22:24:149070error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:359071 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:429072 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259073 GLuint index = c.index;
9074 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359075 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259076 Result* result = GetSharedMemoryAs<Result*>(
9077 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9078 if (!result) {
9079 return error::kOutOfBounds;
9080 }
[email protected]07d0cc82010-02-17 04:51:409081 // Check that the client initialized the result.
9082 if (result->success != 0) {
9083 return error::kInvalidArguments;
9084 }
[email protected]df37b9932013-03-08 05:21:429085 Program* program = GetProgramInfoNotShader(
9086 program_id, "glGetActiveUniform");
9087 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259088 return error::kNoError;
9089 }
[email protected]ed9f9cd2013-02-27 21:12:359090 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429091 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259092 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519093 LOCAL_SET_GL_ERROR(
9094 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259095 return error::kNoError;
9096 }
9097 result->success = 1; // true.
9098 result->size = uniform_info->size;
9099 result->type = uniform_info->type;
9100 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299101 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149102 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329103}
9104
[email protected]f7a64ee2010-02-01 22:24:149105error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:359106 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:429107 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259108 GLuint index = c.index;
9109 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359110 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259111 Result* result = GetSharedMemoryAs<Result*>(
9112 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9113 if (!result) {
9114 return error::kOutOfBounds;
9115 }
[email protected]07d0cc82010-02-17 04:51:409116 // Check that the client initialized the result.
9117 if (result->success != 0) {
9118 return error::kInvalidArguments;
9119 }
[email protected]df37b9932013-03-08 05:21:429120 Program* program = GetProgramInfoNotShader(
9121 program_id, "glGetActiveAttrib");
9122 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259123 return error::kNoError;
9124 }
[email protected]ed9f9cd2013-02-27 21:12:359125 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429126 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259127 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519128 LOCAL_SET_GL_ERROR(
9129 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259130 return error::kNoError;
9131 }
9132 result->success = 1; // true.
9133 result->size = attrib_info->size;
9134 result->type = attrib_info->type;
9135 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299136 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149137 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329138}
9139
[email protected]b273e432010-04-12 17:23:589140error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:359141 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:589142#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519143 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:589144 return error::kNoError;
9145#else
9146 GLsizei n = static_cast<GLsizei>(c.n);
9147 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:519148 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:589149 return error::kNoError;
9150 }
9151 GLsizei length = static_cast<GLsizei>(c.length);
9152 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:519153 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:589154 return error::kNoError;
9155 }
9156 uint32 data_size;
9157 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9158 return error::kOutOfBounds;
9159 }
9160 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9161 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9162 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9163 const void* binary = GetSharedMemoryAs<const void*>(
9164 c.binary_shm_id, c.binary_shm_offset, length);
9165 if (shaders == NULL || binary == NULL) {
9166 return error::kOutOfBounds;
9167 }
[email protected]0782b14b2014-05-24 13:04:169168 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:589169 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:429170 Shader* shader = GetShader(shaders[ii]);
9171 if (!shader) {
[email protected]ab09b612013-03-11 22:11:519172 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:589173 return error::kNoError;
9174 }
[email protected]df37b9932013-03-08 05:21:429175 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:589176 }
9177 // TODO(gman): call glShaderBinary
9178 return error::kNoError;
9179#endif
9180}
9181
[email protected]6d792ee12013-05-15 00:40:569182void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:499183 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:089184
[email protected]64ace852011-05-19 21:49:499185 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:429186 // TRACE_EVENT for gpu tests:
9187 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:429188 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:429189 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9190 "width", (is_offscreen ? offscreen_size_.width() :
9191 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:569192 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:499193 "offscreen", is_offscreen,
9194 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:159195 {
[email protected]a36ed4832014-04-24 16:40:279196 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:159197 }
9198
[email protected]8f9b8dd2013-09-12 18:05:139199 bool is_tracing;
9200 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9201 &is_tracing);
9202 if (is_tracing) {
9203 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9204 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9205 is_offscreen ? offscreen_size_ : surface_->GetSize());
9206 }
9207
[email protected]6217d392010-03-25 22:08:359208 // If offscreen then don't actually SwapBuffers to the display. Just copy
9209 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499210 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319211 TRACE_EVENT2("gpu", "Offscreen",
9212 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539213 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9214 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9215 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9216 // fix this.
[email protected]62e155e2012-10-23 22:43:159217 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539218 offscreen_saved_frame_buffer_->Create();
9219 glFinish();
9220 }
9221
9222 // Allocate the offscreen saved color texture.
9223 DCHECK(offscreen_saved_color_format_);
9224 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099225 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539226
9227 offscreen_saved_frame_buffer_->AttachRenderTexture(
9228 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059229 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9230 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9231 GL_FRAMEBUFFER_COMPLETE) {
9232 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9233 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569234 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9235 return;
[email protected]f0cfe752013-01-14 01:09:059236 }
[email protected]1fb8c482011-08-31 01:01:539237
[email protected]f0cfe752013-01-14 01:09:059238 // Clear the offscreen color texture.
9239 // TODO(piman): Is this still necessary?
9240 {
9241 ScopedFrameBufferBinder binder(this,
9242 offscreen_saved_frame_buffer_->id());
9243 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:459244 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9245 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:059246 glClear(GL_COLOR_BUFFER_BIT);
9247 RestoreClearState();
9248 }
[email protected]1fb8c482011-08-31 01:01:539249 }
9250
9251 UpdateParentTextureInfo();
9252 }
9253
[email protected]f0cfe752013-01-14 01:09:059254 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:569255 return;
[email protected]ab09b612013-03-11 22:11:519256 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:309257 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:359258
[email protected]34ff8b0c2010-10-01 20:06:029259 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:139260 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:279261 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:489262 } else {
[email protected]069944672012-04-25 20:52:239263 ScopedFrameBufferBinder binder(this,
9264 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:139265
[email protected]069944672012-04-25 20:52:239266 if (offscreen_target_buffer_preserved_) {
9267 // Copy the target frame buffer to the saved offscreen texture.
9268 offscreen_saved_color_texture_->Copy(
9269 offscreen_saved_color_texture_->size(),
9270 offscreen_saved_color_format_);
9271 } else {
9272 // Flip the textures in the parent context via the texture manager.
9273 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499274 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239275 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569276
[email protected]069944672012-04-25 20:52:239277 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9278 offscreen_target_frame_buffer_->AttachRenderTexture(
9279 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489280 }
[email protected]069944672012-04-25 20:52:239281
9282 // Ensure the side effects of the copy are visible to the parent
9283 // context. There is no need to do this for ANGLE because it uses a
9284 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:189285 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:239286 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399287 }
[email protected]6217d392010-03-25 22:08:359288 } else {
[email protected]f62a5ab2011-05-23 20:34:159289 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019290 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569291 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019292 }
[email protected]6217d392010-03-25 22:08:359293 }
[email protected]6217d392010-03-25 22:08:359294}
9295
[email protected]d4239852011-08-12 04:51:229296error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359297 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:189298 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289299 if (!bucket || bucket->size() == 0) {
9300 return error::kInvalidArguments;
9301 }
[email protected]ed9f9cd2013-02-27 21:12:359302 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189303 Result* result = GetSharedMemoryAs<Result*>(
9304 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9305 if (!result) {
9306 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109307 }
[email protected]b1d2dcb2010-05-17 19:24:189308 // Check that the client initialized the result.
9309 if (*result != 0) {
9310 return error::kInvalidArguments;
9311 }
9312 std::string feature_str;
9313 if (!bucket->GetAsString(&feature_str)) {
9314 return error::kInvalidArguments;
9315 }
9316
9317 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229318 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189319 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229320 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409321 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9322 // TODO(gman): decide how to remove the need for this const_cast.
9323 // I could make validators_ non const but that seems bad as this is the only
9324 // place it is needed. I could make some special friend class of validators
9325 // just to allow this to set them. That seems silly. I could refactor this
9326 // code to use the extension mechanism or the initialization attributes to
9327 // turn this feature on. Given that the only real point of this is to make
9328 // the conformance tests pass and given that there is lots of real work that
9329 // needs to be done it seems like refactoring for one to one of those
9330 // methods is a very low priority.
9331 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049332 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9333 force_webgl_glsl_validation_ = true;
9334 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189335 } else {
9336 return error::kNoError;
9337 }
9338
9339 *result = 1; // true.
9340 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109341}
9342
[email protected]c2f8c8402010-12-06 18:07:249343error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9344 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359345 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249346 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359347 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199348 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249349 bucket->SetFromString(info->extensions().c_str());
9350 return error::kNoError;
9351}
9352
9353error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359354 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249355 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289356 if (!bucket || bucket->size() == 0) {
9357 return error::kInvalidArguments;
9358 }
[email protected]c2f8c8402010-12-06 18:07:249359 std::string feature_str;
9360 if (!bucket->GetAsString(&feature_str)) {
9361 return error::kInvalidArguments;
9362 }
9363
[email protected]4b7eba92013-01-08 02:23:569364 bool desire_webgl_glsl_validation =
9365 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9366 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499367 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139368 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:069369 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:569370 if (force_webgl_glsl_validation_) {
9371 desire_standard_derivatives =
9372 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499373 desire_frag_depth =
9374 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139375 desire_draw_buffers =
9376 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:069377 desire_shader_texture_lod =
9378 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049379 }
9380
[email protected]4b7eba92013-01-08 02:23:569381 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499382 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139383 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9384 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499385 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9386 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9387 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139388 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:069389 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:249390 InitializeShaderTranslator();
9391 }
9392
[email protected]302ce6d2011-07-07 23:28:119393 UpdateCapabilities();
9394
[email protected]c2f8c8402010-12-06 18:07:249395 return error::kNoError;
9396}
9397
[email protected]372e0412011-06-28 16:08:569398error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359399 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:569400 GLuint count = c.count;
9401 uint32 pnames_size;
9402 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9403 return error::kOutOfBounds;
9404 }
9405 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9406 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9407 if (pnames == NULL) {
9408 return error::kOutOfBounds;
9409 }
9410
9411 // We have to copy them since we use them twice so the client
9412 // can't change them between the time we validate them and the time we use
9413 // them.
[email protected]40d90a22013-04-09 03:39:559414 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:569415 memcpy(enums.get(), pnames, pnames_size);
9416
9417 // Count up the space needed for the result.
9418 uint32 num_results = 0;
9419 for (GLuint ii = 0; ii < count; ++ii) {
9420 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9421 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519422 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]caa13ed2014-02-17 11:29:209423 "glGetMultipleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569424 return error::kNoError;
9425 }
9426 // Num will never be more than 4.
9427 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479428 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569429 return error::kOutOfBounds;
9430 }
9431 }
9432
9433 uint32 result_size = 0;
9434 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9435 return error::kOutOfBounds;
9436 }
9437
9438 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519439 LOCAL_SET_GL_ERROR(
9440 GL_INVALID_VALUE,
[email protected]caa13ed2014-02-17 11:29:209441 "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569442 return error::kNoError;
9443 }
9444
9445 GLint* results = GetSharedMemoryAs<GLint*>(
9446 c.results_shm_id, c.results_shm_offset, result_size);
9447 if (results == NULL) {
9448 return error::kOutOfBounds;
9449 }
9450
9451 // Check the results have been cleared in case the context was lost.
9452 for (uint32 ii = 0; ii < num_results; ++ii) {
9453 if (results[ii]) {
9454 return error::kInvalidArguments;
9455 }
9456 }
9457
9458 // Get each result.
9459 GLint* start = results;
9460 for (GLuint ii = 0; ii < count; ++ii) {
9461 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269462 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539463 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:489464 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:569465 }
9466 results += num_written;
9467 }
9468
9469 // Just to verify. Should this be a DCHECK?
9470 if (static_cast<uint32>(results - start) != num_results) {
9471 return error::kOutOfBounds;
9472 }
9473
9474 return error::kNoError;
9475}
9476
[email protected]2318d342011-07-11 22:27:429477error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359478 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:429479 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429480 uint32 bucket_id = c.bucket_id;
9481 Bucket* bucket = CreateBucket(bucket_id);
9482 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429483 Program* program = NULL;
9484 program = GetProgram(program_id);
9485 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469486 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429487 }
[email protected]df37b9932013-03-08 05:21:429488 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429489 return error::kNoError;
9490}
9491
[email protected]38d139d2011-07-14 00:38:439492error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9493 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439494 case GL_NO_ERROR:
9495 // TODO(kbr): improve the precision of the error code in this case.
9496 // Consider delegating to context for error code if MakeCurrent fails.
9497 return error::kUnknown;
9498 case GL_GUILTY_CONTEXT_RESET_ARB:
9499 return error::kGuilty;
9500 case GL_INNOCENT_CONTEXT_RESET_ARB:
9501 return error::kInnocent;
9502 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9503 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439504 }
9505
9506 NOTREACHED();
9507 return error::kUnknown;
9508}
9509
9510bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099511 if (reset_status_ != GL_NO_ERROR) {
9512 return true;
9513 }
[email protected]706b69f2012-07-27 04:59:309514 if (context_->WasAllocatedUsingRobustnessExtension()) {
9515 GLenum status = GL_NO_ERROR;
9516 if (has_robustness_extension_)
9517 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439518 if (status != GL_NO_ERROR) {
9519 // The graphics card was reset. Signal a lost context to the application.
9520 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229521 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439522 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099523 << " context lost via ARB/EXT_robustness. Reset status = "
9524 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439525 return true;
9526 }
9527 }
9528 return false;
9529}
9530
[email protected]93a7d98f2013-07-11 00:04:229531bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9532 return WasContextLost() && reset_by_robustness_extension_;
9533}
9534
[email protected]c4485aad62012-12-17 10:19:099535void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9536 // Only loses the context once.
9537 if (reset_status_ != GL_NO_ERROR) {
9538 return;
9539 }
9540
9541 // Marks this context as lost.
9542 reset_status_ = reset_status;
9543 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099544}
9545
[email protected]b096d032013-03-08 03:08:019546error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9547 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9548 return error::kUnknownCommand;
9549}
9550
[email protected]840a7e462013-02-27 01:29:519551error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359552 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]00c2cf92014-03-14 00:08:379553 group_->mailbox_manager()->PullTextureUpdates();
[email protected]840a7e462013-02-27 01:29:519554 if (wait_sync_point_callback_.is_null())
9555 return error::kNoError;
9556
9557 return wait_sync_point_callback_.Run(c.sync_point) ?
9558 error::kNoError : error::kDeferCommandUntilLater;
9559}
9560
[email protected]5dfc457b2013-12-13 11:13:079561error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
9562 uint32 immediate_data_size, const cmds::DiscardBackbufferCHROMIUM& c) {
9563 if (surface_->DeferDraws())
9564 return error::kDeferCommandUntilLater;
9565 if (!surface_->SetBackbufferAllocation(false))
9566 return error::kLostContext;
9567 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9568 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9569 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9570 return error::kNoError;
9571}
9572
[email protected]882ba1e22012-03-08 19:02:539573bool GLES2DecoderImpl::GenQueriesEXTHelper(
9574 GLsizei n, const GLuint* client_ids) {
9575 for (GLsizei ii = 0; ii < n; ++ii) {
9576 if (query_manager_->GetQuery(client_ids[ii])) {
9577 return false;
9578 }
9579 }
[email protected]4eea7e62014-04-22 21:14:439580 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:539581 return true;
9582}
9583
9584void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9585 GLsizei n, const GLuint* client_ids) {
9586 for (GLsizei ii = 0; ii < n; ++ii) {
9587 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9588 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139589 ContextState::QueryMap::iterator it =
9590 state_.current_queries.find(query->target());
9591 if (it != state_.current_queries.end())
9592 state_.current_queries.erase(it);
9593
[email protected]c45f1972012-03-14 07:27:369594 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539595 }
[email protected]4eea7e62014-04-22 21:14:439596 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:539597 }
9598}
9599
[email protected]22e3f552012-03-13 01:54:199600bool GLES2DecoderImpl::ProcessPendingQueries() {
9601 if (query_manager_.get() == NULL) {
9602 return false;
9603 }
[email protected]c45f1972012-03-14 07:27:369604 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199605 current_decoder_error_ = error::kOutOfBounds;
9606 }
9607 return query_manager_->HavePendingQueries();
9608}
9609
[email protected]5a36dc132013-07-23 23:17:559610// Note that if there are no pending readpixels right now,
9611// this function will call the callback immediately.
9612void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9613 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9614 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9615 } else {
9616 callback.Run();
9617 }
9618}
9619
9620void GLES2DecoderImpl::ProcessPendingReadPixels() {
9621 while (!pending_readpixel_fences_.empty() &&
9622 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9623 std::vector<base::Closure> callbacks =
9624 pending_readpixel_fences_.front()->callbacks;
9625 pending_readpixel_fences_.pop();
9626 for (size_t i = 0; i < callbacks.size(); i++) {
9627 callbacks[i].Run();
9628 }
9629 }
9630}
9631
[email protected]2b1767cf2013-03-16 09:25:059632bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559633 return !pending_readpixel_fences_.empty() ||
9634 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059635}
9636
9637void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559638 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:489639 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059640 return;
[email protected]b68b100752013-06-05 08:34:489641 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059642 ProcessFinishedAsyncTransfers();
9643}
9644
[email protected]882ba1e22012-03-08 19:02:539645error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359646 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539647 GLenum target = static_cast<GLenum>(c.target);
9648 GLuint client_id = static_cast<GLuint>(c.id);
9649 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9650 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9651
[email protected]c45f1972012-03-14 07:27:369652 switch (target) {
9653 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559654 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:319655 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9656 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009657 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369658 break;
[email protected]6a25ae422014-04-17 23:48:279659 case GL_COMMANDS_COMPLETED_CHROMIUM:
9660 if (!features().chromium_sync_query) {
9661 LOCAL_SET_GL_ERROR(
9662 GL_INVALID_OPERATION, "glBeginQueryEXT",
9663 "not enabled for commands completed queries");
9664 return error::kNoError;
9665 }
9666 break;
[email protected]c45f1972012-03-14 07:27:369667 default:
[email protected]62e155e2012-10-23 22:43:159668 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519669 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009670 GL_INVALID_OPERATION, "glBeginQueryEXT",
9671 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369672 return error::kNoError;
9673 }
9674 break;
[email protected]882ba1e22012-03-08 19:02:539675 }
9676
[email protected]8ebd46c2014-01-08 12:06:139677 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519678 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439679 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539680 return error::kNoError;
9681 }
9682
9683 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519684 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539685 return error::kNoError;
9686 }
9687
9688 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9689 if (!query) {
[email protected]4eea7e62014-04-22 21:14:439690 if (!query_manager_->IsValidQuery(client_id)) {
9691 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9692 "glBeginQueryEXT",
9693 "id not made by glGenQueriesEXT");
9694 return error::kNoError;
9695 }
[email protected]c45f1972012-03-14 07:27:369696 query = query_manager_->CreateQuery(
9697 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539698 }
9699
[email protected]c45f1972012-03-14 07:27:369700 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519701 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439702 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539703 return error::kNoError;
9704 } else if (query->shm_id() != sync_shm_id ||
9705 query->shm_offset() != sync_shm_offset) {
9706 DLOG(ERROR) << "Shared memory used by query not the same as before";
9707 return error::kInvalidArguments;
9708 }
9709
[email protected]c45f1972012-03-14 07:27:369710 if (!query_manager_->BeginQuery(query)) {
9711 return error::kOutOfBounds;
9712 }
[email protected]882ba1e22012-03-08 19:02:539713
[email protected]8ebd46c2014-01-08 12:06:139714 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:539715 return error::kNoError;
9716}
9717
9718error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359719 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539720 GLenum target = static_cast<GLenum>(c.target);
9721 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:139722 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:539723
[email protected]8ebd46c2014-01-08 12:06:139724 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519725 LOCAL_SET_GL_ERROR(
9726 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539727 return error::kNoError;
9728 }
[email protected]882ba1e22012-03-08 19:02:539729
[email protected]8ebd46c2014-01-08 12:06:139730 QueryManager::Query* query = it->second.get();
9731 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369732 return error::kOutOfBounds;
9733 }
9734
[email protected]fe8d73c2013-02-16 22:37:329735 query_manager_->ProcessPendingTransferQueries();
9736
[email protected]8ebd46c2014-01-08 12:06:139737 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:539738 return error::kNoError;
9739}
9740
[email protected]944b62f32012-09-27 02:20:469741bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9742 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469743 for (GLsizei ii = 0; ii < n; ++ii) {
9744 if (GetVertexAttribManager(client_ids[ii])) {
9745 return false;
9746 }
9747 }
[email protected]ab4fd7282012-10-12 16:25:579748
[email protected]62e155e2012-10-23 22:43:159749 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579750 // Emulated VAO
9751 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:489752 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:579753 }
9754 } else {
[email protected]40d90a22013-04-09 03:39:559755 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579756
9757 glGenVertexArraysOES(n, service_ids.get());
9758 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:489759 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:579760 }
[email protected]944b62f32012-09-27 02:20:469761 }
[email protected]ab4fd7282012-10-12 16:25:579762
[email protected]944b62f32012-09-27 02:20:469763 return true;
9764}
9765
9766void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9767 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469768 for (GLsizei ii = 0; ii < n; ++ii) {
9769 VertexAttribManager* vao =
9770 GetVertexAttribManager(client_ids[ii]);
9771 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119772 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:119773 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:469774 }
9775 RemoveVertexAttribManager(client_ids[ii]);
9776 }
9777 }
9778}
9779
9780void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469781 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:469782 if (client_id != 0) {
9783 vao = GetVertexAttribManager(client_id);
9784 if (!vao) {
9785 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9786 // only allows names that have been previously generated. As such, we do
9787 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519788 LOCAL_SET_GL_ERROR(
9789 GL_INVALID_OPERATION,
9790 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469791 current_decoder_error_ = error::kNoError;
9792 return;
[email protected]944b62f32012-09-27 02:20:469793 }
[email protected]944b62f32012-09-27 02:20:469794 } else {
[email protected]81f20a622014-04-18 01:54:529795 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:469796 }
9797
[email protected]ab4fd7282012-10-12 16:25:579798 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:119799 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:249800 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159801 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579802 EmulateVertexArrayState();
9803 } else {
[email protected]da364812014-05-09 21:39:489804 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:579805 glBindVertexArrayOES(service_id);
9806 }
9807 }
9808}
9809
9810// Used when OES_vertex_array_object isn't natively supported
9811void GLES2DecoderImpl::EmulateVertexArrayState() {
9812 // Setup the Vertex attribute state
9813 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:239814 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:579815 }
9816
9817 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219818 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249819 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579820 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9821 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469822}
9823
9824bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469825 const VertexAttribManager* vao =
9826 GetVertexAttribManager(client_id);
9827 return vao && vao->IsValid() && !vao->IsDeleted();
9828}
9829
[email protected]e51bdf32011-11-23 22:21:469830#if defined(OS_MACOSX)
9831void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9832 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9833 texture_id);
9834 if (it != texture_to_io_surface_map_.end()) {
9835 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:539836 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:469837 CFRelease(surface);
9838 texture_to_io_surface_map_.erase(it);
9839 }
9840}
9841#endif
9842
9843void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9844 GLenum target, GLsizei width, GLsizei height,
9845 GLuint io_surface_id, GLuint plane) {
9846#if defined(OS_MACOSX)
9847 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519848 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439849 GL_INVALID_OPERATION,
9850 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469851 return;
9852 }
9853
[email protected]e51bdf32011-11-23 22:21:469854 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9855 // This might be supported in the future, and if we could require
9856 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9857 // could delete a lot of code. For now, perform strict validation so we
9858 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519859 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469860 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439861 "glTexImageIOSurface2DCHROMIUM",
9862 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469863 return;
9864 }
9865
[email protected]09d50362012-10-18 20:54:379866 // Default target might be conceptually valid, but disallow it to avoid
9867 // accidents.
[email protected]c986af502013-08-14 01:04:449868 TextureRef* texture_ref =
9869 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:499870 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519871 LOCAL_SET_GL_ERROR(
9872 GL_INVALID_OPERATION,
9873 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469874 return;
9875 }
[email protected]e51bdf32011-11-23 22:21:469876
9877 // Look up the new IOSurface. Note that because of asynchrony
9878 // between processes this might fail; during live resizing the
9879 // plugin process might allocate and release an IOSurface before
9880 // this process gets a chance to look it up. Hold on to any old
9881 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:539882 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:469883 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519884 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439885 GL_INVALID_OPERATION,
9886 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469887 return;
9888 }
9889
9890 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499891 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469892
9893 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9894 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499895 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469896
9897 CGLContextObj context =
9898 static_cast<CGLContextObj>(context_->GetHandle());
9899
[email protected]c3a6b4a2014-06-04 09:25:539900 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:469901 context,
9902 target,
9903 GL_RGBA,
9904 width,
9905 height,
9906 GL_BGRA,
9907 GL_UNSIGNED_INT_8_8_8_8_REV,
9908 surface,
9909 plane);
9910
9911 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519912 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469913 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439914 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469915 return;
9916 }
9917
9918 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499919 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469920 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9921
9922#else
[email protected]ab09b612013-03-11 22:11:519923 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439924 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469925#endif
9926}
9927
[email protected]97dc7cbe2011-12-06 17:26:179928static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9929 switch (internalformat) {
9930 case GL_RGB565:
9931 return GL_RGB;
9932 case GL_RGBA4:
9933 return GL_RGBA;
9934 case GL_RGB5_A1:
9935 return GL_RGBA;
9936 case GL_RGB8_OES:
9937 return GL_RGB;
9938 case GL_RGBA8_OES:
9939 return GL_RGBA;
9940 case GL_LUMINANCE8_ALPHA8_EXT:
9941 return GL_LUMINANCE_ALPHA;
9942 case GL_LUMINANCE8_EXT:
9943 return GL_LUMINANCE;
9944 case GL_ALPHA8_EXT:
9945 return GL_ALPHA;
9946 case GL_RGBA32F_EXT:
9947 return GL_RGBA;
9948 case GL_RGB32F_EXT:
9949 return GL_RGB;
9950 case GL_ALPHA32F_EXT:
9951 return GL_ALPHA;
9952 case GL_LUMINANCE32F_EXT:
9953 return GL_LUMINANCE;
9954 case GL_LUMINANCE_ALPHA32F_EXT:
9955 return GL_LUMINANCE_ALPHA;
9956 case GL_RGBA16F_EXT:
9957 return GL_RGBA;
9958 case GL_RGB16F_EXT:
9959 return GL_RGB;
9960 case GL_ALPHA16F_EXT:
9961 return GL_ALPHA;
9962 case GL_LUMINANCE16F_EXT:
9963 return GL_LUMINANCE;
9964 case GL_LUMINANCE_ALPHA16F_EXT:
9965 return GL_LUMINANCE_ALPHA;
9966 case GL_BGRA8_EXT:
9967 return GL_BGRA_EXT;
9968 default:
9969 return GL_NONE;
9970 }
9971}
9972
[email protected]43410e92012-04-20 17:06:289973void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039974 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549975 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:089976 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
9977
[email protected]370eaf12013-05-18 09:19:499978 TextureRef* dest_texture_ref = GetTexture(dest_id);
9979 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289980
[email protected]370eaf12013-05-18 09:19:499981 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519982 LOCAL_SET_GL_ERROR(
9983 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289984 return;
9985 }
9986
9987 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519988 LOCAL_SET_GL_ERROR(
9989 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289990 return;
9991 }
9992
[email protected]370eaf12013-05-18 09:19:499993 Texture* source_texture = source_texture_ref->texture();
9994 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079995 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259996 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:349997 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
9998 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:009999 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10000 "glCopyTextureCHROMIUM",
10001 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310002 return;
10003 }
10004
[email protected]43410e92012-04-20 17:06:2810005 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810006
[email protected]3e0dfd72014-02-21 06:28:4110007 gfx::GLImage* image =
10008 source_texture->GetLevelImage(source_texture->target(), 0);
10009 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510010 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610011 source_width = size.width();
10012 source_height = size.height();
10013 if (source_width <= 0 || source_height <= 0) {
10014 LOCAL_SET_GL_ERROR(
10015 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510016 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610017 return;
10018 }
[email protected]3ecc1052013-09-26 08:59:0010019 } else {
10020 if (!source_texture->GetLevelSize(
10021 source_texture->target(), 0, &source_width, &source_height)) {
10022 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10023 "glCopyTextureChromium",
10024 "source texture has no level 0");
10025 return;
10026 }
10027
10028 // Check that this type of texture is allowed.
10029 if (!texture_manager()->ValidForTarget(
10030 source_texture->target(), level, source_width, source_height, 1)) {
10031 LOCAL_SET_GL_ERROR(
10032 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10033 return;
10034 }
[email protected]377976552013-05-14 23:32:5610035 }
10036
[email protected]04b5b37d2014-02-07 02:11:5110037 // Clear the source texture if necessary.
10038 if (!texture_manager()->ClearTextureLevel(
10039 this, source_texture_ref, source_texture->target(), 0)) {
10040 LOCAL_SET_GL_ERROR(
10041 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
10042 return;
10043 }
10044
[email protected]cf6b8f62012-05-25 21:43:3710045 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
10046 // needed because it takes 10s of milliseconds to initialize.
10047 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5110048 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3710049 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2710050 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3710051 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5110052 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3710053 return;
10054 }
10055
[email protected]efc87712014-07-09 00:22:4710056 GLenum dest_type_previous = dest_type;
10057 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0710058 bool dest_level_defined = dest_texture->GetLevelSize(
10059 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2810060
[email protected]0a1e9ad2012-05-04 21:13:0310061 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5410062 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0710063 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0310064 }
10065
10066 // Resize the destination texture to the dimensions of the source texture.
10067 if (!dest_level_defined || dest_width != source_width ||
10068 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5410069 dest_internal_format != internal_format ||
10070 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2810071 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5110072 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0710073 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3810074 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2810075 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0310076 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5110077 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0310078 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0210079 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2810080 return;
[email protected]0a1e9ad2012-05-04 21:13:0310081 }
[email protected]43410e92012-04-20 17:06:2810082
10083 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910084 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0310085 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2510086 } else {
[email protected]02965c22013-03-09 02:40:0710087 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4910088 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2810089 }
10090
[email protected]91c94eb2013-10-22 10:32:5410091 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]00c2cf92014-03-14 00:08:3710092 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5410093
[email protected]5394a4102013-04-18 05:41:3710094 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
10095 // before presenting.
10096 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
10097 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
10098 // instead of using default matrix crbug.com/226218.
10099 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
10100 0.0f, 1.0f, 0.0f, 0.0f,
10101 0.0f, 0.0f, 1.0f, 0.0f,
10102 0.0f, 0.0f, 0.0f, 1.0f};
10103 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
10104 this,
10105 source_texture->target(),
10106 dest_texture->target(),
10107 source_texture->service_id(),
10108 dest_texture->service_id(), level,
10109 source_width, source_height,
10110 unpack_flip_y_,
10111 unpack_premultiply_alpha_,
10112 unpack_unpremultiply_alpha_,
10113 default_matrix);
10114 } else {
10115 copy_texture_CHROMIUM_->DoCopyTexture(
10116 this,
10117 source_texture->target(),
10118 dest_texture->target(),
10119 source_texture->service_id(),
10120 dest_texture->service_id(), level,
10121 source_width, source_height,
10122 unpack_flip_y_,
10123 unpack_premultiply_alpha_,
10124 unpack_unpremultiply_alpha_);
10125 }
[email protected]91c94eb2013-10-22 10:32:5410126
10127 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810128}
10129
[email protected]97dc7cbe2011-12-06 17:26:1710130static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10131 switch (internalformat) {
10132 case GL_RGB565:
10133 return GL_UNSIGNED_SHORT_5_6_5;
10134 case GL_RGBA4:
10135 return GL_UNSIGNED_SHORT_4_4_4_4;
10136 case GL_RGB5_A1:
10137 return GL_UNSIGNED_SHORT_5_5_5_1;
10138 case GL_RGB8_OES:
10139 return GL_UNSIGNED_BYTE;
10140 case GL_RGBA8_OES:
10141 return GL_UNSIGNED_BYTE;
10142 case GL_LUMINANCE8_ALPHA8_EXT:
10143 return GL_UNSIGNED_BYTE;
10144 case GL_LUMINANCE8_EXT:
10145 return GL_UNSIGNED_BYTE;
10146 case GL_ALPHA8_EXT:
10147 return GL_UNSIGNED_BYTE;
10148 case GL_RGBA32F_EXT:
10149 return GL_FLOAT;
10150 case GL_RGB32F_EXT:
10151 return GL_FLOAT;
10152 case GL_ALPHA32F_EXT:
10153 return GL_FLOAT;
10154 case GL_LUMINANCE32F_EXT:
10155 return GL_FLOAT;
10156 case GL_LUMINANCE_ALPHA32F_EXT:
10157 return GL_FLOAT;
10158 case GL_RGBA16F_EXT:
10159 return GL_HALF_FLOAT_OES;
10160 case GL_RGB16F_EXT:
10161 return GL_HALF_FLOAT_OES;
10162 case GL_ALPHA16F_EXT:
10163 return GL_HALF_FLOAT_OES;
10164 case GL_LUMINANCE16F_EXT:
10165 return GL_HALF_FLOAT_OES;
10166 case GL_LUMINANCE_ALPHA16F_EXT:
10167 return GL_HALF_FLOAT_OES;
10168 case GL_BGRA8_EXT:
10169 return GL_UNSIGNED_BYTE;
10170 default:
10171 return GL_NONE;
10172 }
10173}
10174
10175void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4410176 GLenum target,
10177 GLint levels,
10178 GLenum internal_format,
10179 GLsizei width,
10180 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1310181 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
10182 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4110183 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0010184 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5110185 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310186 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1710187 return;
10188 }
[email protected]c986af502013-08-14 01:04:4410189 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10190 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910191 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110192 LOCAL_SET_GL_ERROR(
10193 GL_INVALID_OPERATION,
10194 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1710195 return;
10196 }
[email protected]370eaf12013-05-18 09:19:4910197 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710198 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410199 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1710200 }
[email protected]02965c22013-03-09 02:40:0710201 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5110202 LOCAL_SET_GL_ERROR(
10203 GL_INVALID_OPERATION,
10204 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1710205 return;
10206 }
[email protected]7989c9e2013-01-23 06:39:2610207
10208 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10209 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10210
10211 {
10212 GLsizei level_width = width;
10213 GLsizei level_height = height;
10214 uint32 estimated_size = 0;
10215 for (int ii = 0; ii < levels; ++ii) {
10216 uint32 level_size = 0;
10217 if (!GLES2Util::ComputeImageDataSizes(
10218 level_width, level_height, format, type, state_.unpack_alignment,
10219 &estimated_size, NULL, NULL) ||
10220 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110221 LOCAL_SET_GL_ERROR(
10222 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2610223 return;
10224 }
10225 level_width = std::max(1, level_width >> 1);
10226 level_height = std::max(1, level_height >> 1);
10227 }
10228 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110229 LOCAL_SET_GL_ERROR(
10230 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610231 return;
10232 }
10233 }
10234
[email protected]ab09b612013-03-11 22:11:5110235 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3810236 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5110237 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710238 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510239 GLsizei level_width = width;
10240 GLsizei level_height = height;
10241 for (int ii = 0; ii < levels; ++ii) {
10242 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910243 texture_ref, target, ii, format,
10244 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1510245 level_width = std::max(1, level_width >> 1);
10246 level_height = std::max(1, level_height >> 1);
10247 }
[email protected]02965c22013-03-09 02:40:0710248 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710249 }
[email protected]97dc7cbe2011-12-06 17:26:1710250}
[email protected]e51bdf32011-11-23 22:21:4610251
[email protected]78b514b2012-05-01 21:50:5910252error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510253 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]baed42c2013-10-01 05:06:3510254 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910255}
10256
10257void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710258 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210259 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210260 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710261 "mailbox[0]", static_cast<unsigned char>(data[0]));
10262
[email protected]43f253da2014-06-10 17:51:2210263 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10264 &state_, target);
10265 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
10266}
10267
10268void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
10269 GLenum target, const GLbyte* data) {
10270 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
10271 "context", logger_.GetLogPrefix(),
10272 "mailbox[0]", static_cast<unsigned char>(data[0]));
10273
10274 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
10275 target, data);
10276}
10277
10278void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
10279 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3710280 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2210281 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3710282 "mailbox that was not generated by "
10283 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210284
[email protected]370eaf12013-05-18 09:19:4910285 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110286 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210287 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910288 return;
10289 }
10290
[email protected]62e65f02013-05-29 22:28:1010291 Texture* produced = texture_manager()->Produce(texture_ref);
10292 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110293 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210294 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
10295 return;
10296 }
10297
10298 if (produced->target() != target) {
10299 LOCAL_SET_GL_ERROR(
10300 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5910301 return;
10302 }
10303
[email protected]64ba52f2014-02-15 14:22:3710304 group_->mailbox_manager()->ProduceTexture(target, mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5910305}
10306
10307void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710308 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210309 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210310 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710311 "mailbox[0]", static_cast<unsigned char>(data[0]));
10312 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10313 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10314 "mailbox that was not generated by "
10315 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210316
[email protected]62e65f02013-05-29 22:28:1010317 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410318 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110319 if (!texture_ref.get()) {
10320 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10321 "glConsumeTextureCHROMIUM",
10322 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910323 return;
10324 }
[email protected]62e65f02013-05-29 22:28:1010325 GLuint client_id = texture_ref->client_id();
10326 if (!client_id) {
10327 LOCAL_SET_GL_ERROR(
10328 GL_INVALID_OPERATION,
10329 "glConsumeTextureCHROMIUM", "unknown texture for target");
10330 return;
10331 }
[email protected]64ba52f2014-02-15 14:22:3710332 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
[email protected]62e65f02013-05-29 22:28:1010333 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110334 LOCAL_SET_GL_ERROR(
10335 GL_INVALID_OPERATION,
10336 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910337 return;
10338 }
[email protected]62e65f02013-05-29 22:28:1010339 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110340 LOCAL_SET_GL_ERROR(
10341 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010342 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910343 return;
10344 }
[email protected]62e65f02013-05-29 22:28:1010345
10346 DeleteTexturesHelper(1, &client_id);
10347 texture_ref = texture_manager()->Consume(client_id, texture);
10348 glBindTexture(target, texture_ref->service_id());
10349
10350 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10351 unit.bind_target = target;
10352 switch (target) {
10353 case GL_TEXTURE_2D:
10354 unit.bound_texture_2d = texture_ref;
10355 break;
10356 case GL_TEXTURE_CUBE_MAP:
10357 unit.bound_texture_cube_map = texture_ref;
10358 break;
10359 case GL_TEXTURE_EXTERNAL_OES:
10360 unit.bound_texture_external_oes = texture_ref;
10361 break;
10362 case GL_TEXTURE_RECTANGLE_ARB:
10363 unit.bound_texture_rectangle_arb = texture_ref;
10364 break;
10365 default:
10366 NOTREACHED(); // Validation should prevent us getting here.
10367 break;
10368 }
[email protected]78b514b2012-05-01 21:50:5910369}
10370
[email protected]43f253da2014-06-10 17:51:2210371error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
10372 uint32_t immediate_data_size,
10373 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c) {
10374 GLenum target = static_cast<GLenum>(c.target);
10375 uint32_t data_size;
10376 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
10377 return error::kOutOfBounds;
10378 }
10379 if (data_size > immediate_data_size) {
10380 return error::kOutOfBounds;
10381 }
10382 const GLbyte* mailbox =
10383 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
10384 if (!validators_->texture_bind_target.IsValid(target)) {
10385 LOCAL_SET_GL_ERROR_INVALID_ENUM(
10386 "glCreateAndConsumeTextureCHROMIUM", target, "target");
10387 return error::kNoError;
10388 }
10389 if (mailbox == NULL) {
10390 return error::kOutOfBounds;
10391 }
10392 uint32_t client_id = c.client_id;
10393 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
10394 return error::kNoError;
10395}
10396
10397void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
10398 const GLbyte* data, GLuint client_id) {
10399 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
10400 "context", logger_.GetLogPrefix(),
10401 "mailbox[0]", static_cast<unsigned char>(data[0]));
10402 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10403 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
10404 "passed a mailbox that was not "
10405 "generated by GenMailboxCHROMIUM.";
10406
10407 TextureRef* texture_ref = GetTexture(client_id);
10408 if (texture_ref) {
10409 LOCAL_SET_GL_ERROR(
10410 GL_INVALID_OPERATION,
10411 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
10412 return;
10413 }
10414 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
10415 if (!texture) {
10416 LOCAL_SET_GL_ERROR(
10417 GL_INVALID_OPERATION,
10418 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
10419 return;
10420 }
10421 if (texture->target() != target) {
10422 LOCAL_SET_GL_ERROR(
10423 GL_INVALID_OPERATION,
10424 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
10425 return;
10426 }
10427
10428 IdAllocatorInterface* id_allocator =
10429 group_->GetIdAllocator(id_namespaces::kTextures);
10430 id_allocator->MarkAsUsed(client_id);
10431
10432 texture_ref = texture_manager()->Consume(client_id, texture);
10433}
10434
[email protected]d2a0e1a2012-08-12 02:25:0110435void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10436 GLsizei length, const GLchar* marker) {
10437 if (!marker) {
10438 marker = "";
10439 }
10440 debug_marker_manager_.SetMarker(
10441 length ? std::string(marker, length) : std::string(marker));
10442}
10443
10444void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10445 GLsizei length, const GLchar* marker) {
10446 if (!marker) {
10447 marker = "";
10448 }
[email protected]cac16542014-01-15 17:53:5110449 std::string name = length ? std::string(marker, length) : std::string(marker);
10450 debug_marker_manager_.PushGroup(name);
10451 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110452}
10453
10454void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10455 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110456 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110457}
10458
[email protected]09d50362012-10-18 20:54:3710459void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10460 GLenum target, GLint image_id) {
10461 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710462
[email protected]bc26e8d2014-01-29 00:40:3010463 if (target == GL_TEXTURE_CUBE_MAP) {
10464 LOCAL_SET_GL_ERROR(
10465 GL_INVALID_ENUM,
10466 "glBindTexImage2DCHROMIUM", "invalid target");
10467 return;
10468 }
10469
[email protected]09d50362012-10-18 20:54:3710470 // Default target might be conceptually valid, but disallow it to avoid
10471 // accidents.
[email protected]c986af502013-08-14 01:04:4410472 TextureRef* texture_ref =
10473 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910474 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110475 LOCAL_SET_GL_ERROR(
10476 GL_INVALID_OPERATION,
10477 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710478 return;
10479 }
10480
10481 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10482 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110483 LOCAL_SET_GL_ERROR(
10484 GL_INVALID_OPERATION,
10485 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710486 return;
10487 }
10488
[email protected]b8160812013-04-09 00:41:0410489 {
10490 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010491 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610492 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410493 LOCAL_SET_GL_ERROR(
10494 GL_INVALID_OPERATION,
10495 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10496 return;
10497 }
[email protected]09d50362012-10-18 20:54:3710498 }
10499
10500 gfx::Size size = gl_image->GetSize();
10501 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910502 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710503 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910504 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710505}
10506
10507void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10508 GLenum target, GLint image_id) {
10509 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710510
10511 // Default target might be conceptually valid, but disallow it to avoid
10512 // accidents.
[email protected]c986af502013-08-14 01:04:4410513 TextureRef* texture_ref =
10514 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910515 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110516 LOCAL_SET_GL_ERROR(
10517 GL_INVALID_OPERATION,
10518 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710519 return;
10520 }
10521
10522 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10523 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110524 LOCAL_SET_GL_ERROR(
10525 GL_INVALID_OPERATION,
10526 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710527 return;
10528 }
10529
10530 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910531 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710532 return;
10533
[email protected]b8160812013-04-09 00:41:0410534 {
10535 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010536 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610537 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0410538 }
[email protected]09d50362012-10-18 20:54:3710539
10540 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910541 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710542 GL_RGBA, GL_UNSIGNED_BYTE, false);
10543}
[email protected]d2a0e1a2012-08-12 02:25:0110544
[email protected]94307712012-11-16 23:26:1110545error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510546 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110547 Bucket* bucket = GetBucket(c.bucket_id);
10548 if (!bucket || bucket->size() == 0) {
10549 return error::kInvalidArguments;
10550 }
10551 std::string command_name;
10552 if (!bucket->GetAsString(&command_name)) {
10553 return error::kInvalidArguments;
10554 }
[email protected]fb97b662013-02-20 23:02:1410555 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5110556 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5110557 LOCAL_SET_GL_ERROR(
10558 GL_INVALID_OPERATION,
10559 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410560 return error::kNoError;
10561 }
[email protected]94307712012-11-16 23:26:1110562 return error::kNoError;
10563}
10564
10565void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410566 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110567 LOCAL_SET_GL_ERROR(
10568 GL_INVALID_OPERATION,
10569 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110570 return;
10571 }
[email protected]fb97b662013-02-20 23:02:1410572 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5110573 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1110574}
10575
[email protected]2f143d482013-03-14 18:04:4910576void GLES2DecoderImpl::DoDrawBuffersEXT(
10577 GLsizei count, const GLenum* bufs) {
10578 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10579 LOCAL_SET_GL_ERROR(
10580 GL_INVALID_VALUE,
10581 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10582 return;
10583 }
10584
10585 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10586 if (framebuffer) {
10587 for (GLsizei i = 0; i < count; ++i) {
10588 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10589 bufs[i] != GL_NONE) {
10590 LOCAL_SET_GL_ERROR(
10591 GL_INVALID_OPERATION,
10592 "glDrawBuffersEXT",
10593 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10594 return;
10595 }
10596 }
10597 glDrawBuffersARB(count, bufs);
10598 framebuffer->SetDrawBuffers(count, bufs);
10599 } else { // backbuffer
10600 if (count > 1 ||
10601 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10602 LOCAL_SET_GL_ERROR(
10603 GL_INVALID_OPERATION,
10604 "glDrawBuffersEXT",
10605 "more than one buffer or bufs not GL_NONE or GL_BACK");
10606 return;
10607 }
10608 GLenum mapped_buf = bufs[0];
10609 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10610 bufs[0] == GL_BACK) {
10611 mapped_buf = GL_COLOR_ATTACHMENT0;
10612 }
10613 glDrawBuffersARB(count, &mapped_buf);
10614 group_->set_draw_buffer(bufs[0]);
10615 }
10616}
10617
[email protected]a6a09f852014-05-23 13:05:0310618void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
10619 group_->LoseContexts(other);
10620 reset_status_ = current;
10621 current_decoder_error_ = error::kLostContext;
10622}
10623
[email protected]32145a92012-12-17 09:01:5910624bool GLES2DecoderImpl::ValidateAsyncTransfer(
10625 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710626 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910627 GLenum target,
10628 GLint level,
10629 const void * data) {
10630 // We only support async uploads to 2D textures for now.
10631 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110632 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910633 return false;
10634 }
10635 // We only support uploads to level zero for now.
10636 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110637 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910638 return false;
10639 }
10640 // A transfer buffer must be bound, even for asyncTexImage2D.
10641 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110642 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910643 return false;
10644 }
10645 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710646 if (!texture_ref ||
10647 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110648 LOCAL_SET_GL_ERROR(
10649 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910650 function_name, "transfer already in progress");
10651 return false;
10652 }
10653 return true;
10654}
10655
[email protected]e3c4a9ab2014-03-31 09:07:0210656base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
10657 uint32 async_upload_token,
10658 uint32 sync_data_shm_id,
10659 uint32 sync_data_shm_offset) {
10660 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
10661 if (!buffer || !buffer->GetDataAddress(sync_data_shm_offset,
10662 sizeof(AsyncUploadSync)))
10663 return base::Closure();
10664
10665 AsyncMemoryParams mem_params(buffer,
10666 sync_data_shm_offset,
10667 sizeof(AsyncUploadSync));
10668
10669 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
10670 new AsyncUploadTokenCompletionObserver(async_upload_token));
10671
10672 return base::Bind(
10673 &AsyncPixelTransferManager::AsyncNotifyCompletion,
10674 base::Unretained(GetAsyncPixelTransferManager()),
10675 mem_params,
10676 observer);
10677}
10678
[email protected]69023942012-11-30 19:57:1610679error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510680 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610681 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610682 GLenum target = static_cast<GLenum>(c.target);
10683 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4410684 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1610685 GLsizei width = static_cast<GLsizei>(c.width);
10686 GLsizei height = static_cast<GLsizei>(c.height);
10687 GLint border = static_cast<GLint>(c.border);
10688 GLenum format = static_cast<GLenum>(c.format);
10689 GLenum type = static_cast<GLenum>(c.type);
10690 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10691 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10692 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0210693 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
10694 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
10695 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10696
10697 base::ScopedClosureRunner scoped_completion_callback;
10698 if (async_upload_token) {
10699 base::Closure completion_closure =
10700 AsyncUploadTokenCompletionClosure(async_upload_token,
10701 sync_data_shm_id,
10702 sync_data_shm_offset);
10703 if (completion_closure.is_null())
10704 return error::kInvalidArguments;
10705
10706 scoped_completion_callback.Reset(completion_closure);
10707 }
[email protected]32145a92012-12-17 09:01:5910708
10709 // TODO(epenner): Move this and copies of this memory validation
10710 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610711 if (!GLES2Util::ComputeImageDataSizes(
10712 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10713 NULL)) {
10714 return error::kOutOfBounds;
10715 }
10716 const void* pixels = NULL;
10717 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10718 pixels = GetSharedMemoryAs<const void*>(
10719 pixels_shm_id, pixels_shm_offset, pixels_size);
10720 if (!pixels) {
10721 return error::kOutOfBounds;
10722 }
10723 }
10724
[email protected]c986af502013-08-14 01:04:4410725 TextureManager::DoTextImage2DArguments args = {
10726 target, level, internal_format, width, height, border, format, type,
10727 pixels, pixels_size};
10728 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5910729 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4410730 if (!texture_manager()->ValidateTexImage2D(
10731 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5910732 return error::kNoError;
10733 }
10734
10735 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910736 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910737 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710738 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910739 return error::kNoError;
10740
10741 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710742 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110743 LOCAL_SET_GL_ERROR(
10744 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910745 "glAsyncTexImage2DCHROMIUM", "already defined");
10746 return error::kNoError;
10747 }
10748
[email protected]7989c9e2013-01-23 06:39:2610749 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110750 LOCAL_SET_GL_ERROR(
10751 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610752 return error::kNoError;
10753 }
10754
[email protected]5b3a8e02013-03-13 05:36:4410755 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810756 AsyncTexImage2DParams tex_params = {
10757 target, level, static_cast<GLenum>(internal_format),
10758 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1210759 AsyncMemoryParams mem_params(
10760 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5910761
[email protected]5b3a8e02013-03-13 05:36:4410762 // Set up the async state if needed, and make the texture
10763 // immutable so the async state stays valid. The level info
10764 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1810765 AsyncPixelTransferDelegate* delegate =
10766 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
10767 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4410768 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910769
[email protected]896425e2013-06-12 17:27:1810770 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410771 tex_params,
10772 mem_params,
10773 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910774 // The callback is only invoked if the transfer delegate still
10775 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410776 // ownership that both of these pointers are valid.
10777 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910778 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410779 tex_params));
[email protected]f598f422012-12-07 08:30:0310780 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610781}
10782
10783error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510784 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610785 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610786 GLenum target = static_cast<GLenum>(c.target);
10787 GLint level = static_cast<GLint>(c.level);
10788 GLint xoffset = static_cast<GLint>(c.xoffset);
10789 GLint yoffset = static_cast<GLint>(c.yoffset);
10790 GLsizei width = static_cast<GLsizei>(c.width);
10791 GLsizei height = static_cast<GLsizei>(c.height);
10792 GLenum format = static_cast<GLenum>(c.format);
10793 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0210794 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
10795 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
10796 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10797
10798 base::ScopedClosureRunner scoped_completion_callback;
10799 if (async_upload_token) {
10800 base::Closure completion_closure =
10801 AsyncUploadTokenCompletionClosure(async_upload_token,
10802 sync_data_shm_id,
10803 sync_data_shm_offset);
10804 if (completion_closure.is_null())
10805 return error::kInvalidArguments;
10806
10807 scoped_completion_callback.Reset(completion_closure);
10808 }
[email protected]32145a92012-12-17 09:01:5910809
10810 // TODO(epenner): Move this and copies of this memory validation
10811 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610812 uint32 data_size;
10813 if (!GLES2Util::ComputeImageDataSizes(
10814 width, height, format, type, state_.unpack_alignment, &data_size,
10815 NULL, NULL)) {
10816 return error::kOutOfBounds;
10817 }
10818 const void* pixels = GetSharedMemoryAs<const void*>(
10819 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910820
10821 // All the normal glTexSubImage2D validation.
10822 error::Error error = error::kNoError;
10823 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10824 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10825 return error;
[email protected]69023942012-11-30 19:57:1610826 }
10827
[email protected]32145a92012-12-17 09:01:5910828 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4410829 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10830 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910831 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910832 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710833 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910834 return error::kNoError;
10835
10836 // Guarantee async textures are always 'cleared' as follows:
10837 // - AsyncTexImage2D can not redefine an existing texture
10838 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10839 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10840 // - Textures become immutable after an async call.
10841 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710842 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910843 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10844 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110845 LOCAL_SET_GL_ERROR(
10846 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510847 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910848 return error::kNoError;
10849 }
10850 }
10851
[email protected]5b3a8e02013-03-13 05:36:4410852 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310853 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910854 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1210855 AsyncMemoryParams mem_params(
10856 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1810857 AsyncPixelTransferDelegate* delegate =
10858 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10859 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4410860 // TODO(epenner): We may want to enforce exclusive use
10861 // of async APIs in which case this should become an error,
10862 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310863 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410864 0, 0, 0, 0, 0, 0};
10865 texture->GetLevelSize(target, level, &define_params.width,
10866 &define_params.height);
10867 texture->GetLevelType(target, level, &define_params.type,
10868 &define_params.internal_format);
10869 // Set up the async state if needed, and make the texture
10870 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1810871 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4710872 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4410873 texture->SetImmutable(true);
10874 }
10875
[email protected]896425e2013-06-12 17:27:1810876 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910877 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610878}
10879
[email protected]a00c1f742013-03-05 17:02:1610880error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10881 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10882 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10883 GLenum target = static_cast<GLenum>(c.target);
10884
10885 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110886 LOCAL_SET_GL_ERROR(
10887 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610888 return error::kNoError;
10889 }
[email protected]c986af502013-08-14 01:04:4410890 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10891 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910892 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110893 LOCAL_SET_GL_ERROR(
10894 GL_INVALID_OPERATION,
10895 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610896 return error::kNoError;
10897 }
[email protected]896425e2013-06-12 17:27:1810898 AsyncPixelTransferDelegate* delegate =
10899 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10900 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4910901 LOCAL_SET_GL_ERROR(
10902 GL_INVALID_OPERATION,
10903 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10904 return error::kNoError;
10905 }
[email protected]896425e2013-06-12 17:27:1810906 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0910907 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610908 return error::kNoError;
10909}
10910
[email protected]e3c4a9ab2014-03-31 09:07:0210911error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
10912 uint32 immediate_data_size, const cmds::WaitAllAsyncTexImage2DCHROMIUM& c) {
10913 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10914
10915 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
10916 ProcessFinishedAsyncTransfers();
10917 return error::kNoError;
10918}
10919
[email protected]91c94eb2013-10-22 10:32:5410920void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
10921 TextureRef* texture_ref) {
10922 Texture* texture = texture_ref->texture();
10923 DoDidUseTexImageIfNeeded(texture, texture->target());
10924}
10925
[email protected]828a3932014-04-02 14:43:1310926void GLES2DecoderImpl::OnOutOfMemoryError() {
10927 if (lose_context_when_out_of_memory_) {
10928 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
10929 LoseContext(GL_GUILTY_CONTEXT_RESET_ARB);
10930 }
10931}
10932
[email protected]96449d2c2009-11-25 00:01:3210933// Include the auto-generated part of this file. We split this because it means
10934// we can easily edit the non-auto generated parts right here in this file
10935// instead of having to edit some template or the code generator.
10936#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10937
10938} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510939} // namespace gpu