blob: 04a9eb25443cb2a25d52400ba714c850ea63eca6 [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>
dcastagna504d45c2015-04-06 19:30:3912#include <queue>
[email protected]94307712012-11-16 23:26:1113#include <stack>
[email protected]f39f4b3f2010-05-12 17:04:0814#include <string>
15#include <vector>
[email protected]5a6db6c2010-04-22 18:32:0616
[email protected]00eb49a2010-08-12 20:46:5717#include "base/at_exit.h"
[email protected]9d37f062011-11-22 01:24:5218#include "base/bind.h"
[email protected]e3c4a9ab2014-03-31 09:07:0219#include "base/callback_helpers.h"
[email protected]e844ae22012-01-14 03:36:2620#include "base/command_line.h"
[email protected]5aa95ac2014-08-14 15:20:5621#include "base/float_util.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"
primiano05dadf012015-01-28 13:10:3226#include "base/trace_event/trace_event.h"
27#include "base/trace_event/trace_event_synthetic_delay.h"
[email protected]d37231fa2010-04-09 21:16:0228#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3229#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2230#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3231#include "gpu/command_buffer/common/gles2_cmd_format.h"
32#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1033#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5134#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2235#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
36#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5037#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3238#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5039#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2440#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5041#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1142#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5843#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3244#include "gpu/command_buffer/service/gl_utils.h"
sievers2384f2b2014-11-18 02:10:3545#include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h"
[email protected]43410e92012-04-20 17:06:2846#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4647#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1348#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2649#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1450#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3751#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5952#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2553#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4754#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5355#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5856#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4757#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4558#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0459#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4760#include "gpu/command_buffer/service/texture_manager.h"
orglofchcad5a6742014-11-07 19:51:1261#include "gpu/command_buffer/service/valuebuffer_manager.h"
[email protected]944b62f32012-09-27 02:20:4662#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2263#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]6896d7f2014-04-28 20:24:1564#include "third_party/smhasher/src/City.h"
[email protected]5a36dc132013-07-23 23:17:5565#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3766#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2767#include "ui/gl/gl_implementation.h"
68#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2769
[email protected]e51bdf32011-11-23 22:21:4670#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:5371#include <IOSurface/IOSurfaceAPI.h>
72// Note that this must be included after gl_bindings.h to avoid conflicts.
73#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4674#endif
[email protected]de17df392010-04-23 21:09:4175
[email protected]6eb775352013-08-27 05:57:1676#if defined(OS_WIN)
77#include "base/win/win_util.h"
78#endif
79
[email protected]a7a27ace2009-12-12 00:11:2580namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3281namespace gles2 {
82
[email protected]f0d74742011-10-03 16:31:0483namespace {
[email protected]693ca512012-11-13 18:09:1384
dongseong.hwang46305b12015-03-05 18:28:0485const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
86const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
87const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
88const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
89
90const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
91 0.0f, 1.0f, 0.0f, 0.0f,
92 0.0f, 0.0f, 1.0f, 0.0f,
93 0.0f, 0.0f, 0.0f, 1.0f};
[email protected]693ca512012-11-13 18:09:1394
[email protected]448e459e2013-06-12 17:00:4195static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
96 GLint rangeMax,
97 GLint precision) {
98 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
99}
100
[email protected]8dc1bf92013-03-12 03:58:21101static void GetShaderPrecisionFormatImpl(GLenum shader_type,
102 GLenum precision_type,
dcastagna504d45c2015-04-06 19:30:39103 GLint* range, GLint* precision) {
[email protected]8dc1bf92013-03-12 03:58:21104 switch (precision_type) {
105 case GL_LOW_INT:
106 case GL_MEDIUM_INT:
107 case GL_HIGH_INT:
108 // These values are for a 32-bit twos-complement integer format.
109 range[0] = 31;
110 range[1] = 30;
111 *precision = 0;
112 break;
113 case GL_LOW_FLOAT:
114 case GL_MEDIUM_FLOAT:
115 case GL_HIGH_FLOAT:
116 // These values are for an IEEE single-precision floating-point format.
117 range[0] = 127;
118 range[1] = 127;
119 *precision = 23;
120 break;
121 default:
122 NOTREACHED();
123 break;
124 }
125
[email protected]8af4d5e2013-03-15 23:55:33126 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
127 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21128 // This function is sometimes defined even though it's really just
129 // a stub, so we need to set range and precision as if it weren't
130 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44131 // On Mac OS with some GPUs, calling this generates a
132 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
133 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21134 glGetShaderPrecisionFormat(shader_type, precision_type,
135 range, precision);
[email protected]448e459e2013-06-12 17:00:41136
137 // TODO(brianderson): Make the following official workarounds.
138
139 // Some drivers have bugs where they report the ranges as a negative number.
140 // Taking the absolute value here shouldn't hurt because negative numbers
141 // aren't expected anyway.
142 range[0] = abs(range[0]);
143 range[1] = abs(range[1]);
144
145 // If the driver reports a precision for highp float that isn't actually
146 // highp, don't pretend like it's supported because shader compilation will
147 // fail anyway.
148 if (precision_type == GL_HIGH_FLOAT &&
149 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
150 range[0] = 0;
151 range[1] = 0;
152 *precision = 0;
153 }
[email protected]8dc1bf92013-03-12 03:58:21154 }
155}
156
[email protected]d286ebbc2014-07-03 17:19:10157static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
158 switch (plane_transform) {
159 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
160 return gfx::OVERLAY_TRANSFORM_NONE;
161 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
162 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
163 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
164 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
165 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
166 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
167 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
168 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
169 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
170 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
171 default:
172 return gfx::OVERLAY_TRANSFORM_INVALID;
173 }
174}
175
[email protected]b04e24c2013-01-08 18:35:25176} // namespace
[email protected]f0d74742011-10-03 16:31:04177
[email protected]6217d392010-03-25 22:08:35178class GLES2DecoderImpl;
179
[email protected]ab09b612013-03-11 22:11:51180// Local versions of the SET_GL_ERROR macros
181#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50182 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51183#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50184 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
185 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51186#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50187 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
188 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51189#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50190 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
191 function_name)
[email protected]ab09b612013-03-11 22:11:51192#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50193 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51194#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50195 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51196#define LOCAL_PERFORMANCE_WARNING(msg) \
197 PerformanceWarning(__FILE__, __LINE__, msg)
198#define LOCAL_RENDER_WARNING(msg) \
199 RenderWarning(__FILE__, __LINE__, msg)
200
[email protected]07f54fcc2009-12-22 02:46:30201// Check that certain assumptions the code makes are true. There are places in
202// the code where shared memory is passed direclty to GL. Example, glUniformiv,
203// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
204// a few others) are 32bits. If they are not 32bits the code will have to change
205// to call those GL functions with service side memory and then copy the results
206// to shared memory, converting the sizes.
mostynb7f032092014-12-20 00:36:44207static_assert(sizeof(GLint) == sizeof(uint32), // NOLINT
208 "GLint should be the same size as uint32");
209static_assert(sizeof(GLsizei) == sizeof(uint32), // NOLINT
210 "GLsizei should be the same size as uint32");
211static_assert(sizeof(GLfloat) == sizeof(float), // NOLINT
212 "GLfloat should be the same size as float");
[email protected]07f54fcc2009-12-22 02:46:30213
[email protected]43f28f832010-02-03 02:28:48214// TODO(kbr): the use of this anonymous namespace core dumps the
215// linker on Mac OS X 10.6 when the symbol ordering file is used
216// namespace {
[email protected]96449d2c2009-11-25 00:01:32217
218// Returns the address of the first byte after a struct.
219template <typename T>
220const void* AddressAfterStruct(const T& pod) {
221 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
222}
223
[email protected]07f54fcc2009-12-22 02:46:30224// Returns the address of the frst byte after the struct or NULL if size >
225// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32226template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30227RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
228 uint32 size,
229 uint32 immediate_data_size) {
230 return (size <= immediate_data_size) ?
231 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
232 NULL;
[email protected]96449d2c2009-11-25 00:01:32233}
234
[email protected]07f54fcc2009-12-22 02:46:30235// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18236bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32237 GLuint count,
238 size_t size,
[email protected]a76b0052010-03-05 00:33:18239 unsigned int elements_per_unit,
240 uint32* dst) {
241 uint32 value;
242 if (!SafeMultiplyUint32(count, size, &value)) {
243 return false;
244 }
245 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
246 return false;
247 }
248 *dst = value;
249 return true;
[email protected]96449d2c2009-11-25 00:01:32250}
251
[email protected]258a3313f2011-10-18 20:13:57252// Return true if a character belongs to the ASCII subset as defined in
253// GLSL ES 1.0 spec section 3.1.
254static bool CharacterIsValidForGLES(unsigned char c) {
255 // Printing characters are valid except " $ ` @ \ ' DEL.
256 if (c >= 32 && c <= 126 &&
257 c != '"' &&
258 c != '$' &&
259 c != '`' &&
260 c != '@' &&
261 c != '\\' &&
262 c != '\'') {
263 return true;
264 }
265 // Horizontal tab, line feed, vertical tab, form feed, carriage return
266 // are also valid.
267 if (c >= 9 && c <= 13) {
268 return true;
269 }
270
271 return false;
272}
273
274static bool StringIsValidForGLES(const char* str) {
275 for (; *str; ++str) {
276 if (!CharacterIsValidForGLES(*str)) {
277 return false;
278 }
279 }
280 return true;
281}
282
[email protected]6217d392010-03-25 22:08:35283// This class prevents any GL errors that occur when it is in scope from
284// being reported to the client.
285class ScopedGLErrorSuppressor {
286 public:
[email protected]ab09b612013-03-11 22:11:51287 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30288 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35289 ~ScopedGLErrorSuppressor();
290 private:
[email protected]ab09b612013-03-11 22:11:51291 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30292 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35293 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
294};
295
[email protected]2b10c02d2014-01-29 16:43:02296// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35297// object goes out of scope. Also temporarily switches to using active texture
298// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02299class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35300 public:
[email protected]00c2cf92014-03-14 00:08:37301 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02302 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35303
304 private:
[email protected]ce296892013-10-24 22:04:36305 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02306 GLenum target_;
307 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35308};
309
310// Temporarily changes a decoder's bound render buffer and restore it when this
311// object goes out of scope.
312class ScopedRenderBufferBinder {
313 public:
[email protected]00c2cf92014-03-14 00:08:37314 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35315 ~ScopedRenderBufferBinder();
316
317 private:
[email protected]18e785a2013-10-09 03:29:41318 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35319 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
320};
321
322// Temporarily changes a decoder's bound frame buffer and restore it when this
323// object goes out of scope.
324class ScopedFrameBufferBinder {
325 public:
[email protected]00c2cf92014-03-14 00:08:37326 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35327 ~ScopedFrameBufferBinder();
328
329 private:
330 GLES2DecoderImpl* decoder_;
331 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
332};
333
[email protected]34ff8b0c2010-10-01 20:06:02334// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52335// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27336// if it is bound or enforce_internal_framebuffer is true. If internal is
337// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02338class ScopedResolvedFrameBufferBinder {
339 public:
[email protected]00c2cf92014-03-14 00:08:37340 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
341 bool enforce_internal_framebuffer,
342 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02343 ~ScopedResolvedFrameBufferBinder();
344
345 private:
346 GLES2DecoderImpl* decoder_;
347 bool resolve_and_bind_;
348 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
349};
350
[email protected]00c2cf92014-03-14 00:08:37351class ScopedModifyPixels {
352 public:
353 explicit ScopedModifyPixels(TextureRef* ref);
354 ~ScopedModifyPixels();
355
356 private:
357 TextureRef* ref_;
358};
359
360ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
361 if (ref_)
362 ref_->texture()->OnWillModifyPixels();
363}
364
365ScopedModifyPixels::~ScopedModifyPixels() {
366 if (ref_)
367 ref_->texture()->OnDidModifyPixels();
368}
369
370class ScopedRenderTo {
371 public:
372 explicit ScopedRenderTo(Framebuffer* framebuffer);
373 ~ScopedRenderTo();
374
375 private:
376 const Framebuffer* framebuffer_;
377};
378
379ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
380 : framebuffer_(framebuffer) {
381 if (framebuffer)
382 framebuffer_->OnWillRenderTo();
383}
384
385ScopedRenderTo::~ScopedRenderTo() {
386 if (framebuffer_)
387 framebuffer_->OnDidRenderTo();
388}
389
[email protected]6217d392010-03-25 22:08:35390// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35391class BackTexture {
[email protected]6217d392010-03-25 22:08:35392 public:
[email protected]ce296892013-10-24 22:04:36393 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35394 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35395
396 // Create a new render texture.
397 void Create();
398
399 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09400 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35401
402 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58403 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35404
405 // Destroy the render texture. This must be explicitly called before
406 // destroying this object.
407 void Destroy();
408
[email protected]97872062010-11-03 19:07:05409 // Invalidate the texture. This can be used when a context is lost and it is
410 // not possible to make it current in order to free the resource.
411 void Invalidate();
412
[email protected]6217d392010-03-25 22:08:35413 GLuint id() const {
414 return id_;
415 }
416
[email protected]d37231fa2010-04-09 21:16:02417 gfx::Size size() const {
418 return size_;
419 }
420
[email protected]6217d392010-03-25 22:08:35421 private:
[email protected]ff6493f2012-07-31 19:52:25422 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36423 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48424 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35425 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02426 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35427 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35428};
429
430// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35431class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35432 public:
[email protected]d5a28e452013-10-10 01:01:40433 explicit BackRenderbuffer(
434 RenderbufferManager* renderbuffer_manager,
435 MemoryTracker* memory_tracker,
436 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35437 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35438
439 // Create a new render buffer.
440 void Create();
441
442 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18443 bool AllocateStorage(const FeatureInfo* feature_info,
444 const gfx::Size& size,
445 GLenum format,
446 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35447
448 // Destroy the render buffer. This must be explicitly called before destroying
449 // this object.
450 void Destroy();
451
[email protected]97872062010-11-03 19:07:05452 // Invalidate the render buffer. This can be used when a context is lost and
453 // it is not possible to make it current in order to free the resource.
454 void Invalidate();
455
[email protected]6217d392010-03-25 22:08:35456 GLuint id() const {
457 return id_;
458 }
459
460 private:
[email protected]d5a28e452013-10-10 01:01:40461 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25462 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40463 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48464 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35465 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35466 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35467};
468
469// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35470class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35471 public:
[email protected]ed9f9cd2013-02-27 21:12:35472 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
473 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35474
475 // Create a new frame buffer.
476 void Create();
477
478 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35479 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35480
[email protected]b9363b22010-06-09 22:06:15481 // Attach a render buffer to a frame buffer. Note that this unbinds any
482 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35483 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35484
[email protected]6217d392010-03-25 22:08:35485 // Destroy the frame buffer. This must be explicitly called before destroying
486 // this object.
487 void Destroy();
488
[email protected]97872062010-11-03 19:07:05489 // Invalidate the frame buffer. This can be used when a context is lost and it
490 // is not possible to make it current in order to free the resource.
491 void Invalidate();
492
[email protected]6217d392010-03-25 22:08:35493 // See glCheckFramebufferStatusEXT.
494 GLenum CheckStatus();
495
496 GLuint id() const {
497 return id_;
498 }
499
500 private:
501 GLES2DecoderImpl* decoder_;
502 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35503 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35504};
[email protected]34ff8b0c2010-10-01 20:06:02505
[email protected]5a36dc132013-07-23 23:17:55506struct FenceCallback {
dcastagna504d45c2015-04-06 19:30:39507 FenceCallback()
[email protected]5a36dc132013-07-23 23:17:55508 : fence(gfx::GLFence::Create()) {
509 DCHECK(fence);
510 }
[email protected]5a36dc132013-07-23 23:17:55511 std::vector<base::Closure> callbacks;
512 scoped_ptr<gfx::GLFence> fence;
513};
514
[email protected]e3c4a9ab2014-03-31 09:07:02515class AsyncUploadTokenCompletionObserver
516 : public AsyncPixelTransferCompletionObserver {
517 public:
518 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
519 : async_upload_token_(async_upload_token) {
520 }
521
dcheng1f4d1d72014-10-21 16:21:58522 void DidComplete(const AsyncMemoryParams& mem_params) override {
dcheng6ef3c5552014-08-30 05:34:19523 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02524 void* data = mem_params.GetDataAddress();
525 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
526 sync->SetAsyncUploadToken(async_upload_token_);
527 }
528
529 private:
dcheng1f4d1d72014-10-21 16:21:58530 ~AsyncUploadTokenCompletionObserver() override {}
[email protected]e3c4a9ab2014-03-31 09:07:02531
532 uint32 async_upload_token_;
533
534 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
535};
536
[email protected]43f28f832010-02-03 02:28:48537// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32538
[email protected]efc87712014-07-09 00:22:47539// static
540const unsigned int GLES2Decoder::kDefaultStencilMask =
541 static_cast<unsigned int>(-1);
542
[email protected]ddb1e5a2010-12-13 20:10:45543bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
544 uint32* service_texture_id) {
545 return false;
546}
547
[email protected]a3ded6d2010-10-19 06:44:39548GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06549 : initialized_(false),
550 debug_(false),
zmo84c08202014-11-23 15:28:40551 log_commands_(false),
552 unsafe_es3_apis_enabled_(false) {
[email protected]96449d2c2009-11-25 00:01:32553}
554
[email protected]3916c97e2010-02-25 03:20:50555GLES2Decoder::~GLES2Decoder() {
556}
557
[email protected]cac16542014-01-15 17:53:51558void GLES2Decoder::BeginDecoding() {}
559
560void GLES2Decoder::EndDecoding() {}
561
[email protected]f39f4b3f2010-05-12 17:04:08562// This class implements GLES2Decoder so we don't have to expose all the GLES2
563// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54564class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13565 public FramebufferManager::TextureDetachObserver,
566 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08567 public:
[email protected]aa7666122011-09-02 19:45:52568 explicit GLES2DecoderImpl(ContextGroup* group);
dcheng1f4d1d72014-10-21 16:21:58569 ~GLES2DecoderImpl() override;
[email protected]f39f4b3f2010-05-12 17:04:08570
[email protected]96449d2c2009-11-25 00:01:32571 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58572 Error DoCommand(unsigned int command,
573 unsigned int arg_count,
574 const void* args) override;
[email protected]96449d2c2009-11-25 00:01:32575
dcheng1f4d1d72014-10-21 16:21:58576 error::Error DoCommands(unsigned int num_commands,
577 const void* buffer,
578 int num_entries,
579 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00580
vmiura1c2b1de2014-09-19 19:03:24581 template <bool DebugImpl>
582 error::Error DoCommandsImpl(unsigned int num_commands,
583 const void* buffer,
584 int num_entries,
585 int* entries_processed);
586
[email protected]96449d2c2009-11-25 00:01:32587 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58588 const char* GetCommandName(unsigned int command_id) const override;
[email protected]96449d2c2009-11-25 00:01:32589
590 // Overridden from GLES2Decoder.
dcheng1f4d1d72014-10-21 16:21:58591 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
592 const scoped_refptr<gfx::GLContext>& context,
593 bool offscreen,
dongseong.hwang4c04a162015-03-04 07:27:33594 const gfx::Size& offscreen_size,
dcheng1f4d1d72014-10-21 16:21:58595 const DisallowedFeatures& disallowed_features,
596 const std::vector<int32>& attribs) override;
597 void Destroy(bool have_context) override;
598 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
599 void ProduceFrontBuffer(const Mailbox& mailbox) override;
600 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39601 void UpdateParentTextureInfo();
dcheng1f4d1d72014-10-21 16:21:58602 bool MakeCurrent() override;
603 GLES2Util* GetGLES2Util() override { return &util_; }
604 gfx::GLContext* GetGLContext() override { return context_.get(); }
605 ContextGroup* GetContextGroup() override { return group_.get(); }
606 Capabilities GetCapabilities() override;
607 void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06608
dcheng1f4d1d72014-10-21 16:21:58609 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
610 void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17611 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16612 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55613 }
dcheng1f4d1d72014-10-21 16:21:58614 void RestoreActiveTextureUnitBinding(unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27615 state_.RestoreActiveTextureUnitBinding(target);
616 }
dcheng1f4d1d72014-10-21 16:21:58617 void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06618 state_.RestoreBufferBindings();
619 }
dcheng1f4d1d72014-10-21 16:21:58620 void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
621 void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06622 state_.RestoreProgramBindings();
623 }
dcheng1f4d1d72014-10-21 16:21:58624 void RestoreTextureUnitBindings(unsigned unit) const override {
[email protected]5baa86bc2014-01-16 04:33:16625 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06626 }
dcheng1f4d1d72014-10-21 16:21:58627 void RestoreFramebufferBindings() const override;
628 void RestoreRenderbufferBindings() override;
629 void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06630
dcheng1f4d1d72014-10-21 16:21:58631 void ClearAllAttributes() const override;
632 void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03633
dcheng1f4d1d72014-10-21 16:21:58634 QueryManager* GetQueryManager() override { return query_manager_.get(); }
635 VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46636 return vertex_array_manager_.get();
637 }
dcheng1f4d1d72014-10-21 16:21:58638 ImageManager* GetImageManager() override { return image_manager_.get(); }
orglofch33edd842014-12-03 05:32:15639
640 ValuebufferManager* GetValuebufferManager() override {
641 return valuebuffer_manager();
642 }
643
revemancc241eb2014-11-11 03:30:37644 bool ProcessPendingQueries(bool did_finish) override;
orglofch33edd842014-12-03 05:32:15645
dcheng1f4d1d72014-10-21 16:21:58646 bool HasMoreIdleWork() override;
647 void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48648
dcheng1f4d1d72014-10-21 16:21:58649 void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55650
dcheng1f4d1d72014-10-21 16:21:58651 void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17652 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00653
dcheng1f4d1d72014-10-21 16:21:58654 Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51655
dcheng1f4d1d72014-10-21 16:21:58656 void BeginDecoding() override;
657 void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51658
dcheng1f4d1d72014-10-21 16:21:58659 ErrorState* GetErrorState() override;
660 const ContextState* GetContextState() override { return &state_; }
[email protected]1d82e822013-04-10 21:32:32661
dcheng1f4d1d72014-10-21 16:21:58662 void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
663 void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00664
dcheng1f4d1d72014-10-21 16:21:58665 AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
666 void ResetAsyncPixelTransferManagerForTest() override;
667 void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17668 AsyncPixelTransferManager* manager) override;
dcheng1f4d1d72014-10-21 16:21:58669 void SetIgnoreCachedStateForTest(bool ignore) override;
[email protected]69a8701e2013-03-07 21:31:09670 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59671
dcheng1f4d1d72014-10-21 16:21:58672 bool GetServiceTextureId(uint32 client_texture_id,
673 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48674
dcheng1f4d1d72014-10-21 16:21:58675 uint32 GetTextureUploadCount() override;
676 base::TimeDelta GetTotalTextureUploadTime() override;
677 base::TimeDelta GetTotalProcessingCommandsTime() override;
678 void AddProcessingCommandsTime(base::TimeDelta) override;
[email protected]63b465922012-09-06 02:04:52679
[email protected]8e3e0662010-08-23 18:46:30680 // Restores the current state to the user's settings.
681 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30682
[email protected]297ca1c2011-06-20 23:08:46683 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
684 void ApplyDirtyState();
685
686 // These check the state of the currently bound framebuffer or the
687 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54688 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
689 // check with all attached and enabled color attachments.
690 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46691 bool BoundFramebufferHasDepthAttachment();
692 bool BoundFramebufferHasStencilAttachment();
693
dcheng1f4d1d72014-10-21 16:21:58694 error::ContextLostReason GetContextLostReason() override;
[email protected]38d139d2011-07-14 00:38:43695
[email protected]91c94eb2013-10-22 10:32:54696 // Overridden from FramebufferManager::TextureDetachObserver:
dcheng1f4d1d72014-10-21 16:21:58697 void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54698
[email protected]828a3932014-04-02 14:43:13699 // Overriden from ErrorStateClient.
oetuaho37cc50e2014-10-31 11:19:20700 void OnContextLostError() override;
dcheng1f4d1d72014-10-21 16:21:58701 void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13702
[email protected]8875a5f2014-06-27 08:33:47703 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
704 void EnsureRenderbufferBound();
705
[email protected]f42f05b2013-11-15 21:46:18706 // Helpers to facilitate calling into compatible extensions.
707 static void RenderbufferStorageMultisampleHelper(
708 const FeatureInfo* feature_info,
709 GLenum target,
710 GLsizei samples,
711 GLenum internal_format,
712 GLsizei width,
713 GLsizei height);
714
715 void BlitFramebufferHelper(GLint srcX0,
716 GLint srcY0,
717 GLint srcX1,
718 GLint srcY1,
719 GLint dstX0,
720 GLint dstY0,
721 GLint dstX1,
722 GLint dstY1,
723 GLbitfield mask,
724 GLenum filter);
[email protected]345ba902013-11-14 21:39:00725
[email protected]96449d2c2009-11-25 00:01:32726 private:
[email protected]70d34263c2013-01-09 00:27:45727 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02728 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35729 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35730
[email protected]c2f8c8402010-12-06 18:07:24731 // Initialize or re-initialize the shader translator.
732 bool InitializeShaderTranslator();
733
[email protected]302ce6d2011-07-07 23:28:11734 void UpdateCapabilities();
735
[email protected]ae51d192010-04-27 00:48:03736 // Helpers for the glGen and glDelete functions.
737 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
738 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
739 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
740 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
741 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
742 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
743 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
744 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
orglofchcad5a6742014-11-07 19:51:12745 bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
746 void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53747 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
748 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46749 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
750 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47751
[email protected]e3c4a9ab2014-03-31 09:07:02752 // Helper for async upload token completion notification callback.
753 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
754 uint32 sync_data_shm_id,
755 uint32 sync_data_shm_offset);
756
757
758
[email protected]70d34263c2013-01-09 00:27:45759 // Workarounds
760 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51761 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45762
[email protected]3916c97e2010-02-25 03:20:50763 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50764 BufferManager* buffer_manager() {
765 return group_->buffer_manager();
766 }
767
[email protected]a25fa872010-03-25 02:57:58768 RenderbufferManager* renderbuffer_manager() {
769 return group_->renderbuffer_manager();
770 }
771
772 FramebufferManager* framebuffer_manager() {
773 return group_->framebuffer_manager();
774 }
775
orglofchcad5a6742014-11-07 19:51:12776 ValuebufferManager* valuebuffer_manager() {
777 return group_->valuebuffer_manager();
778 }
779
[email protected]3916c97e2010-02-25 03:20:50780 ProgramManager* program_manager() {
781 return group_->program_manager();
782 }
783
784 ShaderManager* shader_manager() {
785 return group_->shader_manager();
786 }
787
[email protected]03cef9b2014-04-03 15:58:14788 ShaderTranslatorCache* shader_translator_cache() {
789 return group_->shader_translator_cache();
790 }
791
[email protected]29a4d902013-02-26 20:18:06792 const TextureManager* texture_manager() const {
793 return group_->texture_manager();
794 }
795
[email protected]3916c97e2010-02-25 03:20:50796 TextureManager* texture_manager() {
797 return group_->texture_manager();
798 }
799
[email protected]78b514b2012-05-01 21:50:59800 MailboxManager* mailbox_manager() {
801 return group_->mailbox_manager();
802 }
803
[email protected]b63f1d62014-07-18 15:40:59804 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37805
[email protected]944b62f32012-09-27 02:20:46806 VertexArrayManager* vertex_array_manager() {
807 return vertex_array_manager_.get();
808 }
809
[email protected]7989c9e2013-01-23 06:39:26810 MemoryTracker* memory_tracker() {
811 return group_->memory_tracker();
812 }
813
814 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
815 MemoryTracker* tracker = memory_tracker();
816 if (tracker) {
817 return tracker->EnsureGPUMemoryAvailable(estimated_size);
818 }
819 return true;
820 }
821
[email protected]34ff8b0c2010-10-01 20:06:02822 bool IsOffscreenBufferMultisampled() const {
823 return offscreen_target_samples_ > 1;
824 }
825
[email protected]ed9f9cd2013-02-27 21:12:35826 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49827 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03828 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35829 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47830 }
831
832 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49833 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07834 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47835 }
836
837 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35838 void RemoveTexture(GLuint client_id) {
839 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50840 }
[email protected]a93bb842010-02-16 23:03:47841
[email protected]d37231fa2010-04-09 21:16:02842 // Get the size (in pixels) of the currently bound frame buffer (either FBO
843 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30844 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02845
[email protected]9edc6b22010-12-23 02:00:26846 // Get the format of the currently bound frame buffer (either FBO or regular
847 // back buffer)
[email protected]68586372013-12-11 01:27:59848 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26849 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46850 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26851
[email protected]a93bb842010-02-16 23:03:47852 // Wrapper for CompressedTexImage2D commands.
853 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37854 GLenum target,
855 GLint level,
856 GLenum internal_format,
857 GLsizei width,
858 GLsizei height,
859 GLint border,
860 GLsizei image_size,
861 const void* data);
[email protected]a93bb842010-02-16 23:03:47862
[email protected]cadde4a2010-07-31 17:10:43863 // Wrapper for CompressedTexSubImage2D.
864 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37865 GLenum target,
866 GLint level,
867 GLint xoffset,
868 GLint yoffset,
869 GLsizei width,
870 GLsizei height,
871 GLenum format,
872 GLsizei imageSize,
873 const void * data);
[email protected]cadde4a2010-07-31 17:10:43874
875 // Wrapper for CopyTexImage2D.
876 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37877 GLenum target,
878 GLint level,
879 GLenum internal_format,
880 GLint x,
881 GLint y,
882 GLsizei width,
883 GLsizei height,
884 GLint border);
[email protected]cadde4a2010-07-31 17:10:43885
[email protected]6d792ee12013-05-15 00:40:56886 // Wrapper for SwapBuffers.
887 void DoSwapBuffers();
888
bajones2345c1f2014-12-09 04:45:51889 // Wrapper for SwapInterval.
890 void DoSwapInterval(int interval);
891
[email protected]cadde4a2010-07-31 17:10:43892 // Wrapper for CopyTexSubImage2D.
893 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37894 GLenum target,
895 GLint level,
896 GLint xoffset,
897 GLint yoffset,
898 GLint x,
899 GLint y,
900 GLsizei width,
901 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43902
[email protected]f598f422012-12-07 08:30:03903 // Validation for TexSubImage2D.
904 bool ValidateTexSubImage2D(
905 error::Error* error,
906 const char* function_name,
907 GLenum target,
908 GLint level,
909 GLint xoffset,
910 GLint yoffset,
911 GLsizei width,
912 GLsizei height,
913 GLenum format,
914 GLenum type,
915 const void * data);
916
[email protected]cadde4a2010-07-31 17:10:43917 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03918 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37919 GLenum target,
920 GLint level,
921 GLint xoffset,
922 GLint yoffset,
923 GLsizei width,
924 GLsizei height,
925 GLenum format,
926 GLenum type,
927 const void * data);
[email protected]cadde4a2010-07-31 17:10:43928
[email protected]32145a92012-12-17 09:01:59929 // Extra validation for async tex(Sub)Image2D.
930 bool ValidateAsyncTransfer(
931 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47932 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59933 GLenum target,
934 GLint level,
935 const void * data);
936
[email protected]e51bdf32011-11-23 22:21:46937 // Wrapper for TexImageIOSurface2DCHROMIUM.
938 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37939 GLenum target,
940 GLsizei width,
941 GLsizei height,
942 GLuint io_surface_id,
943 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46944
dongseong.hwang46305b12015-03-05 18:28:04945 void DoCopyTextureCHROMIUM(GLenum target,
946 GLuint source_id,
947 GLuint dest_id,
948 GLenum internal_format,
949 GLenum dest_type);
950
951 void DoCopySubTextureCHROMIUM(GLenum target,
952 GLuint source_id,
953 GLuint dest_id,
954 GLint xoffset,
955 GLint yoffset);
[email protected]43410e92012-04-20 17:06:28956
[email protected]97dc7cbe2011-12-06 17:26:17957 // Wrapper for TexStorage2DEXT.
958 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37959 GLenum target,
960 GLint levels,
961 GLenum internal_format,
962 GLsizei width,
963 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17964
[email protected]78b514b2012-05-01 21:50:59965 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22966 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
967 const GLbyte* key);
968 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
969 GLenum target, const GLbyte* data);
970
bajonesd8388be02015-04-04 00:15:43971 void EnsureTextureForClientId(GLenum target, GLuint client_id);
[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
orglofchcad5a6742014-11-07 19:51:12976 bool DoIsValuebufferCHROMIUM(GLuint client_id);
977 void DoBindValueBufferCHROMIUM(GLenum target, GLuint valuebuffer);
978 void DoSubscribeValueCHROMIUM(GLenum target, GLenum subscription);
979 void DoPopulateSubscribedValuesCHROMIUM(GLenum target);
980 void DoUniformValueBufferCHROMIUM(GLint location,
981 GLenum target,
982 GLenum subscription);
983
[email protected]09d50362012-10-18 20:54:37984 void DoBindTexImage2DCHROMIUM(
985 GLenum target,
986 GLint image_id);
987 void DoReleaseTexImage2DCHROMIUM(
988 GLenum target,
989 GLint image_id);
990
[email protected]94307712012-11-16 23:26:11991 void DoTraceEndCHROMIUM(void);
992
[email protected]2f143d482013-03-14 18:04:49993 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
994
[email protected]a6a09f852014-05-23 13:05:03995 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
996
kkinnunen337d59632014-08-26 10:19:57997 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
998 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
999
[email protected]ed9f9cd2013-02-27 21:12:351000 // Creates a Program for the given program.
1001 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:571002 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:351003 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471004 }
1005
[email protected]07f54fcc2009-12-22 02:46:301006 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351007 Program* GetProgram(GLuint client_id) {
1008 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:461009 }
[email protected]07f54fcc2009-12-22 02:46:301010
[email protected]cae20172012-12-07 00:06:191011#if defined(NDEBUG)
1012 void LogClientServiceMapping(
1013 const char* /* function_name */,
1014 GLuint /* client_id */,
1015 GLuint /* service_id */) {
1016 }
1017 template<typename T>
1018 void LogClientServiceForInfo(
1019 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
1020 }
1021#else
1022 void LogClientServiceMapping(
1023 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:261024 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:471025 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1026 << ": client_id = " << client_id
1027 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:261028 }
[email protected]cae20172012-12-07 00:06:191029 }
1030 template<typename T>
1031 void LogClientServiceForInfo(
1032 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:261033 if (info) {
[email protected]cae20172012-12-07 00:06:191034 LogClientServiceMapping(function_name, client_id, info->service_id());
1035 }
1036 }
1037#endif
1038
[email protected]6b8cf1a2010-05-06 16:13:581039 // Gets the program info for the given program. If it's not a program
1040 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351041 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581042 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421043 Program* program = GetProgram(client_id);
1044 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351045 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511046 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431047 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581048 } else {
[email protected]ab09b612013-03-11 22:11:511049 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581050 }
1051 }
[email protected]df37b9932013-03-08 05:21:421052 LogClientServiceForInfo(program, client_id, function_name);
1053 return program;
[email protected]6b8cf1a2010-05-06 16:13:581054 }
1055
1056
[email protected]ed9f9cd2013-02-27 21:12:351057 // Creates a Shader for the given shader.
1058 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571059 GLuint client_id,
1060 GLuint service_id,
1061 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351062 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571063 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311064 }
1065
1066 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351067 Shader* GetShader(GLuint client_id) {
1068 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311069 }
1070
[email protected]6b8cf1a2010-05-06 16:13:581071 // Gets the shader info for the given shader. If it's not a shader generates a
1072 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351073 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581074 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421075 Shader* shader = GetShader(client_id);
1076 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351077 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511078 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431079 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581080 } else {
[email protected]ab09b612013-03-11 22:11:511081 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431082 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581083 }
1084 }
[email protected]df37b9932013-03-08 05:21:421085 LogClientServiceForInfo(shader, client_id, function_name);
1086 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581087 }
1088
[email protected]a93bb842010-02-16 23:03:471089 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351090 void CreateBuffer(GLuint client_id, GLuint service_id) {
1091 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471092 }
1093
[email protected]07f54fcc2009-12-22 02:46:301094 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211095 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071096 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1097 return buffer;
[email protected]1d32bc82010-01-13 22:06:461098 }
[email protected]07f54fcc2009-12-22 02:46:301099
[email protected]a93bb842010-02-16 23:03:471100 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1101 // on glDeleteBuffers so we can make sure the user does not try to render
1102 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351103 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471104
[email protected]a25fa872010-03-25 02:57:581105 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351106 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1107 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581108 }
1109
1110 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061111 Framebuffer* GetFramebuffer(GLuint client_id) {
1112 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581113 }
1114
1115 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351116 void RemoveFramebuffer(GLuint client_id) {
1117 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581118 }
1119
1120 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351121 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1122 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031123 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581124 }
1125
1126 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271127 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1128 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581129 }
1130
1131 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351132 void RemoveRenderbuffer(GLuint client_id) {
1133 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581134 }
1135
orglofchcad5a6742014-11-07 19:51:121136 // Creates a valuebuffer info for the given valuebuffer.
1137 void CreateValuebuffer(GLuint client_id) {
1138 return valuebuffer_manager()->CreateValuebuffer(client_id);
1139 }
1140
1141 // Gets the valuebuffer info for a given valuebuffer.
1142 Valuebuffer* GetValuebuffer(GLuint client_id) {
1143 return valuebuffer_manager()->GetValuebuffer(client_id);
1144 }
1145
1146 // Removes the valuebuffer info for the given valuebuffer.
1147 void RemoveValuebuffer(GLuint client_id) {
1148 valuebuffer_manager()->RemoveValuebuffer(client_id);
1149 }
1150
[email protected]944b62f32012-09-27 02:20:461151 // Gets the vertex attrib manager for the given vertex array.
1152 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1153 VertexAttribManager* info =
1154 vertex_array_manager()->GetVertexAttribManager(client_id);
1155 return info;
1156 }
1157
1158 // Removes the vertex attrib manager for the given vertex array.
1159 void RemoveVertexAttribManager(GLuint client_id) {
1160 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1161 }
1162
1163 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481164 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1165 GLuint client_id,
1166 GLuint service_id,
1167 bool client_visible) {
1168 return vertex_array_manager()->CreateVertexAttribManager(
1169 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461170 }
1171
[email protected]258a3313f2011-10-18 20:13:571172 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331173 void DoBindUniformLocationCHROMIUM(
1174 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571175
[email protected]558847a2010-03-24 07:02:541176 error::Error GetAttribLocationHelper(
zmo4a16ff992015-02-05 22:18:411177 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1178 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541179
1180 error::Error GetUniformLocationHelper(
zmo4a16ff992015-02-05 22:18:411181 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1182 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541183
zmo5393fb52015-01-27 01:50:481184 error::Error GetFragDataLocationHelper(
zmo4a16ff992015-02-05 22:18:411185 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1186 const std::string& name_str);
zmo5393fb52015-01-27 01:50:481187
zmo1bb3d1d2015-01-21 20:29:431188 // Wrapper for glShaderSource.
1189 void DoShaderSource(
1190 GLuint client_id, GLsizei count, const char** data, const GLint* length);
[email protected]07f54fcc2009-12-22 02:46:301191
zmo38923562015-01-29 20:17:391192 // Wrapper for glTransformFeedbackVaryings.
1193 void DoTransformFeedbackVaryings(
1194 GLuint client_program_id, GLsizei count, const char* const* varyings,
1195 GLenum buffer_mode);
1196
[email protected]0d6bfdc2011-11-02 01:32:201197 // Clear any textures used by the current program.
1198 bool ClearUnclearedTextures();
1199
[email protected]0d6bfdc2011-11-02 01:32:201200 // Clears any uncleared attachments attached to the given frame buffer.
1201 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061202 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281203
[email protected]0d6bfdc2011-11-02 01:32:201204 // overridden from GLES2Decoder
boliu45dc77a2015-02-25 23:26:311205 bool ClearLevel(Texture* texture,
dcheng1f4d1d72014-10-21 16:21:581206 unsigned target,
1207 int level,
1208 unsigned internal_format,
1209 unsigned format,
1210 unsigned type,
1211 int width,
1212 int height,
1213 bool is_texture_immutable) override;
[email protected]0d6bfdc2011-11-02 01:32:201214
[email protected]c007aa02010-09-02 22:22:401215 // Restore all GL state that affects clearing.
1216 void RestoreClearState();
1217
[email protected]3a2e7c7b2010-08-06 01:12:281218 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461219 // Returns: true if glEnable/glDisable should actually be called.
1220 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281221
[email protected]0d6bfdc2011-11-02 01:32:201222 // Check that the currently bound framebuffers are valid.
1223 // Generates GL error if not.
1224 bool CheckBoundFramebuffersValid(const char* func_name);
1225
[email protected]2ea5950d2014-07-09 18:20:341226 // Check that the currently bound read framebuffer has a color image
1227 // attached. Generates GL error if not.
1228 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1229
zmo383512cf2014-10-14 00:11:001230 // Check that the currently bound read framebuffer's color image
1231 // isn't the target texture of the glCopyTex{Sub}Image2D.
1232 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1233
[email protected]0d6bfdc2011-11-02 01:32:201234 // Check if a framebuffer meets our requirements.
1235 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351236 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201237 GLenum target,
1238 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271239
orglofchcad5a6742014-11-07 19:51:121240 // Check if the current valuebuffer exists and is valid. If not generates
1241 // the appropriate GL error. Returns true if the current valuebuffer is in
1242 // a usable state.
1243 bool CheckCurrentValuebuffer(const char* function_name);
1244
1245 // Check if the current valuebuffer exists and is valiud and that the
1246 // value buffer is actually subscribed to the given subscription
1247 bool CheckCurrentValuebufferForSubscription(GLenum subscription,
1248 const char* function_name);
1249
1250 // Check if the location can be used for the given subscription target. If not
1251 // generates the appropriate GL error. Returns true if the location is usable
1252 bool CheckSubscriptionTarget(GLint location,
1253 GLenum subscription,
1254 const char* function_name);
1255
[email protected]939e7362010-05-13 20:49:101256 // Checks if the current program exists and is valid. If not generates the
1257 // appropriate GL error. Returns true if the current program is in a usable
1258 // state.
1259 bool CheckCurrentProgram(const char* function_name);
1260
1261 // Checks if the current program exists and is valid and that location is not
1262 // -1. If the current program is not valid generates the appropriate GL
1263 // error. Returns true if the current program is in a usable state and
1264 // location is not -1.
1265 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1266
zmof9a81360f2014-10-17 00:06:141267 // Checks if the current program samples a texture that is also the color
1268 // image of the current bound framebuffer, i.e., the source and destination
1269 // of the draw operation are the same.
1270 bool CheckDrawingFeedbackLoops();
1271
orglofchcad5a6742014-11-07 19:51:121272 // Checks if |api_type| is valid for the given uniform
1273 // If the api type is not valid generates the appropriate GL
1274 // error. Returns true if |api_type| is valid for the uniform
1275 bool CheckUniformForApiType(const Program::UniformInfo* info,
1276 const char* function_name,
1277 Program::UniformApiType api_type);
1278
[email protected]939e7362010-05-13 20:49:101279 // Gets the type of a uniform for a location in the current program. Sets GL
1280 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361281 // program is valid and the location exists. Adjusts count so it
1282 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131283 bool PrepForSetUniformByLocation(GLint fake_location,
1284 const char* function_name,
1285 Program::UniformApiType api_type,
1286 GLint* real_location,
1287 GLenum* type,
1288 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101289
[email protected]b177ae22011-11-01 03:29:111290 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021291 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111292
[email protected]b273e432010-04-12 17:23:581293 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1294 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1295
[email protected]ac77603c72013-03-08 13:52:061296 // Helper for glGetVertexAttrib
1297 void GetVertexAttribHelper(
1298 const VertexAttrib* attrib, GLenum pname, GLint* param);
1299
[email protected]3916c97e2010-02-25 03:20:501300 // Wrapper for glActiveTexture
1301 void DoActiveTexture(GLenum texture_unit);
1302
[email protected]ae51d192010-04-27 00:48:031303 // Wrapper for glAttachShader
1304 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1305
[email protected]96449d2c2009-11-25 00:01:321306 // Wrapper for glBindBuffer since we need to track the current targets.
1307 void DoBindBuffer(GLenum target, GLuint buffer);
1308
[email protected]86093972010-03-11 00:13:561309 // Wrapper for glBindFramebuffer since we need to track the current targets.
1310 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1311
1312 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1313 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1314
[email protected]a93bb842010-02-16 23:03:471315 // Wrapper for glBindTexture since we need to track the current targets.
1316 void DoBindTexture(GLenum target, GLuint texture);
1317
[email protected]944b62f32012-09-27 02:20:461318 // Wrapper for glBindVertexArrayOES
1319 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571320 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461321
[email protected]49cabed2013-11-13 18:15:181322 // Wrapper for glBlitFramebufferCHROMIUM.
1323 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301324 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1325 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1326 GLbitfield mask, GLenum filter);
1327
[email protected]36cef8ce2010-03-16 07:34:451328 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111329 void DoBufferSubData(
1330 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1331
[email protected]36cef8ce2010-03-16 07:34:451332 // Wrapper for glCheckFramebufferStatus
1333 GLenum DoCheckFramebufferStatus(GLenum target);
1334
[email protected]3a03a8f2011-03-19 00:51:271335 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081336 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271337
[email protected]88a61bf2012-10-27 13:00:421338 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421339 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251340 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281341
[email protected]45bf5152010-02-12 00:11:311342 // Wrapper for glCompileShader.
1343 void DoCompileShader(GLuint shader);
1344
[email protected]ae51d192010-04-27 00:48:031345 // Wrapper for glDetachShader
1346 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1347
[email protected]3a2e7c7b2010-08-06 01:12:281348 // Wrapper for glDisable
1349 void DoDisable(GLenum cap);
1350
[email protected]07f54fcc2009-12-22 02:46:301351 // Wrapper for glDisableVertexAttribArray.
1352 void DoDisableVertexAttribArray(GLuint index);
1353
[email protected]60f22d32012-12-12 00:31:581354 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1355 // attachments.
1356 void DoDiscardFramebufferEXT(GLenum target,
1357 GLsizei numAttachments,
1358 const GLenum* attachments);
1359
[email protected]3a2e7c7b2010-08-06 01:12:281360 // Wrapper for glEnable
1361 void DoEnable(GLenum cap);
1362
[email protected]07f54fcc2009-12-22 02:46:301363 // Wrapper for glEnableVertexAttribArray.
1364 void DoEnableVertexAttribArray(GLuint index);
1365
[email protected]882ba1e22012-03-08 19:02:531366 // Wrapper for glFinish.
1367 void DoFinish();
1368
1369 // Wrapper for glFlush.
1370 void DoFlush();
1371
[email protected]36cef8ce2010-03-16 07:34:451372 // Wrapper for glFramebufferRenderbufffer.
1373 void DoFramebufferRenderbuffer(
1374 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1375 GLuint renderbuffer);
1376
1377 // Wrapper for glFramebufferTexture2D.
1378 void DoFramebufferTexture2D(
1379 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1380 GLint level);
1381
[email protected]7d3c36e2013-07-12 14:13:161382 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1383 void DoFramebufferTexture2DMultisample(
1384 GLenum target, GLenum attachment, GLenum textarget,
1385 GLuint texture, GLint level, GLsizei samples);
1386
1387 // Common implementation for both DoFramebufferTexture2D wrappers.
1388 void DoFramebufferTexture2DCommon(const char* name,
1389 GLenum target, GLenum attachment, GLenum textarget,
1390 GLuint texture, GLint level, GLsizei samples);
1391
zmo84c08202014-11-23 15:28:401392 // Wrapper for glFramebufferTextureLayer.
1393 void DoFramebufferTextureLayer(
1394 GLenum target, GLenum attachment, GLuint texture, GLint level,
1395 GLint layer);
1396
[email protected]a93bb842010-02-16 23:03:471397 // Wrapper for glGenerateMipmap
1398 void DoGenerateMipmap(GLenum target);
1399
[email protected]7d3c36e2013-07-12 14:13:161400 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1401 // to account for different pname values defined in different extension
1402 // variants.
1403 GLenum AdjustGetPname(GLenum pname);
1404
[email protected]b273e432010-04-12 17:23:581405 // Wrapper for DoGetBooleanv.
1406 void DoGetBooleanv(GLenum pname, GLboolean* params);
1407
1408 // Wrapper for DoGetFloatv.
1409 void DoGetFloatv(GLenum pname, GLfloat* params);
1410
[email protected]36cef8ce2010-03-16 07:34:451411 // Wrapper for glGetFramebufferAttachmentParameteriv.
1412 void DoGetFramebufferAttachmentParameteriv(
1413 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1414
zmo8ac3bab2015-04-18 02:30:581415 // Wrapper for glGetInteger64v.
1416 void DoGetInteger64v(GLenum pname, GLint64* params);
1417
[email protected]a0c3e972010-04-21 00:49:131418 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581419 void DoGetIntegerv(GLenum pname, GLint* params);
1420
[email protected]29a9eb52010-04-13 09:04:231421 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061422 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231423 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1424
[email protected]17cfbe0e2013-03-07 01:26:081425 // Wrapper for glGetBufferParameteriv.
1426 void DoGetBufferParameteriv(
1427 GLenum target, GLenum pname, GLint* params);
1428
[email protected]a0c3e972010-04-21 00:49:131429 // Wrapper for glGetProgramiv.
1430 void DoGetProgramiv(
1431 GLuint program_id, GLenum pname, GLint* params);
1432
[email protected]36cef8ce2010-03-16 07:34:451433 // Wrapper for glRenderbufferParameteriv.
1434 void DoGetRenderbufferParameteriv(
1435 GLenum target, GLenum pname, GLint* params);
1436
[email protected]ddd968b82010-03-02 00:44:291437 // Wrapper for glGetShaderiv
1438 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1439
[email protected]4c6f5462014-03-05 00:26:561440 // Wrappers for glGetTexParameter.
1441 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1442 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1443 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1444
[email protected]b1122982010-05-17 23:04:241445 // Wrappers for glGetVertexAttrib.
1446 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1447 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1448
[email protected]1958e0e2010-04-22 05:17:151449 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241450 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151451 bool DoIsBuffer(GLuint client_id);
1452 bool DoIsFramebuffer(GLuint client_id);
1453 bool DoIsProgram(GLuint client_id);
1454 bool DoIsRenderbuffer(GLuint client_id);
1455 bool DoIsShader(GLuint client_id);
1456 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461457 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151458
[email protected]07f54fcc2009-12-22 02:46:301459 // Wrapper for glLinkProgram
1460 void DoLinkProgram(GLuint program);
1461
[email protected]36cef8ce2010-03-16 07:34:451462 // Wrapper for glRenderbufferStorage.
1463 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031464 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451465
[email protected]49cabed2013-11-13 18:15:181466 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1467 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301468 GLenum target, GLsizei samples, GLenum internalformat,
1469 GLsizei width, GLsizei height);
1470
[email protected]49cabed2013-11-13 18:15:181471 // Handler for glRenderbufferStorageMultisampleEXT
1472 // (multisampled_render_to_texture).
1473 void DoRenderbufferStorageMultisampleEXT(
1474 GLenum target, GLsizei samples, GLenum internalformat,
1475 GLsizei width, GLsizei height);
1476
1477 // Common validation for multisample extensions.
1478 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1479 GLenum internalformat,
1480 GLsizei width,
1481 GLsizei height);
1482
[email protected]4a4c18b2013-09-13 22:50:101483 // Verifies that the currently bound multisample renderbuffer is valid
1484 // Very slow! Only done on platforms with driver bugs that return invalid
1485 // buffers under memory pressure
1486 bool VerifyMultisampleRenderbufferIntegrity(
1487 GLuint renderbuffer, GLenum format);
1488
[email protected]b273e432010-04-12 17:23:581489 // Wrapper for glReleaseShaderCompiler.
1490 void DoReleaseShaderCompiler() { }
1491
zmobcb3fdd62014-12-11 00:49:031492 // Wrappers for glSamplerParameter*v functions.
1493 void DoSamplerParameterfv(
1494 GLuint sampler, GLenum pname, const GLfloat* params);
1495 void DoSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* params);
1496
[email protected]3916c97e2010-02-25 03:20:501497 // Wrappers for glTexParameter functions.
1498 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1499 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1500 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1501 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1502
1503 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1504 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121505 void DoUniform1i(GLint fake_location, GLint v0);
1506 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1507 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1508 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1509 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101510
1511 // Wrappers for glUniformfv because some drivers don't correctly accept
1512 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121513 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1514 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1515 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1516 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501517
[email protected]43c2f1f2011-03-25 18:35:361518 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121519 GLint fake_location, GLsizei count, GLboolean transpose,
1520 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361521 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121522 GLint fake_location, GLsizei count, GLboolean transpose,
1523 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361524 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121525 GLint fake_location, GLsizei count, GLboolean transpose,
1526 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361527
[email protected]af6380962012-11-29 23:24:131528 bool SetVertexAttribValue(
1529 const char* function_name, GLuint index, const GLfloat* value);
1530
[email protected]b1122982010-05-17 23:04:241531 // Wrappers for glVertexAttrib??
1532 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1533 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1534 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1535 void DoVertexAttrib4f(
1536 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1537 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1538 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1539 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1540 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1541
[email protected]43410e92012-04-20 17:06:281542 // Wrapper for glViewport
1543 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1544
[email protected]07f54fcc2009-12-22 02:46:301545 // Wrapper for glUseProgram
1546 void DoUseProgram(GLuint program);
1547
[email protected]ae51d192010-04-27 00:48:031548 // Wrapper for glValidateProgram.
1549 void DoValidateProgram(GLuint program_client_id);
1550
[email protected]d2a0e1a2012-08-12 02:25:011551 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1552 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1553 void DoPopGroupMarkerEXT(void);
1554
[email protected]4e8a5b122010-05-08 22:00:101555 // Gets the number of values that will be returned by glGetXXX. Returns
1556 // false if pname is unknown.
1557 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1558
[email protected]07f54fcc2009-12-22 02:46:301559 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431560 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101561 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1562 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301563
[email protected]c13e1da62011-09-09 21:48:301564 // Returns true if successful, simulated will be true if attrib0 was
1565 // simulated.
[email protected]c6aef902012-02-14 03:31:421566 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431567 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231568 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241569
[email protected]91c94eb2013-10-22 10:32:541570 // If an image is bound to texture, this will call Will/DidUseTexImage
1571 // if needed.
1572 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1573 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1574
1575 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111576 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541577 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501578
[email protected]8fbedc02010-11-18 18:43:401579 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421580 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431581 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421582 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401583 void RestoreStateForSimulatedFixedAttribs();
1584
[email protected]c6aef902012-02-14 03:31:421585 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101586 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421587 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431588 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421589 bool instanced, GLenum mode, GLint first, GLsizei count,
1590 GLsizei primcount);
1591 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431592 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421593 bool instanced, GLenum mode, GLsizei count, GLenum type,
1594 int32 offset, GLsizei primcount);
1595
[email protected]61eeb33f2011-07-26 15:30:311596 GLenum GetBindTargetForSamplerType(GLenum type) {
1597 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461598 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1599 switch (type) {
1600 case GL_SAMPLER_2D:
1601 return GL_TEXTURE_2D;
1602 case GL_SAMPLER_CUBE:
1603 return GL_TEXTURE_CUBE_MAP;
1604 case GL_SAMPLER_EXTERNAL_OES:
1605 return GL_TEXTURE_EXTERNAL_OES;
1606 case GL_SAMPLER_2D_RECT_ARB:
1607 return GL_TEXTURE_RECTANGLE_ARB;
1608 }
1609
1610 NOTREACHED();
1611 return 0;
[email protected]61eeb33f2011-07-26 15:30:311612 }
1613
[email protected]8e3e0662010-08-23 18:46:301614 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061615 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1616 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301617 switch (target) {
1618 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451619 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341620 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301621 break;
[email protected]ebfb73c2012-08-15 02:37:451622 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341623 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301624 break;
1625 default:
1626 NOTREACHED();
1627 break;
1628 }
[email protected]4d8f0dd2013-03-09 14:37:061629 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301630 }
1631
[email protected]ed9f9cd2013-02-27 21:12:351632 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201633 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271634 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201635 switch (target) {
1636 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111637 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201638 break;
1639 default:
1640 NOTREACHED();
1641 break;
1642 }
[email protected]ee2a79c32013-03-10 03:50:271643 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201644 }
1645
[email protected]f7b85372010-02-03 01:11:371646 // Validates the program and location for a glGetUniform call and returns
1647 // a SizeResult setup to receive the result. Returns true if glGetUniform
1648 // should be called.
vmiura181c74002015-03-20 01:32:511649 bool GetUniformSetup(GLuint program,
1650 GLint fake_location,
1651 uint32 shm_id,
1652 uint32 shm_offset,
1653 error::Error* error,
1654 GLint* real_location,
1655 GLuint* service_id,
1656 void** result,
1657 GLenum* result_type,
1658 GLsizei* result_size);
[email protected]f7b85372010-02-03 01:11:371659
jbauman7a059312014-10-16 19:30:541660 void MaybeExitOnContextLost();
dcheng1f4d1d72014-10-21 16:21:581661 bool WasContextLost() override;
1662 bool WasContextLostByRobustnessExtension() override;
1663 void LoseContext(uint32 reset_status) override;
[email protected]38d139d2011-07-14 00:38:431664
[email protected]e51bdf32011-11-23 22:21:461665#if defined(OS_MACOSX)
1666 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1667#endif
1668
[email protected]ad84a3a2012-06-08 21:42:431669 bool ValidateCompressedTexDimensions(
1670 const char* function_name,
1671 GLint level, GLsizei width, GLsizei height, GLenum format);
1672 bool ValidateCompressedTexFuncData(
1673 const char* function_name,
1674 GLsizei width, GLsizei height, GLenum format, size_t size);
1675 bool ValidateCompressedTexSubDimensions(
1676 const char* function_name,
1677 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1678 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351679 Texture* texture);
dongseong.hwang46305b12015-03-05 18:28:041680 bool ValidateCopyTextureCHROMIUM(const char* function_name,
1681 GLenum target,
1682 TextureRef* source_texture_ref,
1683 TextureRef* dest_texture_ref,
1684 GLenum dest_internal_format);
[email protected]ad84a3a2012-06-08 21:42:431685
[email protected]ab09b612013-03-11 22:11:511686 void RenderWarning(const char* filename, int line, const std::string& msg);
1687 void PerformanceWarning(
1688 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011689
[email protected]62e155e2012-10-23 22:43:151690 const FeatureInfo::FeatureFlags& features() const {
1691 return feature_info_->feature_flags();
1692 }
1693
1694 const FeatureInfo::Workarounds& workarounds() const {
1695 return feature_info_->workarounds();
1696 }
1697
[email protected]a7266a92012-06-28 02:11:081698 bool ShouldDeferDraws() {
1699 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341700 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081701 surface_->DeferDraws();
1702 }
1703
[email protected]09e17272012-11-30 10:30:441704 bool ShouldDeferReads() {
1705 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341706 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441707 surface_->DeferDraws();
1708 }
1709
dongseong.hwange1cb2aa2015-02-11 09:33:331710 bool IsRobustnessSupported() {
1711 return has_robustness_extension_ &&
1712 context_->WasAllocatedUsingRobustnessExtension();
1713 }
1714
[email protected]c76fe672013-12-13 23:30:221715 error::Error WillAccessBoundFramebufferForDraw() {
1716 if (ShouldDeferDraws())
1717 return error::kDeferCommandUntilLater;
1718 if (!offscreen_target_frame_buffer_.get() &&
1719 !framebuffer_state_.bound_draw_framebuffer.get() &&
1720 !surface_->SetBackbufferAllocation(true))
1721 return error::kLostContext;
1722 return error::kNoError;
1723 }
1724
1725 error::Error WillAccessBoundFramebufferForRead() {
1726 if (ShouldDeferReads())
1727 return error::kDeferCommandUntilLater;
1728 if (!offscreen_target_frame_buffer_.get() &&
1729 !framebuffer_state_.bound_read_framebuffer.get() &&
1730 !surface_->SetBackbufferAllocation(true))
1731 return error::kLostContext;
1732 return error::kNoError;
1733 }
1734
vmiura8266ca72014-09-09 21:37:001735 // Set remaining commands to process to 0 to force DoCommands to return
1736 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1737 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1738
[email protected]5a36dc132013-07-23 23:17:551739 void ProcessPendingReadPixels();
1740 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1741
[email protected]96449d2c2009-11-25 00:01:321742 // Generate a member function prototype for each command in an automated and
1743 // typesafe way.
vmiuracd108592014-09-08 14:36:341744#define GLES2_CMD_OP(name) \
1745 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321746
1747 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1748
1749 #undef GLES2_CMD_OP
1750
[email protected]2f2d7042010-04-14 21:45:581751 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381752 scoped_refptr<gfx::GLSurface> surface_;
1753 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021754
[email protected]a3ded6d2010-10-19 06:44:391755 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351756 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391757
[email protected]1d82e822013-04-10 21:32:321758 DebugMarkerManager debug_marker_manager_;
1759 Logger logger_;
1760
[email protected]e259eb412012-10-13 05:47:241761 // All the state for this context.
1762 ContextState state_;
1763
[email protected]34ff8b0c2010-10-01 20:06:021764 // Current width and height of the offscreen frame buffer.
1765 gfx::Size offscreen_size_;
1766
[email protected]96449d2c2009-11-25 00:01:321767 // Util to help with GL.
1768 GLES2Util util_;
1769
[email protected]43410e92012-04-20 17:06:281770 // unpack flip y as last set by glPixelStorei
1771 bool unpack_flip_y_;
1772
[email protected]6c75c712012-06-19 15:43:171773 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281774 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171775 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281776
[email protected]b1122982010-05-17 23:04:241777 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1778 GLuint attrib_0_buffer_id_;
1779
1780 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131781 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241782
[email protected]fc753442011-02-04 19:49:491783 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1784 bool attrib_0_buffer_matches_value_;
1785
[email protected]b1122982010-05-17 23:04:241786 // The size of attrib 0.
1787 GLsizei attrib_0_size_;
1788
[email protected]8fbedc02010-11-18 18:43:401789 // The buffer used to simulate GL_FIXED attribs.
1790 GLuint fixed_attrib_buffer_id_;
1791
1792 // The size of fiixed attrib buffer.
1793 GLsizei fixed_attrib_buffer_size_;
1794
[email protected]b9363b22010-06-09 22:06:151795 // The offscreen frame buffer that the client renders to. With EGL, the
1796 // depth and stencil buffers are separate. With regular GL there is a single
1797 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1798 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351799 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1800 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1801 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1802 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1803 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021804 GLenum offscreen_target_color_format_;
1805 GLenum offscreen_target_depth_format_;
1806 GLenum offscreen_target_stencil_format_;
1807 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561808 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351809
[email protected]de26b3c2011-08-03 21:54:271810 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351811 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1812 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491813 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351814 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271815
1816 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351817 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1818 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051819 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351820
[email protected]882ba1e22012-03-08 19:02:531821 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531822
[email protected]944b62f32012-09-27 02:20:461823 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1824
[email protected]b63f1d62014-07-18 15:40:591825 scoped_ptr<ImageManager> image_manager_;
1826
[email protected]729c0b42013-05-26 02:05:071827 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001828
[email protected]840a7e462013-02-27 01:29:511829 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481830
[email protected]e3932abb2013-03-13 00:01:371831 ShaderCacheCallback shader_cache_callback_;
1832
[email protected]85a4ac22013-05-31 01:58:471833 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421834
[email protected]32fe9aa2011-01-21 23:47:131835 // The format of the back buffer_
1836 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461837 bool back_buffer_has_depth_;
1838 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131839
achaulkcf5316f2014-09-26 19:28:421840 bool surfaceless_;
1841
[email protected]60f22d32012-12-12 00:31:581842 // Backbuffer attachments that are currently undefined.
1843 uint32 backbuffer_needs_clear_bits_;
1844
[email protected]a6a09f852014-05-23 13:05:031845 // The current decoder error communicates the decoder error through command
1846 // processing functions that do not return the error value. Should be set only
1847 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561848 error::Error current_decoder_error_;
1849
[email protected]b1d2dcb2010-05-17 19:24:181850 bool use_shader_translator_;
dyen0ff9e4402015-02-12 22:27:431851 scoped_refptr<ShaderTranslatorInterface> vertex_translator_;
1852 scoped_refptr<ShaderTranslatorInterface> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181853
[email protected]e82fb792011-09-22 00:33:291854 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411855
[email protected]915a59a12010-09-30 21:29:111856 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051857 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351858 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051859
[email protected]65225772011-05-12 21:10:241860 int frame_number_;
1861
vmiura8266ca72014-09-09 21:37:001862 // Number of commands remaining to be processed in DoCommands().
1863 int commands_to_process_;
1864
[email protected]706b69f2012-07-27 04:59:301865 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431866 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221867 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431868 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431869
[email protected]f0d74742011-10-03 16:31:041870 // These flags are used to override the state of the shared feature_info_
1871 // member. Because the same FeatureInfo instance may be shared among many
1872 // contexts, the assumptions on the availablity of extensions in WebGL
1873 // contexts may be broken. These flags override the shared state to preserve
1874 // WebGL semantics.
1875 bool force_webgl_glsl_validation_;
1876 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491877 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131878 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061879 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041880
[email protected]062c38b2012-01-18 03:25:101881 bool compile_shader_always_succeeds_;
1882
[email protected]828a3932014-04-02 14:43:131883 // An optional behaviour to lose the context and group when OOM.
1884 bool lose_context_when_out_of_memory_;
1885
[email protected]cae20172012-12-07 00:06:191886 // Log extra info.
1887 bool service_logging_;
1888
[email protected]e51bdf32011-11-23 22:21:461889#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531890 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461891 TextureToIOSurfaceMap texture_to_io_surface_map_;
1892#endif
1893
[email protected]43410e92012-04-20 17:06:281894 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
sievers2384f2b2014-11-18 02:10:351895 scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_;
[email protected]43410e92012-04-20 17:06:281896
[email protected]1868a342012-11-07 15:56:021897 // Cached values of the currently assigned viewport dimensions.
1898 GLsizei viewport_max_width_;
1899 GLsizei viewport_max_height_;
1900
[email protected]63b465922012-09-06 02:04:521901 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521902 base::TimeDelta total_processing_commands_time_;
1903
[email protected]c986af502013-08-14 01:04:441904 // States related to each manager.
1905 DecoderTextureState texture_state_;
1906 DecoderFramebufferState framebuffer_state_;
1907
[email protected]fb97b662013-02-20 23:02:141908 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131909 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241910 const unsigned char* cb_command_trace_category_;
dyencb86f2f2014-12-09 18:35:411911 const unsigned char* gpu_decoder_category_;
[email protected]cac16542014-01-15 17:53:511912 int gpu_trace_level_;
1913 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241914 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111915
[email protected]5a36dc132013-07-23 23:17:551916 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1917
[email protected]4a4c18b2013-09-13 22:50:101918 // Used to validate multisample renderbuffers if needed
1919 GLuint validation_texture_;
1920 GLuint validation_fbo_multisample_;
1921 GLuint validation_fbo_;
1922
vmiuracd108592014-09-08 14:36:341923 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1924 uint32 immediate_data_size,
1925 const void* data);
1926
1927 // A struct to hold info about each command.
1928 struct CommandInfo {
1929 CmdHandler cmd_handler;
1930 uint8 arg_flags; // How to handle the arguments for this command
1931 uint8 cmd_flags; // How to handle this command
1932 uint16 arg_count; // How many arguments are expected for this command.
1933 };
1934
1935 // A table of CommandInfo for all the commands.
1936 static const CommandInfo command_info[kNumCommands - kStartPoint];
1937
[email protected]96449d2c2009-11-25 00:01:321938 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1939};
1940
vmiuracd108592014-09-08 14:36:341941const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1942#define GLES2_CMD_OP(name) \
1943 { \
1944 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1945 cmds::name::cmd_flags, \
1946 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1947 } \
1948 , /* NOLINT */
1949 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1950#undef GLES2_CMD_OP
1951};
1952
[email protected]ab09b612013-03-11 22:11:511953ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301954 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511955 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301956 error_state_(error_state) {
1957 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351958}
1959
1960ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301961 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351962}
1963
[email protected]2b10c02d2014-01-29 16:43:021964static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361965 TextureUnit& info = state->texture_units[0];
1966 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021967 scoped_refptr<TextureRef> texture_ref;
1968 switch (target) {
1969 case GL_TEXTURE_2D:
1970 texture_ref = info.bound_texture_2d;
1971 break;
1972 case GL_TEXTURE_CUBE_MAP:
1973 texture_ref = info.bound_texture_cube_map;
1974 break;
1975 case GL_TEXTURE_EXTERNAL_OES:
1976 texture_ref = info.bound_texture_external_oes;
1977 break;
1978 case GL_TEXTURE_RECTANGLE_ARB:
1979 texture_ref = info.bound_texture_rectangle_arb;
1980 break;
1981 default:
1982 NOTREACHED();
1983 break;
1984 }
1985 if (texture_ref.get()) {
1986 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361987 } else {
1988 last_id = 0;
1989 }
1990
[email protected]2b10c02d2014-01-29 16:43:021991 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361992 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1993}
1994
[email protected]2b10c02d2014-01-29 16:43:021995ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1996 GLuint id,
1997 GLenum target)
1998 : state_(state),
1999 target_(target) {
[email protected]ab09b612013-03-11 22:11:512000 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:022001 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352002
2003 // TODO(apatrick): Check if there are any other states that need to be reset
2004 // before binding a new texture.
2005 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:022006 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:352007}
2008
[email protected]2b10c02d2014-01-29 16:43:022009ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:512010 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:022011 "ScopedTextureBinder::dtor", state_->GetErrorState());
2012 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:352013}
2014
[email protected]18e785a2013-10-09 03:29:412015ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:352016 GLuint id)
[email protected]18e785a2013-10-09 03:29:412017 : state_(state) {
[email protected]ab09b612013-03-11 22:11:512018 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:412019 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352020 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
2021}
2022
2023ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512024 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:412025 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
2026 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:352027}
2028
2029ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
2030 GLuint id)
2031 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:512032 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302033 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352034 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:452035 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:352036}
2037
2038ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512039 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302040 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:302041 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:352042}
2043
[email protected]34ff8b0c2010-10-01 20:06:022044ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:272045 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:522046 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:342047 resolve_and_bind_ = (
2048 decoder_->offscreen_target_frame_buffer_.get() &&
2049 decoder_->IsOffscreenBufferMultisampled() &&
2050 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
2051 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:022052 if (!resolve_and_bind_)
2053 return;
2054
[email protected]ab09b612013-03-11 22:11:512055 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302056 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022057 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
2058 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:272059 GLuint targetid;
2060 if (internal) {
2061 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
2062 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:352063 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:272064 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352065 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:362066 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:272067 decoder_->offscreen_resolved_color_texture_->Create();
2068
2069 DCHECK(decoder_->offscreen_saved_color_format_);
2070 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:092071 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
2072 false);
[email protected]de26b3c2011-08-03 21:54:272073 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
2074 decoder_->offscreen_resolved_color_texture_.get());
2075 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
2076 GL_FRAMEBUFFER_COMPLETE) {
2077 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
2078 << "because offscreen resolved FBO was incomplete.";
2079 return;
2080 }
2081 }
2082 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
2083 } else {
2084 targetid = decoder_->offscreen_saved_frame_buffer_->id();
2085 }
2086 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022087 const int width = decoder_->offscreen_size_.width();
2088 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:452089 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:182090 decoder->BlitFramebufferHelper(0,
2091 0,
2092 width,
2093 height,
2094 0,
2095 0,
2096 width,
2097 height,
2098 GL_COLOR_BUFFER_BIT,
2099 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272100 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022101}
2102
2103ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2104 if (!resolve_and_bind_)
2105 return;
2106
[email protected]ab09b612013-03-11 22:11:512107 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302108 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022109 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222110 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452111 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182112 }
[email protected]34ff8b0c2010-10-01 20:06:022113}
2114
[email protected]ce296892013-10-24 22:04:362115BackTexture::BackTexture(
2116 MemoryTracker* memory_tracker,
2117 ContextState* state)
2118 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2119 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482120 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252121 id_(0) {
[email protected]6217d392010-03-25 22:08:352122}
2123
[email protected]ed9f9cd2013-02-27 21:12:352124BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352125 // This does not destroy the render texture because that would require that
2126 // the associated GL context was current. Just check that it was explicitly
2127 // destroyed.
2128 DCHECK_EQ(id_, 0u);
2129}
2130
[email protected]ed9f9cd2013-02-27 21:12:352131void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302132 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362133 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352134 Destroy();
2135 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022136 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162141
2142 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2143 // never called on an offscreen context, no data will ever be uploaded to the
2144 // saved offscreen color texture (it is deferred until to when SwapBuffers
2145 // is called). My idea is that some nvidia drivers might have a bug where
2146 // deleting a texture that has never been populated might cause a
2147 // crash.
2148 glTexImage2D(
2149 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482150
2151 bytes_allocated_ = 16u * 16u * 4u;
2152 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352153}
2154
[email protected]ed9f9cd2013-02-27 21:12:352155bool BackTexture::AllocateStorage(
2156 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352157 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302158 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362159 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022160 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092161 uint32 image_size = 0;
2162 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:422163 size.width(), size.height(), 1, format, GL_UNSIGNED_BYTE, 8, &image_size,
[email protected]678a73f2012-12-19 19:22:092164 NULL, NULL);
2165
[email protected]7989c9e2013-01-23 06:39:262166 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2167 return false;
2168 }
2169
[email protected]40d90a22013-04-09 03:39:552170 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092171 if (zero) {
2172 zero_data.reset(new char[image_size]);
2173 memset(zero_data.get(), 0, image_size);
2174 }
[email protected]6217d392010-03-25 22:08:352175
[email protected]8f1d2aa2013-05-10 23:45:382176 glTexImage2D(GL_TEXTURE_2D,
2177 0, // mip level
2178 format,
2179 size.width(),
2180 size.height(),
2181 0, // border
2182 format,
2183 GL_UNSIGNED_BYTE,
2184 zero_data.get());
[email protected]6217d392010-03-25 22:08:352185
[email protected]d37231fa2010-04-09 21:16:022186 size_ = size;
2187
[email protected]1078f912011-12-23 13:12:142188 bool success = glGetError() == GL_NO_ERROR;
2189 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482190 memory_tracker_.TrackMemFree(bytes_allocated_);
2191 bytes_allocated_ = image_size;
2192 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142193 }
2194 return success;
[email protected]6217d392010-03-25 22:08:352195}
2196
[email protected]ed9f9cd2013-02-27 21:12:352197void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352198 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302199 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362200 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022201 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352202 glCopyTexImage2D(GL_TEXTURE_2D,
2203 0, // level
[email protected]3a4d0c52011-06-29 23:11:582204 format,
[email protected]6217d392010-03-25 22:08:352205 0, 0,
2206 size.width(),
2207 size.height(),
2208 0); // border
2209}
2210
[email protected]ed9f9cd2013-02-27 21:12:352211void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352212 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302213 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362214 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352215 glDeleteTextures(1, &id_);
2216 id_ = 0;
2217 }
[email protected]68e81a4a62012-12-13 01:16:482218 memory_tracker_.TrackMemFree(bytes_allocated_);
2219 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352220}
2221
[email protected]ed9f9cd2013-02-27 21:12:352222void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052223 id_ = 0;
2224}
2225
[email protected]d5a28e452013-10-10 01:01:402226BackRenderbuffer::BackRenderbuffer(
2227 RenderbufferManager* renderbuffer_manager,
2228 MemoryTracker* memory_tracker,
2229 ContextState* state)
2230 : renderbuffer_manager_(renderbuffer_manager),
2231 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2232 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482233 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252234 id_(0) {
[email protected]6217d392010-03-25 22:08:352235}
2236
[email protected]ed9f9cd2013-02-27 21:12:352237BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352238 // This does not destroy the render buffer because that would require that
2239 // the associated GL context was current. Just check that it was explicitly
2240 // destroyed.
2241 DCHECK_EQ(id_, 0u);
2242}
2243
[email protected]ed9f9cd2013-02-27 21:12:352244void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302245 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402246 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352247 Destroy();
2248 glGenRenderbuffersEXT(1, &id_);
2249}
2250
[email protected]f42f05b2013-11-15 21:46:182251bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2252 const gfx::Size& size,
2253 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352254 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512255 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402256 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2257 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262258
2259 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402260 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232261 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262262 return false;
2263 }
2264
2265 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2266 return false;
2267 }
2268
[email protected]34ff8b0c2010-10-01 20:06:022269 if (samples <= 1) {
2270 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2271 format,
2272 size.width(),
2273 size.height());
2274 } else {
[email protected]f42f05b2013-11-15 21:46:182275 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2276 GL_RENDERBUFFER,
2277 samples,
2278 format,
2279 size.width(),
2280 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022281 }
[email protected]1078f912011-12-23 13:12:142282 bool success = glGetError() == GL_NO_ERROR;
2283 if (success) {
[email protected]d5a28e452013-10-10 01:01:402284 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482285 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262286 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402287 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482288 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142289 }
2290 return success;
[email protected]6217d392010-03-25 22:08:352291}
2292
[email protected]ed9f9cd2013-02-27 21:12:352293void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352294 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302295 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402296 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352297 glDeleteRenderbuffersEXT(1, &id_);
2298 id_ = 0;
2299 }
[email protected]68e81a4a62012-12-13 01:16:482300 memory_tracker_.TrackMemFree(bytes_allocated_);
2301 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352302}
2303
[email protected]ed9f9cd2013-02-27 21:12:352304void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052305 id_ = 0;
2306}
2307
[email protected]ed9f9cd2013-02-27 21:12:352308BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352309 : decoder_(decoder),
2310 id_(0) {
2311}
2312
[email protected]ed9f9cd2013-02-27 21:12:352313BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352314 // This does not destroy the frame buffer because that would require that
2315 // the associated GL context was current. Just check that it was explicitly
2316 // destroyed.
2317 DCHECK_EQ(id_, 0u);
2318}
2319
[email protected]ed9f9cd2013-02-27 21:12:352320void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302321 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2322 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352323 Destroy();
2324 glGenFramebuffersEXT(1, &id_);
2325}
2326
[email protected]ed9f9cd2013-02-27 21:12:352327void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352328 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512329 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302330 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352331 ScopedFrameBufferBinder binder(decoder_, id_);
2332 GLuint attach_id = texture ? texture->id() : 0;
2333 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2334 GL_COLOR_ATTACHMENT0,
2335 GL_TEXTURE_2D,
2336 attach_id,
2337 0);
2338}
2339
[email protected]ed9f9cd2013-02-27 21:12:352340void BackFramebuffer::AttachRenderBuffer(GLenum target,
2341 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352342 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512343 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302344 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352345 ScopedFrameBufferBinder binder(decoder_, id_);
2346 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2347 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152348 target,
[email protected]6217d392010-03-25 22:08:352349 GL_RENDERBUFFER,
2350 attach_id);
2351}
2352
[email protected]ed9f9cd2013-02-27 21:12:352353void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352354 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302355 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2356 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352357 glDeleteFramebuffersEXT(1, &id_);
2358 id_ = 0;
2359 }
2360}
2361
[email protected]ed9f9cd2013-02-27 21:12:352362void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052363 id_ = 0;
2364}
2365
[email protected]ed9f9cd2013-02-27 21:12:352366GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352367 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302368 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2369 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352370 ScopedFrameBufferBinder binder(decoder_, id_);
2371 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2372}
2373
[email protected]aa7666122011-09-02 19:45:522374GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2375 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322376}
2377
[email protected]aa7666122011-09-02 19:45:522378GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392379 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572380 group_(group),
[email protected]1d82e822013-04-10 21:32:322381 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132382 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282383 unpack_flip_y_(false),
2384 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172385 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242386 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492387 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242388 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402389 fixed_attrib_buffer_id_(0),
2390 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022391 offscreen_target_color_format_(0),
2392 offscreen_target_depth_format_(0),
2393 offscreen_target_stencil_format_(0),
2394 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562395 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052396 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132397 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462398 back_buffer_has_depth_(false),
2399 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422400 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582401 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562402 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052403 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112404 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002405 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432406 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302407 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512408 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222409 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432410 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042411 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102412 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492413 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132414 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062415 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282416 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132417 lose_context_when_out_of_memory_(false),
avi9ab037202014-12-22 23:49:532418 service_logging_(base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]cae20172012-12-07 00:06:192419 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022420 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102421 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002422 texture_state_(group_->feature_info()
2423 ->workarounds()
2424 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242425 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2426 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
dyencb86f2f2014-12-09 18:35:412427 gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2428 TRACE_DISABLED_BY_DEFAULT("gpu_decoder"))),
vmiura1c2b1de2014-09-19 19:03:242429 gpu_trace_level_(2),
2430 gpu_trace_commands_(false),
2431 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102432 validation_texture_(0),
2433 validation_fbo_multisample_(0),
2434 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572435 DCHECK(group);
2436
[email protected]b1122982010-05-17 23:04:242437 attrib_0_value_.v[0] = 0.0f;
2438 attrib_0_value_.v[1] = 0.0f;
2439 attrib_0_value_.v[2] = 0.0f;
2440 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152441
[email protected]c2f8c8402010-12-06 18:07:242442 // The shader translator is used for WebGL even when running on EGL
2443 // because additional restrictions are needed (like only enabling
2444 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562445 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2446 // the empty string to CompileShader and this is not a valid shader.
2447 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
avi9ab037202014-12-22 23:49:532448 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]39ba4f02012-03-26 01:16:002449 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152450 use_shader_translator_ = false;
2451 }
[email protected]96449d2c2009-11-25 00:01:322452}
2453
[email protected]80eb6b52012-01-19 00:14:412454GLES2DecoderImpl::~GLES2DecoderImpl() {
2455}
2456
[email protected]c410da802011-03-14 19:17:412457bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382458 const scoped_refptr<gfx::GLSurface>& surface,
2459 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232460 bool offscreen,
dongseong.hwang4c04a162015-03-04 07:27:332461 const gfx::Size& offscreen_size,
[email protected]e82fb792011-09-22 00:33:292462 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242463 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322464 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382465 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302466 DCHECK(!context_.get());
2467
zmo0ee15862015-03-04 03:50:182468 ContextCreationAttribHelper attrib_parser;
2469 if (!attrib_parser.Parse(attribs))
2470 return false;
2471
jbaumana7604692014-10-17 02:00:392472 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422473
[email protected]55e136f2013-04-03 18:50:062474 set_initialized();
[email protected]8f9b8dd2013-09-12 18:05:132475 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142476
avi9ab037202014-12-22 23:49:532477 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2478 switches::kEnableGPUDebugging)) {
[email protected]e844ae22012-01-14 03:36:262479 set_debug(true);
2480 }
2481
avi9ab037202014-12-22 23:49:532482 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2483 switches::kEnableGPUCommandLogging)) {
[email protected]39ba4f02012-03-26 01:16:002484 set_log_commands(true);
2485 }
2486
avi9ab037202014-12-22 23:49:532487 compile_shader_always_succeeds_ =
2488 base::CommandLine::ForCurrentProcess()->HasSwitch(
2489 switches::kCompileShaderAlwaysSucceeds);
[email protected]062c38b2012-01-18 03:25:102490
[email protected]63c9b052012-05-17 18:27:382491 // Take ownership of the context and surface. The surface can be replaced with
2492 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382493 context_ = context;
[email protected]63c9b052012-05-17 18:27:382494 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182495
dyen5b1c02ff2015-02-26 01:54:002496 // Create GPU Tracer for timing values.
2497 gpu_tracer_.reset(new GPUTracer(this));
2498
[email protected]828a3932014-04-02 14:43:132499 // Save the loseContextWhenOutOfMemory context creation attribute.
2500 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402501 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132502
[email protected]65f7efe2013-11-28 03:11:472503 // If the failIfMajorPerformanceCaveat context creation attribute was true
2504 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402505 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472506 feature_info_->feature_flags().is_swiftshader) {
2507 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2508 Destroy(true);
2509 return false;
2510 }
2511
[email protected]956aec52013-09-05 15:41:192512 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222513 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392514 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422515 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382516 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032517 return false;
[email protected]a3ded6d2010-10-19 06:44:392518 }
[email protected]b64c24952012-04-19 03:20:272519 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282520
zmoac89bdd2015-03-10 02:09:052521 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2522 switches::kEnableUnsafeES3APIs) &&
2523 attrib_parser.es3_context_required &&
2524 feature_info_->IsES3Capable()) {
2525 feature_info_->EnableES3Validators();
2526 set_unsafe_es3_apis_enabled(true);
2527 }
2528
[email protected]e82fb792011-09-22 00:33:292529 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502530
[email protected]af6380962012-11-29 23:24:132531 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482532 vertex_array_manager_.reset(new VertexArrayManager());
2533
2534 GLuint default_vertex_attrib_service_id = 0;
2535 if (features().native_vertex_array_object) {
2536 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2537 glBindVertexArrayOES(default_vertex_attrib_service_id);
2538 }
2539
2540 state_.default_vertex_attrib_manager =
2541 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2542
[email protected]81f20a622014-04-18 01:54:522543 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002544 group_->max_vertex_attribs(),
2545 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462546
[email protected]81f20a622014-04-18 01:54:522547 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572548 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322549
[email protected]7cd76fd2013-06-02 21:11:112550 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532551
[email protected]b63f1d62014-07-18 15:40:592552 image_manager_.reset(new ImageManager);
2553
[email protected]302ce6d2011-07-07 23:28:112554 util_.set_num_compressed_texture_formats(
2555 validators_->compressed_texture_format.GetValues().size());
2556
[email protected]1071e572011-02-09 20:00:122557 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2558 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2559 // OpenGL ES 2.0 does not have this issue.
2560 glEnableVertexAttribArray(0);
2561 }
[email protected]b1122982010-05-17 23:04:242562 glGenBuffersARB(1, &attrib_0_buffer_id_);
2563 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2564 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2565 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402566 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082567
[email protected]1868a342012-11-07 15:56:022568 state_.texture_units.resize(group_->max_texture_units());
2569 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492570 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312571 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492572 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152573 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492574 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072575 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492576 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572577 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312578 }
[email protected]62e155e2012-10-23 22:43:152579 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492580 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072581 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492582 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572583 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462584 }
[email protected]370eaf12013-05-18 09:19:492585 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2586 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572587 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492588 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2589 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572590 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152591 }
[email protected]00f893d2010-08-24 18:55:492592 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502593 CHECK_GL_ERROR();
2594
[email protected]069944672012-04-25 20:52:232595 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402596 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542597 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022598 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432599 // max_sample_count must be initialized to a sane value. If
2600 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2601 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022602 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402603 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022604 max_sample_count);
2605 } else {
2606 offscreen_target_samples_ = 1;
2607 }
[email protected]845c4e32014-08-13 11:50:402608 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022609
2610 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2611 const bool rgb8_supported =
2612 context_->HasExtension("GL_OES_rgb8_rgba8");
2613 // The only available default render buffer formats in GLES2 have very
2614 // little precision. Don't enable multisampling unless 8-bit render
2615 // buffer formats are available--instead fall back to 8-bit textures.
2616 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402617 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022618 GL_RGBA8 : GL_RGB8;
2619 } else {
2620 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402621 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022622 GL_RGBA : GL_RGB;
2623 }
2624
2625 // ANGLE only supports packed depth/stencil formats, so use it if it is
2626 // available.
2627 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182628 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272629 VLOG(1) << "GL_OES_packed_depth_stencil "
2630 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402631 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002632 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022633 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2634 offscreen_target_stencil_format_ = 0;
2635 } else {
2636 // It may be the case that this depth/stencil combination is not
2637 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402638 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022639 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402640 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022641 GL_STENCIL_INDEX8 : 0;
2642 }
2643 } else {
[email protected]845c4e32014-08-13 11:50:402644 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022645 GL_RGBA : GL_RGB;
2646
2647 // If depth is requested at all, use the packed depth stencil format if
2648 // it's available, as some desktop GL drivers don't support any non-packed
2649 // formats for depth attachments.
2650 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182651 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272652 VLOG(1) << "GL_EXT_packed_depth_stencil "
2653 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022654
[email protected]845c4e32014-08-13 11:50:402655 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002656 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022657 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2658 offscreen_target_stencil_format_ = 0;
2659 } else {
[email protected]845c4e32014-08-13 11:50:402660 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022661 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402662 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022663 GL_STENCIL_INDEX : 0;
2664 }
2665 }
2666
[email protected]845c4e32014-08-13 11:50:402667 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052668 GL_RGBA : GL_RGB;
2669
[email protected]6217d392010-03-25 22:08:352670 // Create the target frame buffer. This is the one that the client renders
2671 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352672 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352673 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022674 // Due to GLES2 format limitations, either the color texture (for
2675 // non-multisampling) or the color render buffer (for multisampling) will be
2676 // attached to the offscreen frame buffer. The render buffer has more
2677 // limited formats available to it, but the texture can't do multisampling.
2678 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402679 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2680 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022681 offscreen_target_color_render_buffer_->Create();
2682 } else {
[email protected]ce296892013-10-24 22:04:362683 offscreen_target_color_texture_.reset(new BackTexture(
2684 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022685 offscreen_target_color_texture_->Create();
2686 }
[email protected]d5a28e452013-10-10 01:01:402687 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2688 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152689 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402690 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2691 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152692 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352693
2694 // Create the saved offscreen texture. The target frame buffer is copied
2695 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352696 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022697 offscreen_saved_frame_buffer_->Create();
2698 //
[email protected]ce296892013-10-24 22:04:362699 offscreen_saved_color_texture_.reset(new BackTexture(
2700 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352701 offscreen_saved_color_texture_->Create();
2702
[email protected]6217d392010-03-25 22:08:352703 // Allocate the render buffers at their initial size and check the status
2704 // of the frame buffers is okay.
dongseong.hwang4c04a162015-03-04 07:27:332705 if (!ResizeOffscreenFrameBuffer(offscreen_size)) {
[email protected]d0498742010-09-20 20:27:012706 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382707 Destroy(true);
[email protected]6217d392010-03-25 22:08:352708 return false;
2709 }
2710
dongseong.hwang4c04a162015-03-04 07:27:332711 state_.viewport_width = offscreen_size.width();
2712 state_.viewport_height = offscreen_size.height();
2713
[email protected]678a73f2012-12-19 19:22:092714 // Allocate the offscreen saved color texture.
2715 DCHECK(offscreen_saved_color_format_);
2716 offscreen_saved_color_texture_->AllocateStorage(
2717 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2718
2719 offscreen_saved_frame_buffer_->AttachRenderTexture(
2720 offscreen_saved_color_texture_.get());
2721 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2722 GL_FRAMEBUFFER_COMPLETE) {
2723 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2724 Destroy(true);
2725 return false;
2726 }
2727
[email protected]6217d392010-03-25 22:08:352728 // Bind to the new default frame buffer (the offscreen target frame buffer).
2729 // This should now be associated with ID zero.
2730 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102731 } else {
2732 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2733 // These are NOT if the back buffer has these proprorties. They are
2734 // if we want the command buffer to enforce them regardless of what
2735 // the real backbuffer is assuming the real back buffer gives us more than
2736 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2737 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2738 // can't do anything about that.
2739
achaulkcf5316f2014-09-26 19:28:422740 if (!surfaceless_) {
kbrc9f0e10c2015-03-31 19:49:122741 GLint alpha_bits = 0;
2742 GLint depth_bits = 0;
2743 GLint stencil_bits = 0;
2744
2745 bool default_fb = (GetBackbufferServiceId() == 0);
2746
marcheu1856f5d52015-04-04 01:42:532747 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:122748 glGetFramebufferAttachmentParameterivEXT(
2749 GL_FRAMEBUFFER,
2750 default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0,
2751 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits);
2752 glGetFramebufferAttachmentParameterivEXT(
2753 GL_FRAMEBUFFER,
2754 default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT,
2755 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits);
2756 glGetFramebufferAttachmentParameterivEXT(
2757 GL_FRAMEBUFFER,
2758 default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT,
2759 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits);
2760 } else {
2761 glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);
2762 glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
2763 glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
2764 }
2765
achaulkcf5316f2014-09-26 19:28:422766 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2767 // the user requested RGB then RGB. If the user did not specify a
2768 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2769 back_buffer_color_format_ =
kbrc9f0e10c2015-03-31 19:49:122770 (attrib_parser.alpha_size != 0 && alpha_bits > 0) ? GL_RGBA : GL_RGB;
2771 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && depth_bits > 0;
2772 back_buffer_has_stencil_ =
2773 attrib_parser.stencil_size != 0 && stencil_bits > 0;
achaulkcf5316f2014-09-26 19:28:422774 }
dongseong.hwang4c04a162015-03-04 07:27:332775
2776 state_.viewport_width = surface->GetSize().width();
2777 state_.viewport_height = surface->GetSize().height();
[email protected]6217d392010-03-25 22:08:352778 }
2779
[email protected]76a0ee102010-04-07 21:03:042780 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2781 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2782 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372783 // mailing list archives. It also implicitly enables the desktop GL
2784 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2785 // variable in fragment shaders.
marcheu1856f5d52015-04-04 01:42:532786 if (!feature_info_->gl_version_info().BehavesLikeGLES()) {
[email protected]b9363b22010-06-09 22:06:152787 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372788 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152789 }
[email protected]de17df392010-04-23 21:09:412790
[email protected]706b69f2012-07-27 04:59:302791 has_robustness_extension_ =
2792 context->HasExtension("GL_ARB_robustness") ||
oetuaho37cc50e2014-10-31 11:19:202793 context->HasExtension("GL_KHR_robustness") ||
[email protected]706b69f2012-07-27 04:59:302794 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432795
[email protected]c2f8c8402010-12-06 18:07:242796 if (!InitializeShaderTranslator()) {
2797 return false;
[email protected]de17df392010-04-23 21:09:412798 }
[email protected]76a0ee102010-04-07 21:03:042799
[email protected]5904806b2012-05-08 18:10:222800 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282801 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022802 viewport_max_width_ = viewport_params[0];
2803 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282804
[email protected]88a61bf2012-10-27 13:00:422805 state_.scissor_width = state_.viewport_width;
2806 state_.scissor_height = state_.viewport_height;
2807
[email protected]11f3e702012-06-19 19:00:012808 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342809 state_.InitCapabilities(NULL);
2810 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242811 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012812
2813 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2814 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2815 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2816 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
orglofchcad5a6742014-11-07 19:51:122817 DoBindValueBufferCHROMIUM(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, 0);
[email protected]11f3e702012-06-19 19:00:012818
achaulkcf5316f2014-09-26 19:28:422819 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002820#if defined(OS_ANDROID)
2821 // Temporary workaround for Android WebView because this clear ignores the
2822 // clip and corrupts that external UI of the App. Not calling glClear is ok
2823 // because the system already clears the buffer before each draw. Proper
2824 // fix might be setting the scissor clip properly before initialize. See
2825 // crbug.com/259023 for details.
2826 call_gl_clear = surface_->GetHandle();
2827#endif
2828 if (call_gl_clear) {
2829 // Clear the backbuffer.
2830 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2831 }
[email protected]561cc0a62013-05-07 18:34:452832
[email protected]b381ee32014-03-22 02:43:432833 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2834 if (feature_info_->workarounds()
2835 .disable_post_sub_buffers_for_onscreen_surfaces &&
2836 !surface->IsOffscreen())
2837 supports_post_sub_buffer_ = false;
2838
[email protected]62e155e2012-10-23 22:43:152839 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462840 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2841 }
[email protected]dd289a5d62012-06-30 22:05:462842
[email protected]9b753992013-04-27 02:04:412843 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2844 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242845 }
[email protected]85cb4682013-04-20 00:54:242846
[email protected]97419c02013-04-10 02:52:382847 // Only compositor contexts are known to use only the subset of GL
2848 // that can be safely migrated between the iGPU and the dGPU. Mark
2849 // those contexts as safe to forcibly transition between the GPUs.
2850 // http://crbug.com/180876, http://crbug.com/227228
2851 if (!offscreen)
2852 context_->SetSafeToForceGpuSwitch();
2853
[email protected]85a4ac22013-05-31 01:58:472854 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072855 AsyncPixelTransferManager::Create(context.get()));
2856 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592857
sievers2384f2b2014-11-18 02:10:352858 if (workarounds().gl_clear_broken) {
2859 DCHECK(!clear_framebuffer_blit_.get());
2860 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit");
2861 clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this));
2862 if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR)
2863 return false;
2864 }
2865
[email protected]91c94eb2013-10-22 10:32:542866 framebuffer_manager()->AddObserver(this);
2867
[email protected]246a70452010-03-05 21:53:502868 return true;
[email protected]96449d2c2009-11-25 00:01:322869}
2870
[email protected]6d668892013-12-04 21:37:122871Capabilities GLES2DecoderImpl::GetCapabilities() {
2872 DCHECK(initialized());
2873
2874 Capabilities caps;
piman1c2e0a852014-11-12 05:17:552875 caps.VisitPrecisions([](GLenum shader, GLenum type,
2876 Capabilities::ShaderPrecision* shader_precision) {
2877 GLint range[2] = {0, 0};
2878 GLint precision = 0;
2879 GetShaderPrecisionFormatImpl(shader, type, range, &precision);
2880 shader_precision->min_range = range[0];
2881 shader_precision->max_range = range[1];
2882 shader_precision->precision = precision;
2883 });
2884 DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
2885 &caps.max_combined_texture_image_units);
2886 DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size);
2887 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
2888 &caps.max_fragment_uniform_vectors);
2889 DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size);
2890 DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units);
2891 DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size);
2892 DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors);
2893 DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs);
2894 DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
2895 &caps.max_vertex_texture_image_units);
2896 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
2897 &caps.max_vertex_uniform_vectors);
2898 DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
2899 &caps.num_compressed_texture_formats);
2900 DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats);
2901 DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
2902 &caps.bind_generates_resource_chromium);
heejin.r.chung8f143292015-02-05 02:44:002903 if (unsafe_es3_apis_enabled()) {
zmoba1fe9d22015-04-15 21:42:512904 // TODO(zmo): Note that some parameter values could be more than 32-bit,
2905 // but for now we clamp them to 32-bit max.
2906 DoGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps.max_3d_texture_size);
2907 DoGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps.max_array_texture_layers);
2908 DoGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps.max_color_attachments);
2909 DoGetIntegerv(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
2910 &caps.max_combined_fragment_uniform_components);
2911 DoGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS,
2912 &caps.max_combined_uniform_blocks);
2913 DoGetIntegerv(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
2914 &caps.max_combined_vertex_uniform_components);
2915 DoGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps.max_draw_buffers);
2916 DoGetIntegerv(GL_MAX_ELEMENT_INDEX, &caps.max_element_index);
2917 DoGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps.max_elements_indices);
2918 DoGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps.max_elements_vertices);
2919 DoGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS,
2920 &caps.max_fragment_input_components);
2921 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
2922 &caps.max_fragment_uniform_blocks);
2923 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
2924 &caps.max_fragment_uniform_components);
2925 DoGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET,
2926 &caps.max_program_texel_offset);
2927 DoGetIntegerv(GL_MAX_SAMPLES, &caps.max_samples);
2928 DoGetIntegerv(GL_MAX_SERVER_WAIT_TIMEOUT, &caps.max_server_wait_timeout);
2929 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
2930 &caps.max_transform_feedback_interleaved_components);
heejin.r.chung8f143292015-02-05 02:44:002931 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
2932 &caps.max_transform_feedback_separate_attribs);
zmoba1fe9d22015-04-15 21:42:512933 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,
2934 &caps.max_transform_feedback_separate_components);
2935 DoGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &caps.max_uniform_block_size);
heejin.r.chung8f143292015-02-05 02:44:002936 DoGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
2937 &caps.max_uniform_buffer_bindings);
zmoba1fe9d22015-04-15 21:42:512938 DoGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps.max_varying_components);
2939 DoGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
2940 &caps.max_vertex_output_components);
2941 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS,
2942 &caps.max_vertex_uniform_blocks);
2943 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS,
2944 &caps.max_vertex_uniform_components);
2945 DoGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps.min_program_texel_offset);
2946 DoGetIntegerv(GL_NUM_EXTENSIONS, &caps.num_extensions);
2947 DoGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS,
2948 &caps.num_program_binary_formats);
heejin.r.chung8f143292015-02-05 02:44:002949 DoGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
2950 &caps.uniform_buffer_offset_alignment);
zmoba1fe9d22015-04-15 21:42:512951 // TODO(zmo): once we switch to MANGLE, we should query version numbers.
2952 caps.major_version = 3;
2953 caps.minor_version = 0;
heejin.r.chung8f143292015-02-05 02:44:002954 }
[email protected]6d668892013-12-04 21:37:122955
[email protected]6d668892013-12-04 21:37:122956 caps.egl_image_external =
2957 feature_info_->feature_flags().oes_egl_image_external;
christiank07b6d8b2015-02-25 09:41:252958 caps.texture_format_atc =
2959 feature_info_->feature_flags().ext_texture_format_atc;
[email protected]6d668892013-12-04 21:37:122960 caps.texture_format_bgra8888 =
2961 feature_info_->feature_flags().ext_texture_format_bgra8888;
christiank07b6d8b2015-02-25 09:41:252962 caps.texture_format_dxt1 =
2963 feature_info_->feature_flags().ext_texture_format_dxt1;
2964 caps.texture_format_dxt5 =
2965 feature_info_->feature_flags().ext_texture_format_dxt5;
[email protected]6d668892013-12-04 21:37:122966 caps.texture_format_etc1 =
2967 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202968 caps.texture_format_etc1_npot =
2969 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122970 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2971 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2972 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2973 caps.discard_framebuffer =
2974 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352975 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122976
2977#if defined(OS_MACOSX)
2978 // This is unconditionally true on mac, no need to test for it at runtime.
2979 caps.iosurface = true;
2980#endif
2981
[email protected]b381ee32014-03-22 02:43:432982 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452983 caps.image = true;
[email protected]6d668892013-12-04 21:37:122984
ed9198b422014-10-23 15:01:372985 caps.blend_equation_advanced =
2986 feature_info_->feature_flags().blend_equation_advanced;
2987 caps.blend_equation_advanced_coherent =
2988 feature_info_->feature_flags().blend_equation_advanced_coherent;
hendrikwfc25ca6192014-12-02 06:05:132989 caps.texture_rg = feature_info_->feature_flags().ext_texture_rg;
[email protected]6d668892013-12-04 21:37:122990 return caps;
2991}
2992
[email protected]302ce6d2011-07-07 23:28:112993void GLES2DecoderImpl::UpdateCapabilities() {
2994 util_.set_num_compressed_texture_formats(
2995 validators_->compressed_texture_format.GetValues().size());
2996 util_.set_num_shader_binary_formats(
2997 validators_->shader_binary_format.GetValues().size());
2998}
2999
[email protected]c2f8c8402010-12-06 18:07:243000bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:443001 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
3002
[email protected]c2f8c8402010-12-06 18:07:243003 if (!use_shader_translator_) {
3004 return true;
3005 }
3006 ShBuiltInResources resources;
3007 ShInitBuiltInResources(&resources);
3008 resources.MaxVertexAttribs = group_->max_vertex_attribs();
3009 resources.MaxVertexUniformVectors =
3010 group_->max_vertex_uniform_vectors();
3011 resources.MaxVaryingVectors = group_->max_varying_vectors();
3012 resources.MaxVertexTextureImageUnits =
3013 group_->max_vertex_texture_image_units();
3014 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
3015 resources.MaxTextureImageUnits = group_->max_texture_image_units();
3016 resources.MaxFragmentUniformVectors =
3017 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:493018 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:243019 resources.MaxExpressionComplexity = 256;
3020 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:043021
[email protected]46c86752013-05-21 05:08:393022 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:213023 GLint precision = 0;
3024 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
3025 range, &precision);
[email protected]448e459e2013-06-12 17:00:413026 resources.FragmentPrecisionHigh =
3027 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:143028
[email protected]f0d74742011-10-03 16:31:043029 if (force_webgl_glsl_validation_) {
3030 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:493031 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:133032 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:443033 if (!draw_buffers_explicitly_enabled_)
3034 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:063035 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:463036 resources.NV_draw_buffers =
3037 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:043038 } else {
3039 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:153040 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:463041 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:153042 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:063043 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:153044 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:493045 resources.EXT_draw_buffers =
3046 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:493047 resources.EXT_frag_depth =
3048 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:063049 resources.EXT_shader_texture_lod =
3050 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:463051 resources.NV_draw_buffers =
3052 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:043053 }
3054
zmo0ee15862015-03-04 03:50:183055 ShShaderSpec shader_spec;
3056 if (force_webgl_glsl_validation_) {
3057 shader_spec = unsafe_es3_apis_enabled() ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC;
3058 } else {
3059 shader_spec = unsafe_es3_apis_enabled() ? SH_GLES3_SPEC : SH_GLES2_SPEC;
3060 }
3061
3062 if ((shader_spec == SH_WEBGL_SPEC || shader_spec == SH_WEBGL2_SPEC) &&
3063 features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:023064 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:053065 else
3066 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:123067 ShaderTranslatorInterface::GlslImplementationType implementation_type =
marcheu1856f5d52015-04-04 01:42:533068 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
3069 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:213070 int driver_bug_workarounds = 0;
3071 if (workarounds().needs_glsl_built_in_function_emulation)
3072 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:543073 if (workarounds().init_gl_position_in_vertex_shader)
3074 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:113075 if (workarounds().unfold_short_circuit_as_ternary_operation)
3076 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:053077 if (workarounds().init_varyings_without_static_use)
3078 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:063079 if (workarounds().unroll_for_loop_with_sampler_array_index)
3080 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:253081 if (workarounds().scalarize_vec_and_mat_constructor_args)
3082 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:273083 if (workarounds().regenerate_struct_names)
3084 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:043085
avi9ab037202014-12-22 23:49:533086 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
3087 switches::kEmulateShaderPrecision))
oetuahoaffd85abe2014-12-11 09:47:093088 resources.WEBGL_debug_shader_precision = true;
3089
[email protected]03cef9b2014-04-03 15:58:143090 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:263091 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:143092 shader_spec,
3093 &resources,
[email protected]a6739bc2013-09-07 04:45:213094 implementation_type,
3095 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:043096 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:243097 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:383098 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:243099 return false;
3100 }
[email protected]87fb6ab2012-06-13 22:28:043101
[email protected]03cef9b2014-04-03 15:58:143102 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:263103 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:143104 shader_spec,
3105 &resources,
[email protected]a6739bc2013-09-07 04:45:213106 implementation_type,
3107 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:043108 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:243109 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:383110 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:243111 return false;
3112 }
3113 return true;
3114}
3115
[email protected]ae51d192010-04-27 00:48:033116bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:473117 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353118 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033119 return false;
3120 }
3121 }
[email protected]40d90a22013-04-09 03:39:553122 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033123 glGenBuffersARB(n, service_ids.get());
3124 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353125 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033126 }
3127 return true;
3128}
3129
3130bool GLES2DecoderImpl::GenFramebuffersHelper(
3131 GLsizei n, const GLuint* client_ids) {
3132 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353133 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033134 return false;
3135 }
3136 }
[email protected]40d90a22013-04-09 03:39:553137 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033138 glGenFramebuffersEXT(n, service_ids.get());
3139 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353140 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033141 }
3142 return true;
3143}
3144
3145bool GLES2DecoderImpl::GenRenderbuffersHelper(
3146 GLsizei n, const GLuint* client_ids) {
3147 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353148 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033149 return false;
3150 }
3151 }
[email protected]40d90a22013-04-09 03:39:553152 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033153 glGenRenderbuffersEXT(n, service_ids.get());
3154 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353155 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033156 }
3157 return true;
3158}
3159
orglofchcad5a6742014-11-07 19:51:123160bool GLES2DecoderImpl::GenValuebuffersCHROMIUMHelper(GLsizei n,
3161 const GLuint* client_ids) {
3162 for (GLsizei ii = 0; ii < n; ++ii) {
3163 if (GetValuebuffer(client_ids[ii])) {
3164 return false;
3165 }
3166 }
3167 for (GLsizei ii = 0; ii < n; ++ii) {
3168 CreateValuebuffer(client_ids[ii]);
3169 }
3170 return true;
3171}
3172
[email protected]ae51d192010-04-27 00:48:033173bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
3174 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353175 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033176 return false;
3177 }
3178 }
[email protected]40d90a22013-04-09 03:39:553179 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033180 glGenTextures(n, service_ids.get());
3181 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353182 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033183 }
3184 return true;
3185}
3186
3187void GLES2DecoderImpl::DeleteBuffersHelper(
3188 GLsizei n, const GLuint* client_ids) {
3189 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:213190 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103191 if (buffer && !buffer->IsDeleted()) {
zmo2a09dc052015-03-12 00:48:253192 buffer->RemoveMappedRange();
[email protected]e259eb412012-10-13 05:47:243193 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:113194 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:243195 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103196 }
[email protected]ed9f9cd2013-02-27 21:12:353197 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033198 }
[email protected]a93bb842010-02-16 23:03:473199 }
[email protected]07f54fcc2009-12-22 02:46:303200}
3201
[email protected]ae51d192010-04-27 00:48:033202void GLES2DecoderImpl::DeleteFramebuffersHelper(
3203 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453204 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153205 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:113206
[email protected]a25fa872010-03-25 02:57:583207 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353208 Framebuffer* framebuffer =
3209 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103210 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:343211 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]ebfb73c2012-08-15 02:37:453212 GLenum target = supports_separate_framebuffer_binds ?
3213 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
vmiura7d08fee52015-02-18 18:39:343214
3215 // Unbind attachments on FBO before deletion.
3216 if (workarounds().unbind_attachments_on_bound_render_fbo_delete)
3217 framebuffer->DoUnbindGLAttachmentsForWorkaround(target);
3218
[email protected]b177ae22011-11-01 03:29:113219 glBindFramebufferEXT(target, GetBackbufferServiceId());
vmiura7d08fee52015-02-18 18:39:343220 framebuffer_state_.bound_draw_framebuffer = NULL;
3221 framebuffer_state_.clear_state_dirty = true;
[email protected]b177ae22011-11-01 03:29:113222 }
[email protected]9d3b2e12013-10-02 01:04:343223 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
3224 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:453225 GLenum target = supports_separate_framebuffer_binds ?
3226 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113227 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:463228 }
[email protected]70d34263c2013-01-09 00:27:453229 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:353230 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033231 }
[email protected]a25fa872010-03-25 02:57:583232 }
[email protected]07f54fcc2009-12-22 02:46:303233}
3234
[email protected]ae51d192010-04-27 00:48:033235void GLES2DecoderImpl::DeleteRenderbuffersHelper(
3236 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453237 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153238 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:583239 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353240 Renderbuffer* renderbuffer =
3241 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103242 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:113243 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:243244 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103245 }
3246 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453247 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343248 if (framebuffer_state_.bound_read_framebuffer.get()) {
3249 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113250 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103251 }
[email protected]9d3b2e12013-10-02 01:04:343252 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3253 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113254 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103255 }
3256 } else {
[email protected]9d3b2e12013-10-02 01:04:343257 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3258 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113259 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103260 }
3261 }
[email protected]c986af502013-08-14 01:04:443262 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353263 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033264 }
[email protected]a25fa872010-03-25 02:57:583265 }
[email protected]07f54fcc2009-12-22 02:46:303266}
3267
orglofchcad5a6742014-11-07 19:51:123268void GLES2DecoderImpl::DeleteValuebuffersCHROMIUMHelper(
3269 GLsizei n,
3270 const GLuint* client_ids) {
3271 for (GLsizei ii = 0; ii < n; ++ii) {
3272 Valuebuffer* valuebuffer = GetValuebuffer(client_ids[ii]);
3273 if (valuebuffer) {
3274 if (state_.bound_valuebuffer.get() == valuebuffer) {
3275 state_.bound_valuebuffer = NULL;
3276 }
3277 RemoveValuebuffer(client_ids[ii]);
3278 }
3279 }
3280}
3281
[email protected]ae51d192010-04-27 00:48:033282void GLES2DecoderImpl::DeleteTexturesHelper(
3283 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453284 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153285 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473286 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493287 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3288 if (texture_ref) {
3289 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103290 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443291 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463292 }
[email protected]370eaf12013-05-18 09:19:493293 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023294 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493295 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103296 }
3297 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453298 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343299 if (framebuffer_state_.bound_read_framebuffer.get()) {
3300 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113301 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103302 }
[email protected]9d3b2e12013-10-02 01:04:343303 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3304 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113305 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103306 }
3307 } else {
[email protected]9d3b2e12013-10-02 01:04:343308 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3309 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113310 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103311 }
3312 }
[email protected]e51bdf32011-11-23 22:21:463313#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073314 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463315 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3316 ReleaseIOSurfaceForTexture(service_id);
3317 }
3318#endif
[email protected]ed9f9cd2013-02-27 21:12:353319 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033320 }
[email protected]a93bb842010-02-16 23:03:473321 }
[email protected]07f54fcc2009-12-22 02:46:303322}
3323
[email protected]43f28f832010-02-03 02:28:483324// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323325
[email protected]eb54a562010-01-20 21:55:183326bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343327 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383328 return false;
3329
[email protected]177d1342013-12-07 04:20:343330 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433331 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293332
jbauman7a059312014-10-16 19:30:543333 MaybeExitOnContextLost();
[email protected]e9f0ca82013-04-01 23:52:293334
[email protected]63c9b052012-05-17 18:27:383335 return false;
[email protected]38d139d2011-07-14 00:38:433336 }
3337
[email protected]69a8701e2013-03-07 21:31:093338 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093339
[email protected]9b753992013-04-27 02:04:413340 // Rebind the FBO if it was unbound by the context.
3341 if (workarounds().unbind_fbo_on_context_switch)
3342 RestoreFramebufferBindings();
3343
[email protected]c986af502013-08-14 01:04:443344 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493345
[email protected]69a8701e2013-03-07 21:31:093346 return true;
3347}
3348
3349void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553350 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323351 if (engine() && query_manager_.get())
3352 query_manager_->ProcessPendingTransferQueries();
3353
[email protected]5b3a8e02013-03-13 05:36:443354 // TODO(epenner): Is there a better place to do this?
3355 // This needs to occur before we execute any batch of commands
3356 // from the client, as the client may have recieved an async
3357 // completion while issuing those commands.
3358 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483359 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183360}
3361
[email protected]8e3e0662010-08-23 18:46:303362static void RebindCurrentFramebuffer(
3363 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063364 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243365 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063366 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463367
[email protected]a3783712012-01-20 22:18:243368 if (framebuffer_id == 0) {
3369 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303370 }
[email protected]297ca1c2011-06-20 23:08:463371
[email protected]8e3e0662010-08-23 18:46:303372 glBindFramebufferEXT(target, framebuffer_id);
3373}
3374
3375void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443376 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463377
[email protected]62e155e2012-10-23 22:43:153378 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303379 RebindCurrentFramebuffer(
3380 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343381 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243382 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303383 } else {
3384 RebindCurrentFramebuffer(
3385 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343386 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243387 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303388 RebindCurrentFramebuffer(
3389 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343390 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243391 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303392 }
[email protected]70d34263c2013-01-09 00:27:453393 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303394}
3395
[email protected]0d6bfdc2011-11-02 01:32:203396bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353397 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203398 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103399 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423400 if (surfaceless_)
3401 return false;
[email protected]60f22d32012-12-12 00:31:583402 if (backbuffer_needs_clear_bits_) {
3403 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323404 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453405 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583406 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473407 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3408 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583409 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453410 state_.SetDeviceDepthMask(GL_TRUE);
3411 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423412 bool reset_draw_buffer = false;
brucedawson18249152014-10-31 23:02:323413 if ((backbuffer_needs_clear_bits_ & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]ee757922014-06-06 05:21:423414 group_->draw_buffer() == GL_NONE) {
3415 reset_draw_buffer = true;
3416 GLenum buf = GL_BACK;
3417 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3418 buf = GL_COLOR_ATTACHMENT0;
3419 glDrawBuffersARB(1, &buf);
3420 }
[email protected]60f22d32012-12-12 00:31:583421 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423422 if (reset_draw_buffer) {
3423 GLenum buf = GL_NONE;
3424 glDrawBuffersARB(1, &buf);
3425 }
[email protected]60f22d32012-12-12 00:31:583426 backbuffer_needs_clear_bits_ = 0;
3427 RestoreClearState();
3428 }
[email protected]0d6bfdc2011-11-02 01:32:203429 return true;
3430 }
3431
[email protected]968351b2011-12-20 08:26:513432 if (framebuffer_manager()->IsComplete(framebuffer)) {
3433 return true;
3434 }
3435
[email protected]0d6bfdc2011-11-02 01:32:203436 GLenum completeness = framebuffer->IsPossiblyComplete();
3437 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513438 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433439 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273440 return false;
3441 }
[email protected]0d6bfdc2011-11-02 01:32:203442
3443 // Are all the attachments cleared?
3444 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3445 texture_manager()->HaveUnclearedMips()) {
3446 if (!framebuffer->IsCleared()) {
3447 // Can we clear them?
[email protected]73276522012-11-09 05:50:203448 if (framebuffer->GetStatus(texture_manager(), target) !=
3449 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513450 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433451 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3452 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203453 return false;
3454 }
3455 ClearUnclearedAttachments(target, framebuffer);
3456 }
3457 }
3458
[email protected]968351b2011-12-20 08:26:513459 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203460 if (framebuffer->GetStatus(texture_manager(), target) !=
3461 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513462 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433463 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3464 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513465 return false;
3466 }
3467 framebuffer_manager()->MarkAsComplete(framebuffer);
3468 }
3469
[email protected]0d6bfdc2011-11-02 01:32:203470 // NOTE: At this point we don't know if the framebuffer is complete but
3471 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273472 return true;
3473}
3474
[email protected]0d6bfdc2011-11-02 01:32:203475bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153476 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513477 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343478 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3479 func_name);
[email protected]28718a92013-04-04 12:12:513480
3481 if (valid)
3482 OnUseFramebuffer();
3483
3484 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203485 }
[email protected]9d3b2e12013-10-02 01:04:343486 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113487 GL_DRAW_FRAMEBUFFER_EXT,
3488 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343489 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113490 GL_READ_FRAMEBUFFER_EXT,
3491 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203492}
3493
[email protected]2ea5950d2014-07-09 18:20:343494bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3495 const char* func_name) {
3496 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3497 framebuffer_state_.bound_read_framebuffer.get() :
3498 framebuffer_state_.bound_draw_framebuffer.get();
3499 if (!framebuffer)
3500 return true;
3501 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3502 LOCAL_SET_GL_ERROR(
3503 GL_INVALID_OPERATION, func_name, "no color image attached");
3504 return false;
3505 }
3506 return true;
3507}
3508
zmo383512cf2014-10-14 00:11:003509bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3510 TextureRef* texture, GLint level) {
3511 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3512 framebuffer_state_.bound_read_framebuffer.get() :
3513 framebuffer_state_.bound_draw_framebuffer.get();
3514 if (!framebuffer)
3515 return false;
3516 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3517 GL_COLOR_ATTACHMENT0);
3518 if (!attachment)
3519 return false;
3520 return attachment->FormsFeedbackLoop(texture, level);
3521}
3522
[email protected]8e3e0662010-08-23 18:46:303523gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353524 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453525 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203526 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353527 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203528 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263529 if (attachment) {
3530 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503531 }
[email protected]9edc6b22010-12-23 02:00:263532 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023533 } else if (offscreen_target_frame_buffer_.get()) {
3534 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353535 } else {
[email protected]f62a5ab2011-05-23 20:34:153536 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023537 }
[email protected]246a70452010-03-05 21:53:503538}
3539
[email protected]68586372013-12-11 01:27:593540GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3541 Framebuffer* framebuffer =
3542 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3543 if (framebuffer != NULL) {
3544 return framebuffer->GetColorAttachmentTextureType();
3545 } else {
3546 return GL_UNSIGNED_BYTE;
3547 }
3548}
3549
[email protected]9edc6b22010-12-23 02:00:263550GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353551 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453552 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203553 if (framebuffer != NULL) {
3554 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463555 } else if (offscreen_target_frame_buffer_.get()) {
3556 return offscreen_target_color_format_;
3557 } else {
3558 return back_buffer_color_format_;
3559 }
3560}
3561
3562GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353563 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453564 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203565 if (framebuffer != NULL) {
3566 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263567 } else if (offscreen_target_frame_buffer_.get()) {
3568 return offscreen_target_color_format_;
3569 } else {
[email protected]32fe9aa2011-01-21 23:47:133570 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263571 }
3572}
3573
[email protected]9a5afa432011-07-22 18:16:393574void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513575 if (!offscreen_saved_color_texture_info_.get())
3576 return;
3577 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3578 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3579 texture_manager()->SetLevelInfo(
3580 offscreen_saved_color_texture_info_.get(),
3581 GL_TEXTURE_2D,
3582 0, // level
3583 GL_RGBA,
3584 offscreen_size_.width(),
3585 offscreen_size_.height(),
3586 1, // depth
3587 0, // border
3588 GL_RGBA,
3589 GL_UNSIGNED_BYTE,
3590 true);
[email protected]737191ee72014-03-09 08:02:423591 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513592 "UpdateParentTextureInfo",
3593 GetErrorState(),
3594 offscreen_saved_color_texture_info_.get(),
3595 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263596 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423597 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513598 "UpdateParentTextureInfo",
3599 GetErrorState(),
3600 offscreen_saved_color_texture_info_.get(),
3601 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263602 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423603 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513604 "UpdateParentTextureInfo",
3605 GetErrorState(),
3606 offscreen_saved_color_texture_info_.get(),
3607 GL_TEXTURE_WRAP_S,
3608 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423609 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513610 "UpdateParentTextureInfo",
3611 GetErrorState(),
3612 offscreen_saved_color_texture_info_.get(),
3613 GL_TEXTURE_WRAP_T,
3614 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443615 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3616 &state_, target);
[email protected]2ad674132013-06-05 07:48:513617 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353618}
3619
[email protected]799b4b22011-08-22 17:09:593620void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073621 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523622 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003623}
3624
[email protected]1d82e822013-04-10 21:32:323625Logger* GLES2DecoderImpl::GetLogger() {
3626 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523627}
3628
[email protected]cac16542014-01-15 17:53:513629void GLES2DecoderImpl::BeginDecoding() {
3630 gpu_tracer_->BeginDecoding();
dyencb86f2f2014-12-09 18:35:413631 gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_;
vmiura1c2b1de2014-09-19 19:03:243632 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3633 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513634}
3635
3636void GLES2DecoderImpl::EndDecoding() {
3637 gpu_tracer_->EndDecoding();
3638}
3639
[email protected]d3eba342013-04-18 21:11:503640ErrorState* GLES2DecoderImpl::GetErrorState() {
3641 return state_.GetErrorState();
3642}
3643
[email protected]e3932abb2013-03-13 00:01:373644void GLES2DecoderImpl::SetShaderCacheCallback(
3645 const ShaderCacheCallback& callback) {
3646 shader_cache_callback_ = callback;
3647}
3648
[email protected]840a7e462013-02-27 01:29:513649void GLES2DecoderImpl::SetWaitSyncPointCallback(
3650 const WaitSyncPointCallback& callback) {
3651 wait_sync_point_callback_ = callback;
3652}
3653
[email protected]85a4ac22013-05-31 01:58:473654AsyncPixelTransferManager*
3655 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3656 return async_pixel_transfer_manager_.get();
3657}
3658
3659void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3660 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593661}
3662
[email protected]498b5c072013-06-04 19:30:073663void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3664 AsyncPixelTransferManager* manager) {
3665 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3666}
3667
[email protected]1318e922010-09-17 22:03:163668bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3669 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493670 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3671 if (texture_ref) {
3672 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163673 return true;
3674 }
3675 return false;
3676}
3677
[email protected]63b465922012-09-06 02:04:523678uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443679 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483680 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523681}
3682
3683base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443684 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483685 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523686}
3687
3688base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3689 return total_processing_commands_time_;
3690}
3691
[email protected]dc25dda2012-09-27 21:36:303692void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3693 total_processing_commands_time_ += time;
3694}
3695
[email protected]63c9b052012-05-17 18:27:383696void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063697 if (!initialized())
3698 return;
3699
[email protected]63c9b052012-05-17 18:27:383700 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053701
[email protected]80eb6b52012-01-19 00:14:413702 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243703 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523704 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023705 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243706 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133707 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343708 framebuffer_state_.bound_read_framebuffer = NULL;
3709 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243710 state_.bound_renderbuffer = NULL;
orglofchcad5a6742014-11-07 19:51:123711 state_.bound_valuebuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413712
[email protected]cadac622013-06-11 16:46:363713 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513714 DCHECK(offscreen_target_color_texture_);
3715 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3716 offscreen_saved_color_texture_->id());
3717 offscreen_saved_color_texture_->Invalidate();
3718 offscreen_saved_color_texture_info_ = NULL;
3719 }
[email protected]eadc96792010-10-27 19:39:393720 if (have_context) {
[email protected]c322e882012-05-23 18:06:183721 if (copy_texture_CHROMIUM_.get()) {
3722 copy_texture_CHROMIUM_->Destroy();
3723 copy_texture_CHROMIUM_.reset();
3724 }
[email protected]43410e92012-04-20 17:06:283725
sievers2384f2b2014-11-18 02:10:353726 clear_framebuffer_blit_.reset();
3727
[email protected]7cd76fd2013-06-02 21:11:113728 if (state_.current_program.get()) {
3729 program_manager()->UnuseProgram(shader_manager(),
3730 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143731 }
3732
[email protected]b1122982010-05-17 23:04:243733 if (attrib_0_buffer_id_) {
3734 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3735 }
[email protected]8fbedc02010-11-18 18:43:403736 if (fixed_attrib_buffer_id_) {
3737 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3738 }
[email protected]b1122982010-05-17 23:04:243739
[email protected]4a4c18b2013-09-13 22:50:103740 if (validation_texture_) {
3741 glDeleteTextures(1, &validation_texture_);
3742 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3743 glDeleteFramebuffersEXT(1, &validation_fbo_);
3744 }
3745
[email protected]97872062010-11-03 19:07:053746 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543747 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053748 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543749 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053750 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023751 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053752 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153753 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053754 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153755 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053756 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023757 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053758 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543759 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273760 if (offscreen_resolved_frame_buffer_.get())
3761 offscreen_resolved_frame_buffer_->Destroy();
3762 if (offscreen_resolved_color_texture_.get())
3763 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053764 } else {
3765 if (offscreen_target_frame_buffer_.get())
3766 offscreen_target_frame_buffer_->Invalidate();
3767 if (offscreen_target_color_texture_.get())
3768 offscreen_target_color_texture_->Invalidate();
3769 if (offscreen_target_color_render_buffer_.get())
3770 offscreen_target_color_render_buffer_->Invalidate();
3771 if (offscreen_target_depth_render_buffer_.get())
3772 offscreen_target_depth_render_buffer_->Invalidate();
3773 if (offscreen_target_stencil_render_buffer_.get())
3774 offscreen_target_stencil_render_buffer_->Invalidate();
3775 if (offscreen_saved_frame_buffer_.get())
3776 offscreen_saved_frame_buffer_->Invalidate();
3777 if (offscreen_saved_color_texture_.get())
3778 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273779 if (offscreen_resolved_frame_buffer_.get())
3780 offscreen_resolved_frame_buffer_->Invalidate();
3781 if (offscreen_resolved_color_texture_.get())
3782 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023783 }
[email protected]83a52d032013-07-24 10:30:373784
3785 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3786 // Otherwise, we can leak objects. http://crbug.com/258772.
3787 // state_.current_program must be reset before group_ is reset because
3788 // the later deletes the ProgramManager object that referred by
3789 // state_.current_program object.
3790 state_.current_program = NULL;
3791
[email protected]43410e92012-04-20 17:06:283792 copy_texture_CHROMIUM_.reset();
sievers2384f2b2014-11-18 02:10:353793 clear_framebuffer_blit_.reset();
[email protected]97872062010-11-03 19:07:053794
[email protected]882ba1e22012-03-08 19:02:533795 if (query_manager_.get()) {
3796 query_manager_->Destroy(have_context);
3797 query_manager_.reset();
3798 }
3799
[email protected]944b62f32012-09-27 02:20:463800 if (vertex_array_manager_ .get()) {
3801 vertex_array_manager_->Destroy(have_context);
3802 vertex_array_manager_.reset();
3803 }
3804
[email protected]d2eaf52f2014-07-31 15:01:243805 if (image_manager_.get()) {
3806 image_manager_->Destroy(have_context);
3807 image_manager_.reset();
3808 }
3809
[email protected]97872062010-11-03 19:07:053810 offscreen_target_frame_buffer_.reset();
3811 offscreen_target_color_texture_.reset();
3812 offscreen_target_color_render_buffer_.reset();
3813 offscreen_target_depth_render_buffer_.reset();
3814 offscreen_target_stencil_render_buffer_.reset();
3815 offscreen_saved_frame_buffer_.reset();
3816 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273817 offscreen_resolved_frame_buffer_.reset();
3818 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463819
[email protected]03cef9b2014-04-03 15:58:143820 // Need to release these before releasing |group_| which may own the
3821 // ShaderTranslatorCache.
3822 fragment_translator_ = NULL;
3823 vertex_translator_ = NULL;
3824
[email protected]85a4ac22013-05-31 01:58:473825 // Should destroy the transfer manager before the texture manager held
3826 // by the context group.
3827 async_pixel_transfer_manager_.reset();
3828
dyendbfb90d2015-03-26 02:41:463829 // Destroy the GPU Tracer which may own some in process GPU Timings.
dyen8ef659882015-03-26 23:32:513830 if (gpu_tracer_) {
3831 gpu_tracer_->Destroy(have_context);
3832 gpu_tracer_.reset();
3833 }
dyendbfb90d2015-03-26 02:41:463834
[email protected]7cd76fd2013-06-02 21:11:113835 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393836 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233837 group_->Destroy(this, have_context);
3838 group_ = NULL;
3839 }
3840
3841 if (context_.get()) {
3842 context_->ReleaseCurrent(NULL);
3843 context_ = NULL;
3844 }
3845
[email protected]e51bdf32011-11-23 22:21:463846#if defined(OS_MACOSX)
3847 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3848 it != texture_to_io_surface_map_.end(); ++it) {
3849 CFRelease(it->second);
3850 }
3851 texture_to_io_surface_map_.clear();
3852#endif
[email protected]96449d2c2009-11-25 00:01:323853}
3854
[email protected]63c9b052012-05-17 18:27:383855void GLES2DecoderImpl::SetSurface(
3856 const scoped_refptr<gfx::GLSurface>& surface) {
3857 DCHECK(context_->IsCurrent(NULL));
3858 DCHECK(surface_.get());
3859 surface_ = surface;
3860 RestoreCurrentFramebufferBindings();
3861}
3862
[email protected]aba551b2014-02-08 03:38:323863void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3864 if (!offscreen_saved_color_texture_.get()) {
3865 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3866 return;
3867 }
[email protected]2ad674132013-06-05 07:48:513868 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243869 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073870 offscreen_saved_color_texture_info_ = TextureRef::Create(
3871 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513872 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3873 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393874 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243875 }
[email protected]aba551b2014-02-08 03:38:323876 mailbox_manager()->ProduceTexture(
sievers8b373ec52014-10-24 23:04:063877 mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243878}
3879
[email protected]799b4b22011-08-22 17:09:593880bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3881 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3882 if (!is_offscreen) {
3883 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3884 << " with an onscreen framebuffer.";
3885 return false;
3886 }
3887
3888 if (offscreen_size_ == size)
3889 return true;
3890
3891 offscreen_size_ = size;
3892 int w = offscreen_size_.width();
3893 int h = offscreen_size_.height();
3894 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3895 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3896 << "to allocate storage due to excessive dimensions.";
3897 return false;
3898 }
3899
3900 // Reallocate the offscreen target buffers.
3901 DCHECK(offscreen_target_color_format_);
3902 if (IsOffscreenBufferMultisampled()) {
3903 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253904 feature_info_.get(),
3905 offscreen_size_,
3906 offscreen_target_color_format_,
3907 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593908 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3909 << "to allocate storage for offscreen target color buffer.";
3910 return false;
3911 }
3912 } else {
3913 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093914 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593915 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3916 << "to allocate storage for offscreen target color texture.";
3917 return false;
3918 }
3919 }
3920 if (offscreen_target_depth_format_ &&
3921 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253922 feature_info_.get(),
3923 offscreen_size_,
3924 offscreen_target_depth_format_,
3925 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593926 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3927 << "to allocate storage for offscreen target depth buffer.";
3928 return false;
3929 }
3930 if (offscreen_target_stencil_format_ &&
3931 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253932 feature_info_.get(),
3933 offscreen_size_,
3934 offscreen_target_stencil_format_,
3935 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593936 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3937 << "to allocate storage for offscreen target stencil buffer.";
3938 return false;
3939 }
3940
3941 // Attach the offscreen target buffers to the target frame buffer.
3942 if (IsOffscreenBufferMultisampled()) {
3943 offscreen_target_frame_buffer_->AttachRenderBuffer(
3944 GL_COLOR_ATTACHMENT0,
3945 offscreen_target_color_render_buffer_.get());
3946 } else {
3947 offscreen_target_frame_buffer_->AttachRenderTexture(
3948 offscreen_target_color_texture_.get());
3949 }
3950 if (offscreen_target_depth_format_) {
3951 offscreen_target_frame_buffer_->AttachRenderBuffer(
3952 GL_DEPTH_ATTACHMENT,
3953 offscreen_target_depth_render_buffer_.get());
3954 }
3955 const bool packed_depth_stencil =
3956 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3957 if (packed_depth_stencil) {
3958 offscreen_target_frame_buffer_->AttachRenderBuffer(
3959 GL_STENCIL_ATTACHMENT,
3960 offscreen_target_depth_render_buffer_.get());
3961 } else if (offscreen_target_stencil_format_) {
3962 offscreen_target_frame_buffer_->AttachRenderBuffer(
3963 GL_STENCIL_ATTACHMENT,
3964 offscreen_target_stencil_render_buffer_.get());
3965 }
3966
3967 if (offscreen_target_frame_buffer_->CheckStatus() !=
3968 GL_FRAMEBUFFER_COMPLETE) {
3969 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3970 << "because offscreen FBO was incomplete.";
3971 return false;
3972 }
3973
3974 // Clear the target frame buffer.
3975 {
3976 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3977 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323978 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453979 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593980 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473981 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3982 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593983 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453984 state_.SetDeviceDepthMask(GL_TRUE);
3985 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593986 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3987 RestoreClearState();
3988 }
[email protected]d85ef76d2011-09-08 22:21:433989
3990 // Destroy the offscreen resolved framebuffers.
3991 if (offscreen_resolved_frame_buffer_.get())
3992 offscreen_resolved_frame_buffer_->Destroy();
3993 if (offscreen_resolved_color_texture_.get())
3994 offscreen_resolved_color_texture_->Destroy();
3995 offscreen_resolved_color_texture_.reset();
3996 offscreen_resolved_frame_buffer_.reset();
3997
[email protected]799b4b22011-08-22 17:09:593998 return true;
[email protected]6217d392010-03-25 22:08:353999}
4000
vmiuracd108592014-09-08 14:36:344001error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
4002 const void* cmd_data) {
4003 const gles2::cmds::ResizeCHROMIUM& c =
4004 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:444005 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:024006 return error::kDeferCommandUntilLater;
4007
[email protected]799b4b22011-08-22 17:09:594008 GLuint width = static_cast<GLuint>(c.width);
4009 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:074010 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:594011 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:414012
4013 width = std::max(1U, width);
4014 height = std::max(1U, height);
4015
[email protected]a0d989162011-11-22 13:15:074016#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
4017 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:004018 // Make sure that we are done drawing to the back buffer before resizing.
4019 glFinish();
4020#endif
[email protected]799b4b22011-08-22 17:09:594021 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
4022 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:494023 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
4024 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
4025 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:594026 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:494027 }
[email protected]7ff86b92010-11-25 17:50:004028 }
[email protected]799b4b22011-08-22 17:09:594029
[email protected]9d37f062011-11-22 01:24:524030 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:074031 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:444032 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:494033 if (!context_->IsCurrent(surface_.get())) {
4034 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
4035 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:054036 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:494037 }
[email protected]658f7562011-09-09 05:24:054038 }
[email protected]799b4b22011-08-22 17:09:594039
4040 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:394041}
4042
[email protected]96449d2c2009-11-25 00:01:324043const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
4044 if (command_id > kStartPoint && command_id < kNumCommands) {
4045 return gles2::GetCommandName(static_cast<CommandId>(command_id));
4046 }
4047 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
4048}
4049
vmiura8266ca72014-09-09 21:37:004050// Decode a command, and call the corresponding GL functions.
4051// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
4052// of commands at once, and is now only used for tests that need to track
4053// individual commands.
4054error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
4055 unsigned int arg_count,
4056 const void* cmd_data) {
4057 return DoCommands(1, cmd_data, arg_count + 1, 0);
4058}
4059
4060// Decode multiple commands, and call the corresponding GL functions.
4061// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
4062// changed by a (malicious) client at any time, so if validation has to happen,
4063// it should operate on a copy of them.
4064// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
4065// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:244066template <bool DebugImpl>
4067error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
4068 const void* buffer,
4069 int num_entries,
4070 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:004071 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:144072 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:004073 const CommandBufferEntry* cmd_data =
4074 static_cast<const CommandBufferEntry*>(buffer);
4075 int process_pos = 0;
4076 unsigned int command = 0;
4077
4078 while (process_pos < num_entries && result == error::kNoError &&
4079 commands_to_process_--) {
4080 const unsigned int size = cmd_data->value_header.size;
4081 command = cmd_data->value_header.command;
4082
4083 if (size == 0) {
4084 result = error::kInvalidSize;
4085 break;
4086 }
4087
4088 if (static_cast<int>(size) + process_pos > num_entries) {
4089 result = error::kOutOfBounds;
4090 break;
4091 }
4092
vmiura1c2b1de2014-09-19 19:03:244093 if (DebugImpl) {
4094 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4095 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:004096
vmiura1c2b1de2014-09-19 19:03:244097 if (log_commands()) {
4098 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
4099 << "cmd: " << GetCommandName(command);
4100 }
vmiura8266ca72014-09-09 21:37:004101 }
4102
4103 const unsigned int arg_count = size - 1;
4104 unsigned int command_index = command - kStartPoint - 1;
4105 if (command_index < arraysize(command_info)) {
4106 const CommandInfo& info = command_info[command_index];
4107 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
4108 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
4109 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
4110 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:244111 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:004112 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
4113 doing_gpu_trace = true;
dyencb86f2f2014-12-09 18:35:414114 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_decoder"),
4115 GetCommandName(command),
4116 kTraceDecoder);
vmiura8266ca72014-09-09 21:37:004117 }
[email protected]cac16542014-01-15 17:53:514118 }
[email protected]cac16542014-01-15 17:53:514119
vmiura8266ca72014-09-09 21:37:004120 uint32 immediate_data_size = (arg_count - info_arg_count) *
4121 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:324122
vmiura8266ca72014-09-09 21:37:004123 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:514124
vmiura1c2b1de2014-09-19 19:03:244125 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:004126 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:514127
vmiura1c2b1de2014-09-19 19:03:244128 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:004129 GLenum error;
4130 while ((error = glGetError()) != GL_NO_ERROR) {
4131 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
4132 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
4133 << " : " << GetCommandName(command);
4134 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
4135 }
[email protected]b9849abf2009-11-25 19:13:194136 }
vmiura8266ca72014-09-09 21:37:004137 } else {
4138 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:324139 }
4140 } else {
vmiura8266ca72014-09-09 21:37:004141 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:324142 }
vmiura1c2b1de2014-09-19 19:03:244143
4144 if (DebugImpl) {
4145 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4146 GetCommandName(command));
4147 }
4148
vmiura8266ca72014-09-09 21:37:004149 if (result == error::kNoError &&
4150 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:564151 result = current_decoder_error_;
4152 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:004153 }
4154
4155 if (result != error::kDeferCommandUntilLater) {
4156 process_pos += size;
4157 cmd_data += size;
4158 }
[email protected]a3a93e7b2010-08-28 00:48:564159 }
vmiura8266ca72014-09-09 21:37:004160
4161 if (entries_processed)
4162 *entries_processed = process_pos;
4163
4164 if (error::IsError(result)) {
4165 LOG(ERROR) << "Error: " << result << " for Command "
4166 << GetCommandName(command);
4167 }
4168
[email protected]b9849abf2009-11-25 19:13:194169 return result;
[email protected]96449d2c2009-11-25 00:01:324170}
4171
vmiura1c2b1de2014-09-19 19:03:244172error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
4173 const void* buffer,
4174 int num_entries,
4175 int* entries_processed) {
4176 if (gpu_debug_commands_) {
4177 return DoCommandsImpl<true>(
4178 num_commands, buffer, num_entries, entries_processed);
4179 } else {
4180 return DoCommandsImpl<false>(
4181 num_commands, buffer, num_entries, entries_processed);
4182 }
4183}
4184
[email protected]ed9f9cd2013-02-27 21:12:354185void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
4186 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:504187}
4188
[email protected]882ba1e22012-03-08 19:02:534189void GLES2DecoderImpl::DoFinish() {
4190 glFinish();
[email protected]5a36dc132013-07-23 23:17:554191 ProcessPendingReadPixels();
revemancc241eb2014-11-11 03:30:374192 ProcessPendingQueries(true);
[email protected]882ba1e22012-03-08 19:02:534193}
4194
4195void GLES2DecoderImpl::DoFlush() {
4196 glFlush();
revemancc241eb2014-11-11 03:30:374197 ProcessPendingQueries(false);
[email protected]882ba1e22012-03-08 19:02:534198}
4199
[email protected]3916c97e2010-02-25 03:20:504200void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:454201 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:024202 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:514203 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:534204 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:504205 return;
4206 }
[email protected]e259eb412012-10-13 05:47:244207 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:454208 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:504209}
4210
[email protected]051b1372010-04-12 02:42:084211void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:074212 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:084213 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034214 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:074215 buffer = GetBuffer(client_id);
4216 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:354217 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224218 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4219 "glBindBuffer",
4220 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:354221 return;
4222 }
4223
[email protected]b10492f2013-03-08 05:24:074224 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:034225 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354226 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:074227 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034228 }
[email protected]051b1372010-04-12 02:42:084229 }
[email protected]b10492f2013-03-08 05:24:074230 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
4231 if (buffer) {
4232 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:514233 LOCAL_SET_GL_ERROR(
4234 GL_INVALID_OPERATION,
4235 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:474236 return;
4237 }
[email protected]b10492f2013-03-08 05:24:074238 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:474239 }
[email protected]96449d2c2009-11-25 00:01:324240 switch (target) {
4241 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074242 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:324243 break;
4244 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074245 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:324246 break;
4247 default:
[email protected]a93bb842010-02-16 23:03:474248 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:324249 break;
4250 }
[email protected]051b1372010-04-12 02:42:084251 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:324252}
4253
[email protected]f3b191b2013-06-19 03:43:544254bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
4255 bool all_draw_buffers) {
4256 Framebuffer* framebuffer =
4257 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4258 if (!all_draw_buffers || !framebuffer) {
4259 return (GLES2Util::GetChannelsForFormat(
4260 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
4261 }
4262 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:464263}
4264
4265bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354266 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454267 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204268 if (framebuffer) {
4269 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464270 }
4271 if (offscreen_target_frame_buffer_.get()) {
4272 return offscreen_target_depth_format_ != 0;
4273 }
4274 return back_buffer_has_depth_;
4275}
4276
4277bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354278 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454279 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204280 if (framebuffer) {
4281 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464282 }
4283 if (offscreen_target_frame_buffer_.get()) {
4284 return offscreen_target_stencil_format_ != 0 ||
4285 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4286 }
4287 return back_buffer_has_stencil_;
4288}
4289
4290void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444291 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454292 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4293 state_.SetDeviceColorMask(state_.color_mask_red,
4294 state_.color_mask_green,
4295 state_.color_mask_blue,
4296 state_.color_mask_alpha && have_alpha);
4297
[email protected]297ca1c2011-06-20 23:08:464298 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454299 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4300
[email protected]297ca1c2011-06-20 23:08:464301 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454302 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424303 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454304 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424305 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454306
4307 state_.SetDeviceCapabilityState(
4308 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4309 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224310 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444311 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464312 }
4313}
4314
[email protected]1868a342012-11-07 15:56:024315GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114316 return (offscreen_target_frame_buffer_.get())
4317 ? offscreen_target_frame_buffer_->id()
4318 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024319}
4320
[email protected]8875a5f2014-06-27 08:33:474321void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144322 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4323 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064324 // Restore the Framebuffer first because of bugs in Intel drivers.
4325 // Intel drivers incorrectly clip the viewport settings to
4326 // the size of the current framebuffer object.
4327 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164328 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064329}
4330
4331void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344332 GLuint service_id =
4333 framebuffer_state_.bound_draw_framebuffer.get()
4334 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4335 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064336 if (!features().chromium_framebuffer_multisample) {
4337 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4338 } else {
4339 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344340 service_id = framebuffer_state_.bound_read_framebuffer.get()
4341 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114342 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064343 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4344 }
[email protected]70d34263c2013-01-09 00:27:454345 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064346}
4347
[email protected]8875a5f2014-06-27 08:33:474348void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4349 state_.RestoreRenderbufferBindings();
4350}
4351
[email protected]29a4d902013-02-26 20:18:064352void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104353 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4354 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254355 GLenum target = texture->target();
4356 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064357 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254358 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064359 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254360 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064361 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254362 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064363 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254364 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064365 RestoreTextureUnitBindings(state_.active_texture_unit);
4366 }
[email protected]70d34263c2013-01-09 00:27:454367}
4368
[email protected]cd2ef752014-02-12 23:16:034369void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524370 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4371 // other VAOs.
4372 if (feature_info_->feature_flags().native_vertex_array_object)
4373 glBindVertexArrayOES(0);
4374
[email protected]cd2ef752014-02-12 23:16:034375 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
dcastagna504d45c2015-04-06 19:30:394376 if (i != 0) // Never disable attribute 0
[email protected]cd2ef752014-02-12 23:16:034377 glDisableVertexAttribArray(i);
dcastagna504d45c2015-04-06 19:30:394378 if (features().angle_instanced_arrays)
[email protected]cd2ef752014-02-12 23:16:034379 glVertexAttribDivisorANGLE(i, 0);
4380 }
4381}
4382
4383void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524384 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034385}
4386
[email protected]454157e2014-05-03 02:49:454387void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4388 state_.SetIgnoreCachedStateForTest(ignore);
4389}
4390
[email protected]70d34263c2013-01-09 00:27:454391void GLES2DecoderImpl::OnFboChanged() const {
4392 if (workarounds().restore_scissor_on_fbo_change)
zmo8ac3bab2015-04-18 02:30:584393 state_.fbo_binding_for_scissor_workaround_dirty = true;
ccameron4ff12a732014-12-12 21:38:194394
4395 if (workarounds().gl_begin_gl_end_on_fbo_change_to_backbuffer) {
4396 GLint bound_fbo_unsigned = -1;
4397 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_fbo_unsigned);
4398 GLuint bound_fbo = static_cast<GLuint>(bound_fbo_unsigned);
4399 if (surface_ && surface_->GetBackingFrameBufferObject() == bound_fbo)
4400 surface_->NotifyWasBound();
4401 }
[email protected]28718a92013-04-04 12:12:514402}
4403
4404// Called after the FBO is checked for completeness.
4405void GLES2DecoderImpl::OnUseFramebuffer() const {
zmo8ac3bab2015-04-18 02:30:584406 if (state_.fbo_binding_for_scissor_workaround_dirty) {
4407 state_.fbo_binding_for_scissor_workaround_dirty = false;
[email protected]81fc9d02013-03-14 23:53:324408 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514409 glScissor(state_.scissor_x,
4410 state_.scissor_y,
4411 state_.scissor_width,
4412 state_.scissor_height);
4413
4414 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4415 // it's unclear how this bug works.
4416 glFlush();
4417 }
[email protected]b177ae22011-11-01 03:29:114418}
4419
[email protected]051b1372010-04-12 02:42:084420void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064421 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084422 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034423 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064424 framebuffer = GetFramebuffer(client_id);
4425 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354426 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224427 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4428 "glBindFramebuffer",
4429 "id not generated by glGenFramebuffers");
4430 return;
[email protected]bf5a8d132011-08-16 08:39:354431 }
4432
[email protected]4d8f0dd2013-03-09 14:37:064433 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034434 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354435 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064436 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034437 } else {
[email protected]4d8f0dd2013-03-09 14:37:064438 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084439 }
[email protected]4d8f0dd2013-03-09 14:37:064440 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084441 }
[email protected]4d8f0dd2013-03-09 14:37:064442 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304443
4444 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344445 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304446 }
[email protected]cac16542014-01-15 17:53:514447
4448 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304449 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344450 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304451 }
[email protected]6217d392010-03-25 22:08:354452
[email protected]c986af502013-08-14 01:04:444453 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464454
[email protected]b177ae22011-11-01 03:29:114455 // If we are rendering to the backbuffer get the FBO id for any simulated
4456 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064457 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114458 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464459 }
[email protected]6217d392010-03-25 22:08:354460
[email protected]051b1372010-04-12 02:42:084461 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454462 OnFboChanged();
[email protected]86093972010-03-11 00:13:564463}
4464
[email protected]051b1372010-04-12 02:42:084465void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274466 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084467 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034468 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274469 renderbuffer = GetRenderbuffer(client_id);
4470 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354471 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224472 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4473 "glBindRenderbuffer",
4474 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354475 return;
4476 }
4477
[email protected]8875a5f2014-06-27 08:33:474478 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034479 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354480 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274481 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034482 } else {
[email protected]ee2a79c32013-03-10 03:50:274483 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084484 }
[email protected]ee2a79c32013-03-10 03:50:274485 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084486 }
[email protected]caa13ed2014-02-17 11:29:204487 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274488 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474489 state_.bound_renderbuffer_valid = true;
4490 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564491}
4492
[email protected]051b1372010-04-12 02:42:084493void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494494 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084495 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034496 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494497 texture_ref = GetTexture(client_id);
4498 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354499 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224500 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4501 "glBindTexture",
4502 "id not generated by glGenTextures");
4503 return;
[email protected]bf5a8d132011-08-16 08:39:354504 }
4505
[email protected]02965c22013-03-09 02:40:074506 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034507 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414508 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354509 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494510 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034511 }
4512 } else {
[email protected]370eaf12013-05-18 09:19:494513 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084514 }
[email protected]ae51d192010-04-27 00:48:034515
[email protected]1958e0e2010-04-22 05:17:154516 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574517 if (texture_ref) {
4518 Texture* texture = texture_ref->texture();
4519 // Check that we are not trying to bind it to a different target.
4520 if (texture->target() != 0 && texture->target() != target) {
4521 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4522 "glBindTexture",
4523 "texture bound to more than 1 target.");
4524 return;
4525 }
4526 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4527 if (texture->target() == 0) {
4528 texture_manager()->SetTarget(texture_ref, target);
4529 }
4530 glBindTexture(target, texture->service_id());
4531 } else {
4532 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154533 }
[email protected]32145a92012-12-17 09:01:594534
[email protected]e259eb412012-10-13 05:47:244535 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504536 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474537 switch (target) {
4538 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494539 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474540 break;
4541 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494542 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474543 break;
[email protected]61eeb33f2011-07-26 15:30:314544 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494545 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314546 break;
[email protected]e51bdf32011-11-23 22:21:464547 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494548 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464549 break;
[email protected]a93bb842010-02-16 23:03:474550 default:
4551 NOTREACHED(); // Validation should prevent us getting here.
4552 break;
4553 }
4554}
4555
[email protected]07f54fcc2009-12-22 02:46:304556void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244557 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124558 if (index != 0 ||
4559 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244560 glDisableVertexAttribArray(index);
4561 }
[email protected]07f54fcc2009-12-22 02:46:304562 } else {
[email protected]ab09b612013-03-11 22:11:514563 LOCAL_SET_GL_ERROR(
4564 GL_INVALID_VALUE,
4565 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304566 }
4567}
4568
[email protected]60f22d32012-12-12 00:31:584569void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4570 GLsizei numAttachments,
4571 const GLenum* attachments) {
aelias8ef99b8a2015-04-07 23:19:354572 if (workarounds().disable_discard_framebuffer)
dyen5f38cadc2015-03-26 16:58:424573 return;
4574
[email protected]ed9f9cd2013-02-27 21:12:354575 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584576 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4577
4578 // Validates the attachments. If one of them fails
4579 // the whole command fails.
4580 for (GLsizei i = 0; i < numAttachments; ++i) {
4581 if ((framebuffer &&
4582 !validators_->attachment.IsValid(attachments[i])) ||
4583 (!framebuffer &&
4584 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514585 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4586 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584587 return;
4588 }
4589 }
4590
4591 // Marks each one of them as not cleared
4592 for (GLsizei i = 0; i < numAttachments; ++i) {
4593 if (framebuffer) {
4594 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4595 texture_manager(),
4596 attachments[i],
4597 false);
4598 } else {
4599 switch (attachments[i]) {
4600 case GL_COLOR_EXT:
4601 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4602 break;
4603 case GL_DEPTH_EXT:
4604 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4605 case GL_STENCIL_EXT:
4606 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4607 break;
4608 default:
4609 NOTREACHED();
4610 break;
4611 }
4612 }
4613 }
4614
[email protected]d49c5402013-09-11 15:39:024615 // If the default framebuffer is bound but we are still rendering to an
4616 // FBO, translate attachment names that refer to default framebuffer
4617 // channels to corresponding framebuffer attachments.
4618 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4619 for (GLsizei i = 0; i < numAttachments; ++i) {
4620 GLenum attachment = attachments[i];
4621 if (!framebuffer && GetBackbufferServiceId()) {
4622 switch (attachment) {
4623 case GL_COLOR_EXT:
4624 attachment = GL_COLOR_ATTACHMENT0;
4625 break;
4626 case GL_DEPTH_EXT:
4627 attachment = GL_DEPTH_ATTACHMENT;
4628 break;
4629 case GL_STENCIL_EXT:
4630 attachment = GL_STENCIL_ATTACHMENT;
4631 break;
4632 default:
4633 NOTREACHED();
4634 return;
4635 }
4636 }
4637 translated_attachments[i] = attachment;
4638 }
4639
boliu2e7d8a7a2014-10-16 20:35:204640 ScopedRenderTo do_render(framebuffer);
marcheu1856f5d52015-04-04 01:42:534641 if (feature_info_->gl_version_info().is_es3) {
zmo68fcdc62014-12-05 21:51:494642 glInvalidateFramebuffer(
4643 target, numAttachments, translated_attachments.get());
4644 } else {
4645 glDiscardFramebufferEXT(
4646 target, numAttachments, translated_attachments.get());
4647 }
[email protected]60f22d32012-12-12 00:31:584648}
4649
[email protected]07f54fcc2009-12-22 02:46:304650void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244651 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304652 glEnableVertexAttribArray(index);
4653 } else {
[email protected]ab09b612013-03-11 22:11:514654 LOCAL_SET_GL_ERROR(
4655 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304656 }
4657}
4658
[email protected]a93bb842010-02-16 23:03:474659void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444660 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4661 &state_, target);
[email protected]370eaf12013-05-18 09:19:494662 if (!texture_ref ||
4663 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514664 LOCAL_SET_GL_ERROR(
4665 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474666 return;
4667 }
[email protected]38c0a972012-05-12 00:48:024668
[email protected]12d95352012-12-14 07:23:544669 if (target == GL_TEXTURE_CUBE_MAP) {
4670 for (int i = 0; i < 6; ++i) {
4671 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494672 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514673 LOCAL_SET_GL_ERROR(
4674 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544675 return;
4676 }
4677 }
4678 } else {
[email protected]370eaf12013-05-18 09:19:494679 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514680 LOCAL_SET_GL_ERROR(
4681 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544682 return;
4683 }
[email protected]7687479c2012-05-14 23:54:044684 }
4685
[email protected]ab09b612013-03-11 22:11:514686 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194687 // Workaround for Mac driver bug. In the large scheme of things setting
4688 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564689 // hit so there's probably no need to make this conditional. The bug appears
4690 // to be that if the filtering mode is set to something that doesn't require
4691 // mipmaps for rendering, or is never set to something other than the default,
4692 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154693 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194694 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4695 }
[email protected]a93bb842010-02-16 23:03:474696 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154697 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494698 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4699 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194700 }
[email protected]ab09b612013-03-11 22:11:514701 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024702 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494703 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024704 }
[email protected]a93bb842010-02-16 23:03:474705}
4706
[email protected]b273e432010-04-12 17:23:584707bool GLES2DecoderImpl::GetHelper(
4708 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584709 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154710 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4711 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434712 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4713 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214714 // Return the GL implementation's preferred format and (see below type)
4715 // if we have the GL extension that exposes this. This allows the GPU
4716 // client to use the implementation's preferred format for glReadPixels
4717 // for optimisation.
4718 //
4719 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4720 // case when requested on integer/floating point buffers but which is
4721 // acceptable on GLES2 and with the GL_OES_read_format extension.
4722 //
4723 // Therefore if an error occurs we swallow the error and use the
4724 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434725 if (params) {
[email protected]c959a09a2014-03-27 11:44:214726 if (context_->HasExtension("GL_OES_read_format")) {
4727 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4728 GetErrorState());
4729 glGetIntegerv(pname, params);
4730 if (glGetError() == GL_NO_ERROR)
4731 return true;
4732 }
[email protected]68586372013-12-11 01:27:594733 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4734 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434735 }
4736 return true;
4737 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4738 *num_written = 1;
4739 if (params) {
[email protected]c959a09a2014-03-27 11:44:214740 if (context_->HasExtension("GL_OES_read_format")) {
4741 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4742 GetErrorState());
4743 glGetIntegerv(pname, params);
4744 if (glGetError() == GL_NO_ERROR)
4745 return true;
4746 }
[email protected]68586372013-12-11 01:27:594747 *params = GLES2Util::GetPreferredGLReadPixelsType(
4748 GetBoundReadFrameBufferInternalFormat(),
4749 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434750 }
4751 return true;
4752 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4753 *num_written = 1;
4754 if (params) {
4755 *params = group_->max_fragment_uniform_vectors();
4756 }
4757 return true;
4758 case GL_MAX_VARYING_VECTORS:
4759 *num_written = 1;
4760 if (params) {
4761 *params = group_->max_varying_vectors();
4762 }
4763 return true;
4764 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4765 *num_written = 1;
4766 if (params) {
4767 *params = group_->max_vertex_uniform_vectors();
4768 }
4769 return true;
[email protected]4e8a5b122010-05-08 22:00:104770 }
[email protected]5cb735d2011-10-13 01:37:234771 }
4772 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244773 case GL_MAX_VIEWPORT_DIMS:
4774 if (offscreen_target_frame_buffer_.get()) {
4775 *num_written = 2;
4776 if (params) {
4777 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4778 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4779 }
4780 return true;
4781 }
[email protected]5cb735d2011-10-13 01:37:234782 return false;
[email protected]84afefa2011-10-19 21:45:534783 case GL_MAX_SAMPLES:
4784 *num_written = 1;
4785 if (params) {
4786 params[0] = renderbuffer_manager()->max_samples();
4787 }
4788 return true;
4789 case GL_MAX_RENDERBUFFER_SIZE:
4790 *num_written = 1;
4791 if (params) {
4792 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4793 }
4794 return true;
[email protected]5cb735d2011-10-13 01:37:234795 case GL_MAX_TEXTURE_SIZE:
4796 *num_written = 1;
4797 if (params) {
4798 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4799 }
4800 return true;
4801 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4802 *num_written = 1;
4803 if (params) {
4804 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4805 }
4806 return true;
[email protected]2f143d482013-03-14 18:04:494807 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4808 *num_written = 1;
4809 if (params) {
4810 params[0] = group_->max_color_attachments();
4811 }
4812 return true;
4813 case GL_MAX_DRAW_BUFFERS_ARB:
4814 *num_written = 1;
4815 if (params) {
4816 params[0] = group_->max_draw_buffers();
4817 }
4818 return true;
[email protected]297ca1c2011-06-20 23:08:464819 case GL_ALPHA_BITS:
4820 *num_written = 1;
4821 if (params) {
4822 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:534823 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:124824 Framebuffer* framebuffer =
4825 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4826 if (framebuffer) {
4827 glGetFramebufferAttachmentParameterivEXT(
4828 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
4829 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &v);
4830 } else {
4831 v = (back_buffer_color_format_ == GL_RGBA ? 8 : 0);
4832 }
4833 } else {
4834 glGetIntegerv(GL_ALPHA_BITS, &v);
4835 }
4836 params[0] =
4837 BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464838 }
4839 return true;
4840 case GL_DEPTH_BITS:
4841 *num_written = 1;
4842 if (params) {
4843 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:534844 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:124845 Framebuffer* framebuffer =
4846 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4847 if (framebuffer) {
4848 glGetFramebufferAttachmentParameterivEXT(
4849 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
4850 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &v);
4851 } else {
4852 v = (back_buffer_has_depth_ ? 24 : 0);
4853 }
4854 } else {
4855 glGetIntegerv(GL_DEPTH_BITS, &v);
4856 }
[email protected]297ca1c2011-06-20 23:08:464857 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4858 }
4859 return true;
kbrc9f0e10c2015-03-31 19:49:124860 case GL_RED_BITS:
4861 case GL_GREEN_BITS:
4862 case GL_BLUE_BITS:
4863 *num_written = 1;
4864 if (params) {
4865 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:534866 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:124867 Framebuffer* framebuffer =
4868 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4869 if (framebuffer) {
4870 GLenum framebuffer_enum = 0;
4871 switch (pname) {
4872 case GL_RED_BITS:
4873 framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
4874 break;
4875 case GL_GREEN_BITS:
4876 framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
4877 break;
4878 case GL_BLUE_BITS:
4879 framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
4880 break;
4881 }
4882 glGetFramebufferAttachmentParameterivEXT(
4883 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, framebuffer_enum, &v);
4884 } else {
4885 v = 8;
4886 }
4887 } else {
4888 glGetIntegerv(pname, &v);
4889 }
4890 params[0] = v;
4891 }
4892 return true;
[email protected]297ca1c2011-06-20 23:08:464893 case GL_STENCIL_BITS:
4894 *num_written = 1;
4895 if (params) {
4896 GLint v = 0;
marcheu1856f5d52015-04-04 01:42:534897 if (feature_info_->gl_version_info().is_desktop_core_profile) {
kbrc9f0e10c2015-03-31 19:49:124898 Framebuffer* framebuffer =
4899 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4900 if (framebuffer) {
4901 glGetFramebufferAttachmentParameterivEXT(
4902 GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
4903 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &v);
4904 } else {
4905 v = (back_buffer_has_stencil_ ? 8 : 0);
4906 }
4907 } else {
4908 glGetIntegerv(GL_STENCIL_BITS, &v);
4909 }
[email protected]297ca1c2011-06-20 23:08:464910 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4911 }
4912 return true;
[email protected]656dcaad2010-05-07 17:18:374913 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114914 *num_written = validators_->compressed_texture_format.GetValues().size();
4915 if (params) {
4916 for (GLint ii = 0; ii < *num_written; ++ii) {
4917 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4918 }
4919 }
[email protected]656dcaad2010-05-07 17:18:374920 return true;
[email protected]b273e432010-04-12 17:23:584921 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4922 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104923 if (params) {
[email protected]302ce6d2011-07-07 23:28:114924 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104925 }
[email protected]b273e432010-04-12 17:23:584926 return true;
4927 case GL_NUM_SHADER_BINARY_FORMATS:
4928 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104929 if (params) {
[email protected]302ce6d2011-07-07 23:28:114930 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104931 }
[email protected]b273e432010-04-12 17:23:584932 return true;
4933 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114934 *num_written = validators_->shader_binary_format.GetValues().size();
4935 if (params) {
4936 for (GLint ii = 0; ii < *num_written; ++ii) {
4937 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4938 }
4939 }
4940 return true;
[email protected]b273e432010-04-12 17:23:584941 case GL_SHADER_COMPILER:
4942 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104943 if (params) {
4944 *params = GL_TRUE;
4945 }
[email protected]b273e432010-04-12 17:23:584946 return true;
[email protected]6b8cf1a2010-05-06 16:13:584947 case GL_ARRAY_BUFFER_BINDING:
4948 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104949 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114950 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104951 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244952 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104953 &client_id);
4954 *params = client_id;
4955 } else {
4956 *params = 0;
4957 }
[email protected]6b8cf1a2010-05-06 16:13:584958 }
4959 return true;
4960 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4961 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104962 if (params) {
[email protected]e259eb412012-10-13 05:47:244963 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104964 GLuint client_id = 0;
4965 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254966 state_.vertex_attrib_manager->element_array_buffer()->
4967 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104968 *params = client_id;
4969 } else {
4970 *params = 0;
4971 }
[email protected]6b8cf1a2010-05-06 16:13:584972 }
4973 return true;
4974 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304975 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584976 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104977 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354978 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454979 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204980 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104981 GLuint client_id = 0;
4982 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204983 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304984 *params = client_id;
4985 } else {
4986 *params = 0;
4987 }
4988 }
4989 return true;
[email protected]ebfb73c2012-08-15 02:37:454990 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304991 *num_written = 1;
4992 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354993 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454994 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204995 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304996 GLuint client_id = 0;
4997 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204998 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104999 *params = client_id;
5000 } else {
5001 *params = 0;
5002 }
[email protected]6b8cf1a2010-05-06 16:13:585003 }
5004 return true;
5005 case GL_RENDERBUFFER_BINDING:
5006 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105007 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:355008 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205009 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5010 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:105011 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:105012 } else {
5013 *params = 0;
5014 }
[email protected]6b8cf1a2010-05-06 16:13:585015 }
5016 return true;
5017 case GL_CURRENT_PROGRAM:
5018 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:105019 if (params) {
[email protected]7cd76fd2013-06-02 21:11:115020 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:105021 GLuint client_id = 0;
5022 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:245023 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:105024 *params = client_id;
5025 } else {
5026 *params = 0;
5027 }
[email protected]6b8cf1a2010-05-06 16:13:585028 }
5029 return true;
[email protected]bf835842012-11-19 15:21:515030 case GL_VERTEX_ARRAY_BINDING_OES:
5031 *num_written = 1;
5032 if (params) {
[email protected]7cd76fd2013-06-02 21:11:115033 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:525034 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:515035 GLuint client_id = 0;
5036 vertex_array_manager_->GetClientId(
5037 state_.vertex_attrib_manager->service_id(), &client_id);
5038 *params = client_id;
5039 } else {
5040 *params = 0;
5041 }
5042 }
5043 return true;
[email protected]4e8a5b122010-05-08 22:00:105044 case GL_TEXTURE_BINDING_2D:
5045 *num_written = 1;
5046 if (params) {
[email protected]e259eb412012-10-13 05:47:245047 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115048 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:105049 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:585050 } else {
5051 *params = 0;
5052 }
[email protected]6b8cf1a2010-05-06 16:13:585053 }
[email protected]4e8a5b122010-05-08 22:00:105054 return true;
5055 case GL_TEXTURE_BINDING_CUBE_MAP:
5056 *num_written = 1;
5057 if (params) {
[email protected]e259eb412012-10-13 05:47:245058 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115059 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:105060 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:585061 } else {
5062 *params = 0;
5063 }
[email protected]6b8cf1a2010-05-06 16:13:585064 }
[email protected]4e8a5b122010-05-08 22:00:105065 return true;
[email protected]61eeb33f2011-07-26 15:30:315066 case GL_TEXTURE_BINDING_EXTERNAL_OES:
5067 *num_written = 1;
5068 if (params) {
[email protected]e259eb412012-10-13 05:47:245069 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115070 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:105071 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:315072 } else {
5073 *params = 0;
5074 }
5075 }
5076 return true;
[email protected]e51bdf32011-11-23 22:21:465077 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
5078 *num_written = 1;
5079 if (params) {
[email protected]e259eb412012-10-13 05:47:245080 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:115081 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:105082 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:465083 } else {
5084 *params = 0;
5085 }
5086 }
5087 return true;
[email protected]6c75c712012-06-19 15:43:175088 case GL_UNPACK_FLIP_Y_CHROMIUM:
5089 *num_written = 1;
5090 if (params) {
5091 params[0] = unpack_flip_y_;
5092 }
5093 return true;
5094 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
5095 *num_written = 1;
5096 if (params) {
5097 params[0] = unpack_premultiply_alpha_;
5098 }
5099 return true;
5100 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
5101 *num_written = 1;
5102 if (params) {
5103 params[0] = unpack_unpremultiply_alpha_;
5104 }
5105 return true;
[email protected]6eda6822014-04-03 23:00:505106 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
5107 *num_written = 1;
5108 if (params) {
5109 params[0] = group_->bind_generates_resource() ? 1 : 0;
5110 }
5111 return true;
[email protected]b273e432010-04-12 17:23:585112 default:
[email protected]2f143d482013-03-14 18:04:495113 if (pname >= GL_DRAW_BUFFER0_ARB &&
5114 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
5115 *num_written = 1;
5116 if (params) {
5117 Framebuffer* framebuffer =
5118 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
5119 if (framebuffer) {
5120 params[0] = framebuffer->GetDrawBuffer(pname);
5121 } else { // backbuffer
5122 if (pname == GL_DRAW_BUFFER0_ARB)
5123 params[0] = group_->draw_buffer();
5124 else
5125 params[0] = GL_NONE;
5126 }
5127 }
5128 return true;
5129 }
[email protected]4e8a5b122010-05-08 22:00:105130 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:535131 return false;
[email protected]b273e432010-04-12 17:23:585132 }
5133}
5134
[email protected]4e8a5b122010-05-08 22:00:105135bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
5136 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:265137 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:535138 return true;
5139 }
[email protected]4e8a5b122010-05-08 22:00:105140 return GetHelper(pname, NULL, num_values);
5141}
5142
[email protected]7d3c36e2013-07-12 14:13:165143GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
5144 if (GL_MAX_SAMPLES == pname &&
5145 features().use_img_for_multisampled_render_to_texture) {
5146 return GL_MAX_SAMPLES_IMG;
5147 }
5148 return pname;
5149}
5150
[email protected]b273e432010-04-12 17:23:585151void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
5152 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:105153 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:535154 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:555155 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:265156 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:535157 GetHelper(pname, values.get(), &num_written);
5158 }
[email protected]b273e432010-04-12 17:23:585159 for (GLsizei ii = 0; ii < num_written; ++ii) {
5160 params[ii] = static_cast<GLboolean>(values[ii]);
5161 }
5162 } else {
[email protected]7d3c36e2013-07-12 14:13:165163 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:585164 glGetBooleanv(pname, params);
5165 }
5166}
5167
5168void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
5169 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:105170 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:265171 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:535172 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:555173 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:535174 GetHelper(pname, values.get(), &num_written);
5175 for (GLsizei ii = 0; ii < num_written; ++ii) {
5176 params[ii] = static_cast<GLfloat>(values[ii]);
5177 }
5178 } else {
[email protected]7d3c36e2013-07-12 14:13:165179 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:535180 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:585181 }
[email protected]b273e432010-04-12 17:23:585182 }
5183}
5184
zmo8ac3bab2015-04-18 02:30:585185void GLES2DecoderImpl::DoGetInteger64v(GLenum pname, GLint64* params) {
5186 DCHECK(params);
5187 pname = AdjustGetPname(pname);
5188 glGetInteger64v(pname, params);
5189}
5190
[email protected]b273e432010-04-12 17:23:585191void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
5192 DCHECK(params);
5193 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:265194 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:535195 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:165196 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:585197 glGetIntegerv(pname, params);
5198 }
5199}
5200
[email protected]a0c3e972010-04-21 00:49:135201void GLES2DecoderImpl::DoGetProgramiv(
5202 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:425203 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
5204 if (!program) {
[email protected]a0c3e972010-04-21 00:49:135205 return;
5206 }
[email protected]df37b9932013-03-08 05:21:425207 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:135208}
5209
[email protected]17cfbe0e2013-03-07 01:26:085210void GLES2DecoderImpl::DoGetBufferParameteriv(
5211 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:135212 // Just delegate it. Some validation is actually done before this.
5213 buffer_manager()->ValidateAndDoGetBufferParameteriv(
5214 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:085215}
5216
[email protected]258a3313f2011-10-18 20:13:575217void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:425218 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:575219 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515220 LOCAL_SET_GL_ERROR(
5221 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:575222 return;
5223 }
[email protected]68dcb1f2012-04-07 00:14:565224 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515225 LOCAL_SET_GL_ERROR(
5226 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:565227 return;
5228 }
5229 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:515230 LOCAL_SET_GL_ERROR(
5231 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:565232 return;
5233 }
[email protected]df37b9932013-03-08 05:21:425234 Program* program = GetProgramInfoNotShader(
5235 program_id, "glBindAttribLocation");
5236 if (!program) {
[email protected]258a3313f2011-10-18 20:13:575237 return;
[email protected]558847a2010-03-24 07:02:545238 }
zmo460b593e2014-10-13 23:07:455239 // At this point, the program's shaders may not be translated yet,
5240 // therefore, we may not find the hashed attribute name.
5241 // glBindAttribLocation call with original name is useless.
5242 // So instead, we should simply cache the binding, and then call
5243 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:425244 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:455245 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:425246 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:575247}
5248
[email protected]558847a2010-03-24 07:02:545249error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:345250 uint32 immediate_data_size,
5251 const void* cmd_data) {
5252 const gles2::cmds::BindAttribLocationBucket& c =
5253 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:585254 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:545255 GLuint index = static_cast<GLuint>(c.index);
5256 Bucket* bucket = GetBucket(c.name_bucket_id);
5257 if (!bucket || bucket->size() == 0) {
5258 return error::kInvalidArguments;
5259 }
5260 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:185261 if (!bucket->GetAsString(&name_str)) {
5262 return error::kInvalidArguments;
5263 }
[email protected]258a3313f2011-10-18 20:13:575264 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:545265 return error::kNoError;
5266}
5267
[email protected]2be6abf32012-06-26 00:28:335268void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:425269 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:335270 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515271 LOCAL_SET_GL_ERROR(
5272 GL_INVALID_VALUE,
5273 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:335274 return;
5275 }
5276 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515277 LOCAL_SET_GL_ERROR(
5278 GL_INVALID_OPERATION,
5279 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:335280 return;
5281 }
5282 if (location < 0 || static_cast<uint32>(location) >=
5283 (group_->max_fragment_uniform_vectors() +
5284 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:515285 LOCAL_SET_GL_ERROR(
5286 GL_INVALID_VALUE,
5287 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335288 return;
5289 }
[email protected]df37b9932013-03-08 05:21:425290 Program* program = GetProgramInfoNotShader(
5291 program_id, "glBindUniformLocationCHROMIUM");
5292 if (!program) {
[email protected]2be6abf32012-06-26 00:28:335293 return;
5294 }
[email protected]df37b9932013-03-08 05:21:425295 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:515296 LOCAL_SET_GL_ERROR(
5297 GL_INVALID_VALUE,
5298 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335299 }
5300}
5301
[email protected]2be6abf32012-06-26 00:28:335302error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
5303 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:345304 const void* cmd_data) {
5305 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
5306 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
5307 cmd_data);
[email protected]2be6abf32012-06-26 00:28:335308 GLuint program = static_cast<GLuint>(c.program);
5309 GLint location = static_cast<GLint>(c.location);
5310 Bucket* bucket = GetBucket(c.name_bucket_id);
5311 if (!bucket || bucket->size() == 0) {
5312 return error::kInvalidArguments;
5313 }
5314 std::string name_str;
5315 if (!bucket->GetAsString(&name_str)) {
5316 return error::kInvalidArguments;
5317 }
5318 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
5319 return error::kNoError;
5320}
5321
vmiuracd108592014-09-08 14:36:345322error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
5323 const void* cmd_data) {
5324 const gles2::cmds::DeleteShader& c =
5325 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035326 GLuint client_id = c.shader;
5327 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425328 Shader* shader = GetShader(client_id);
5329 if (shader) {
5330 if (!shader->IsDeleted()) {
dyenc6a36cdd2015-02-25 05:24:315331 shader_manager()->Delete(shader);
[email protected]ca488e12010-12-13 20:06:145332 }
[email protected]ae51d192010-04-27 00:48:035333 } else {
[email protected]ab09b612013-03-11 22:11:515334 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:035335 }
[email protected]96449d2c2009-11-25 00:01:325336 }
[email protected]f7a64ee2010-02-01 22:24:145337 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325338}
5339
vmiuracd108592014-09-08 14:36:345340error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
5341 const void* cmd_data) {
5342 const gles2::cmds::DeleteProgram& c =
5343 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035344 GLuint client_id = c.program;
5345 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425346 Program* program = GetProgram(client_id);
5347 if (program) {
5348 if (!program->IsDeleted()) {
5349 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:145350 }
[email protected]ae51d192010-04-27 00:48:035351 } else {
[email protected]ab09b612013-03-11 22:11:515352 LOCAL_SET_GL_ERROR(
5353 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:035354 }
[email protected]96449d2c2009-11-25 00:01:325355 }
[email protected]f7a64ee2010-02-01 22:24:145356 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325357}
5358
[email protected]a7266a92012-06-28 02:11:085359error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445360 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205361 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465362 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:205363 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
sievers2384f2b2014-11-18 02:10:355364 if (workarounds().gl_clear_broken) {
5365 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround",
5366 GetErrorState());
5367 if (!BoundFramebufferHasDepthAttachment())
5368 mask &= ~GL_DEPTH_BUFFER_BIT;
5369 if (!BoundFramebufferHasStencilAttachment())
5370 mask &= ~GL_STENCIL_BUFFER_BIT;
5371 clear_framebuffer_blit_->ClearFramebuffer(
5372 this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red,
5373 state_.color_clear_green, state_.color_clear_blue,
5374 state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear);
5375 return error::kNoError;
5376 }
[email protected]3a03a8f2011-03-19 00:51:275377 glClear(mask);
5378 }
[email protected]a7266a92012-06-28 02:11:085379 return error::kNoError;
5380}
5381
[email protected]36cef8ce2010-03-16 07:34:455382void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5383 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035384 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065385 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5386 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515387 LOCAL_SET_GL_ERROR(
5388 GL_INVALID_OPERATION,
5389 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455390 return;
5391 }
[email protected]ae51d192010-04-27 00:48:035392 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275393 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035394 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275395 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5396 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515397 LOCAL_SET_GL_ERROR(
5398 GL_INVALID_OPERATION,
5399 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035400 return;
5401 }
[email protected]ee2a79c32013-03-10 03:50:275402 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035403 }
[email protected]ab09b612013-03-11 22:11:515404 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035405 glFramebufferRenderbufferEXT(
5406 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515407 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265408 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275409 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285410 }
[email protected]9d3b2e12013-10-02 01:04:345411 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445412 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465413 }
[email protected]81fc9d02013-03-14 23:53:325414 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285415}
5416
[email protected]3a2e7c7b2010-08-06 01:12:285417void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465418 if (SetCapabilityState(cap, false)) {
5419 glDisable(cap);
5420 }
[email protected]3a2e7c7b2010-08-06 01:12:285421}
5422
5423void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465424 if (SetCapabilityState(cap, true)) {
5425 glEnable(cap);
5426 }
[email protected]3a2e7c7b2010-08-06 01:12:285427}
5428
[email protected]88a61bf2012-10-27 13:00:425429void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5430 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5431 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5432 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285433}
5434
[email protected]b04e24c2013-01-08 18:35:255435void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425436 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5437 state_.sample_coverage_invert = (invert != 0);
5438 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285439}
5440
[email protected]0d6bfdc2011-11-02 01:32:205441// Assumes framebuffer is complete.
5442void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065443 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305444 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205445 // bind this to the DRAW point, clear then bind back to READ
5446 // TODO(gman): I don't think there is any guarantee that an FBO that
5447 // is complete on the READ attachment will be complete as a DRAW
5448 // attachment.
5449 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065450 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305451 }
[email protected]3a2e7c7b2010-08-06 01:12:285452 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425453 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465454 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205455 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465456 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065457 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5458 1.0f);
[email protected]454157e2014-05-03 02:49:455459 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285460 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535461 if (feature_info_->feature_flags().ext_draw_buffers)
5462 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285463 }
5464
[email protected]4d8f0dd2013-03-09 14:37:065465 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5466 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285467 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475468 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5469 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285470 clear_bits |= GL_STENCIL_BUFFER_BIT;
5471 }
5472
[email protected]4d8f0dd2013-03-09 14:37:065473 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5474 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285475 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455476 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285477 clear_bits |= GL_DEPTH_BUFFER_BIT;
5478 }
5479
[email protected]454157e2014-05-03 02:49:455480 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285481 glClear(clear_bits);
5482
brucedawson18249152014-10-31 23:02:325483 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]0e58af82014-08-08 14:02:535484 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425485 framebuffer->RestoreDrawBuffersAfterClear();
5486
[email protected]968351b2011-12-20 08:26:515487 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065488 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285489
[email protected]c007aa02010-09-02 22:22:405490 RestoreClearState();
5491
5492 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065493 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5494 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485495 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065496 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5497 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485498 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405499 }
5500}
5501
5502void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445503 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245504 glClearColor(
5505 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5506 state_.color_clear_alpha);
5507 glClearStencil(state_.stencil_clear);
5508 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225509 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455510 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285511 }
[email protected]36cef8ce2010-03-16 07:34:455512}
5513
5514GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355515 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305516 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205517 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455518 return GL_FRAMEBUFFER_COMPLETE;
5519 }
[email protected]0d6bfdc2011-11-02 01:32:205520 GLenum completeness = framebuffer->IsPossiblyComplete();
5521 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5522 return completeness;
5523 }
[email protected]73276522012-11-09 05:50:205524 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455525}
5526
5527void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035528 GLenum target, GLenum attachment, GLenum textarget,
5529 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165530 DoFramebufferTexture2DCommon(
5531 "glFramebufferTexture2D", target, attachment,
5532 textarget, client_texture_id, level, 0);
5533}
5534
5535void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5536 GLenum target, GLenum attachment, GLenum textarget,
5537 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165538 DoFramebufferTexture2DCommon(
5539 "glFramebufferTexture2DMultisample", target, attachment,
5540 textarget, client_texture_id, level, samples);
5541}
5542
5543void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5544 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5545 GLuint client_texture_id, GLint level, GLsizei samples) {
5546 if (samples > renderbuffer_manager()->max_samples()) {
5547 LOCAL_SET_GL_ERROR(
5548 GL_INVALID_VALUE,
5549 "glFramebufferTexture2DMultisample", "samples too large");
5550 return;
5551 }
[email protected]4d8f0dd2013-03-09 14:37:065552 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5553 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515554 LOCAL_SET_GL_ERROR(
5555 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165556 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455557 return;
5558 }
[email protected]ae51d192010-04-27 00:48:035559 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495560 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035561 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495562 texture_ref = GetTexture(client_texture_id);
5563 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515564 LOCAL_SET_GL_ERROR(
5565 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165566 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035567 return;
5568 }
[email protected]370eaf12013-05-18 09:19:495569 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035570 }
[email protected]0d6bfdc2011-11-02 01:32:205571
[email protected]80eb6b52012-01-19 00:14:415572 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515573 LOCAL_SET_GL_ERROR(
5574 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165575 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205576 return;
5577 }
5578
[email protected]91c94eb2013-10-22 10:32:545579 if (texture_ref)
5580 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5581
[email protected]7d3c36e2013-07-12 14:13:165582 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5583 if (0 == samples) {
5584 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5585 } else {
5586 if (features().use_img_for_multisampled_render_to_texture) {
5587 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5588 service_id, level, samples);
5589 } else {
5590 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5591 service_id, level, samples);
5592 }
5593 }
5594 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265595 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165596 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5597 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285598 }
[email protected]9d3b2e12013-10-02 01:04:345599 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445600 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465601 }
[email protected]91c94eb2013-10-22 10:32:545602
5603 if (texture_ref)
5604 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5605
[email protected]81fc9d02013-03-14 23:53:325606 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455607}
5608
zmo84c08202014-11-23 15:28:405609void GLES2DecoderImpl::DoFramebufferTextureLayer(
5610 GLenum target, GLenum attachment, GLuint client_texture_id,
5611 GLint level, GLint layer) {
5612 // TODO(zmo): Unsafe ES3 API, missing states update.
5613 GLuint service_id = 0;
5614 TextureRef* texture_ref = NULL;
5615 if (client_texture_id) {
5616 texture_ref = GetTexture(client_texture_id);
5617 if (!texture_ref) {
5618 LOCAL_SET_GL_ERROR(
5619 GL_INVALID_OPERATION,
5620 "glFramebufferTextureLayer", "unknown texture_ref");
5621 return;
5622 }
5623 service_id = texture_ref->service_id();
5624 }
5625 glFramebufferTextureLayer(target, attachment, service_id, level, layer);
5626}
5627
[email protected]36cef8ce2010-03-16 07:34:455628void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5629 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065630 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5631 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515632 LOCAL_SET_GL_ERROR(
5633 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205634 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455635 return;
5636 }
[email protected]74c1ec42010-08-12 01:55:575637 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105638 const Framebuffer::Attachment* attachment_object =
5639 framebuffer->GetAttachment(attachment);
5640 *params = attachment_object ? attachment_object->object_name() : 0;
5641 } else {
[email protected]7d3c36e2013-07-12 14:13:165642 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5643 features().use_img_for_multisampled_render_to_texture) {
5644 pname = GL_TEXTURE_SAMPLES_IMG;
5645 }
[email protected]62e65f02013-05-29 22:28:105646 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575647 }
[email protected]36cef8ce2010-03-16 07:34:455648}
5649
5650void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5651 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355652 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205653 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5654 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515655 LOCAL_SET_GL_ERROR(
5656 GL_INVALID_OPERATION,
5657 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455658 return;
5659 }
[email protected]8875a5f2014-06-27 08:33:475660
5661 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275662 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435663 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5664 *params = renderbuffer->internal_format();
5665 break;
5666 case GL_RENDERBUFFER_WIDTH:
5667 *params = renderbuffer->width();
5668 break;
5669 case GL_RENDERBUFFER_HEIGHT:
5670 *params = renderbuffer->height();
5671 break;
[email protected]7d3c36e2013-07-12 14:13:165672 case GL_RENDERBUFFER_SAMPLES_EXT:
5673 if (features().use_img_for_multisampled_render_to_texture) {
5674 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5675 params);
5676 } else {
5677 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5678 params);
5679 }
[email protected]ad84a3a2012-06-08 21:42:435680 default:
5681 glGetRenderbufferParameterivEXT(target, pname, params);
5682 break;
[email protected]b71f52c2010-06-18 22:20:205683 }
[email protected]36cef8ce2010-03-16 07:34:455684}
5685
[email protected]49cabed2013-11-13 18:15:185686void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305687 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5688 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5689 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445690 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165691
[email protected]49cabed2013-11-13 18:15:185692 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165693 return;
5694 }
5695
[email protected]454157e2014-05-03 02:49:455696 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205697 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185698 BlitFramebufferHelper(
5699 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455700 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5701 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185702}
5703
[email protected]8875a5f2014-06-27 08:33:475704void GLES2DecoderImpl::EnsureRenderbufferBound() {
5705 if (!state_.bound_renderbuffer_valid) {
5706 state_.bound_renderbuffer_valid = true;
5707 glBindRenderbufferEXT(GL_RENDERBUFFER,
5708 state_.bound_renderbuffer.get()
5709 ? state_.bound_renderbuffer->service_id()
5710 : 0);
5711 }
5712}
5713
[email protected]f42f05b2013-11-15 21:46:185714void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5715 const FeatureInfo* feature_info,
5716 GLenum target,
5717 GLsizei samples,
5718 GLenum internal_format,
5719 GLsizei width,
5720 GLsizei height) {
5721 // TODO(sievers): This could be resolved at the GL binding level, but the
5722 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495723 if (feature_info->gl_version_info().is_angle) {
[email protected]f42f05b2013-11-15 21:46:185724 glRenderbufferStorageMultisampleANGLE(
5725 target, samples, internal_format, width, height);
5726 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5727 glRenderbufferStorageMultisample(
5728 target, samples, internal_format, width, height);
5729 } else {
5730 glRenderbufferStorageMultisampleEXT(
5731 target, samples, internal_format, width, height);
5732 }
5733}
5734
5735void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5736 GLint srcY0,
5737 GLint srcX1,
5738 GLint srcY1,
5739 GLint dstX0,
5740 GLint dstY0,
5741 GLint dstX1,
5742 GLint dstY1,
5743 GLbitfield mask,
5744 GLenum filter) {
5745 // TODO(sievers): This could be resolved at the GL binding level, but the
5746 // binding process is currently a bit too 'brute force'.
marcheu1856f5d52015-04-04 01:42:535747 if (feature_info_->gl_version_info().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245748 glBlitFramebufferANGLE(
5749 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185750 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5751 glBlitFramebuffer(
5752 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245753 } else {
5754 glBlitFramebufferEXT(
5755 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5756 }
[email protected]8e3e0662010-08-23 18:46:305757}
5758
[email protected]49cabed2013-11-13 18:15:185759bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5760 GLsizei samples,
5761 GLenum internalformat,
5762 GLsizei width,
5763 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535764 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515765 LOCAL_SET_GL_ERROR(
5766 GL_INVALID_VALUE,
5767 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185768 return false;
[email protected]84afefa2011-10-19 21:45:535769 }
5770
5771 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5772 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515773 LOCAL_SET_GL_ERROR(
5774 GL_INVALID_VALUE,
5775 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185776 return false;
[email protected]84afefa2011-10-19 21:45:535777 }
5778
[email protected]7989c9e2013-01-23 06:39:265779 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235780 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5781 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515782 LOCAL_SET_GL_ERROR(
5783 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205784 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185785 return false;
[email protected]8e3e0662010-08-23 18:46:305786 }
5787
[email protected]7989c9e2013-01-23 06:39:265788 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515789 LOCAL_SET_GL_ERROR(
5790 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205791 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185792 return false;
5793 }
5794
5795 return true;
5796}
5797
5798void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5799 GLenum target, GLsizei samples, GLenum internalformat,
5800 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185801 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5802 if (!renderbuffer) {
5803 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5804 "glRenderbufferStorageMultisampleCHROMIUM",
5805 "no renderbuffer bound");
5806 return;
5807 }
5808
5809 if (!ValidateRenderbufferStorageMultisample(
5810 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265811 return;
5812 }
5813
[email protected]8875a5f2014-06-27 08:33:475814 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235815 GLenum impl_format =
5816 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5817 internalformat);
[email protected]49cabed2013-11-13 18:15:185818 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5819 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185820 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255821 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185822 GLenum error =
5823 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265824 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105825 if (workarounds().validate_multisample_buffer_allocation) {
5826 if (!VerifyMultisampleRenderbufferIntegrity(
5827 renderbuffer->service_id(), impl_format)) {
5828 LOCAL_SET_GL_ERROR(
5829 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185830 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105831 return;
5832 }
5833 }
5834
[email protected]968351b2011-12-20 08:26:515835 // TODO(gman): If renderbuffers tracked which framebuffers they were
5836 // attached to we could just mark those framebuffers as not complete.
5837 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205838 renderbuffer_manager()->SetInfo(
5839 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265840 }
[email protected]8e3e0662010-08-23 18:46:305841}
5842
[email protected]49cabed2013-11-13 18:15:185843// This is the handler for multisampled_render_to_texture extensions.
5844void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5845 GLenum target, GLsizei samples, GLenum internalformat,
5846 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185847 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5848 if (!renderbuffer) {
5849 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5850 "glRenderbufferStorageMultisampleEXT",
5851 "no renderbuffer bound");
5852 return;
5853 }
5854
5855 if (!ValidateRenderbufferStorageMultisample(
5856 samples, internalformat, width, height)) {
5857 return;
5858 }
5859
[email protected]8875a5f2014-06-27 08:33:475860 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185861 GLenum impl_format =
5862 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5863 internalformat);
5864 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5865 if (features().use_img_for_multisampled_render_to_texture) {
5866 glRenderbufferStorageMultisampleIMG(
5867 target, samples, impl_format, width, height);
5868 } else {
5869 glRenderbufferStorageMultisampleEXT(
5870 target, samples, impl_format, width, height);
5871 }
5872 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5873 if (error == GL_NO_ERROR) {
5874 // TODO(gman): If renderbuffers tracked which framebuffers they were
5875 // attached to we could just mark those framebuffers as not complete.
5876 framebuffer_manager()->IncFramebufferStateChangeCount();
5877 renderbuffer_manager()->SetInfo(
5878 renderbuffer, samples, internalformat, width, height);
5879 }
5880}
5881
[email protected]4a4c18b2013-09-13 22:50:105882// This function validates the allocation of a multisampled renderbuffer
5883// by clearing it to a key color, blitting the contents to a texture, and
5884// reading back the color to ensure it matches the key.
5885bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5886 GLuint renderbuffer, GLenum format) {
5887
5888 // Only validate color buffers.
5889 // These formats have been selected because they are very common or are known
5890 // to be used by the WebGL backbuffer. If problems are observed with other
5891 // color formats they can be added here.
dcastagna504d45c2015-04-06 19:30:395892 switch (format) {
[email protected]4a4c18b2013-09-13 22:50:105893 case GL_RGB:
5894 case GL_RGB8:
5895 case GL_RGBA:
5896 case GL_RGBA8:
5897 break;
5898 default:
5899 return true;
5900 }
5901
5902 GLint draw_framebuffer, read_framebuffer;
5903
5904 // Cache framebuffer and texture bindings.
5905 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5906 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5907
5908 if (!validation_texture_) {
5909 GLint bound_texture;
5910 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5911
5912 // Create additional resources needed for the verification.
5913 glGenTextures(1, &validation_texture_);
5914 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5915 glGenFramebuffersEXT(1, &validation_fbo_);
5916
5917 // Texture only needs to be 1x1.
5918 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5919 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5920 GL_UNSIGNED_BYTE, NULL);
5921
5922 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5923 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5924 GL_TEXTURE_2D, validation_texture_, 0);
5925
5926 glBindTexture(GL_TEXTURE_2D, bound_texture);
5927 }
5928
5929 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5930 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5931 GL_RENDERBUFFER, renderbuffer);
5932
5933 // Cache current state and reset it to the values we require.
5934 GLboolean scissor_enabled = false;
5935 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5936 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455937 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105938
[email protected]454157e2014-05-03 02:49:455939 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105940 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455941 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105942
5943 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5944 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5945 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5946
5947 // Clear the buffer to the desired key color.
5948 glClear(GL_COLOR_BUFFER_BIT);
5949
5950 // Blit from the multisample buffer to a standard texture.
5951 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5952 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5953
[email protected]f42f05b2013-11-15 21:46:185954 BlitFramebufferHelper(
5955 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105956
5957 // Read a pixel from the buffer.
5958 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5959
5960 unsigned char pixel[3] = {0, 0, 0};
5961 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5962
5963 // Detach the renderbuffer.
5964 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5965 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5966 GL_RENDERBUFFER, 0);
5967
5968 // Restore cached state.
5969 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455970 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105971
[email protected]454157e2014-05-03 02:49:455972 state_.SetDeviceColorMask(
5973 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105974 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5975 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5976 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5977
5978 // Return true if the pixel matched the desired key color.
5979 return (pixel[0] == 0xFF &&
5980 pixel[1] == 0x00 &&
5981 pixel[2] == 0xFF);
5982}
5983
[email protected]36cef8ce2010-03-16 07:34:455984void GLES2DecoderImpl::DoRenderbufferStorage(
5985 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355986 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205987 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5988 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515989 LOCAL_SET_GL_ERROR(
5990 GL_INVALID_OPERATION,
5991 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455992 return;
5993 }
[email protected]876f6fee2010-08-02 23:10:325994
[email protected]84afefa2011-10-19 21:45:535995 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5996 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515997 LOCAL_SET_GL_ERROR(
5998 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535999 return;
6000 }
6001
[email protected]7989c9e2013-01-23 06:39:266002 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:236003 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
6004 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:516005 LOCAL_SET_GL_ERROR(
6006 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:266007 return;
6008 }
6009
6010 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:516011 LOCAL_SET_GL_ERROR(
6012 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:266013 return;
[email protected]b71f52c2010-06-18 22:20:206014 }
[email protected]876f6fee2010-08-02 23:10:326015
[email protected]8875a5f2014-06-27 08:33:476016 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:516017 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:266018 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:236019 target,
6020 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
6021 internalformat),
6022 width,
6023 height);
[email protected]ab09b612013-03-11 22:11:516024 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:266025 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:516026 // TODO(gman): If tetxures tracked which framebuffers they were attached to
6027 // we could just mark those framebuffers as not complete.
6028 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:206029 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:266030 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:266031 }
[email protected]36cef8ce2010-03-16 07:34:456032}
6033
[email protected]df37b9932013-03-08 05:21:426034void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:386035 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:426036 Program* program = GetProgramInfoNotShader(
6037 program_id, "glLinkProgram");
6038 if (!program) {
[email protected]a93bb842010-02-16 23:03:476039 return;
6040 }
[email protected]05afda12011-01-20 00:17:346041
[email protected]df37b9932013-03-08 05:21:426042 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]df37b9932013-03-08 05:21:426043 if (program->Link(shader_manager(),
[email protected]008401532014-02-07 00:10:506044 workarounds().count_all_in_varyings_packing ?
6045 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:116046 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:426047 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:186048 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:426049 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:186050 if (workarounds().clear_uniforms_before_first_program_use)
6051 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:546052 }
6053 }
vmiura8266ca72014-09-09 21:37:006054
6055 // LinkProgram can be very slow. Exit command processing to allow for
6056 // context preemption and GPU watchdog checks.
6057 ExitCommandProcessingEarly();
dcastagna504d45c2015-04-06 19:30:396058}
[email protected]07f54fcc2009-12-22 02:46:306059
zmobcb3fdd62014-12-11 00:49:036060void GLES2DecoderImpl::DoSamplerParameterfv(
6061 GLuint sampler, GLenum pname, const GLfloat* params) {
6062 DCHECK(params);
6063 glSamplerParameterf(sampler, pname, params[0]);
6064}
6065
6066void GLES2DecoderImpl::DoSamplerParameteriv(
6067 GLuint sampler, GLenum pname, const GLint* params) {
6068 DCHECK(params);
6069 glSamplerParameteri(sampler, pname, params[0]);
6070}
6071
[email protected]3916c97e2010-02-25 03:20:506072void GLES2DecoderImpl::DoTexParameterf(
6073 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:446074 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6075 &state_, target);
[email protected]02965c22013-03-09 02:40:076076 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516077 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246078 return;
[email protected]07f54fcc2009-12-22 02:46:306079 }
[email protected]cbb22e42011-05-12 23:36:246080
[email protected]737191ee72014-03-09 08:02:426081 texture_manager()->SetParameterf(
6082 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:306083}
6084
[email protected]3916c97e2010-02-25 03:20:506085void GLES2DecoderImpl::DoTexParameteri(
6086 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:446087 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6088 &state_, target);
[email protected]02965c22013-03-09 02:40:076089 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516090 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246091 return;
[email protected]3916c97e2010-02-25 03:20:506092 }
[email protected]cbb22e42011-05-12 23:36:246093
[email protected]737191ee72014-03-09 08:02:426094 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:506095 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:506096}
6097
6098void GLES2DecoderImpl::DoTexParameterfv(
6099 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:446100 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6101 &state_, target);
[email protected]02965c22013-03-09 02:40:076102 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516103 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246104 return;
[email protected]3916c97e2010-02-25 03:20:506105 }
[email protected]cbb22e42011-05-12 23:36:246106
[email protected]737191ee72014-03-09 08:02:426107 texture_manager()->SetParameterf(
6108 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:506109}
6110
6111void GLES2DecoderImpl::DoTexParameteriv(
6112 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:446113 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
6114 &state_, target);
[email protected]02965c22013-03-09 02:40:076115 if (!texture) {
[email protected]ab09b612013-03-11 22:11:516116 LOCAL_SET_GL_ERROR(
6117 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:246118 return;
[email protected]3916c97e2010-02-25 03:20:506119 }
[email protected]cbb22e42011-05-12 23:36:246120
[email protected]737191ee72014-03-09 08:02:426121 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:506122 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:506123}
6124
orglofchcad5a6742014-11-07 19:51:126125bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
6126 if (!state_.bound_valuebuffer.get()) {
6127 // There is no valuebuffer bound
6128 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6129 "no valuebuffer in use");
6130 return false;
6131 }
6132 return true;
6133}
6134
6135bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
6136 GLenum subscription,
6137 const char* function_name) {
6138 if (!CheckCurrentValuebuffer(function_name)) {
6139 return false;
6140 }
6141 if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
6142 // The valuebuffer is not subscribed to the target
6143 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6144 "valuebuffer is not subscribed");
6145 return false;
6146 }
6147 return true;
6148}
6149
6150bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
6151 GLenum subscription,
6152 const char* function_name) {
6153 if (!CheckCurrentProgramForUniform(location, function_name)) {
6154 return false;
6155 }
6156 GLint real_location = -1;
6157 GLint array_index = -1;
6158 const Program::UniformInfo* info =
6159 state_.current_program->GetUniformInfoByFakeLocation(
6160 location, &real_location, &array_index);
6161 if (!info) {
6162 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
6163 return false;
6164 }
6165 if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
6166 info->accepts_api_type) == 0) {
6167 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6168 "wrong type for subscription");
6169 return false;
6170 }
6171 return true;
6172}
6173
[email protected]939e7362010-05-13 20:49:106174bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:116175 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:436176 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:516177 LOCAL_SET_GL_ERROR(
6178 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:436179 return false;
[email protected]939e7362010-05-13 20:49:106180 }
[email protected]e259eb412012-10-13 05:47:246181 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:516182 LOCAL_SET_GL_ERROR(
6183 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:106184 return false;
6185 }
6186 return true;
6187}
6188
6189bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
6190 GLint location, const char* function_name) {
6191 if (!CheckCurrentProgram(function_name)) {
6192 return false;
6193 }
6194 return location != -1;
6195}
6196
zmof9a81360f2014-10-17 00:06:146197bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
6198 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
6199 if (!framebuffer)
6200 return false;
6201 const Framebuffer::Attachment* attachment =
6202 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
6203 if (!attachment)
6204 return false;
6205
6206 DCHECK(state_.current_program.get());
6207 const Program::SamplerIndices& sampler_indices =
6208 state_.current_program->sampler_indices();
6209 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6210 const Program::UniformInfo* uniform_info =
6211 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6212 DCHECK(uniform_info);
6213 if (uniform_info->type != GL_SAMPLER_2D)
6214 continue;
6215 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6216 GLuint texture_unit_index = uniform_info->texture_units[jj];
6217 if (texture_unit_index >= state_.texture_units.size())
6218 continue;
6219 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6220 TextureRef* texture_ref =
6221 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
6222 if (attachment->IsTexture(texture_ref))
6223 return true;
6224 }
6225 }
6226 return false;
6227}
6228
orglofchcad5a6742014-11-07 19:51:126229bool GLES2DecoderImpl::CheckUniformForApiType(
6230 const Program::UniformInfo* info,
6231 const char* function_name,
6232 Program::UniformApiType api_type) {
6233 DCHECK(info);
6234 if ((api_type & info->accepts_api_type) == 0) {
6235 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6236 "wrong uniform function for type");
6237 return false;
6238 }
6239 return true;
6240}
6241
[email protected]43c2f1f2011-03-25 18:35:366242bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:136243 GLint fake_location,
6244 const char* function_name,
6245 Program::UniformApiType api_type,
6246 GLint* real_location,
6247 GLenum* type,
6248 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:366249 DCHECK(type);
6250 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:126251 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:526252
[email protected]1b0a6752012-02-22 03:44:126253 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:106254 return false;
6255 }
[email protected]43c2f1f2011-03-25 18:35:366256 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:356257 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:246258 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:126259 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:366260 if (!info) {
[email protected]ab09b612013-03-11 22:11:516261 LOCAL_SET_GL_ERROR(
6262 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:106263 return false;
6264 }
orglofchcad5a6742014-11-07 19:51:126265 if (!CheckUniformForApiType(info, function_name, api_type)) {
[email protected]476ccb72012-12-06 15:52:526266 return false;
6267 }
[email protected]43c2f1f2011-03-25 18:35:366268 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:516269 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436270 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:366271 return false;
6272 }
6273 *count = std::min(info->size - array_index, *count);
6274 if (*count <= 0) {
6275 return false;
6276 }
6277 *type = info->type;
[email protected]939e7362010-05-13 20:49:106278 return true;
6279}
6280
[email protected]1b0a6752012-02-22 03:44:126281void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
6282 GLenum type = 0;
6283 GLsizei count = 1;
6284 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136285 if (!PrepForSetUniformByLocation(fake_location,
6286 "glUniform1i",
6287 Program::kUniform1i,
6288 &real_location,
6289 &type,
6290 &count)) {
[email protected]3916c97e2010-02-25 03:20:506291 return;
6292 }
[email protected]e259eb412012-10-13 05:47:246293 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026294 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:516295 LOCAL_SET_GL_ERROR(
6296 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466297 return;
6298 }
[email protected]1b0a6752012-02-22 03:44:126299 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:506300}
6301
6302void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:126303 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:366304 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126305 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136306 if (!PrepForSetUniformByLocation(fake_location,
6307 "glUniform1iv",
6308 Program::kUniform1i,
6309 &real_location,
6310 &type,
6311 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366312 return;
6313 }
[email protected]74727112012-06-13 21:18:086314 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
6315 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:246316 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026317 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:516318 LOCAL_SET_GL_ERROR(
6319 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466320 return;
6321 }
[email protected]43c2f1f2011-03-25 18:35:366322 }
[email protected]1b0a6752012-02-22 03:44:126323 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:506324}
6325
[email protected]939e7362010-05-13 20:49:106326void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:126327 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366328 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126329 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136330 if (!PrepForSetUniformByLocation(fake_location,
6331 "glUniform1fv",
6332 Program::kUniform1f,
6333 &real_location,
6334 &type,
6335 &count)) {
[email protected]939e7362010-05-13 20:49:106336 return;
6337 }
6338 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:556339 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:106340 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:536341 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106342 }
[email protected]1b0a6752012-02-22 03:44:126343 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106344 } else {
[email protected]1b0a6752012-02-22 03:44:126345 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106346 }
6347}
6348
6349void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:126350 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366351 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126352 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136353 if (!PrepForSetUniformByLocation(fake_location,
6354 "glUniform2fv",
6355 Program::kUniform2f,
6356 &real_location,
6357 &type,
6358 &count)) {
[email protected]939e7362010-05-13 20:49:106359 return;
6360 }
6361 if (type == GL_BOOL_VEC2) {
6362 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:556363 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106364 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536365 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106366 }
[email protected]1b0a6752012-02-22 03:44:126367 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106368 } else {
[email protected]1b0a6752012-02-22 03:44:126369 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106370 }
6371}
6372
6373void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126374 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366375 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126376 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136377 if (!PrepForSetUniformByLocation(fake_location,
6378 "glUniform3fv",
6379 Program::kUniform3f,
6380 &real_location,
6381 &type,
6382 &count)) {
[email protected]939e7362010-05-13 20:49:106383 return;
6384 }
6385 if (type == GL_BOOL_VEC3) {
6386 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556387 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106388 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536389 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106390 }
[email protected]1b0a6752012-02-22 03:44:126391 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106392 } else {
[email protected]1b0a6752012-02-22 03:44:126393 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106394 }
6395}
6396
6397void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126398 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366399 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126400 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136401 if (!PrepForSetUniformByLocation(fake_location,
6402 "glUniform4fv",
6403 Program::kUniform4f,
6404 &real_location,
6405 &type,
6406 &count)) {
[email protected]939e7362010-05-13 20:49:106407 return;
6408 }
6409 if (type == GL_BOOL_VEC4) {
6410 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556411 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106412 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536413 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106414 }
[email protected]1b0a6752012-02-22 03:44:126415 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106416 } else {
[email protected]1b0a6752012-02-22 03:44:126417 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106418 }
6419}
6420
[email protected]43c2f1f2011-03-25 18:35:366421void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126422 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366423 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126424 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136425 if (!PrepForSetUniformByLocation(fake_location,
6426 "glUniform2iv",
6427 Program::kUniform2i,
6428 &real_location,
6429 &type,
6430 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366431 return;
6432 }
[email protected]1b0a6752012-02-22 03:44:126433 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366434}
6435
6436void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126437 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366438 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126439 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136440 if (!PrepForSetUniformByLocation(fake_location,
6441 "glUniform3iv",
6442 Program::kUniform3i,
6443 &real_location,
6444 &type,
6445 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366446 return;
6447 }
[email protected]1b0a6752012-02-22 03:44:126448 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366449}
6450
6451void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126452 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366453 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126454 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136455 if (!PrepForSetUniformByLocation(fake_location,
6456 "glUniform4iv",
6457 Program::kUniform4i,
6458 &real_location,
6459 &type,
6460 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366461 return;
6462 }
[email protected]1b0a6752012-02-22 03:44:126463 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366464}
6465
6466void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126467 GLint fake_location, GLsizei count, GLboolean transpose,
6468 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366469 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126470 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136471 if (!PrepForSetUniformByLocation(fake_location,
6472 "glUniformMatrix2fv",
6473 Program::kUniformMatrix2f,
6474 &real_location,
6475 &type,
6476 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366477 return;
6478 }
[email protected]1b0a6752012-02-22 03:44:126479 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366480}
6481
6482void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126483 GLint fake_location, GLsizei count, GLboolean transpose,
6484 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366485 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126486 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136487 if (!PrepForSetUniformByLocation(fake_location,
6488 "glUniformMatrix3fv",
6489 Program::kUniformMatrix3f,
6490 &real_location,
6491 &type,
6492 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366493 return;
6494 }
[email protected]1b0a6752012-02-22 03:44:126495 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366496}
6497
6498void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126499 GLint fake_location, GLsizei count, GLboolean transpose,
6500 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366501 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126502 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136503 if (!PrepForSetUniformByLocation(fake_location,
6504 "glUniformMatrix4fv",
6505 Program::kUniformMatrix4f,
6506 &real_location,
6507 &type,
6508 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366509 return;
6510 }
[email protected]1b0a6752012-02-22 03:44:126511 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366512}
6513
[email protected]df37b9932013-03-08 05:21:426514void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036515 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426516 Program* program = NULL;
6517 if (program_id) {
6518 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6519 if (!program) {
[email protected]ae51d192010-04-27 00:48:036520 return;
6521 }
[email protected]df37b9932013-03-08 05:21:426522 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506523 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516524 LOCAL_SET_GL_ERROR(
6525 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506526 return;
6527 }
[email protected]df37b9932013-03-08 05:21:426528 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506529 }
[email protected]7cd76fd2013-06-02 21:11:116530 if (state_.current_program.get()) {
6531 program_manager()->UnuseProgram(shader_manager(),
6532 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146533 }
[email protected]df37b9932013-03-08 05:21:426534 state_.current_program = program;
6535 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546536 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116537 if (state_.current_program.get()) {
6538 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186539 if (workarounds().clear_uniforms_before_first_program_use)
6540 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146541 }
[email protected]3916c97e2010-02-25 03:20:506542}
6543
[email protected]ab09b612013-03-11 22:11:516544void GLES2DecoderImpl::RenderWarning(
6545 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326546 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016547}
6548
[email protected]ab09b612013-03-11 22:11:516549void GLES2DecoderImpl::PerformanceWarning(
6550 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506551 logger_.LogMessage(filename, line,
6552 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016553}
6554
[email protected]91c94eb2013-10-22 10:32:546555void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6556 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546557 // Image is already in use if texture is attached to a framebuffer.
6558 if (texture && !texture->IsAttachedToFramebuffer()) {
6559 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6560 if (image) {
6561 ScopedGLErrorSuppressor suppressor(
6562 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6563 GetErrorState());
6564 glBindTexture(textarget, texture->service_id());
6565 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026566 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546567 }
6568 }
6569}
6570
6571void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6572 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546573 // Image is still in use if texture is attached to a framebuffer.
6574 if (texture && !texture->IsAttachedToFramebuffer()) {
6575 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6576 if (image) {
6577 ScopedGLErrorSuppressor suppressor(
6578 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6579 GetErrorState());
6580 glBindTexture(textarget, texture->service_id());
6581 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026582 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546583 }
6584 }
6585}
6586
[email protected]e56131d22013-07-28 16:14:116587bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116588 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546589 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556590 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116591 return true;
[email protected]ef526492010-06-02 23:12:256592 }
[email protected]e2367b42013-05-31 03:37:216593
[email protected]ef526492010-06-02 23:12:256594 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356595 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246596 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506597 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356598 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246599 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506600 DCHECK(uniform_info);
6601 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6602 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026603 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246604 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546605 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366606 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546607 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6608 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256609 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506610 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6611 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546612 textarget,
[email protected]00f893d2010-08-24 18:55:496613 texture_manager()->black_texture_id(uniform_info->type));
dongseong.hwang7d87d722015-01-14 20:02:406614 if (!texture_ref) {
6615 LOCAL_RENDER_WARNING(
6616 std::string("there is no texture bound to the unit ") +
6617 base::IntToString(texture_unit_index));
6618 } else {
6619 LOCAL_RENDER_WARNING(
6620 std::string("texture bound to texture unit ") +
6621 base::IntToString(texture_unit_index) +
6622 " is not renderable. It maybe non-power-of-2 and have"
6623 " incompatible texture filtering.");
6624 }
[email protected]91c94eb2013-10-22 10:32:546625 continue;
[email protected]3916c97e2010-02-25 03:20:506626 }
[email protected]91c94eb2013-10-22 10:32:546627
[email protected]4e7b89202014-01-28 01:44:066628 if (textarget != GL_TEXTURE_CUBE_MAP) {
6629 Texture* texture = texture_ref->texture();
6630 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6631 if (image && !texture->IsAttachedToFramebuffer()) {
6632 ScopedGLErrorSuppressor suppressor(
6633 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6634 textures_set = true;
6635 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6636 image->WillUseTexImage();
6637 continue;
6638 }
[email protected]91c94eb2013-10-22 10:32:546639 }
[email protected]3916c97e2010-02-25 03:20:506640 }
6641 // else: should this be an error?
6642 }
6643 }
[email protected]e56131d22013-07-28 16:14:116644 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506645}
6646
[email protected]91c94eb2013-10-22 10:32:546647void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116648 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356649 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116650 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506651 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356652 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246653 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506654 DCHECK(uniform_info);
6655 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6656 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026657 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246658 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116659 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546660 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496661 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506662 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496663 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116664 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6665 ? texture_unit.bound_texture_2d.get()
6666 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506667 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496668 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546669 continue;
6670 }
6671
[email protected]4e7b89202014-01-28 01:44:066672 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6673 Texture* texture = texture_ref->texture();
6674 gfx::GLImage* image =
6675 texture->GetLevelImage(texture_unit.bind_target, 0);
6676 if (image && !texture->IsAttachedToFramebuffer()) {
6677 ScopedGLErrorSuppressor suppressor(
6678 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6679 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6680 image->DidUseTexImage();
6681 continue;
6682 }
[email protected]3916c97e2010-02-25 03:20:506683 }
6684 }
6685 }
6686 }
6687 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246688 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306689}
6690
[email protected]0d6bfdc2011-11-02 01:32:206691bool GLES2DecoderImpl::ClearUnclearedTextures() {
6692 // Only check if there are some uncleared textures.
6693 if (!texture_manager()->HaveUnsafeTextures()) {
6694 return true;
6695 }
6696
6697 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116698 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356699 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116700 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206701 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356702 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246703 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206704 DCHECK(uniform_info);
6705 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6706 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026707 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246708 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496709 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366710 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496711 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6712 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206713 return false;
6714 }
6715 }
6716 }
6717 }
6718 }
6719 }
6720 return true;
6721}
6722
[email protected]c6aef902012-02-14 03:31:426723bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106724 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6725 GLsizei primcount) {
6726 DCHECK(instanced || primcount == 1);
6727
[email protected]689fa1c52010-06-09 18:35:036728 // NOTE: We specifically do not check current_program->IsValid() because
6729 // it could never be invalid since glUseProgram would have failed. While
6730 // glLinkProgram could later mark the program as invalid the previous
6731 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116732 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506733 // The program does not exist.
6734 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516735 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506736 return false;
6737 }
[email protected]c6aef902012-02-14 03:31:426738
zmof9a81360f2014-10-17 00:06:146739 if (CheckDrawingFeedbackLoops()) {
6740 LOCAL_SET_GL_ERROR(
6741 GL_INVALID_OPERATION, function_name,
6742 "Source and destination textures of the draw are the same.");
6743 return false;
6744 }
6745
[email protected]7cd76fd2013-06-02 21:11:116746 return state_.vertex_attrib_manager
6747 ->ValidateBindings(function_name,
6748 this,
6749 feature_info_.get(),
6750 state_.current_program.get(),
6751 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106752 instanced,
[email protected]7cd76fd2013-06-02 21:11:116753 primcount);
[email protected]b1122982010-05-17 23:04:246754}
6755
[email protected]c13e1da62011-09-09 21:48:306756bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436757 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306758 DCHECK(simulated);
6759 *simulated = false;
6760
marcheu1856f5d52015-04-04 01:42:536761 if (feature_info_->gl_version_info().BehavesLikeGLES())
[email protected]c13e1da62011-09-09 21:48:306762 return true;
[email protected]876f6fee2010-08-02 23:10:326763
[email protected]ac77603c72013-03-08 13:52:066764 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356765 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246766 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246767 bool attrib_0_used =
6768 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066769 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306770 return true;
[email protected]b1122982010-05-17 23:04:246771 }
6772
[email protected]b1122982010-05-17 23:04:246773 // Make a buffer with a single repeated vec4 value enough to
6774 // simulate the constant value that is supposed to be here.
6775 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306776 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476777 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306778
6779 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476780 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306781 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516782 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306783 return false;
6784 }
6785
[email protected]ab09b612013-03-11 22:11:516786 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016787 "Attribute 0 is disabled. This has signficant performance penalty");
6788
[email protected]ab09b612013-03-11 22:11:516789 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306790 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6791
[email protected]8f0b86c2f2012-04-10 05:48:286792 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6793 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496794 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306795 GLenum error = glGetError();
6796 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516797 LOCAL_SET_GL_ERROR(
6798 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306799 return false;
6800 }
[email protected]fc753442011-02-04 19:49:496801 }
[email protected]af6380962012-11-29 23:24:136802
6803 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286804 if (new_buffer ||
6805 (attrib_0_used &&
6806 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136807 (value.v[0] != attrib_0_value_.v[0] ||
6808 value.v[1] != attrib_0_value_.v[1] ||
6809 value.v[2] != attrib_0_value_.v[2] ||
6810 value.v[3] != attrib_0_value_.v[3])))) {
6811 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496812 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6813 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136814 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246815 attrib_0_size_ = size_needed;
6816 }
6817
6818 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6819
[email protected]ac77603c72013-03-08 13:52:066820 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426821 glVertexAttribDivisorANGLE(0, 0);
6822
[email protected]c13e1da62011-09-09 21:48:306823 *simulated = true;
[email protected]b1122982010-05-17 23:04:246824 return true;
[email protected]b1122982010-05-17 23:04:246825}
6826
[email protected]3fc38e22014-05-30 00:13:236827void GLES2DecoderImpl::RestoreStateForAttrib(
6828 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066829 const VertexAttrib* attrib =
6830 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236831 if (restore_array_binding) {
6832 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6833 Buffer* buffer = attrib->buffer();
6834 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6835 glVertexAttribPointer(
6836 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6837 attrib->gl_stride(), ptr);
6838 }
[email protected]ac77603c72013-03-08 13:52:066839 if (attrib->divisor())
6840 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246841 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236842 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6843 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286844
[email protected]265f8992012-07-20 01:03:146845 // Never touch vertex attribute 0's state (in particular, never
6846 // disable it) when running on desktop GL because it will never be
6847 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066848 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146849 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066850 if (attrib->enabled()) {
6851 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146852 } else {
[email protected]ac77603c72013-03-08 13:52:066853 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146854 }
[email protected]43410e92012-04-20 17:06:286855 }
[email protected]b1122982010-05-17 23:04:246856}
[email protected]07f54fcc2009-12-22 02:46:306857
[email protected]8fbedc02010-11-18 18:43:406858bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436859 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426860 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406861 DCHECK(simulated);
6862 *simulated = false;
6863 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6864 return true;
6865
[email protected]e259eb412012-10-13 05:47:246866 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406867 return true;
6868 }
6869
[email protected]ab09b612013-03-11 22:11:516870 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016871 "GL_FIXED attributes have a signficant performance penalty");
6872
[email protected]8fbedc02010-11-18 18:43:406873 // NOTE: we could be smart and try to check if a buffer is used
6874 // twice in 2 different attribs, find the overlapping parts and therefore
6875 // duplicate the minimum amount of data but this whole code path is not meant
6876 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6877 // tests so we just add to the buffer attrib used.
6878
[email protected]c13e1da62011-09-09 21:48:306879 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066880 const VertexAttribManager::VertexAttribList& enabled_attribs =
6881 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6882 for (VertexAttribManager::VertexAttribList::const_iterator it =
6883 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6884 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356885 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066886 state_.current_program->GetAttribInfoByLocation(attrib->index());
6887 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6888 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426889 GLuint num_vertices = max_accessed + 1;
6890 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516891 LOCAL_SET_GL_ERROR(
6892 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426893 return false;
6894 }
[email protected]8fbedc02010-11-18 18:43:406895 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066896 attrib->CanAccess(max_accessed) &&
6897 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476898 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066899 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476900 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516901 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436902 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406903 return false;
6904 }
6905 }
6906 }
6907
[email protected]3aad1a32012-09-07 20:54:476908 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6909 uint32 size_needed = 0;
6910 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306911 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516912 LOCAL_SET_GL_ERROR(
6913 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406914 return false;
6915 }
6916
[email protected]ab09b612013-03-11 22:11:516917 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406918
6919 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306920 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406921 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306922 GLenum error = glGetError();
6923 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516924 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436925 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306926 return false;
6927 }
[email protected]8fbedc02010-11-18 18:43:406928 }
6929
6930 // Copy the elements and convert to float
6931 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066932 for (VertexAttribManager::VertexAttribList::const_iterator it =
6933 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6934 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356935 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066936 state_.current_program->GetAttribInfoByLocation(attrib->index());
6937 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426938 max_vertex_accessed);
6939 GLuint num_vertices = max_accessed + 1;
6940 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516941 LOCAL_SET_GL_ERROR(
6942 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426943 return false;
6944 }
[email protected]8fbedc02010-11-18 18:43:406945 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066946 attrib->CanAccess(max_accessed) &&
6947 attrib->type() == GL_FIXED) {
penghuang5a3210b2014-10-29 18:24:366948 int num_elements = attrib->size() * num_vertices;
6949 const int src_size = num_elements * sizeof(int32);
6950 const int dst_size = num_elements * sizeof(float);
6951 scoped_ptr<float[]> data(new float[num_elements]);
[email protected]8fbedc02010-11-18 18:43:406952 const int32* src = reinterpret_cast<const int32 *>(
penghuang5a3210b2014-10-29 18:24:366953 attrib->buffer()->GetRange(attrib->offset(), src_size));
[email protected]8fbedc02010-11-18 18:43:406954 const int32* end = src + num_elements;
6955 float* dst = data.get();
6956 while (src != end) {
6957 *dst++ = static_cast<float>(*src++) / 65536.0f;
6958 }
penghuang5a3210b2014-10-29 18:24:366959 glBufferSubData(GL_ARRAY_BUFFER, offset, dst_size, data.get());
[email protected]8fbedc02010-11-18 18:43:406960 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066961 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406962 reinterpret_cast<GLvoid*>(offset));
penghuang5a3210b2014-10-29 18:24:366963 offset += dst_size;
[email protected]8fbedc02010-11-18 18:43:406964 }
6965 }
6966 *simulated = true;
6967 return true;
6968}
6969
6970void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6971 // There's no need to call glVertexAttribPointer because we shadow all the
6972 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246973 glBindBuffer(
6974 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116975 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6976 : 0);
[email protected]8fbedc02010-11-18 18:43:406977}
6978
[email protected]ad84a3a2012-06-08 21:42:436979error::Error GLES2DecoderImpl::DoDrawArrays(
6980 const char* function_name,
6981 bool instanced,
6982 GLenum mode,
6983 GLint first,
6984 GLsizei count,
6985 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226986 error::Error error = WillAccessBoundFramebufferForDraw();
6987 if (error != error::kNoError)
6988 return error;
[email protected]38d139d2011-07-14 00:38:436989 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516990 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436991 return error::kNoError;
6992 }
6993 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516994 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436995 return error::kNoError;
6996 }
[email protected]c6aef902012-02-14 03:31:426997 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516998 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426999 return error::kNoError;
7000 }
[email protected]ad84a3a2012-06-08 21:42:437001 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:437002 return error::kNoError;
7003 }
7004 // We have to check this here because the prototype for glDrawArrays
7005 // is GLint not GLsizei.
7006 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:517007 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:437008 return error::kNoError;
7009 }
7010
[email protected]ac6904d62014-07-30 12:00:107011 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:517012 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:437013 return error::kNoError;
7014 }
7015
7016 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:107017 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:207018 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:517019 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:207020 return error::kNoError;
7021 }
[email protected]c13e1da62011-09-09 21:48:307022 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:437023 if (!SimulateAttrib0(
7024 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:307025 return error::kNoError;
7026 }
[email protected]38d139d2011-07-14 00:38:437027 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:437028 if (SimulateFixedAttribs(
7029 function_name, max_vertex_accessed, &simulated_fixed_attribs,
7030 primcount)) {
[email protected]e56131d22013-07-28 16:14:117031 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:437032 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:377033 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:427034 if (!instanced) {
7035 glDrawArrays(mode, first, count);
7036 } else {
7037 glDrawArraysInstancedANGLE(mode, first, count, primcount);
7038 }
[email protected]38d139d2011-07-14 00:38:437039 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:547040 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:437041 }
7042 if (simulated_fixed_attribs) {
7043 RestoreStateForSimulatedFixedAttribs();
7044 }
7045 }
7046 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:237047 // We don't have to restore attrib 0 generic data at the end of this
7048 // function even if it is simulated. This is because we will simulate
7049 // it in each draw call, and attrib 0 generic data queries use cached
7050 // values instead of passing down to the underlying driver.
7051 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:437052 }
[email protected]38d139d2011-07-14 00:38:437053 }
7054 return error::kNoError;
7055}
7056
vmiuracd108592014-09-08 14:36:347057error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
7058 const void* cmd_data) {
7059 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437060 return DoDrawArrays("glDrawArrays",
7061 false,
[email protected]c6aef902012-02-14 03:31:427062 static_cast<GLenum>(c.mode),
7063 static_cast<GLint>(c.first),
7064 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:107065 1);
[email protected]c6aef902012-02-14 03:31:427066}
7067
7068error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:347069 uint32 immediate_data_size,
7070 const void* cmd_data) {
7071 const gles2::cmds::DrawArraysInstancedANGLE& c =
7072 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157073 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517074 LOCAL_SET_GL_ERROR(
7075 GL_INVALID_OPERATION,
7076 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427077 return error::kNoError;
7078 }
[email protected]ad84a3a2012-06-08 21:42:437079 return DoDrawArrays("glDrawArraysIntancedANGLE",
7080 true,
[email protected]c6aef902012-02-14 03:31:427081 static_cast<GLenum>(c.mode),
7082 static_cast<GLint>(c.first),
7083 static_cast<GLsizei>(c.count),
7084 static_cast<GLsizei>(c.primcount));
7085}
7086
[email protected]ad84a3a2012-06-08 21:42:437087error::Error GLES2DecoderImpl::DoDrawElements(
7088 const char* function_name,
7089 bool instanced,
7090 GLenum mode,
7091 GLsizei count,
7092 GLenum type,
7093 int32 offset,
7094 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:227095 error::Error error = WillAccessBoundFramebufferForDraw();
7096 if (error != error::kNoError)
7097 return error;
[email protected]e259eb412012-10-13 05:47:247098 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:517099 LOCAL_SET_GL_ERROR(
7100 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:297101 return error::kNoError;
7102 }
7103
[email protected]8eee29c2010-04-29 03:38:297104 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:517105 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:297106 return error::kNoError;
7107 }
7108 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517109 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297110 return error::kNoError;
7111 }
[email protected]9438b012010-06-15 22:55:057112 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:517113 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:297114 return error::kNoError;
7115 }
[email protected]9438b012010-06-15 22:55:057116 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517117 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:297118 return error::kNoError;
7119 }
[email protected]c6aef902012-02-14 03:31:427120 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:517121 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:427122 return error::kNoError;
7123 }
[email protected]8eee29c2010-04-29 03:38:297124
[email protected]ad84a3a2012-06-08 21:42:437125 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:277126 return error::kNoError;
7127 }
7128
[email protected]ac6904d62014-07-30 12:00:107129 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:317130 return error::kNoError;
7131 }
7132
[email protected]8eee29c2010-04-29 03:38:297133 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:087134 Buffer* element_array_buffer =
7135 state_.vertex_attrib_manager->element_array_buffer();
7136
7137 if (!element_array_buffer->GetMaxValueForRange(
7138 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:517139 LOCAL_SET_GL_ERROR(
7140 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:297141 return error::kNoError;
7142 }
7143
[email protected]ac6904d62014-07-30 12:00:107144 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:207145 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:517146 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:207147 return error::kNoError;
7148 }
[email protected]c13e1da62011-09-09 21:48:307149 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:437150 if (!SimulateAttrib0(
7151 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:307152 return error::kNoError;
7153 }
[email protected]8fbedc02010-11-18 18:43:407154 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:437155 if (SimulateFixedAttribs(
7156 function_name, max_vertex_accessed, &simulated_fixed_attribs,
7157 primcount)) {
[email protected]e56131d22013-07-28 16:14:117158 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:467159 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:087160 // TODO(gman): Refactor to hide these details in BufferManager or
7161 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:407162 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:087163 bool used_client_side_array = false;
7164 if (element_array_buffer->IsClientSideArray()) {
7165 used_client_side_array = true;
7166 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
7167 indices = element_array_buffer->GetRange(offset, 0);
7168 }
7169
[email protected]00c2cf92014-03-14 00:08:377170 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:427171 if (!instanced) {
7172 glDrawElements(mode, count, type, indices);
7173 } else {
7174 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
7175 }
[email protected]17cfbe0e2013-03-07 01:26:087176
7177 if (used_client_side_array) {
7178 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
7179 element_array_buffer->service_id());
7180 }
7181
[email protected]8fbedc02010-11-18 18:43:407182 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:547183 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:407184 }
7185 if (simulated_fixed_attribs) {
7186 RestoreStateForSimulatedFixedAttribs();
7187 }
[email protected]ba3176a2009-12-16 18:19:467188 }
[email protected]b1122982010-05-17 23:04:247189 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:237190 // We don't have to restore attrib 0 generic data at the end of this
7191 // function even if it is simulated. This is because we will simulate
7192 // it in each draw call, and attrib 0 generic data queries use cached
7193 // values instead of passing down to the underlying driver.
7194 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:247195 }
[email protected]96449d2c2009-11-25 00:01:327196 }
[email protected]f7a64ee2010-02-01 22:24:147197 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327198}
7199
vmiuracd108592014-09-08 14:36:347200error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
7201 const void* cmd_data) {
7202 const gles2::cmds::DrawElements& c =
7203 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437204 return DoDrawElements("glDrawElements",
7205 false,
[email protected]c6aef902012-02-14 03:31:427206 static_cast<GLenum>(c.mode),
7207 static_cast<GLsizei>(c.count),
7208 static_cast<GLenum>(c.type),
7209 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:107210 1);
[email protected]c6aef902012-02-14 03:31:427211}
7212
7213error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:347214 uint32 immediate_data_size,
7215 const void* cmd_data) {
7216 const gles2::cmds::DrawElementsInstancedANGLE& c =
7217 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157218 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517219 LOCAL_SET_GL_ERROR(
7220 GL_INVALID_OPERATION,
7221 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427222 return error::kNoError;
7223 }
[email protected]ad84a3a2012-06-08 21:42:437224 return DoDrawElements("glDrawElementsInstancedANGLE",
7225 true,
[email protected]c6aef902012-02-14 03:31:427226 static_cast<GLenum>(c.mode),
7227 static_cast<GLsizei>(c.count),
7228 static_cast<GLenum>(c.type),
7229 static_cast<int32>(c.index_offset),
7230 static_cast<GLsizei>(c.primcount));
7231}
7232
[email protected]269200b12010-11-18 22:53:067233GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:237234 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
7235 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:077236 Buffer* buffer = GetBuffer(buffer_id);
7237 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:037238 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517239 LOCAL_SET_GL_ERROR(
7240 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:237241 } else {
[email protected]b10492f2013-03-08 05:24:077242 if (!buffer->GetMaxValueForRange(
7243 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:037244 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517245 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:067246 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437247 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:237248 }
7249 }
7250 return max_vertex_accessed;
7251}
7252
zmo1bb3d1d2015-01-21 20:29:437253void GLES2DecoderImpl::DoShaderSource(
7254 GLuint client_id, GLsizei count, const char** data, const GLint* length) {
7255 std::string str;
7256 for (GLsizei ii = 0; ii < count; ++ii) {
dyen7b0b4ba52015-02-04 21:38:067257 if (length && length[ii] > 0)
7258 str.append(data[ii], length[ii]);
7259 else
7260 str.append(data[ii]);
zmo1bb3d1d2015-01-21 20:29:437261 }
[email protected]df37b9932013-03-08 05:21:427262 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
7263 if (!shader) {
zmo1bb3d1d2015-01-21 20:29:437264 return;
[email protected]96449d2c2009-11-25 00:01:327265 }
[email protected]45bf5152010-02-12 00:11:317266 // Note: We don't actually call glShaderSource here. We wait until
dyen7b0b4ba52015-02-04 21:38:067267 // we actually compile the shader.
zmo576a0492014-09-13 01:12:327268 shader->set_source(str);
[email protected]558847a2010-03-24 07:02:547269}
7270
zmo38923562015-01-29 20:17:397271void GLES2DecoderImpl::DoTransformFeedbackVaryings(
7272 GLuint client_program_id, GLsizei count, const char* const* varyings,
7273 GLenum buffer_mode) {
7274 Program* program = GetProgramInfoNotShader(
7275 client_program_id, "glTransformFeedbackVaryings");
7276 if (!program) {
7277 return;
7278 }
bajones63ead732015-03-14 00:12:467279 program->TransformFeedbackVaryings(count, varyings, buffer_mode);
zmo38923562015-01-29 20:17:397280 glTransformFeedbackVaryings(
7281 program->service_id(), count, varyings, buffer_mode);
7282}
7283
[email protected]ae51d192010-04-27 00:48:037284void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:387285 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:427286 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
7287 if (!shader) {
[email protected]45bf5152010-02-12 00:11:317288 return;
7289 }
dyen0ff9e4402015-02-12 22:27:437290
7291 scoped_refptr<ShaderTranslatorInterface> translator;
[email protected]b1d2dcb2010-05-17 19:24:187292 if (use_shader_translator_) {
dyen0ff9e4402015-02-12 22:27:437293 translator = shader->shader_type() == GL_VERTEX_SHADER ?
7294 vertex_translator_ : fragment_translator_;
[email protected]de17df392010-04-23 21:09:417295 }
[email protected]de17df392010-04-23 21:09:417296
dyen0ff9e4402015-02-12 22:27:437297 const Shader::TranslatedShaderSourceType source_type =
7298 feature_info_->feature_flags().angle_translated_shader_source ?
7299 Shader::kANGLE : Shader::kGL;
7300 shader->RequestCompile(translator, source_type);
vmiura8266ca72014-09-09 21:37:007301}
[email protected]45bf5152010-02-12 00:11:317302
[email protected]ddd968b82010-03-02 00:44:297303void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:427304 GLuint shader_id, GLenum pname, GLint* params) {
7305 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
7306 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:297307 return;
7308 }
dyen0ff9e4402015-02-12 22:27:437309
7310 // Compile now for statuses that require it.
7311 switch (pname) {
7312 case GL_COMPILE_STATUS:
7313 case GL_INFO_LOG_LENGTH:
7314 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
7315 shader->DoCompile();
7316 break;
7317
7318 default:
7319 break;
7320 }
7321
[email protected]8f1ccdac2010-05-19 21:01:487322 switch (pname) {
7323 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:327324 *params = shader->source().size();
7325 if (*params)
7326 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:487327 return;
7328 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:327329 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:417330 return;
[email protected]8f1ccdac2010-05-19 21:01:487331 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:327332 *params = shader->log_info().size();
7333 if (*params)
7334 ++(*params);
[email protected]e5186162010-06-14 18:54:417335 return;
[email protected]d6a53e42011-10-05 00:09:367336 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:327337 *params = shader->translated_source().size();
7338 if (*params)
7339 ++(*params);
[email protected]d6a53e42011-10-05 00:09:367340 return;
[email protected]8f1ccdac2010-05-19 21:01:487341 default:
7342 break;
[email protected]ddd968b82010-03-02 00:44:297343 }
[email protected]df37b9932013-03-08 05:21:427344 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:297345}
7346
vmiuracd108592014-09-08 14:36:347347error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
7348 const void* cmd_data) {
7349 const gles2::cmds::GetShaderSource& c =
7350 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427351 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:037352 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7353 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427354 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:327355 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:297356 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:297357 return error::kNoError;
7358 }
zmo576a0492014-09-13 01:12:327359 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:037360 return error::kNoError;
7361}
7362
[email protected]d6a53e42011-10-05 00:09:367363error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
7364 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347365 const void* cmd_data) {
7366 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
7367 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
7368 cmd_data);
[email protected]df37b9932013-03-08 05:21:427369 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:367370 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7371 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427372 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:207373 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:427374 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:367375 bucket->SetSize(0);
7376 return error::kNoError;
7377 }
7378
dyen0ff9e4402015-02-12 22:27:437379 // Make sure translator has been utilized in compile.
7380 shader->DoCompile();
7381
zmo576a0492014-09-13 01:12:327382 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:367383 return error::kNoError;
7384}
7385
[email protected]ae51d192010-04-27 00:48:037386error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:347387 uint32 immediate_data_size,
7388 const void* cmd_data) {
7389 const gles2::cmds::GetProgramInfoLog& c =
7390 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427391 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:587392 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7393 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427394 Program* program = GetProgramInfoNotShader(
7395 program_id, "glGetProgramInfoLog");
7396 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:467397 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037398 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317399 }
[email protected]df37b9932013-03-08 05:21:427400 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037401 return error::kNoError;
7402}
7403
7404error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347405 uint32 immediate_data_size,
7406 const void* cmd_data) {
7407 const gles2::cmds::GetShaderInfoLog& c =
7408 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427409 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587410 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7411 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427412 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327413 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467414 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037415 return error::kNoError;
7416 }
dyen0ff9e4402015-02-12 22:27:437417
7418 // Shader must be compiled in order to get the info log.
7419 shader->DoCompile();
7420
zmo576a0492014-09-13 01:12:327421 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037422 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327423}
7424
[email protected]d058bca2012-11-26 10:27:267425bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7426 return state_.GetEnabled(cap);
7427}
7428
[email protected]1958e0e2010-04-22 05:17:157429bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217430 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107431 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157432}
7433
7434bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357435 const Framebuffer* framebuffer =
7436 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107437 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157438}
7439
7440bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367441 // IsProgram is true for programs as soon as they are created, until they are
7442 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357443 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107444 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157445}
7446
7447bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357448 const Renderbuffer* renderbuffer =
7449 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107450 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157451}
7452
7453bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367454 // IsShader is true for shaders as soon as they are created, until they
7455 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357456 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107457 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157458}
7459
7460bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497461 const TextureRef* texture_ref = GetTexture(client_id);
7462 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037463}
7464
7465void GLES2DecoderImpl::DoAttachShader(
7466 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427467 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587468 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427469 if (!program) {
[email protected]ae51d192010-04-27 00:48:037470 return;
[email protected]1958e0e2010-04-22 05:17:157471 }
[email protected]df37b9932013-03-08 05:21:427472 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7473 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037474 return;
7475 }
[email protected]df37b9932013-03-08 05:21:427476 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517477 LOCAL_SET_GL_ERROR(
7478 GL_INVALID_OPERATION,
7479 "glAttachShader",
7480 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317481 return;
7482 }
[email protected]df37b9932013-03-08 05:21:427483 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037484}
7485
7486void GLES2DecoderImpl::DoDetachShader(
7487 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427488 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587489 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427490 if (!program) {
[email protected]ae51d192010-04-27 00:48:037491 return;
7492 }
[email protected]df37b9932013-03-08 05:21:427493 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7494 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037495 return;
7496 }
[email protected]df37b9932013-03-08 05:21:427497 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517498 LOCAL_SET_GL_ERROR(
7499 GL_INVALID_OPERATION,
7500 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227501 return;
7502 }
[email protected]df37b9932013-03-08 05:21:427503 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037504}
7505
7506void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427507 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587508 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427509 if (!program) {
[email protected]ae51d192010-04-27 00:48:037510 return;
7511 }
[email protected]df37b9932013-03-08 05:21:427512 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157513}
7514
[email protected]ac77603c72013-03-08 13:52:067515void GLES2DecoderImpl::GetVertexAttribHelper(
7516 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247517 switch (pname) {
7518 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067519 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247520 if (buffer && !buffer->IsDeleted()) {
7521 GLuint client_id;
7522 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7523 *params = client_id;
7524 }
7525 break;
7526 }
7527 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067528 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247529 break;
7530 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067531 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247532 break;
7533 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067534 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247535 break;
7536 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067537 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247538 break;
7539 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067540 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247541 break;
[email protected]c6aef902012-02-14 03:31:427542 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067543 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427544 break;
[email protected]ac77603c72013-03-08 13:52:067545 default:
7546 NOTREACHED();
7547 break;
7548 }
7549}
7550
[email protected]4c6f5462014-03-05 00:26:567551void GLES2DecoderImpl::DoGetTexParameterfv(
7552 GLenum target, GLenum pname, GLfloat* params) {
7553 InitTextureMaxAnisotropyIfNeeded(target, pname);
7554 glGetTexParameterfv(target, pname, params);
7555}
7556
7557void GLES2DecoderImpl::DoGetTexParameteriv(
7558 GLenum target, GLenum pname, GLint* params) {
7559 InitTextureMaxAnisotropyIfNeeded(target, pname);
7560 glGetTexParameteriv(target, pname, params);
7561}
7562
7563void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7564 GLenum target, GLenum pname) {
7565 if (!workarounds().init_texture_max_anisotropy)
7566 return;
7567 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7568 !validators_->texture_parameter.IsValid(pname)) {
7569 return;
7570 }
7571
7572 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7573 &state_, target);
7574 if (!texture_ref) {
7575 LOCAL_SET_GL_ERROR(
7576 GL_INVALID_OPERATION,
7577 "glGetTexParamter{fi}v", "unknown texture for target");
7578 return;
7579 }
7580 Texture* texture = texture_ref->texture();
7581 texture->InitTextureMaxAnisotropyIfNeeded(target);
7582}
7583
[email protected]ac77603c72013-03-08 13:52:067584void GLES2DecoderImpl::DoGetVertexAttribfv(
7585 GLuint index, GLenum pname, GLfloat* params) {
7586 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7587 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517588 LOCAL_SET_GL_ERROR(
7589 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067590 return;
7591 }
7592 switch (pname) {
7593 case GL_CURRENT_VERTEX_ATTRIB: {
7594 const Vec4& value = state_.attrib_values[index];
7595 params[0] = value.v[0];
7596 params[1] = value.v[1];
7597 params[2] = value.v[2];
7598 params[3] = value.v[3];
7599 break;
7600 }
7601 default: {
7602 GLint value = 0;
7603 GetVertexAttribHelper(attrib, pname, &value);
7604 *params = static_cast<GLfloat>(value);
7605 break;
7606 }
7607 }
7608}
7609
7610void GLES2DecoderImpl::DoGetVertexAttribiv(
7611 GLuint index, GLenum pname, GLint* params) {
7612 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7613 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517614 LOCAL_SET_GL_ERROR(
7615 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067616 return;
7617 }
7618 switch (pname) {
[email protected]af6380962012-11-29 23:24:137619 case GL_CURRENT_VERTEX_ATTRIB: {
7620 const Vec4& value = state_.attrib_values[index];
7621 params[0] = static_cast<GLint>(value.v[0]);
7622 params[1] = static_cast<GLint>(value.v[1]);
7623 params[2] = static_cast<GLint>(value.v[2]);
7624 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247625 break;
[email protected]af6380962012-11-29 23:24:137626 }
[email protected]b1122982010-05-17 23:04:247627 default:
[email protected]ac77603c72013-03-08 13:52:067628 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247629 break;
7630 }
7631}
7632
[email protected]af6380962012-11-29 23:24:137633bool GLES2DecoderImpl::SetVertexAttribValue(
7634 const char* function_name, GLuint index, const GLfloat* value) {
7635 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517636 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137637 return false;
[email protected]b1122982010-05-17 23:04:247638 }
[email protected]af6380962012-11-29 23:24:137639 Vec4& v = state_.attrib_values[index];
7640 v.v[0] = value[0];
7641 v.v[1] = value[1];
7642 v.v[2] = value[2];
7643 v.v[3] = value[3];
7644 return true;
7645}
7646
7647void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7648 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7649 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7650 glVertexAttrib1f(index, v0);
7651 }
[email protected]b1122982010-05-17 23:04:247652}
7653
7654void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137655 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7656 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7657 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247658 }
[email protected]b1122982010-05-17 23:04:247659}
7660
7661void GLES2DecoderImpl::DoVertexAttrib3f(
7662 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137663 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7664 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7665 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247666 }
[email protected]b1122982010-05-17 23:04:247667}
7668
7669void GLES2DecoderImpl::DoVertexAttrib4f(
7670 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137671 GLfloat v[4] = { v0, v1, v2, v3, };
7672 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7673 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247674 }
[email protected]b1122982010-05-17 23:04:247675}
7676
7677void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137678 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7679 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7680 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247681 }
[email protected]b1122982010-05-17 23:04:247682}
7683
7684void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137685 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7686 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7687 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247688 }
[email protected]b1122982010-05-17 23:04:247689}
7690
7691void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137692 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7693 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7694 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247695 }
[email protected]b1122982010-05-17 23:04:247696}
7697
7698void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137699 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7700 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247701 }
[email protected]b1122982010-05-17 23:04:247702}
7703
zmo0c4b7cf2014-11-26 00:52:117704error::Error GLES2DecoderImpl::HandleVertexAttribIPointer(
7705 uint32 immediate_data_size,
7706 const void* cmd_data) {
7707 // TODO(zmo): Unsafe ES3 API, missing states update.
7708 if (!unsafe_es3_apis_enabled())
7709 return error::kUnknownCommand;
7710 const gles2::cmds::VertexAttribIPointer& c =
7711 *static_cast<const gles2::cmds::VertexAttribIPointer*>(cmd_data);
7712 GLuint indx = c.indx;
7713 GLint size = c.size;
7714 GLenum type = c.type;
7715 GLsizei stride = c.stride;
7716 GLsizei offset = c.offset;
7717 const void* ptr = reinterpret_cast<const void*>(offset);
7718 glVertexAttribIPointer(indx, size, type, stride, ptr);
7719 return error::kNoError;
7720}
7721
[email protected]f7a64ee2010-02-01 22:24:147722error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347723 uint32 immediate_data_size,
7724 const void* cmd_data) {
7725 const gles2::cmds::VertexAttribPointer& c =
7726 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467727
[email protected]7cd76fd2013-06-02 21:11:117728 if (!state_.bound_array_buffer.get() ||
7729 state_.bound_array_buffer->IsDeleted()) {
7730 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527731 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517732 LOCAL_SET_GL_ERROR(
7733 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467734 return error::kNoError;
7735 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517736 LOCAL_SET_GL_ERROR(
7737 GL_INVALID_VALUE,
7738 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467739 return error::kNoError;
7740 }
[email protected]96449d2c2009-11-25 00:01:327741 }
[email protected]8eee29c2010-04-29 03:38:297742
7743 GLuint indx = c.indx;
7744 GLint size = c.size;
7745 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327746 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297747 GLsizei stride = c.stride;
7748 GLsizei offset = c.offset;
7749 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057750 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517751 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297752 return error::kNoError;
7753 }
[email protected]9438b012010-06-15 22:55:057754 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517755 LOCAL_SET_GL_ERROR(
7756 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297757 return error::kNoError;
7758 }
7759 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517760 LOCAL_SET_GL_ERROR(
7761 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297762 return error::kNoError;
7763 }
7764 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517765 LOCAL_SET_GL_ERROR(
7766 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297767 return error::kNoError;
7768 }
7769 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517770 LOCAL_SET_GL_ERROR(
7771 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297772 return error::kNoError;
7773 }
7774 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517775 LOCAL_SET_GL_ERROR(
7776 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297777 return error::kNoError;
7778 }
7779 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317780 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127781 // component_size must be a power of two to use & as optimized modulo.
7782 DCHECK(GLES2Util::IsPOT(component_size));
7783 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517784 LOCAL_SET_GL_ERROR(
7785 GL_INVALID_OPERATION,
7786 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317787 return error::kNoError;
7788 }
[email protected]a07a23602014-08-05 11:36:127789 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517790 LOCAL_SET_GL_ERROR(
7791 GL_INVALID_OPERATION,
7792 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297793 return error::kNoError;
7794 }
[email protected]7cd76fd2013-06-02 21:11:117795 state_.vertex_attrib_manager
7796 ->SetAttribInfo(indx,
7797 state_.bound_array_buffer.get(),
7798 size,
7799 type,
7800 normalized,
7801 stride,
7802 stride != 0 ? stride : component_size * size,
7803 offset);
[email protected]8fbedc02010-11-18 18:43:407804 if (type != GL_FIXED) {
7805 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7806 }
[email protected]f7a64ee2010-02-01 22:24:147807 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327808}
7809
[email protected]43410e92012-04-20 17:06:287810void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7811 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247812 state_.viewport_x = x;
7813 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027814 state_.viewport_width = std::min(width, viewport_max_width_);
7815 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287816 glViewport(x, y, width, height);
7817}
7818
[email protected]c6aef902012-02-14 03:31:427819error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347820 uint32 immediate_data_size,
7821 const void* cmd_data) {
7822 const gles2::cmds::VertexAttribDivisorANGLE& c =
7823 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157824 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517825 LOCAL_SET_GL_ERROR(
7826 GL_INVALID_OPERATION,
7827 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537828 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427829 }
7830 GLuint index = c.index;
7831 GLuint divisor = c.divisor;
7832 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517833 LOCAL_SET_GL_ERROR(
7834 GL_INVALID_VALUE,
7835 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427836 return error::kNoError;
7837 }
7838
[email protected]e259eb412012-10-13 05:47:247839 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427840 index,
7841 divisor);
7842 glVertexAttribDivisorANGLE(index, divisor);
7843 return error::kNoError;
7844}
7845
[email protected]68586372013-12-11 01:27:597846template <typename pixel_data_type>
7847static void WriteAlphaData(
dcastagna504d45c2015-04-06 19:30:397848 void* pixels, uint32 row_count, uint32 channel_count,
[email protected]68586372013-12-11 01:27:597849 uint32 alpha_channel_index, uint32 unpadded_row_size,
7850 uint32 padded_row_size, pixel_data_type alpha_value) {
7851 DCHECK_GT(channel_count, 0U);
7852 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7853 uint32 unpadded_row_size_in_elements =
7854 unpadded_row_size / sizeof(pixel_data_type);
7855 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7856 uint32 padded_row_size_in_elements =
7857 padded_row_size / sizeof(pixel_data_type);
7858 pixel_data_type* dst =
7859 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7860 for (uint32 yy = 0; yy < row_count; ++yy) {
7861 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7862 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7863 *d = alpha_value;
7864 }
7865 dst += padded_row_size_in_elements;
7866 }
7867}
7868
[email protected]5a36dc132013-07-23 23:17:557869void GLES2DecoderImpl::FinishReadPixels(
7870 const cmds::ReadPixels& c,
7871 GLuint buffer) {
7872 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7873 GLsizei width = c.width;
7874 GLsizei height = c.height;
7875 GLenum format = c.format;
7876 GLenum type = c.type;
7877 typedef cmds::ReadPixels::Result Result;
7878 uint32 pixels_size;
7879 Result* result = NULL;
7880 if (c.result_shm_id != 0) {
7881 result = GetSharedMemoryAs<Result*>(
7882 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7883 if (!result) {
7884 if (buffer != 0) {
7885 glDeleteBuffersARB(1, &buffer);
7886 }
7887 return;
7888 }
7889 }
7890 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427891 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]5a36dc132013-07-23 23:17:557892 NULL, NULL);
7893 void* pixels = GetSharedMemoryAs<void*>(
7894 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7895 if (!pixels) {
7896 if (buffer != 0) {
7897 glDeleteBuffersARB(1, &buffer);
7898 }
7899 return;
7900 }
7901
7902 if (buffer != 0) {
7903 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337904 void* data;
7905 if (features().map_buffer_range) {
7906 data = glMapBufferRange(
7907 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7908 } else {
7909 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7910 }
miub70d78592014-11-15 03:53:477911 if (!data) {
7912 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer",
7913 "Unable to map memory for readback.");
7914 return;
7915 }
[email protected]5a36dc132013-07-23 23:17:557916 memcpy(pixels, data, pixels_size);
7917 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7918 // have to restore the state.
7919 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7920 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7921 glDeleteBuffersARB(1, &buffer);
7922 }
7923
7924 if (result != NULL) {
7925 *result = true;
7926 }
7927
7928 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7929 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7930 if ((channels_exist & 0x0008) == 0 &&
7931 workarounds().clear_alpha_in_readpixels) {
7932 // Set the alpha to 255 because some drivers are buggy in this regard.
7933 uint32 temp_size;
7934
7935 uint32 unpadded_row_size;
7936 uint32 padded_row_size;
7937 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427938 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]5a36dc132013-07-23 23:17:557939 &unpadded_row_size, &padded_row_size)) {
7940 return;
7941 }
[email protected]68586372013-12-11 01:27:597942
7943 uint32 channel_count = 0;
7944 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557945 switch (format) {
7946 case GL_RGBA:
7947 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597948 channel_count = 4;
7949 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557950 break;
[email protected]68586372013-12-11 01:27:597951 case GL_ALPHA:
7952 channel_count = 1;
7953 alpha_channel = 0;
7954 break;
7955 }
7956
7957 if (channel_count > 0) {
7958 switch (type) {
7959 case GL_UNSIGNED_BYTE:
7960 WriteAlphaData<uint8>(
7961 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7962 padded_row_size, 0xFF);
7963 break;
7964 case GL_FLOAT:
7965 WriteAlphaData<float>(
7966 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7967 padded_row_size, 1.0f);
7968 break;
7969 case GL_HALF_FLOAT:
7970 WriteAlphaData<uint16>(
7971 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7972 padded_row_size, 0x3C00);
7973 break;
[email protected]5a36dc132013-07-23 23:17:557974 }
[email protected]5a36dc132013-07-23 23:17:557975 }
7976 }
7977}
7978
vmiuracd108592014-09-08 14:36:347979error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7980 const void* cmd_data) {
7981 const gles2::cmds::ReadPixels& c =
7982 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217983 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227984 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7985 if (fbo_error != error::kNoError)
7986 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317987 GLint x = c.x;
7988 GLint y = c.y;
7989 GLsizei width = c.width;
7990 GLsizei height = c.height;
7991 GLenum format = c.format;
7992 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327993 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567994 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517995 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567996 return error::kNoError;
7997 }
[email protected]ed9f9cd2013-02-27 21:12:357998 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187999 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348000 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428001 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:248002 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:188003 return error::kOutOfBounds;
8004 }
[email protected]612d2f82009-12-08 20:49:318005 void* pixels = GetSharedMemoryAs<void*>(
8006 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:108007 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148008 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:468009 }
[email protected]de43f082013-04-02 01:16:108010 Result* result = NULL;
8011 if (c.result_shm_id != 0) {
8012 result = GetSharedMemoryAs<Result*>(
8013 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8014 if (!result) {
8015 return error::kOutOfBounds;
8016 }
8017 }
[email protected]a51788e2010-02-24 21:54:258018
[email protected]9438b012010-06-15 22:55:058019 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518020 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:298021 return error::kNoError;
8022 }
[email protected]68586372013-12-11 01:27:598023 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518024 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:128025 return error::kNoError;
8026 }
[email protected]68586372013-12-11 01:27:598027 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
8028 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
8029 // format and type are acceptable enums but not guaranteed to be supported
8030 // for this framebuffer. Have to ask gl if they are valid.
8031 GLint preferred_format = 0;
8032 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
8033 GLint preferred_type = 0;
8034 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
8035 if (format != static_cast<GLenum>(preferred_format) ||
8036 type != static_cast<GLenum>(preferred_type)) {
8037 LOCAL_SET_GL_ERROR(
8038 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
8039 "with the current read framebuffer");
8040 return error::kNoError;
8041 }
8042 }
[email protected]57f223832010-03-19 01:57:568043 if (width == 0 || height == 0) {
8044 return error::kNoError;
8045 }
8046
[email protected]57f223832010-03-19 01:57:568047 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:308048 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:568049
[email protected]3aad1a32012-09-07 20:54:478050 int32 max_x;
8051 int32 max_y;
8052 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:518053 LOCAL_SET_GL_ERROR(
8054 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:148055 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:318056 }
[email protected]57f223832010-03-19 01:57:568057
[email protected]2ea5950d2014-07-09 18:20:348058 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
8059 return error::kNoError;
8060 }
8061
[email protected]0d6bfdc2011-11-02 01:32:208062 if (!CheckBoundFramebuffersValid("glReadPixels")) {
8063 return error::kNoError;
8064 }
8065
[email protected]caa13ed2014-02-17 11:29:208066 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:108067
8068 ScopedResolvedFrameBufferBinder binder(this, false, true);
8069
[email protected]d37231fa2010-04-09 21:16:028070 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:568071 // The user requested an out of range area. Get the results 1 line
8072 // at a time.
8073 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:348074 uint32 unpadded_row_size;
8075 uint32 padded_row_size;
8076 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428077 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:348078 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:518079 LOCAL_SET_GL_ERROR(
8080 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:568081 return error::kNoError;
8082 }
8083
8084 GLint dest_x_offset = std::max(-x, 0);
8085 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:348086 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428087 dest_x_offset, 1, 1, format, type, state_.pack_alignment,
8088 &dest_row_offset, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518089 LOCAL_SET_GL_ERROR(
8090 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:568091 return error::kNoError;
8092 }
8093
8094 // Copy each row into the larger dest rect.
8095 int8* dst = static_cast<int8*>(pixels);
8096 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:028097 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:568098 GLint read_width = read_end_x - read_x;
8099 for (GLint yy = 0; yy < height; ++yy) {
8100 GLint ry = y + yy;
8101
8102 // Clear the row.
8103 memset(dst, 0, unpadded_row_size);
8104
8105 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:028106 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:568107 glReadPixels(
8108 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
8109 }
8110 dst += padded_row_size;
8111 }
8112 } else {
[email protected]5a36dc132013-07-23 23:17:558113 if (async && features().use_async_readpixels) {
miu50cef602014-11-11 01:35:418114 GLuint buffer = 0;
[email protected]5a36dc132013-07-23 23:17:558115 glGenBuffersARB(1, &buffer);
8116 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
miub70d78592014-11-15 03:53:478117 // For ANGLE client version 2, GL_STREAM_READ is not available.
marcheu1856f5d52015-04-04 01:42:538118 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ?
zmo68fcdc62014-12-05 21:51:498119 GL_STATIC_DRAW : GL_STREAM_READ;
miub70d78592014-11-15 03:53:478120 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint);
[email protected]5a36dc132013-07-23 23:17:558121 GLenum error = glGetError();
8122 if (error == GL_NO_ERROR) {
8123 glReadPixels(x, y, width, height, format, type, 0);
8124 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
8125 new FenceCallback()));
8126 WaitForReadPixels(base::Bind(
8127 &GLES2DecoderImpl::FinishReadPixels,
8128 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
8129 <GLES2DecoderImpl>(this),
8130 c, buffer));
8131 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
8132 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:598133 } else {
8134 // On error, unbind pack buffer and fall through to sync readpixels
8135 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
miu50cef602014-11-11 01:35:418136 glDeleteBuffersARB(1, &buffer);
[email protected]5a36dc132013-07-23 23:17:558137 }
8138 }
[email protected]57f223832010-03-19 01:57:568139 glReadPixels(x, y, width, height, format, type, pixels);
8140 }
[email protected]ab09b612013-03-11 22:11:518141 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:258142 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:108143 if (result != NULL) {
8144 *result = true;
8145 }
[email protected]5a36dc132013-07-23 23:17:558146 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:258147 }
[email protected]4848b9f82011-03-10 18:37:568148
[email protected]f7a64ee2010-02-01 22:24:148149 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328150}
8151
vmiuracd108592014-09-08 14:36:348152error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
8153 const void* cmd_data) {
8154 const gles2::cmds::PixelStorei& c =
8155 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198156 GLenum pname = c.pname;
8157 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:058158 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518159 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:128160 return error::kNoError;
8161 }
[email protected]222471d2011-11-30 18:06:398162 switch (pname) {
8163 case GL_PACK_ALIGNMENT:
8164 case GL_UNPACK_ALIGNMENT:
8165 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:518166 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:208167 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:398168 return error::kNoError;
8169 }
[email protected]164d6d52012-05-05 00:55:038170 break;
[email protected]0a1e9ad2012-05-04 21:13:038171 case GL_UNPACK_FLIP_Y_CHROMIUM:
8172 unpack_flip_y_ = (param != 0);
8173 return error::kNoError;
8174 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
8175 unpack_premultiply_alpha_ = (param != 0);
8176 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:178177 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
8178 unpack_unpremultiply_alpha_ = (param != 0);
8179 return error::kNoError;
[email protected]222471d2011-11-30 18:06:398180 default:
8181 break;
[email protected]b9849abf2009-11-25 19:13:198182 }
8183 glPixelStorei(pname, param);
8184 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:438185 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:248186 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:438187 break;
8188 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:428189 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:438190 break;
8191 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:248192 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:438193 break;
8194 default:
8195 // Validation should have prevented us from getting here.
8196 NOTREACHED();
8197 break;
[email protected]b9849abf2009-11-25 19:13:198198 }
[email protected]f7a64ee2010-02-01 22:24:148199 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198200}
8201
[email protected]1c75a3702011-11-11 14:15:288202error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:348203 uint32 immediate_data_size,
8204 const void* cmd_data) {
8205 const gles2::cmds::PostSubBufferCHROMIUM& c =
8206 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:388207 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:278208 {
8209 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
8210 }
[email protected]b381ee32014-03-22 02:43:438211 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:518212 LOCAL_SET_GL_ERROR(
8213 GL_INVALID_OPERATION,
8214 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:288215 return error::kNoError;
8216 }
[email protected]8f9b8dd2013-09-12 18:05:138217 bool is_tracing;
8218 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8219 &is_tracing);
8220 if (is_tracing) {
8221 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
8222 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8223 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8224 is_offscreen ? offscreen_size_ : surface_->GetSize());
8225 }
[email protected]7794d512012-04-17 20:36:498226 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:288227 return error::kNoError;
[email protected]7794d512012-04-17 20:36:498228 } else {
8229 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:288230 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:498231 }
[email protected]1c75a3702011-11-11 14:15:288232}
8233
[email protected]957f0642014-04-09 16:50:018234error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
8235 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348236 const void* cmd_data) {
8237 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
8238 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:108239 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
8240 if (!ref) {
8241 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8242 "glScheduleOverlayPlaneCHROMIUM",
8243 "unknown texture");
8244 return error::kNoError;
8245 }
8246 gfx::GLImage* image =
8247 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
8248 if (!image) {
8249 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8250 "glScheduleOverlayPlaneCHROMIUM",
8251 "unsupported texture format");
8252 return error::kNoError;
8253 }
8254 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
8255 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
8256 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
8257 "glScheduleOverlayPlaneCHROMIUM",
8258 "invalid transform enum");
8259 return error::kNoError;
8260 }
8261 if (!surface_->ScheduleOverlayPlane(
8262 c.plane_z_order,
8263 transform,
8264 image,
8265 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
8266 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
8267 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8268 "glScheduleOverlayPlaneCHROMIUM",
8269 "failed to schedule overlay");
8270 }
[email protected]957f0642014-04-09 16:50:018271 return error::kNoError;
8272}
8273
[email protected]558847a2010-03-24 07:02:548274error::Error GLES2DecoderImpl::GetAttribLocationHelper(
8275 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8276 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578277 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518278 LOCAL_SET_GL_ERROR(
8279 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578280 return error::kNoError;
8281 }
[email protected]df37b9932013-03-08 05:21:428282 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:588283 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:428284 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148285 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198286 }
[email protected]df37b9932013-03-08 05:21:428287 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518288 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438289 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258290 return error::kNoError;
8291 }
[email protected]b9849abf2009-11-25 19:13:198292 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548293 location_shm_id, location_shm_offset, sizeof(GLint));
8294 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148295 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198296 }
[email protected]558847a2010-03-24 07:02:548297 // Require the client to init this incase the context is lost and we are no
8298 // longer executing commands.
8299 if (*location != -1) {
8300 return error::kGenericError;
8301 }
[email protected]df37b9932013-03-08 05:21:428302 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148303 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198304}
8305
[email protected]558847a2010-03-24 07:02:548306error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:348307 uint32 immediate_data_size,
8308 const void* cmd_data) {
8309 const gles2::cmds::GetAttribLocation& c =
8310 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548311 Bucket* bucket = GetBucket(c.name_bucket_id);
8312 if (!bucket) {
8313 return error::kInvalidArguments;
8314 }
8315 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188316 if (!bucket->GetAsString(&name_str)) {
8317 return error::kInvalidArguments;
8318 }
[email protected]558847a2010-03-24 07:02:548319 return GetAttribLocationHelper(
8320 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8321}
8322
8323error::Error GLES2DecoderImpl::GetUniformLocationHelper(
8324 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8325 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578326 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518327 LOCAL_SET_GL_ERROR(
8328 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578329 return error::kNoError;
8330 }
[email protected]df37b9932013-03-08 05:21:428331 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:208332 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:428333 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148334 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198335 }
[email protected]df37b9932013-03-08 05:21:428336 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518337 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438338 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258339 return error::kNoError;
8340 }
[email protected]b9849abf2009-11-25 19:13:198341 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548342 location_shm_id, location_shm_offset, sizeof(GLint));
8343 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148344 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198345 }
[email protected]558847a2010-03-24 07:02:548346 // Require the client to init this incase the context is lost an we are no
8347 // longer executing commands.
8348 if (*location != -1) {
8349 return error::kGenericError;
8350 }
[email protected]df37b9932013-03-08 05:21:428351 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148352 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198353}
8354
[email protected]f7a64ee2010-02-01 22:24:148355error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:348356 uint32 immediate_data_size,
8357 const void* cmd_data) {
8358 const gles2::cmds::GetUniformLocation& c =
8359 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548360 Bucket* bucket = GetBucket(c.name_bucket_id);
8361 if (!bucket) {
8362 return error::kInvalidArguments;
8363 }
8364 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188365 if (!bucket->GetAsString(&name_str)) {
8366 return error::kInvalidArguments;
8367 }
[email protected]558847a2010-03-24 07:02:548368 return GetUniformLocationHelper(
8369 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:198370}
8371
zmo155435a42015-02-13 05:06:538372error::Error GLES2DecoderImpl::HandleGetUniformIndices(
8373 uint32 immediate_data_size,
8374 const void* cmd_data) {
8375 if (!unsafe_es3_apis_enabled())
8376 return error::kUnknownCommand;
8377 const gles2::cmds::GetUniformIndices& c =
8378 *static_cast<const gles2::cmds::GetUniformIndices*>(cmd_data);
8379 Bucket* bucket = GetBucket(c.names_bucket_id);
8380 if (!bucket) {
8381 return error::kInvalidArguments;
8382 }
8383 GLsizei count = 0;
8384 std::vector<char*> names;
8385 std::vector<GLint> len;
8386 if (!bucket->GetAsStrings(&count, &names, &len) || count <= 0) {
8387 return error::kInvalidArguments;
8388 }
8389 typedef cmds::GetUniformIndices::Result Result;
8390 Result* result = GetSharedMemoryAs<Result*>(
8391 c.indices_shm_id, c.indices_shm_offset,
8392 Result::ComputeSize(static_cast<size_t>(count)));
8393 GLuint* indices = result ? result->GetData() : NULL;
8394 if (indices == NULL) {
8395 return error::kOutOfBounds;
8396 }
8397 // Check that the client initialized the result.
8398 if (result->size != 0) {
8399 return error::kInvalidArguments;
8400 }
8401 Program* program = GetProgramInfoNotShader(c.program, "glGetUniformIndices");
8402 if (!program) {
8403 return error::kNoError;
8404 }
8405 GLuint service_id = program->service_id();
8406 GLint link_status = GL_FALSE;
8407 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
8408 if (link_status != GL_TRUE) {
8409 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8410 "glGetUniformIndices", "program not linked");
8411 return error::kNoError;
8412 }
8413 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetUniformIndices");
8414 glGetUniformIndices(service_id, count, &names[0], indices);
8415 GLenum error = glGetError();
8416 if (error == GL_NO_ERROR) {
8417 result->SetNumResults(count);
8418 } else {
8419 LOCAL_SET_GL_ERROR(error, "GetUniformIndices", "");
8420 }
8421 return error::kNoError;
8422}
8423
zmo5393fb52015-01-27 01:50:488424error::Error GLES2DecoderImpl::GetFragDataLocationHelper(
8425 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8426 const std::string& name_str) {
8427 GLint* location = GetSharedMemoryAs<GLint*>(
8428 location_shm_id, location_shm_offset, sizeof(GLint));
8429 if (!location) {
8430 return error::kOutOfBounds;
8431 }
8432 // Require the client to init this incase the context is lost and we are no
8433 // longer executing commands.
8434 if (*location != -1) {
8435 return error::kGenericError;
8436 }
8437 Program* program = GetProgramInfoNotShader(
8438 client_id, "glGetFragDataLocation");
8439 if (!program) {
8440 return error::kNoError;
8441 }
8442 *location = glGetFragDataLocation(program->service_id(), name_str.c_str());
8443 return error::kNoError;
8444}
8445
8446error::Error GLES2DecoderImpl::HandleGetFragDataLocation(
8447 uint32 immediate_data_size,
8448 const void* cmd_data) {
8449 if (!unsafe_es3_apis_enabled())
8450 return error::kUnknownCommand;
8451 const gles2::cmds::GetFragDataLocation& c =
8452 *static_cast<const gles2::cmds::GetFragDataLocation*>(cmd_data);
8453 Bucket* bucket = GetBucket(c.name_bucket_id);
8454 if (!bucket) {
8455 return error::kInvalidArguments;
8456 }
8457 std::string name_str;
8458 if (!bucket->GetAsString(&name_str)) {
8459 return error::kInvalidArguments;
8460 }
8461 return GetFragDataLocationHelper(
8462 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8463}
8464
zmo4a16ff992015-02-05 22:18:418465error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex(
8466 uint32 immediate_data_size, const void* cmd_data) {
8467 if (!unsafe_es3_apis_enabled())
8468 return error::kUnknownCommand;
8469 const gles2::cmds::GetUniformBlockIndex& c =
8470 *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data);
8471 Bucket* bucket = GetBucket(c.name_bucket_id);
8472 if (!bucket) {
8473 return error::kInvalidArguments;
8474 }
8475 std::string name_str;
8476 if (!bucket->GetAsString(&name_str)) {
8477 return error::kInvalidArguments;
8478 }
8479 GLuint* index = GetSharedMemoryAs<GLuint*>(
8480 c.index_shm_id, c.index_shm_offset, sizeof(GLuint));
8481 if (!index) {
8482 return error::kOutOfBounds;
8483 }
8484 // Require the client to init this in case the context is lost and we are no
8485 // longer executing commands.
8486 if (*index != GL_INVALID_INDEX) {
8487 return error::kGenericError;
8488 }
8489 Program* program = GetProgramInfoNotShader(
8490 c.program, "glGetUniformBlockIndex");
8491 if (!program) {
8492 return error::kNoError;
8493 }
8494 *index = glGetUniformBlockIndex(program->service_id(), name_str.c_str());
8495 return error::kNoError;
8496}
8497
vmiuracd108592014-09-08 14:36:348498error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
8499 const void* cmd_data) {
8500 const gles2::cmds::GetString& c =
8501 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:298502 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:058503 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:518504 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:298505 return error::kNoError;
8506 }
kbrc9f0e10c2015-03-31 19:49:128507
8508 const char* str = nullptr;
[email protected]f0d74742011-10-03 16:31:048509 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:158510 switch (name) {
8511 case GL_VERSION:
8512 str = "OpenGL ES 2.0 Chromium";
8513 break;
8514 case GL_SHADING_LANGUAGE_VERSION:
8515 str = "OpenGL ES GLSL ES 1.0 Chromium";
8516 break;
[email protected]32939602012-05-09 06:25:168517 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:168518 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:388519 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
8520 // They are used by WEBGL_debug_renderer_info.
8521 if (!force_webgl_glsl_validation_)
8522 str = "Chromium";
kbrc9f0e10c2015-03-31 19:49:128523 else
8524 str = reinterpret_cast<const char*>(glGetString(name));
[email protected]32939602012-05-09 06:25:168525 break;
[email protected]1958e0e2010-04-22 05:17:158526 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:048527 {
[email protected]70dc60932013-06-04 03:33:498528 // For WebGL contexts, strip out the OES derivatives and
8529 // EXT frag depth extensions if they have not been enabled.
8530 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:048531 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:498532 if (!derivatives_explicitly_enabled_) {
8533 size_t offset = extensions.find(kOESDerivativeExtension);
8534 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098535 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:498536 std::string());
8537 }
8538 }
8539 if (!frag_depth_explicitly_enabled_) {
8540 size_t offset = extensions.find(kEXTFragDepthExtension);
8541 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098542 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:498543 std::string());
8544 }
[email protected]f0d74742011-10-03 16:31:048545 }
[email protected]aff39ac82013-06-08 04:53:138546 if (!draw_buffers_explicitly_enabled_) {
8547 size_t offset = extensions.find(kEXTDrawBuffersExtension);
8548 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098549 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:138550 std::string());
8551 }
8552 }
[email protected]93c2fd82014-04-16 02:46:068553 if (!shader_texture_lod_explicitly_enabled_) {
8554 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
8555 if (std::string::npos != offset) {
8556 extensions.replace(offset,
8557 arraysize(kEXTShaderTextureLodExtension),
8558 std::string());
8559 }
8560 }
[email protected]f0d74742011-10-03 16:31:048561 } else {
[email protected]6f5fac9d12012-06-26 21:02:458562 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048563 }
[email protected]b381ee32014-03-22 02:43:438564 if (supports_post_sub_buffer_)
8565 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458566 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048567 }
[email protected]1958e0e2010-04-22 05:17:158568 break;
8569 default:
kbrc9f0e10c2015-03-31 19:49:128570 str = reinterpret_cast<const char*>(glGetString(name));
[email protected]1958e0e2010-04-22 05:17:158571 break;
8572 }
[email protected]ddd968b82010-03-02 00:44:298573 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158574 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298575 return error::kNoError;
8576}
8577
vmiuracd108592014-09-08 14:36:348578error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8579 const void* cmd_data) {
8580 const gles2::cmds::BufferData& c =
8581 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118582 GLenum target = static_cast<GLenum>(c.target);
8583 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8584 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8585 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8586 GLenum usage = static_cast<GLenum>(c.usage);
8587 const void* data = NULL;
8588 if (data_shm_id != 0 || data_shm_offset != 0) {
8589 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8590 if (!data) {
8591 return error::kOutOfBounds;
8592 }
8593 }
[email protected]0fbba3732013-07-17 15:40:138594 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148595 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198596}
8597
[email protected]0c86dbf2010-03-05 08:14:118598void GLES2DecoderImpl::DoBufferSubData(
8599 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138600 // Just delegate it. Some validation is actually done before this.
8601 buffer_manager()->ValidateAndDoBufferSubData(
8602 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198603}
8604
[email protected]0d6bfdc2011-11-02 01:32:208605bool GLES2DecoderImpl::ClearLevel(
boliu45dc77a2015-02-25 23:26:318606 Texture* texture,
[email protected]0d6bfdc2011-11-02 01:32:208607 unsigned target,
8608 int level,
[email protected]d8e6c9242014-02-20 16:56:258609 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:208610 unsigned format,
8611 unsigned type,
8612 int width,
[email protected]4502e6492011-12-14 19:39:158613 int height,
8614 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:008615 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008616 if (feature_info_->feature_flags().angle_depth_texture &&
8617 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008618 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8619 // on depth formats.
8620 GLuint fb = 0;
8621 glGenFramebuffersEXT(1, &fb);
8622 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8623
8624 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8625 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8626 GL_DEPTH_ATTACHMENT;
8627
boliu45dc77a2015-02-25 23:26:318628 glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, attachment, target,
8629 texture->service_id(), level);
[email protected]81375742012-06-08 00:04:008630 // ANGLE promises a depth only attachment ok.
8631 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8632 GL_FRAMEBUFFER_COMPLETE) {
8633 return false;
8634 }
8635 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478636 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8637 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008638 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458639 state_.SetDeviceDepthMask(GL_TRUE);
8640 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008641 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8642
8643 RestoreClearState();
8644
8645 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358646 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008647 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8648 GLuint fb_service_id =
8649 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8650 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8651 return true;
8652 }
8653
[email protected]45d15a62012-04-18 14:33:178654 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8655
8656 uint32 size;
8657 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348658 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428659 width, height, 1, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178660 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208661 return false;
8662 }
[email protected]45d15a62012-04-18 14:33:178663
[email protected]a5d3dad2012-05-26 04:34:448664 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8665
[email protected]45d15a62012-04-18 14:33:178666 int tile_height;
8667
8668 if (size > kMaxZeroSize) {
8669 if (kMaxZeroSize < padded_row_size) {
8670 // That'd be an awfully large texture.
8671 return false;
8672 }
8673 // We should never have a large total size with a zero row size.
8674 DCHECK_GT(padded_row_size, 0U);
8675 tile_height = kMaxZeroSize / padded_row_size;
8676 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428677 width, tile_height, 1, format, type, state_.unpack_alignment, &size,
[email protected]e259eb412012-10-13 05:47:248678 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178679 return false;
8680 }
[email protected]4502e6492011-12-14 19:39:158681 } else {
[email protected]45d15a62012-04-18 14:33:178682 tile_height = height;
8683 }
8684
8685 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558686 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178687 memset(zero.get(), 0, size);
boliu45dc77a2015-02-25 23:26:318688 glBindTexture(texture->target(), texture->service_id());
[email protected]45d15a62012-04-18 14:33:178689
boliu45dc77a2015-02-25 23:26:318690 bool has_images = texture->HasImages();
[email protected]45d15a62012-04-18 14:33:178691 GLint y = 0;
8692 while (y < height) {
8693 GLint h = y + tile_height > height ? height - y : tile_height;
boliu45dc77a2015-02-25 23:26:318694 if (is_texture_immutable || h != height || has_images) {
[email protected]45d15a62012-04-18 14:33:178695 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8696 } else {
[email protected]8f1d2aa2013-05-10 23:45:388697 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258698 target, level, internal_format, width, h, 0, format, type,
8699 zero.get());
[email protected]45d15a62012-04-18 14:33:178700 }
8701 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158702 }
boliu45dc77a2015-02-25 23:26:318703 TextureRef* bound_texture =
8704 texture_manager()->GetTextureInfoForTarget(&state_, texture->target());
8705 glBindTexture(texture->target(),
8706 bound_texture ? bound_texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208707 return true;
8708}
8709
[email protected]ad84a3a2012-06-08 21:42:438710namespace {
8711
8712const int kS3TCBlockWidth = 4;
8713const int kS3TCBlockHeight = 4;
8714const int kS3TCDXT1BlockSize = 8;
8715const int kS3TCDXT3AndDXT5BlockSize = 16;
8716
8717bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518718 return (size == 1) ||
8719 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438720}
8721
[email protected]8aec81ec2014-04-29 01:04:518722bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128723 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518724}
8725
[email protected]ad84a3a2012-06-08 21:42:438726} // anonymous namespace.
8727
8728bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8729 const char* function_name,
8730 GLsizei width, GLsizei height, GLenum format, size_t size) {
8731 unsigned int bytes_required = 0;
8732
8733 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518734 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438735 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518736 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8737 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438738 int num_blocks_across =
8739 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8740 int num_blocks_down =
8741 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8742 int num_blocks = num_blocks_across * num_blocks_down;
8743 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8744 break;
8745 }
[email protected]8aec81ec2014-04-29 01:04:518746 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8747 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438748 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8749 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8750 int num_blocks_across =
8751 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8752 int num_blocks_down =
8753 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8754 int num_blocks = num_blocks_across * num_blocks_down;
8755 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8756 break;
8757 }
[email protected]8aec81ec2014-04-29 01:04:518758 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8759 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8760 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8761 break;
8762 }
8763 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8764 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8765 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078766 break;
8767 }
[email protected]ad84a3a2012-06-08 21:42:438768 default:
[email protected]ab09b612013-03-11 22:11:518769 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438770 return false;
8771 }
8772
8773 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518774 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438775 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8776 return false;
8777 }
8778
8779 return true;
8780}
8781
8782bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8783 const char* function_name,
8784 GLint level, GLsizei width, GLsizei height, GLenum format) {
8785 switch (format) {
8786 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8787 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8788 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8789 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8790 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518791 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438792 GL_INVALID_OPERATION, function_name,
8793 "width or height invalid for level");
8794 return false;
8795 }
8796 return true;
8797 }
[email protected]8aec81ec2014-04-29 01:04:518798 case GL_ATC_RGB_AMD:
8799 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8800 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8801 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078802 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518803 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078804 GL_INVALID_OPERATION, function_name,
8805 "width or height invalid for level");
8806 return false;
8807 }
8808 return true;
[email protected]8aec81ec2014-04-29 01:04:518809 }
8810 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8811 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8812 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8813 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8814 if (!IsValidPVRTCSize(level, width) ||
8815 !IsValidPVRTCSize(level, height)) {
8816 LOCAL_SET_GL_ERROR(
8817 GL_INVALID_OPERATION, function_name,
8818 "width or height invalid for level");
8819 return false;
8820 }
8821 return true;
8822 }
[email protected]ad84a3a2012-06-08 21:42:438823 default:
8824 return false;
8825 }
8826}
8827
8828bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8829 const char* function_name,
8830 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8831 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358832 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438833 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518834 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438835 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8836 return false;
8837 }
8838
8839 switch (format) {
8840 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8841 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8842 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8843 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8844 const int kBlockWidth = 4;
8845 const int kBlockHeight = 4;
8846 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518847 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438848 GL_INVALID_OPERATION, function_name,
8849 "xoffset or yoffset not multiple of 4");
8850 return false;
8851 }
8852 GLsizei tex_width = 0;
8853 GLsizei tex_height = 0;
8854 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8855 width - xoffset > tex_width ||
8856 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518857 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438858 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8859 return false;
8860 }
8861 return ValidateCompressedTexDimensions(
8862 function_name, level, width, height, format);
8863 }
[email protected]8aec81ec2014-04-29 01:04:518864 case GL_ATC_RGB_AMD:
8865 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8866 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8867 LOCAL_SET_GL_ERROR(
8868 GL_INVALID_OPERATION, function_name,
8869 "not supported for ATC textures");
8870 return false;
8871 }
[email protected]2d3765b2012-10-03 00:31:078872 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518873 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078874 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208875 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078876 return false;
8877 }
[email protected]8aec81ec2014-04-29 01:04:518878 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8879 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8880 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8881 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8882 if ((xoffset != 0) || (yoffset != 0)) {
8883 LOCAL_SET_GL_ERROR(
8884 GL_INVALID_OPERATION, function_name,
8885 "xoffset and yoffset must be zero");
8886 return false;
8887 }
8888 GLsizei tex_width = 0;
8889 GLsizei tex_height = 0;
8890 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8891 width != tex_width ||
8892 height != tex_height) {
8893 LOCAL_SET_GL_ERROR(
8894 GL_INVALID_OPERATION, function_name,
8895 "dimensions must match existing texture level dimensions");
8896 return false;
8897 }
8898 return ValidateCompressedTexDimensions(
8899 function_name, level, width, height, format);
8900 }
[email protected]ad84a3a2012-06-08 21:42:438901 default:
8902 return false;
8903 }
8904}
8905
[email protected]a93bb842010-02-16 23:03:478906error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8907 GLenum target,
8908 GLint level,
8909 GLenum internal_format,
8910 GLsizei width,
8911 GLsizei height,
8912 GLint border,
8913 GLsizei image_size,
8914 const void* data) {
[email protected]a93bb842010-02-16 23:03:478915 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058916 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518917 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8918 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298919 return error::kNoError;
8920 }
[email protected]9438b012010-06-15 22:55:058921 if (!validators_->compressed_texture_format.IsValid(
8922 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518923 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538924 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478925 return error::kNoError;
8926 }
[email protected]80eb6b52012-01-19 00:14:418927 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478928 border != 0) {
[email protected]ab09b612013-03-11 22:11:518929 LOCAL_SET_GL_ERROR(
8930 GL_INVALID_VALUE,
8931 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478932 return error::kNoError;
8933 }
[email protected]c986af502013-08-14 01:04:448934 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8935 &state_, target);
[email protected]370eaf12013-05-18 09:19:498936 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518937 LOCAL_SET_GL_ERROR(
8938 GL_INVALID_VALUE,
8939 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478940 return error::kNoError;
8941 }
[email protected]370eaf12013-05-18 09:19:498942 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078943 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518944 LOCAL_SET_GL_ERROR(
8945 GL_INVALID_OPERATION,
8946 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438947 return error::kNoError;
8948 }
8949
8950 if (!ValidateCompressedTexDimensions(
8951 "glCompressedTexImage2D", level, width, height, internal_format) ||
8952 !ValidateCompressedTexFuncData(
8953 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178954 return error::kNoError;
8955 }
[email protected]968351b2011-12-20 08:26:518956
[email protected]7989c9e2013-01-23 06:39:268957 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518958 LOCAL_SET_GL_ERROR(
8959 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268960 return error::kNoError;
8961 }
8962
[email protected]02965c22013-03-09 02:40:078963 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448964 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518965 }
8966
[email protected]40d90a22013-04-09 03:39:558967 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478968 if (!data) {
8969 zero.reset(new int8[image_size]);
8970 memset(zero.get(), 0, image_size);
8971 data = zero.get();
8972 }
[email protected]ab09b612013-03-11 22:11:518973 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478974 glCompressedTexImage2D(
8975 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518976 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438977 if (error == GL_NO_ERROR) {
8978 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498979 texture_ref, target, level, internal_format,
8980 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438981 }
vmiura8266ca72014-09-09 21:37:008982
8983 // This may be a slow command. Exit command processing to allow for
8984 // context preemption and GPU watchdog checks.
8985 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478986 return error::kNoError;
8987}
8988
[email protected]f7a64ee2010-02-01 22:24:148989error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348990 uint32 immediate_data_size,
8991 const void* cmd_data) {
8992 const gles2::cmds::CompressedTexImage2D& c =
8993 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198994 GLenum target = static_cast<GLenum>(c.target);
8995 GLint level = static_cast<GLint>(c.level);
8996 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8997 GLsizei width = static_cast<GLsizei>(c.width);
8998 GLsizei height = static_cast<GLsizei>(c.height);
8999 GLint border = static_cast<GLint>(c.border);
9000 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
9001 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
9002 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
9003 const void* data = NULL;
9004 if (data_shm_id != 0 || data_shm_offset != 0) {
9005 data = GetSharedMemoryAs<const void*>(
9006 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:469007 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:149008 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:199009 }
9010 }
[email protected]a93bb842010-02-16 23:03:479011 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:199012 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:199013}
9014
[email protected]b6140d02010-05-17 14:47:169015error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:349016 uint32 immediate_data_size,
9017 const void* cmd_data) {
9018 const gles2::cmds::CompressedTexImage2DBucket& c =
9019 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:169020 GLenum target = static_cast<GLenum>(c.target);
9021 GLint level = static_cast<GLint>(c.level);
9022 GLenum internal_format = static_cast<GLenum>(c.internalformat);
9023 GLsizei width = static_cast<GLsizei>(c.width);
9024 GLsizei height = static_cast<GLsizei>(c.height);
9025 GLint border = static_cast<GLint>(c.border);
9026 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289027 if (!bucket) {
9028 return error::kInvalidArguments;
9029 }
9030 uint32 data_size = bucket->size();
9031 GLsizei imageSize = data_size;
9032 const void* data = bucket->GetData(0, data_size);
9033 if (!data) {
9034 return error::kInvalidArguments;
9035 }
[email protected]b6140d02010-05-17 14:47:169036 return DoCompressedTexImage2D(
9037 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:289038 imageSize, data);
[email protected]b6140d02010-05-17 14:47:169039}
9040
9041error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
9042 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:349043 const void* cmd_data) {
9044 const gles2::cmds::CompressedTexSubImage2DBucket& c =
9045 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:169046 GLenum target = static_cast<GLenum>(c.target);
9047 GLint level = static_cast<GLint>(c.level);
9048 GLint xoffset = static_cast<GLint>(c.xoffset);
9049 GLint yoffset = static_cast<GLint>(c.yoffset);
9050 GLsizei width = static_cast<GLsizei>(c.width);
9051 GLsizei height = static_cast<GLsizei>(c.height);
9052 GLenum format = static_cast<GLenum>(c.format);
9053 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289054 if (!bucket) {
9055 return error::kInvalidArguments;
9056 }
[email protected]b6140d02010-05-17 14:47:169057 uint32 data_size = bucket->size();
9058 GLsizei imageSize = data_size;
9059 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:289060 if (!data) {
9061 return error::kInvalidArguments;
9062 }
[email protected]9438b012010-06-15 22:55:059063 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519064 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:539065 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:169066 return error::kNoError;
9067 }
[email protected]9438b012010-06-15 22:55:059068 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:519069 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9070 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:059071 return error::kNoError;
9072 }
[email protected]b6140d02010-05-17 14:47:169073 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519074 LOCAL_SET_GL_ERROR(
9075 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:169076 return error::kNoError;
9077 }
9078 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519079 LOCAL_SET_GL_ERROR(
9080 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:169081 return error::kNoError;
9082 }
9083 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:519084 LOCAL_SET_GL_ERROR(
9085 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:169086 return error::kNoError;
9087 }
[email protected]cadde4a2010-07-31 17:10:439088 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:169089 target, level, xoffset, yoffset, width, height, format, imageSize, data);
9090 return error::kNoError;
9091}
9092
vmiuracd108592014-09-08 14:36:349093error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
9094 const void* cmd_data) {
9095 const gles2::cmds::TexImage2D& c =
9096 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139097 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
9098 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:449099 // Set as failed for now, but if it successed, this will be set to not failed.
9100 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:199101 GLenum target = static_cast<GLenum>(c.target);
9102 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:449103 // TODO(kloveless): Change TexImage2D command to use unsigned integer
9104 // for internalformat.
9105 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:199106 GLsizei width = static_cast<GLsizei>(c.width);
9107 GLsizei height = static_cast<GLsizei>(c.height);
9108 GLint border = static_cast<GLint>(c.border);
9109 GLenum format = static_cast<GLenum>(c.format);
9110 GLenum type = static_cast<GLenum>(c.type);
9111 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9112 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:189113 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:349114 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429115 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
9116 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:189117 return error::kOutOfBounds;
9118 }
[email protected]b9849abf2009-11-25 19:13:199119 const void* pixels = NULL;
9120 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9121 pixels = GetSharedMemoryAs<const void*>(
9122 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:469123 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:149124 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:199125 }
9126 }
[email protected]f598f422012-12-07 08:30:039127
bajones6b0124f42015-04-07 23:14:429128 // For testing only. Allows us to stress the ability to respond to OOM errors.
9129 if (workarounds().simulate_out_of_memory_on_large_textures &&
9130 (width * height >= 4096 * 4096)) {
9131 LOCAL_SET_GL_ERROR(
9132 GL_OUT_OF_MEMORY,
9133 "glTexImage2D", "synthetic out of memory");
9134 return error::kNoError;
9135 }
9136
[email protected]c986af502013-08-14 01:04:449137 TextureManager::DoTextImage2DArguments args = {
9138 target, level, internal_format, width, height, border, format, type,
9139 pixels, pixels_size};
9140 texture_manager()->ValidateAndDoTexImage2D(
9141 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:009142
9143 // This may be a slow command. Exit command processing to allow for
9144 // context preemption and GPU watchdog checks.
9145 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039146 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:199147}
9148
zmobcadd6592015-01-08 20:13:429149error::Error GLES2DecoderImpl::HandleTexImage3D(uint32 immediate_data_size,
9150 const void* cmd_data) {
9151 // TODO(zmo): Unsafe ES3 API.
9152 if (!unsafe_es3_apis_enabled())
9153 return error::kUnknownCommand;
9154
9155 const gles2::cmds::TexImage3D& c =
9156 *static_cast<const gles2::cmds::TexImage3D*>(cmd_data);
9157 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D",
9158 "widthXheight", c.width * c.height, "depth", c.depth);
9159 GLenum target = static_cast<GLenum>(c.target);
9160 GLint level = static_cast<GLint>(c.level);
9161 GLenum internal_format = static_cast<GLenum>(c.internalformat);
9162 GLsizei width = static_cast<GLsizei>(c.width);
9163 GLsizei height = static_cast<GLsizei>(c.height);
9164 GLsizei depth = static_cast<GLsizei>(c.depth);
9165 GLint border = static_cast<GLint>(c.border);
9166 GLenum format = static_cast<GLenum>(c.format);
9167 GLenum type = static_cast<GLenum>(c.type);
9168 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
9169 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
9170 uint32 pixels_size;
9171 if (!GLES2Util::ComputeImageDataSizes(
9172 width, height, depth, format, type, state_.unpack_alignment, &pixels_size,
9173 NULL, NULL)) {
9174 return error::kOutOfBounds;
9175 }
9176 const void* pixels = NULL;
9177 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
9178 pixels = GetSharedMemoryAs<const void*>(
9179 pixels_shm_id, pixels_shm_offset, pixels_size);
9180 if (!pixels) {
9181 return error::kOutOfBounds;
9182 }
9183 }
9184
9185 glTexImage3D(target, level, internal_format, width, height, depth, border,
9186 format, type, pixels);
9187
9188 // This may be a slow command. Exit command processing to allow for
9189 // context preemption and GPU watchdog checks.
9190 ExitCommandProcessingEarly();
9191 return error::kNoError;
9192}
9193
[email protected]cadde4a2010-07-31 17:10:439194void GLES2DecoderImpl::DoCompressedTexSubImage2D(
9195 GLenum target,
9196 GLint level,
9197 GLint xoffset,
9198 GLint yoffset,
9199 GLsizei width,
9200 GLsizei height,
9201 GLenum format,
9202 GLsizei image_size,
9203 const void * data) {
[email protected]c986af502013-08-14 01:04:449204 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9205 &state_, target);
[email protected]370eaf12013-05-18 09:19:499206 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519207 LOCAL_SET_GL_ERROR(
9208 GL_INVALID_OPERATION,
9209 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439210 return;
9211 }
[email protected]370eaf12013-05-18 09:19:499212 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439213 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:529214 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079215 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519216 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:529217 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439218 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:529219 return;
9220 }
9221 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:519222 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:529223 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439224 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:529225 return;
9226 }
[email protected]02965c22013-03-09 02:40:079227 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529228 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519229 LOCAL_SET_GL_ERROR(
9230 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439231 return;
9232 }
[email protected]ad84a3a2012-06-08 21:42:439233
9234 if (!ValidateCompressedTexFuncData(
9235 "glCompressedTexSubImage2D", width, height, format, image_size) ||
9236 !ValidateCompressedTexSubDimensions(
9237 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:079238 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:439239 return;
9240 }
9241
9242
[email protected]0d6bfdc2011-11-02 01:32:209243 // Note: There is no need to deal with texture cleared tracking here
9244 // because the validation above means you can only get here if the level
9245 // is already a matching compressed format and in that case
9246 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:439247 glCompressedTexSubImage2D(
9248 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:009249
9250 // This may be a slow command. Exit command processing to allow for
9251 // context preemption and GPU watchdog checks.
9252 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439253}
9254
[email protected]6e288612010-12-21 20:45:039255static void Clip(
9256 GLint start, GLint range, GLint sourceRange,
9257 GLint* out_start, GLint* out_range) {
9258 DCHECK(out_start);
9259 DCHECK(out_range);
9260 if (start < 0) {
9261 range += start;
9262 start = 0;
9263 }
9264 GLint end = start + range;
9265 if (end > sourceRange) {
9266 range -= end - sourceRange;
9267 }
9268 *out_start = start;
9269 *out_range = range;
9270}
9271
[email protected]cadde4a2010-07-31 17:10:439272void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:449273 GLenum target,
9274 GLint level,
9275 GLenum internal_format,
9276 GLint x,
9277 GLint y,
9278 GLsizei width,
9279 GLsizei height,
9280 GLint border) {
[email protected]09e17272012-11-30 10:30:449281 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449282 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9283 &state_, target);
[email protected]370eaf12013-05-18 09:19:499284 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519285 LOCAL_SET_GL_ERROR(
9286 GL_INVALID_OPERATION,
9287 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439288 return;
9289 }
[email protected]370eaf12013-05-18 09:19:499290 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079291 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519292 LOCAL_SET_GL_ERROR(
9293 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:539294 return;
[email protected]97dc7cbe2011-12-06 17:26:179295 }
[email protected]80eb6b52012-01-19 00:14:419296 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:189297 border != 0) {
[email protected]ab09b612013-03-11 22:11:519298 LOCAL_SET_GL_ERROR(
9299 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:189300 return;
9301 }
[email protected]17a961192014-02-14 15:20:529302 if (!texture_manager()->ValidateFormatAndTypeCombination(
9303 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
9304 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:009305 return;
9306 }
[email protected]f5719fb2010-08-04 18:27:189307
[email protected]9edc6b22010-12-23 02:00:269308 // Check we have compatible formats.
9309 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9310 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9311 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
9312
9313 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519314 LOCAL_SET_GL_ERROR(
9315 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269316 return;
9317 }
9318
[email protected]81375742012-06-08 00:04:009319 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519320 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009321 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:269322 "glCopyTexImage2D", "can not be used with depth or stencil textures");
9323 return;
9324 }
9325
9326 uint32 estimated_size = 0;
9327 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429328 width, height, 1, internal_format, GL_UNSIGNED_BYTE,
9329 state_.unpack_alignment, &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519330 LOCAL_SET_GL_ERROR(
9331 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269332 return;
9333 }
9334
9335 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519336 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:009337 return;
9338 }
9339
[email protected]2ea5950d2014-07-09 18:20:349340 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
9341 return;
9342 }
9343
zmo383512cf2014-10-14 00:11:009344 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9345 LOCAL_SET_GL_ERROR(
9346 GL_INVALID_OPERATION,
9347 "glCopyTexImage2D", "source and destination textures are the same");
9348 return;
9349 }
9350
[email protected]a0b78dc2011-11-11 10:43:109351 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
9352 return;
9353 }
9354
[email protected]ab09b612013-03-11 22:11:519355 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:279356 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039357 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:269358
[email protected]02965c22013-03-09 02:40:079359 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449360 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:469361 }
9362
[email protected]9edc6b22010-12-23 02:00:269363 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:039364 GLint copyX = 0;
9365 GLint copyY = 0;
9366 GLint copyWidth = 0;
9367 GLint copyHeight = 0;
9368 Clip(x, width, size.width(), &copyX, &copyWidth);
9369 Clip(y, height, size.height(), &copyY, &copyHeight);
9370
9371 if (copyX != x ||
9372 copyY != y ||
9373 copyWidth != width ||
9374 copyHeight != height) {
9375 // some part was clipped so clear the texture.
boliu45dc77a2015-02-25 23:26:319376 if (!ClearLevel(texture, target, level, internal_format, internal_format,
9377 GL_UNSIGNED_BYTE, width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:519378 LOCAL_SET_GL_ERROR(
9379 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:039380 return;
9381 }
[email protected]6e288612010-12-21 20:45:039382 if (copyHeight > 0 && copyWidth > 0) {
9383 GLint dx = copyX - x;
9384 GLint dy = copyY - y;
9385 GLint destX = dx;
9386 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:379387 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039388 glCopyTexSubImage2D(target, level,
9389 destX, destY, copyX, copyY,
9390 copyWidth, copyHeight);
9391 }
9392 } else {
[email protected]00c2cf92014-03-14 00:08:379393 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039394 glCopyTexImage2D(target, level, internal_format,
9395 copyX, copyY, copyWidth, copyHeight, border);
9396 }
[email protected]ab09b612013-03-11 22:11:519397 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:439398 if (error == GL_NO_ERROR) {
9399 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499400 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:209401 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:439402 }
vmiura8266ca72014-09-09 21:37:009403
9404 // This may be a slow command. Exit command processing to allow for
9405 // context preemption and GPU watchdog checks.
9406 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439407}
9408
9409void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:449410 GLenum target,
9411 GLint level,
9412 GLint xoffset,
9413 GLint yoffset,
9414 GLint x,
9415 GLint y,
9416 GLsizei width,
9417 GLsizei height) {
[email protected]09e17272012-11-30 10:30:449418 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449419 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9420 &state_, target);
[email protected]370eaf12013-05-18 09:19:499421 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519422 LOCAL_SET_GL_ERROR(
9423 GL_INVALID_OPERATION,
9424 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439425 return;
9426 }
[email protected]370eaf12013-05-18 09:19:499427 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439428 GLenum type = 0;
9429 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:079430 if (!texture->GetLevelType(target, level, &type, &format) ||
9431 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529432 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519433 LOCAL_SET_GL_ERROR(
9434 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439435 return;
9436 }
[email protected]85a4ac22013-05-31 01:58:479437 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519438 LOCAL_SET_GL_ERROR(
9439 GL_INVALID_OPERATION,
9440 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599441 return;
9442 }
[email protected]9edc6b22010-12-23 02:00:269443
9444 // Check we have compatible formats.
9445 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9446 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9447 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
9448
[email protected]2d3765b2012-10-03 00:31:079449 if (!channels_needed ||
9450 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519451 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439452 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269453 return;
9454 }
9455
[email protected]81375742012-06-08 00:04:009456 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519457 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009458 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439459 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:009460 return;
9461 }
9462
[email protected]2ea5950d2014-07-09 18:20:349463 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
9464 return;
9465 }
9466
zmo383512cf2014-10-14 00:11:009467 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9468 LOCAL_SET_GL_ERROR(
9469 GL_INVALID_OPERATION,
9470 "glCopyTexSubImage2D", "source and destination textures are the same");
9471 return;
9472 }
9473
[email protected]a0b78dc2011-11-11 10:43:109474 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
9475 return;
9476 }
9477
[email protected]de26b3c2011-08-03 21:54:279478 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039479 gfx::Size size = GetBoundReadFrameBufferSize();
9480 GLint copyX = 0;
9481 GLint copyY = 0;
9482 GLint copyWidth = 0;
9483 GLint copyHeight = 0;
9484 Clip(x, width, size.width(), &copyX, &copyWidth);
9485 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:209486
dongseong.hwang351519f2015-01-21 14:33:599487 if (xoffset != 0 || yoffset != 0 || width != size.width() ||
9488 height != size.height()) {
9489 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
9490 level)) {
9491 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D",
9492 "dimensions too big");
9493 return;
9494 }
9495 } else {
9496 // Write all pixels in below.
9497 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0d6bfdc2011-11-02 01:32:209498 }
9499
[email protected]6e288612010-12-21 20:45:039500 if (copyX != x ||
9501 copyY != y ||
9502 copyWidth != width ||
9503 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:209504 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:039505 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:349506 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429507 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:249508 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519509 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439510 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:039511 return;
9512 }
[email protected]40d90a22013-04-09 03:39:559513 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:039514 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:379515 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039516 glTexSubImage2D(
9517 target, level, xoffset, yoffset, width, height,
9518 format, type, zero.get());
9519 }
[email protected]0d6bfdc2011-11-02 01:32:209520
[email protected]6e288612010-12-21 20:45:039521 if (copyHeight > 0 && copyWidth > 0) {
9522 GLint dx = copyX - x;
9523 GLint dy = copyY - y;
9524 GLint destX = xoffset + dx;
9525 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:379526 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039527 glCopyTexSubImage2D(target, level,
9528 destX, destY, copyX, copyY,
9529 copyWidth, copyHeight);
9530 }
vmiura8266ca72014-09-09 21:37:009531
9532 // This may be a slow command. Exit command processing to allow for
9533 // context preemption and GPU watchdog checks.
9534 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439535}
9536
[email protected]f598f422012-12-07 08:30:039537bool GLES2DecoderImpl::ValidateTexSubImage2D(
9538 error::Error* error,
9539 const char* function_name,
9540 GLenum target,
9541 GLint level,
9542 GLint xoffset,
9543 GLint yoffset,
9544 GLsizei width,
9545 GLsizei height,
9546 GLenum format,
9547 GLenum type,
9548 const void * data) {
9549 (*error) = error::kNoError;
9550 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519551 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:039552 return false;
9553 }
9554 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519555 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:039556 return false;
9557 }
9558 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519559 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:039560 return false;
9561 }
[email protected]c986af502013-08-14 01:04:449562 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9563 &state_, target);
[email protected]370eaf12013-05-18 09:19:499564 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519565 LOCAL_SET_GL_ERROR(
9566 GL_INVALID_OPERATION,
9567 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:039568 return false;
[email protected]cadde4a2010-07-31 17:10:439569 }
[email protected]370eaf12013-05-18 09:19:499570 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:529571 GLenum current_type = 0;
9572 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079573 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519574 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:039575 GL_INVALID_OPERATION, function_name, "level does not exist.");
9576 return false;
[email protected]df6cf1ad2011-01-29 01:20:529577 }
[email protected]17a961192014-02-14 15:20:529578 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
9579 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:039580 return false;
[email protected]df6cf1ad2011-01-29 01:20:529581 }
9582 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:519583 LOCAL_SET_GL_ERROR(
9584 GL_INVALID_OPERATION,
9585 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:039586 return false;
[email protected]df6cf1ad2011-01-29 01:20:529587 }
[email protected]85a4ac22013-05-31 01:58:479588 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519589 LOCAL_SET_GL_ERROR(
9590 GL_INVALID_OPERATION,
9591 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599592 return false;
9593 }
[email protected]02965c22013-03-09 02:40:079594 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529595 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519596 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:039597 return false;
[email protected]cadde4a2010-07-31 17:10:439598 }
[email protected]81375742012-06-08 00:04:009599 if ((GLES2Util::GetChannelsForFormat(format) &
9600 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519601 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009602 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:039603 function_name, "can not supply data for depth or stencil textures");
9604 return false;
[email protected]81375742012-06-08 00:04:009605 }
[email protected]f598f422012-12-07 08:30:039606 if (data == NULL) {
9607 (*error) = error::kOutOfBounds;
9608 return false;
9609 }
9610 return true;
9611}
[email protected]81375742012-06-08 00:04:009612
[email protected]f598f422012-12-07 08:30:039613error::Error GLES2DecoderImpl::DoTexSubImage2D(
9614 GLenum target,
9615 GLint level,
9616 GLint xoffset,
9617 GLint yoffset,
9618 GLsizei width,
9619 GLsizei height,
9620 GLenum format,
9621 GLenum type,
9622 const void * data) {
9623 error::Error error = error::kNoError;
9624 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
9625 xoffset, yoffset, width, height, format, type, data)) {
9626 return error;
9627 }
[email protected]c986af502013-08-14 01:04:449628 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9629 &state_, target);
[email protected]370eaf12013-05-18 09:19:499630 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:159631 GLsizei tex_width = 0;
9632 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:079633 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:159634 DCHECK(ok);
9635 if (xoffset != 0 || yoffset != 0 ||
9636 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:499637 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
9638 target, level)) {
[email protected]ab09b612013-03-11 22:11:519639 LOCAL_SET_GL_ERROR(
9640 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:039641 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:309642 }
[email protected]c986af502013-08-14 01:04:449643 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159644 glTexSubImage2D(
9645 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:039646 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:209647 }
[email protected]4502e6492011-12-14 19:39:159648
[email protected]345ba902013-11-14 21:39:009649 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
boliu45dc77a2015-02-25 23:26:319650 !texture->IsImmutable() &&
9651 !texture->HasImages()) {
[email protected]c986af502013-08-14 01:04:449652 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:259653 GLenum internal_format;
9654 GLenum tex_type;
9655 texture->GetLevelType(target, level, &tex_type, &internal_format);
9656 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9657 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:389658 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:259659 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:159660 } else {
[email protected]c986af502013-08-14 01:04:449661 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159662 glTexSubImage2D(
9663 target, level, xoffset, yoffset, width, height, format, type, data);
9664 }
[email protected]370eaf12013-05-18 09:19:499665 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:009666
9667 // This may be a slow command. Exit command processing to allow for
9668 // context preemption and GPU watchdog checks.
9669 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039670 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:439671}
9672
vmiuracd108592014-09-08 14:36:349673error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
9674 const void* cmd_data) {
9675 const gles2::cmds::TexSubImage2D& c =
9676 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139677 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
9678 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:009679 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:449680 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:009681 return error::kNoError;
9682
9683 GLenum target = static_cast<GLenum>(c.target);
9684 GLint level = static_cast<GLint>(c.level);
9685 GLint xoffset = static_cast<GLint>(c.xoffset);
9686 GLint yoffset = static_cast<GLint>(c.yoffset);
9687 GLsizei width = static_cast<GLsizei>(c.width);
9688 GLsizei height = static_cast<GLsizei>(c.height);
9689 GLenum format = static_cast<GLenum>(c.format);
9690 GLenum type = static_cast<GLenum>(c.type);
9691 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349692 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429693 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]e259eb412012-10-13 05:47:249694 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009695 return error::kOutOfBounds;
9696 }
9697 const void* pixels = GetSharedMemoryAs<const void*>(
9698 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039699 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009700 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009701}
9702
zmobcadd6592015-01-08 20:13:429703// TODO(zmo): Remove the below stub once we add the real function binding.
9704// Currently it's missing due to a gmock limitation.
9705static void glTexSubImage3D(
9706 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
9707 GLsizei height, GLsizei width, GLsizei depth, GLenum format, GLenum type,
9708 const void* pixels) {
9709 NOTIMPLEMENTED();
9710}
9711
9712error::Error GLES2DecoderImpl::HandleTexSubImage3D(uint32 immediate_data_size,
9713 const void* cmd_data) {
9714 // TODO(zmo): Unsafe ES3 API.
9715 if (!unsafe_es3_apis_enabled())
9716 return error::kUnknownCommand;
9717
9718 const gles2::cmds::TexSubImage3D& c =
9719 *static_cast<const gles2::cmds::TexSubImage3D*>(cmd_data);
9720 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D",
9721 "widthXheight", c.width * c.height, "depth", c.depth);
9722 GLenum target = static_cast<GLenum>(c.target);
9723 GLint level = static_cast<GLint>(c.level);
9724 GLint xoffset = static_cast<GLint>(c.xoffset);
9725 GLint yoffset = static_cast<GLint>(c.yoffset);
9726 GLint zoffset = static_cast<GLint>(c.zoffset);
9727 GLsizei width = static_cast<GLsizei>(c.width);
9728 GLsizei height = static_cast<GLsizei>(c.height);
9729 GLsizei depth = static_cast<GLsizei>(c.depth);
9730 GLenum format = static_cast<GLenum>(c.format);
9731 GLenum type = static_cast<GLenum>(c.type);
9732 uint32 data_size;
9733 if (!GLES2Util::ComputeImageDataSizes(
9734 width, height, depth, format, type, state_.unpack_alignment, &data_size,
9735 NULL, NULL)) {
9736 return error::kOutOfBounds;
9737 }
9738 const void* pixels = GetSharedMemoryAs<const void*>(
9739 c.pixels_shm_id, c.pixels_shm_offset, data_size);
9740 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
9741 depth, format, type, pixels);
9742 return error::kNoError;
9743}
9744
[email protected]f7a64ee2010-02-01 22:24:149745error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349746 uint32 immediate_data_size,
9747 const void* cmd_data) {
9748 const gles2::cmds::GetVertexAttribPointerv& c =
9749 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369750 GLuint index = static_cast<GLuint>(c.index);
9751 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359752 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259753 Result* result = GetSharedMemoryAs<Result*>(
9754 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369755 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149756 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369757 }
[email protected]07d0cc82010-02-17 04:51:409758 // Check that the client initialized the result.
9759 if (result->size != 0) {
9760 return error::kInvalidArguments;
9761 }
[email protected]9438b012010-06-15 22:55:059762 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519763 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9764 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149765 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369766 }
[email protected]3916c97e2010-02-25 03:20:509767 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519768 LOCAL_SET_GL_ERROR(
9769 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149770 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369771 }
[email protected]0bfd9882010-02-05 23:02:259772 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089773 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359774 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149775 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329776}
9777
vmiura181c74002015-03-20 01:32:519778bool GLES2DecoderImpl::GetUniformSetup(GLuint program_id,
9779 GLint fake_location,
9780 uint32 shm_id,
9781 uint32 shm_offset,
9782 error::Error* error,
9783 GLint* real_location,
9784 GLuint* service_id,
9785 void** result_pointer,
9786 GLenum* result_type,
9787 GLsizei* result_size) {
[email protected]939e7362010-05-13 20:49:109788 DCHECK(error);
9789 DCHECK(service_id);
9790 DCHECK(result_pointer);
9791 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129792 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379793 *error = error::kNoError;
9794 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259795 SizedResult<GLint>* result;
9796 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9797 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9798 if (!result) {
[email protected]f7b85372010-02-03 01:11:379799 *error = error::kOutOfBounds;
9800 return false;
9801 }
[email protected]0bfd9882010-02-05 23:02:259802 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379803 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259804 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429805 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9806 if (!program) {
[email protected]ae51d192010-04-27 00:48:039807 return false;
9808 }
[email protected]df37b9932013-03-08 05:21:429809 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379810 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519811 LOCAL_SET_GL_ERROR(
9812 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379813 return false;
9814 }
[email protected]df37b9932013-03-08 05:21:429815 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369816 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359817 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429818 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129819 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369820 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379821 // No such location.
[email protected]ab09b612013-03-11 22:11:519822 LOCAL_SET_GL_ERROR(
9823 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379824 return false;
9825 }
[email protected]43c2f1f2011-03-25 18:35:369826 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509827 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379828 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519829 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379830 return false;
9831 }
[email protected]0bfd9882010-02-05 23:02:259832 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9833 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9834 if (!result) {
[email protected]f7b85372010-02-03 01:11:379835 *error = error::kOutOfBounds;
9836 return false;
9837 }
[email protected]0bfd9882010-02-05 23:02:259838 result->size = size;
vmiura181c74002015-03-20 01:32:519839 *result_size = size;
[email protected]939e7362010-05-13 20:49:109840 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379841 return true;
9842}
9843
vmiuracd108592014-09-08 14:36:349844error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9845 const void* cmd_data) {
9846 const gles2::cmds::GetUniformiv& c =
9847 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379848 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339849 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379850 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109851 GLenum result_type;
vmiura181c74002015-03-20 01:32:519852 GLsizei result_size;
[email protected]1b0a6752012-02-22 03:44:129853 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379854 Error error;
[email protected]0bfd9882010-02-05 23:02:259855 void* result;
vmiura181c74002015-03-20 01:32:519856 if (GetUniformSetup(program, fake_location, c.params_shm_id,
9857 c.params_shm_offset, &error, &real_location, &service_id,
9858 &result, &result_type, &result_size)) {
[email protected]0bfd9882010-02-05 23:02:259859 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129860 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359861 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379862 }
9863 return error;
[email protected]96449d2c2009-11-25 00:01:329864}
9865
vmiuracd108592014-09-08 14:36:349866error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9867 const void* cmd_data) {
9868 const gles2::cmds::GetUniformfv& c =
9869 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379870 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339871 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379872 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129873 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379874 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359875 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109876 Result* result;
9877 GLenum result_type;
vmiura181c74002015-03-20 01:32:519878 GLsizei result_size;
9879 if (GetUniformSetup(program, fake_location, c.params_shm_id,
9880 c.params_shm_offset, &error, &real_location, &service_id,
9881 reinterpret_cast<void**>(&result), &result_type,
9882 &result_size)) {
[email protected]939e7362010-05-13 20:49:109883 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9884 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
vmiura181c74002015-03-20 01:32:519885 GLsizei num_values = result_size / sizeof(Result::Type);
[email protected]40d90a22013-04-09 03:39:559886 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129887 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109888 GLfloat* dst = result->GetData();
9889 for (GLsizei ii = 0; ii < num_values; ++ii) {
9890 dst[ii] = (temp[ii] != 0);
9891 }
9892 } else {
[email protected]1b0a6752012-02-22 03:44:129893 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109894 }
[email protected]f7b85372010-02-03 01:11:379895 }
9896 return error;
[email protected]96449d2c2009-11-25 00:01:329897}
9898
[email protected]f7a64ee2010-02-01 22:24:149899error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349900 uint32 immediate_data_size,
9901 const void* cmd_data) {
9902 const gles2::cmds::GetShaderPrecisionFormat& c =
9903 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259904 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9905 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359906 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259907 Result* result = GetSharedMemoryAs<Result*>(
9908 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9909 if (!result) {
9910 return error::kOutOfBounds;
9911 }
[email protected]07d0cc82010-02-17 04:51:409912 // Check that the client initialized the result.
9913 if (result->success != 0) {
9914 return error::kInvalidArguments;
9915 }
[email protected]9438b012010-06-15 22:55:059916 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519917 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539918 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299919 return error::kNoError;
9920 }
[email protected]9438b012010-06-15 22:55:059921 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519922 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539923 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299924 return error::kNoError;
9925 }
9926
9927 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409928
[email protected]46c86752013-05-21 05:08:399929 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409930 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219931 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409932
9933 result->min_range = range[0];
9934 result->max_range = range[1];
9935 result->precision = precision;
9936
[email protected]f7a64ee2010-02-01 22:24:149937 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329938}
9939
[email protected]f7a64ee2010-02-01 22:24:149940error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349941 uint32 immediate_data_size,
9942 const void* cmd_data) {
9943 const gles2::cmds::GetAttachedShaders& c =
9944 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259945 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429946 GLuint program_id = static_cast<GLuint>(c.program);
9947 Program* program = GetProgramInfoNotShader(
9948 program_id, "glGetAttachedShaders");
9949 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259950 return error::kNoError;
9951 }
[email protected]ed9f9cd2013-02-27 21:12:359952 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259953 uint32 max_count = Result::ComputeMaxResults(result_size);
9954 Result* result = GetSharedMemoryAs<Result*>(
9955 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9956 if (!result) {
9957 return error::kOutOfBounds;
9958 }
[email protected]07d0cc82010-02-17 04:51:409959 // Check that the client initialized the result.
9960 if (result->size != 0) {
9961 return error::kInvalidArguments;
9962 }
[email protected]0bfd9882010-02-05 23:02:259963 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039964 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429965 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259966 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039967 if (!shader_manager()->GetClientId(result->GetData()[ii],
9968 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259969 NOTREACHED();
9970 return error::kGenericError;
9971 }
9972 }
9973 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149974 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329975}
9976
[email protected]f7a64ee2010-02-01 22:24:149977error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349978 uint32 immediate_data_size,
9979 const void* cmd_data) {
9980 const gles2::cmds::GetActiveUniform& c =
9981 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429982 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259983 GLuint index = c.index;
9984 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359985 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259986 Result* result = GetSharedMemoryAs<Result*>(
9987 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9988 if (!result) {
9989 return error::kOutOfBounds;
9990 }
[email protected]07d0cc82010-02-17 04:51:409991 // Check that the client initialized the result.
9992 if (result->success != 0) {
9993 return error::kInvalidArguments;
9994 }
[email protected]df37b9932013-03-08 05:21:429995 Program* program = GetProgramInfoNotShader(
9996 program_id, "glGetActiveUniform");
9997 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259998 return error::kNoError;
9999 }
[email protected]ed9f9cd2013-02-27 21:12:3510000 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:4210001 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:2510002 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:5110003 LOCAL_SET_GL_ERROR(
10004 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:2510005 return error::kNoError;
10006 }
10007 result->success = 1; // true.
10008 result->size = uniform_info->size;
10009 result->type = uniform_info->type;
10010 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:2910011 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:1410012 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:3210013}
10014
zmoa2b555d2015-02-06 23:50:3910015error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockiv(
10016 uint32 immediate_data_size, const void* cmd_data) {
10017 if (!unsafe_es3_apis_enabled())
10018 return error::kUnknownCommand;
10019 const gles2::cmds::GetActiveUniformBlockiv& c =
10020 *static_cast<const gles2::cmds::GetActiveUniformBlockiv*>(cmd_data);
10021 GLuint program_id = c.program;
10022 GLuint index = static_cast<GLuint>(c.index);
10023 GLenum pname = static_cast<GLenum>(c.pname);
10024 Program* program = GetProgramInfoNotShader(
zmo8fab00c2015-02-07 02:45:0510025 program_id, "glGetActiveUniformBlockiv");
zmoa2b555d2015-02-06 23:50:3910026 if (!program) {
10027 return error::kNoError;
10028 }
10029 GLuint service_id = program->service_id();
10030 GLint link_status = GL_FALSE;
10031 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10032 if (link_status != GL_TRUE) {
10033 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10034 "glGetActiveActiveUniformBlockiv", "program not linked");
10035 return error::kNoError;
10036 }
10037 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformBlockiv");
10038 GLsizei num_values = 1;
10039 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
10040 GLint num = 0;
10041 glGetActiveUniformBlockiv(
10042 service_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num);
10043 GLenum error = glGetError();
10044 if (error != GL_NO_ERROR) {
10045 // Assume this will the same error if calling with pname.
10046 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
10047 return error::kNoError;
10048 }
10049 num_values = static_cast<GLsizei>(num);
10050 }
10051 typedef cmds::GetActiveUniformBlockiv::Result Result;
10052 Result* result = GetSharedMemoryAs<Result*>(
10053 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
10054 GLint* params = result ? result->GetData() : NULL;
10055 if (params == NULL) {
10056 return error::kOutOfBounds;
10057 }
10058 // Check that the client initialized the result.
10059 if (result->size != 0) {
10060 return error::kInvalidArguments;
10061 }
10062 glGetActiveUniformBlockiv(service_id, index, pname, params);
10063 GLenum error = glGetError();
10064 if (error == GL_NO_ERROR) {
10065 result->SetNumResults(num_values);
10066 } else {
10067 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
10068 }
10069 return error::kNoError;
10070}
10071
zmo4a16ff992015-02-05 22:18:4110072error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockName(
10073 uint32 immediate_data_size, const void* cmd_data) {
10074 if (!unsafe_es3_apis_enabled())
10075 return error::kUnknownCommand;
10076 const gles2::cmds::GetActiveUniformBlockName& c =
10077 *static_cast<const gles2::cmds::GetActiveUniformBlockName*>(cmd_data);
10078 GLuint program_id = c.program;
10079 GLuint index = c.index;
10080 uint32 name_bucket_id = c.name_bucket_id;
10081 typedef cmds::GetActiveUniformBlockName::Result Result;
10082 Result* result = GetSharedMemoryAs<Result*>(
10083 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10084 if (!result) {
10085 return error::kOutOfBounds;
10086 }
10087 // Check that the client initialized the result.
10088 if (*result != 0) {
10089 return error::kInvalidArguments;
10090 }
10091 Program* program = GetProgramInfoNotShader(
10092 program_id, "glGetActiveUniformBlockName");
10093 if (!program) {
10094 return error::kNoError;
10095 }
10096 GLuint service_id = program->service_id();
10097 GLint link_status = GL_FALSE;
10098 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10099 if (link_status != GL_TRUE) {
10100 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10101 "glGetActiveActiveUniformBlockName", "program not linked");
10102 return error::kNoError;
10103 }
10104 GLint max_length = 0;
10105 glGetProgramiv(
10106 service_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_length);
10107 // Increase one so &buffer[0] is always valid.
10108 GLsizei buf_size = static_cast<GLsizei>(max_length) + 1;
10109 std::vector<char> buffer(buf_size);
10110 GLsizei length = 0;
10111 glGetActiveUniformBlockName(
10112 service_id, index, buf_size, &length, &buffer[0]);
10113 if (length == 0) {
10114 *result = 0;
10115 return error::kNoError;
10116 }
10117 *result = 1;
10118 Bucket* bucket = CreateBucket(name_bucket_id);
10119 DCHECK_GT(buf_size, length);
10120 DCHECK_EQ(0, buffer[length]);
10121 bucket->SetFromString(&buffer[0]);
10122 return error::kNoError;
10123}
10124
zmoc7e7e13f2015-02-17 22:07:0710125error::Error GLES2DecoderImpl::HandleGetActiveUniformsiv(
10126 uint32 immediate_data_size, const void* cmd_data) {
10127 if (!unsafe_es3_apis_enabled())
10128 return error::kUnknownCommand;
10129 const gles2::cmds::GetActiveUniformsiv& c =
10130 *static_cast<const gles2::cmds::GetActiveUniformsiv*>(cmd_data);
10131 GLuint program_id = c.program;
10132 GLenum pname = static_cast<GLenum>(c.pname);
10133 Bucket* bucket = GetBucket(c.indices_bucket_id);
10134 if (!bucket) {
10135 return error::kInvalidArguments;
10136 }
10137 GLsizei count = static_cast<GLsizei>(bucket->size() / sizeof(GLuint));
10138 const GLuint* indices = bucket->GetDataAs<const GLuint*>(0, bucket->size());
10139 typedef cmds::GetActiveUniformsiv::Result Result;
10140 Result* result = GetSharedMemoryAs<Result*>(
10141 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(count));
10142 GLint* params = result ? result->GetData() : NULL;
10143 if (params == NULL) {
10144 return error::kOutOfBounds;
10145 }
10146 // Check that the client initialized the result.
10147 if (result->size != 0) {
10148 return error::kInvalidArguments;
10149 }
10150 Program* program = GetProgramInfoNotShader(
10151 program_id, "glGetActiveUniformsiv");
10152 if (!program) {
10153 return error::kNoError;
10154 }
10155 GLuint service_id = program->service_id();
10156 GLint link_status = GL_FALSE;
10157 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10158 if (link_status != GL_TRUE) {
10159 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10160 "glGetActiveUniformsiv", "program not linked");
10161 return error::kNoError;
10162 }
10163 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformsiv");
10164 glGetActiveUniformsiv(service_id, count, indices, pname, params);
10165 GLenum error = glGetError();
10166 if (error == GL_NO_ERROR) {
10167 result->SetNumResults(count);
10168 } else {
10169 LOCAL_SET_GL_ERROR(error, "GetActiveUniformsiv", "");
10170 }
10171 return error::kNoError;
10172}
10173
vmiuracd108592014-09-08 14:36:3410174error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
10175 const void* cmd_data) {
10176 const gles2::cmds::GetActiveAttrib& c =
10177 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4210178 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:2510179 GLuint index = c.index;
10180 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:3510181 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:2510182 Result* result = GetSharedMemoryAs<Result*>(
10183 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10184 if (!result) {
10185 return error::kOutOfBounds;
10186 }
[email protected]07d0cc82010-02-17 04:51:4010187 // Check that the client initialized the result.
10188 if (result->success != 0) {
10189 return error::kInvalidArguments;
10190 }
[email protected]df37b9932013-03-08 05:21:4210191 Program* program = GetProgramInfoNotShader(
10192 program_id, "glGetActiveAttrib");
10193 if (!program) {
[email protected]0bfd9882010-02-05 23:02:2510194 return error::kNoError;
10195 }
[email protected]ed9f9cd2013-02-27 21:12:3510196 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:4210197 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:2510198 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:5110199 LOCAL_SET_GL_ERROR(
10200 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:2510201 return error::kNoError;
10202 }
10203 result->success = 1; // true.
10204 result->size = attrib_info->size;
10205 result->type = attrib_info->type;
10206 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:2910207 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:1410208 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:3210209}
10210
vmiuracd108592014-09-08 14:36:3410211error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
10212 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:5810213#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:5110214 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:5810215 return error::kNoError;
10216#else
10217 GLsizei n = static_cast<GLsizei>(c.n);
10218 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:5110219 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:5810220 return error::kNoError;
10221 }
10222 GLsizei length = static_cast<GLsizei>(c.length);
10223 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:5110224 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:5810225 return error::kNoError;
10226 }
10227 uint32 data_size;
10228 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
10229 return error::kOutOfBounds;
10230 }
10231 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
10232 c.shaders_shm_id, c.shaders_shm_offset, data_size);
10233 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
10234 const void* binary = GetSharedMemoryAs<const void*>(
10235 c.binary_shm_id, c.binary_shm_offset, length);
10236 if (shaders == NULL || binary == NULL) {
10237 return error::kOutOfBounds;
10238 }
[email protected]0782b14b2014-05-24 13:04:1610239 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:5810240 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:4210241 Shader* shader = GetShader(shaders[ii]);
10242 if (!shader) {
[email protected]ab09b612013-03-11 22:11:5110243 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:5810244 return error::kNoError;
10245 }
[email protected]df37b9932013-03-08 05:21:4210246 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:5810247 }
10248 // TODO(gman): call glShaderBinary
10249 return error::kNoError;
10250#endif
10251}
10252
[email protected]6d792ee12013-05-15 00:40:5610253void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:4910254 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:0810255
[email protected]64ace852011-05-19 21:49:4910256 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:4210257 // TRACE_EVENT for gpu tests:
10258 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:4210259 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:4210260 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
10261 "width", (is_offscreen ? offscreen_size_.width() :
10262 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:5610263 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:4910264 "offscreen", is_offscreen,
10265 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:1510266 {
[email protected]a36ed4832014-04-24 16:40:2710267 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:1510268 }
10269
dyenb547eff62015-01-17 00:14:5610270 ScopedGPUTrace scoped_gpu_trace(gpu_tracer_.get(), kTraceDecoder,
10271 "gpu_toplevel", "SwapBuffer");
10272
[email protected]8f9b8dd2013-09-12 18:05:1310273 bool is_tracing;
10274 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
10275 &is_tracing);
10276 if (is_tracing) {
10277 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
10278 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
10279 is_offscreen ? offscreen_size_ : surface_->GetSize());
10280 }
10281
[email protected]6217d392010-03-25 22:08:3510282 // If offscreen then don't actually SwapBuffers to the display. Just copy
10283 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:4910284 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:3110285 TRACE_EVENT2("gpu", "Offscreen",
10286 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:5310287 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
10288 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
10289 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
10290 // fix this.
[email protected]62e155e2012-10-23 22:43:1510291 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:5310292 offscreen_saved_frame_buffer_->Create();
10293 glFinish();
10294 }
10295
10296 // Allocate the offscreen saved color texture.
10297 DCHECK(offscreen_saved_color_format_);
10298 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:0910299 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:5310300
10301 offscreen_saved_frame_buffer_->AttachRenderTexture(
10302 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:0510303 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
10304 if (offscreen_saved_frame_buffer_->CheckStatus() !=
10305 GL_FRAMEBUFFER_COMPLETE) {
10306 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
10307 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:5610308 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
10309 return;
[email protected]f0cfe752013-01-14 01:09:0510310 }
[email protected]1fb8c482011-08-31 01:01:5310311
[email protected]f0cfe752013-01-14 01:09:0510312 // Clear the offscreen color texture.
10313 // TODO(piman): Is this still necessary?
10314 {
10315 ScopedFrameBufferBinder binder(this,
10316 offscreen_saved_frame_buffer_->id());
10317 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:4510318 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
10319 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:0510320 glClear(GL_COLOR_BUFFER_BIT);
10321 RestoreClearState();
10322 }
[email protected]1fb8c482011-08-31 01:01:5310323 }
10324
10325 UpdateParentTextureInfo();
10326 }
10327
[email protected]f0cfe752013-01-14 01:09:0510328 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:5610329 return;
[email protected]ab09b612013-03-11 22:11:5110330 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010331 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:3510332
[email protected]34ff8b0c2010-10-01 20:06:0210333 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:1310334 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:2710335 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:4810336 } else {
[email protected]069944672012-04-25 20:52:2310337 ScopedFrameBufferBinder binder(this,
10338 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:1310339
[email protected]069944672012-04-25 20:52:2310340 if (offscreen_target_buffer_preserved_) {
10341 // Copy the target frame buffer to the saved offscreen texture.
10342 offscreen_saved_color_texture_->Copy(
10343 offscreen_saved_color_texture_->size(),
10344 offscreen_saved_color_format_);
10345 } else {
10346 // Flip the textures in the parent context via the texture manager.
10347 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:4910348 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:2310349 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:5610350
[email protected]069944672012-04-25 20:52:2310351 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
10352 offscreen_target_frame_buffer_->AttachRenderTexture(
10353 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:4810354 }
[email protected]069944672012-04-25 20:52:2310355
10356 // Ensure the side effects of the copy are visible to the parent
10357 // context. There is no need to do this for ANGLE because it uses a
10358 // single D3D device for all contexts.
marcheu1856f5d52015-04-04 01:42:5310359 if (!feature_info_->gl_version_info().is_angle)
[email protected]069944672012-04-25 20:52:2310360 glFlush();
[email protected]0c8c9d22010-06-25 17:36:3910361 }
[email protected]6217d392010-03-25 22:08:3510362 } else {
[email protected]f62a5ab2011-05-23 20:34:1510363 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:0110364 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:5610365 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:0110366 }
[email protected]6217d392010-03-25 22:08:3510367 }
vmiura8266ca72014-09-09 21:37:0010368
10369 // This may be a slow command. Exit command processing to allow for
10370 // context preemption and GPU watchdog checks.
10371 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:3510372}
10373
dcastagna504d45c2015-04-06 19:30:3910374void GLES2DecoderImpl::DoSwapInterval(int interval) {
bajones2345c1f2014-12-09 04:45:5110375 context_->SetSwapInterval(interval);
10376}
10377
[email protected]d4239852011-08-12 04:51:2210378error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:3410379 uint32 immediate_data_size,
10380 const void* cmd_data) {
10381 const gles2::cmds::EnableFeatureCHROMIUM& c =
10382 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:1810383 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810384 if (!bucket || bucket->size() == 0) {
10385 return error::kInvalidArguments;
10386 }
[email protected]ed9f9cd2013-02-27 21:12:3510387 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:1810388 Result* result = GetSharedMemoryAs<Result*>(
10389 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10390 if (!result) {
10391 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:1010392 }
[email protected]b1d2dcb2010-05-17 19:24:1810393 // Check that the client initialized the result.
10394 if (*result != 0) {
10395 return error::kInvalidArguments;
10396 }
10397 std::string feature_str;
10398 if (!bucket->GetAsString(&feature_str)) {
10399 return error::kInvalidArguments;
10400 }
10401
10402 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:2210403 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:1810404 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:2210405 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
penghuang0140c182015-01-12 23:20:1210406 buffer_manager()->set_allow_fixed_attribs(true);
[email protected]8fbedc02010-11-18 18:43:4010407 // TODO(gman): decide how to remove the need for this const_cast.
10408 // I could make validators_ non const but that seems bad as this is the only
10409 // place it is needed. I could make some special friend class of validators
10410 // just to allow this to set them. That seems silly. I could refactor this
10411 // code to use the extension mechanism or the initialization attributes to
10412 // turn this feature on. Given that the only real point of this is to make
10413 // the conformance tests pass and given that there is lots of real work that
10414 // needs to be done it seems like refactoring for one to one of those
10415 // methods is a very low priority.
10416 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:0410417 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
10418 force_webgl_glsl_validation_ = true;
10419 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:1810420 } else {
10421 return error::kNoError;
10422 }
10423
10424 *result = 1; // true.
10425 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:1010426}
10427
[email protected]c2f8c8402010-12-06 18:07:2410428error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
10429 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:3410430 const void* cmd_data) {
10431 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
10432 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
10433 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410434 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:3510435 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:1910436 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:2410437 bucket->SetFromString(info->extensions().c_str());
10438 return error::kNoError;
10439}
10440
10441error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:3410442 uint32 immediate_data_size,
10443 const void* cmd_data) {
10444 const gles2::cmds::RequestExtensionCHROMIUM& c =
10445 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410446 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810447 if (!bucket || bucket->size() == 0) {
10448 return error::kInvalidArguments;
10449 }
[email protected]c2f8c8402010-12-06 18:07:2410450 std::string feature_str;
10451 if (!bucket->GetAsString(&feature_str)) {
10452 return error::kInvalidArguments;
10453 }
10454
[email protected]4b7eba92013-01-08 02:23:5610455 bool desire_webgl_glsl_validation =
10456 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
10457 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:4910458 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:1310459 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:0610460 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:5610461 if (force_webgl_glsl_validation_) {
10462 desire_standard_derivatives =
10463 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:4910464 desire_frag_depth =
10465 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:1310466 desire_draw_buffers =
10467 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:0610468 desire_shader_texture_lod =
10469 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:0410470 }
10471
[email protected]4b7eba92013-01-08 02:23:5610472 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:4910473 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:1310474 desire_frag_depth != frag_depth_explicitly_enabled_ ||
10475 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:4910476 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
10477 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
10478 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:1310479 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:0610480 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:2410481 InitializeShaderTranslator();
10482 }
10483
[email protected]302ce6d2011-07-07 23:28:1110484 UpdateCapabilities();
10485
[email protected]c2f8c8402010-12-06 18:07:2410486 return error::kNoError;
10487}
10488
[email protected]2318d342011-07-11 22:27:4210489error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:3410490 uint32 immediate_data_size,
10491 const void* cmd_data) {
10492 const gles2::cmds::GetProgramInfoCHROMIUM& c =
10493 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4210494 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:4210495 uint32 bucket_id = c.bucket_id;
10496 Bucket* bucket = CreateBucket(bucket_id);
10497 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:4210498 Program* program = NULL;
10499 program = GetProgram(program_id);
10500 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:4610501 return error::kNoError;
[email protected]2318d342011-07-11 22:27:4210502 }
[email protected]df37b9932013-03-08 05:21:4210503 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:4210504 return error::kNoError;
10505}
10506
zmo4a16ff992015-02-05 22:18:4110507error::Error GLES2DecoderImpl::HandleGetUniformBlocksCHROMIUM(
10508 uint32 immediate_data_size, const void* cmd_data) {
10509 if (!unsafe_es3_apis_enabled())
10510 return error::kUnknownCommand;
10511 const gles2::cmds::GetUniformBlocksCHROMIUM& c =
10512 *static_cast<const gles2::cmds::GetUniformBlocksCHROMIUM*>(cmd_data);
10513 GLuint program_id = static_cast<GLuint>(c.program);
10514 uint32 bucket_id = c.bucket_id;
10515 Bucket* bucket = CreateBucket(bucket_id);
10516 bucket->SetSize(sizeof(UniformBlocksHeader)); // in case we fail.
10517 Program* program = NULL;
10518 program = GetProgram(program_id);
10519 if (!program || !program->IsValid()) {
10520 return error::kNoError;
10521 }
10522 program->GetUniformBlocks(bucket);
10523 return error::kNoError;
10524}
10525
zmoc7e7e13f2015-02-17 22:07:0710526error::Error GLES2DecoderImpl::HandleGetUniformsES3CHROMIUM(
10527 uint32 immediate_data_size, const void* cmd_data) {
10528 if (!unsafe_es3_apis_enabled())
10529 return error::kUnknownCommand;
10530 const gles2::cmds::GetUniformsES3CHROMIUM& c =
10531 *static_cast<const gles2::cmds::GetUniformsES3CHROMIUM*>(cmd_data);
10532 GLuint program_id = static_cast<GLuint>(c.program);
10533 uint32 bucket_id = c.bucket_id;
10534 Bucket* bucket = CreateBucket(bucket_id);
10535 bucket->SetSize(sizeof(UniformsES3Header)); // in case we fail.
10536 Program* program = NULL;
10537 program = GetProgram(program_id);
10538 if (!program || !program->IsValid()) {
10539 return error::kNoError;
10540 }
10541 program->GetUniformsES3(bucket);
10542 return error::kNoError;
10543}
10544
zmo10842492015-02-12 00:44:1610545error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVarying(
10546 uint32 immediate_data_size,
10547 const void* cmd_data) {
10548 if (!unsafe_es3_apis_enabled())
10549 return error::kUnknownCommand;
10550 const gles2::cmds::GetTransformFeedbackVarying& c =
10551 *static_cast<const gles2::cmds::GetTransformFeedbackVarying*>(cmd_data);
10552 GLuint program_id = c.program;
10553 GLuint index = c.index;
10554 uint32 name_bucket_id = c.name_bucket_id;
10555 typedef cmds::GetTransformFeedbackVarying::Result Result;
10556 Result* result = GetSharedMemoryAs<Result*>(
10557 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10558 if (!result) {
10559 return error::kOutOfBounds;
10560 }
10561 // Check that the client initialized the result.
10562 if (result->success != 0) {
10563 return error::kInvalidArguments;
10564 }
10565 Program* program = GetProgramInfoNotShader(
10566 program_id, "glGetTransformFeedbackVarying");
10567 if (!program) {
10568 return error::kNoError;
10569 }
10570 GLuint service_id = program->service_id();
10571 GLint link_status = GL_FALSE;
10572 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10573 if (link_status != GL_TRUE) {
10574 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10575 "glGetTransformFeedbackVarying", "program not linked");
10576 return error::kNoError;
10577 }
10578 GLint max_length = 0;
10579 glGetProgramiv(
10580 service_id, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_length);
10581 max_length = std::max(1, max_length);
10582 std::vector<char> buffer(max_length);
10583 GLsizei length = 0;
10584 GLsizei size = 0;
10585 GLenum type = 0;
10586 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTransformFeedbackVarying");
10587 glGetTransformFeedbackVarying(
10588 service_id, index, max_length, &length, &size, &type, &buffer[0]);
10589 GLenum error = glGetError();
10590 if (error != GL_NO_ERROR) {
10591 LOCAL_SET_GL_ERROR(error, "glGetTransformFeedbackVarying", "");
10592 return error::kNoError;
10593 }
10594 result->success = 1; // true.
10595 result->size = static_cast<int32_t>(size);
10596 result->type = static_cast<uint32_t>(type);
10597 Bucket* bucket = CreateBucket(name_bucket_id);
10598 DCHECK(length >= 0 && length < max_length);
10599 buffer[length] = '\0'; // Just to be safe.
10600 bucket->SetFromString(&buffer[0]);
10601 return error::kNoError;
10602}
10603
10604error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVaryingsCHROMIUM(
10605 uint32 immediate_data_size, const void* cmd_data) {
10606 if (!unsafe_es3_apis_enabled())
10607 return error::kUnknownCommand;
10608 const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM& c =
10609 *static_cast<const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM*>(
10610 cmd_data);
10611 GLuint program_id = static_cast<GLuint>(c.program);
10612 uint32 bucket_id = c.bucket_id;
10613 Bucket* bucket = CreateBucket(bucket_id);
10614 bucket->SetSize(sizeof(TransformFeedbackVaryingsHeader)); // in case we fail.
10615 Program* program = NULL;
10616 program = GetProgram(program_id);
10617 if (!program || !program->IsValid()) {
10618 return error::kNoError;
10619 }
10620 program->GetTransformFeedbackVaryings(bucket);
10621 return error::kNoError;
10622}
10623
[email protected]38d139d2011-07-14 00:38:4310624error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
10625 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:4310626 case GL_NO_ERROR:
10627 // TODO(kbr): improve the precision of the error code in this case.
10628 // Consider delegating to context for error code if MakeCurrent fails.
10629 return error::kUnknown;
10630 case GL_GUILTY_CONTEXT_RESET_ARB:
10631 return error::kGuilty;
10632 case GL_INNOCENT_CONTEXT_RESET_ARB:
10633 return error::kInnocent;
10634 case GL_UNKNOWN_CONTEXT_RESET_ARB:
10635 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:4310636 }
10637
10638 NOTREACHED();
10639 return error::kUnknown;
10640}
10641
jbauman7a059312014-10-16 19:30:5410642void GLES2DecoderImpl::MaybeExitOnContextLost() {
10643 // Some D3D drivers cannot recover from device lost in the GPU process
10644 // sandbox. Allow a new GPU process to launch.
10645 if (workarounds().exit_on_context_lost) {
10646 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
10647 << " a D3D device in the Chrome GPU process sandbox.";
10648#if defined(OS_WIN)
10649 base::win::SetShouldCrashOnProcessDetach(false);
10650#endif
10651 exit(0);
10652 }
10653}
10654
[email protected]38d139d2011-07-14 00:38:4310655bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:0910656 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:5410657 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:0910658 return true;
10659 }
dongseong.hwange1cb2aa2015-02-11 09:33:3310660 if (IsRobustnessSupported()) {
10661 GLenum status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:4310662 if (status != GL_NO_ERROR) {
10663 // The graphics card was reset. Signal a lost context to the application.
10664 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:2210665 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:4310666 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:0910667 << " context lost via ARB/EXT_robustness. Reset status = "
10668 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:5410669 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:4310670 return true;
10671 }
10672 }
10673 return false;
10674}
10675
[email protected]93a7d98f2013-07-11 00:04:2210676bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
10677 return WasContextLost() && reset_by_robustness_extension_;
10678}
10679
[email protected]c4485aad62012-12-17 10:19:0910680void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
10681 // Only loses the context once.
10682 if (reset_status_ != GL_NO_ERROR) {
10683 return;
10684 }
10685
oetuaho37cc50e2014-10-31 11:19:2010686 if (workarounds().use_virtualized_gl_contexts) {
10687 // If the context is virtual, the real context being guilty does not ensure
10688 // that the virtual context is guilty.
10689 if (reset_status == GL_GUILTY_CONTEXT_RESET_ARB) {
10690 reset_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
10691 }
10692 } else if (reset_status == GL_UNKNOWN_CONTEXT_RESET_ARB &&
dongseong.hwange1cb2aa2015-02-11 09:33:3310693 IsRobustnessSupported()) {
oetuaho37cc50e2014-10-31 11:19:2010694 // If the reason for the call was a GL error, we can try to determine the
10695 // reset status more accurately.
10696 GLenum driver_status = glGetGraphicsResetStatusARB();
10697 if (driver_status == GL_GUILTY_CONTEXT_RESET_ARB ||
10698 driver_status == GL_INNOCENT_CONTEXT_RESET_ARB) {
10699 reset_status = driver_status;
10700 }
10701 }
10702
[email protected]c4485aad62012-12-17 10:19:0910703 // Marks this context as lost.
10704 reset_status_ = reset_status;
10705 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:0910706}
10707
[email protected]b096d032013-03-08 03:08:0110708error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410709 uint32 immediate_data_size,
10710 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:0110711 return error::kUnknownCommand;
10712}
10713
[email protected]840a7e462013-02-27 01:29:5110714error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410715 uint32 immediate_data_size,
10716 const void* cmd_data) {
10717 const gles2::cmds::WaitSyncPointCHROMIUM& c =
10718 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:3210719 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:5110720 if (wait_sync_point_callback_.is_null())
10721 return error::kNoError;
10722
sievers173a20d2014-10-22 18:19:3210723 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:5110724 error::kNoError : error::kDeferCommandUntilLater;
10725}
10726
[email protected]5dfc457b2013-12-13 11:13:0710727error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:3410728 uint32 immediate_data_size,
10729 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:0710730 if (surface_->DeferDraws())
10731 return error::kDeferCommandUntilLater;
10732 if (!surface_->SetBackbufferAllocation(false))
10733 return error::kLostContext;
10734 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
10735 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
10736 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
10737 return error::kNoError;
10738}
10739
[email protected]882ba1e22012-03-08 19:02:5310740bool GLES2DecoderImpl::GenQueriesEXTHelper(
10741 GLsizei n, const GLuint* client_ids) {
10742 for (GLsizei ii = 0; ii < n; ++ii) {
10743 if (query_manager_->GetQuery(client_ids[ii])) {
10744 return false;
10745 }
10746 }
[email protected]4eea7e62014-04-22 21:14:4310747 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:5310748 return true;
10749}
10750
10751void GLES2DecoderImpl::DeleteQueriesEXTHelper(
10752 GLsizei n, const GLuint* client_ids) {
10753 for (GLsizei ii = 0; ii < n; ++ii) {
10754 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
10755 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:1310756 ContextState::QueryMap::iterator it =
10757 state_.current_queries.find(query->target());
10758 if (it != state_.current_queries.end())
10759 state_.current_queries.erase(it);
10760
[email protected]c45f1972012-03-14 07:27:3610761 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:5310762 }
[email protected]4eea7e62014-04-22 21:14:4310763 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:5310764 }
10765}
10766
revemancc241eb2014-11-11 03:30:3710767bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
[email protected]22e3f552012-03-13 01:54:1910768 if (query_manager_.get() == NULL) {
10769 return false;
10770 }
revemancc241eb2014-11-11 03:30:3710771 if (!query_manager_->ProcessPendingQueries(did_finish)) {
[email protected]22e3f552012-03-13 01:54:1910772 current_decoder_error_ = error::kOutOfBounds;
10773 }
10774 return query_manager_->HavePendingQueries();
10775}
10776
[email protected]5a36dc132013-07-23 23:17:5510777// Note that if there are no pending readpixels right now,
10778// this function will call the callback immediately.
10779void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
10780 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
10781 pending_readpixel_fences_.back()->callbacks.push_back(callback);
10782 } else {
10783 callback.Run();
10784 }
10785}
10786
10787void GLES2DecoderImpl::ProcessPendingReadPixels() {
10788 while (!pending_readpixel_fences_.empty() &&
10789 pending_readpixel_fences_.front()->fence->HasCompleted()) {
10790 std::vector<base::Closure> callbacks =
10791 pending_readpixel_fences_.front()->callbacks;
10792 pending_readpixel_fences_.pop();
10793 for (size_t i = 0; i < callbacks.size(); i++) {
10794 callbacks[i].Run();
10795 }
10796 }
10797}
10798
[email protected]2b1767cf2013-03-16 09:25:0510799bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510800 return !pending_readpixel_fences_.empty() ||
10801 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510802}
10803
10804void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510805 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:4810806 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:0510807 return;
[email protected]b68b100752013-06-05 08:34:4810808 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510809 ProcessFinishedAsyncTransfers();
10810}
10811
vmiuracd108592014-09-08 14:36:3410812error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
10813 const void* cmd_data) {
10814 const gles2::cmds::BeginQueryEXT& c =
10815 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310816 GLenum target = static_cast<GLenum>(c.target);
10817 GLuint client_id = static_cast<GLuint>(c.id);
10818 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
10819 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10820
[email protected]c45f1972012-03-14 07:27:3610821 switch (target) {
10822 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:5510823 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:3110824 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
10825 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:0010826 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:3610827 break;
[email protected]6a25ae422014-04-17 23:48:2710828 case GL_COMMANDS_COMPLETED_CHROMIUM:
10829 if (!features().chromium_sync_query) {
10830 LOCAL_SET_GL_ERROR(
10831 GL_INVALID_OPERATION, "glBeginQueryEXT",
10832 "not enabled for commands completed queries");
10833 return error::kNoError;
10834 }
10835 break;
[email protected]c45f1972012-03-14 07:27:3610836 default:
[email protected]62e155e2012-10-23 22:43:1510837 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:5110838 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:0010839 GL_INVALID_OPERATION, "glBeginQueryEXT",
10840 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:3610841 return error::kNoError;
10842 }
10843 break;
[email protected]882ba1e22012-03-08 19:02:5310844 }
10845
[email protected]8ebd46c2014-01-08 12:06:1310846 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110847 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310848 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:5310849 return error::kNoError;
10850 }
10851
10852 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:5110853 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:5310854 return error::kNoError;
10855 }
10856
10857 QueryManager::Query* query = query_manager_->GetQuery(client_id);
10858 if (!query) {
[email protected]4eea7e62014-04-22 21:14:4310859 if (!query_manager_->IsValidQuery(client_id)) {
10860 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10861 "glBeginQueryEXT",
10862 "id not made by glGenQueriesEXT");
10863 return error::kNoError;
10864 }
[email protected]c45f1972012-03-14 07:27:3610865 query = query_manager_->CreateQuery(
10866 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:5310867 }
10868
[email protected]c45f1972012-03-14 07:27:3610869 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110870 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310871 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:5310872 return error::kNoError;
10873 } else if (query->shm_id() != sync_shm_id ||
10874 query->shm_offset() != sync_shm_offset) {
10875 DLOG(ERROR) << "Shared memory used by query not the same as before";
10876 return error::kInvalidArguments;
10877 }
10878
[email protected]c45f1972012-03-14 07:27:3610879 if (!query_manager_->BeginQuery(query)) {
10880 return error::kOutOfBounds;
10881 }
[email protected]882ba1e22012-03-08 19:02:5310882
[email protected]8ebd46c2014-01-08 12:06:1310883 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:5310884 return error::kNoError;
10885}
10886
vmiuracd108592014-09-08 14:36:3410887error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
10888 const void* cmd_data) {
10889 const gles2::cmds::EndQueryEXT& c =
10890 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310891 GLenum target = static_cast<GLenum>(c.target);
10892 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:1310893 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:5310894
[email protected]8ebd46c2014-01-08 12:06:1310895 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110896 LOCAL_SET_GL_ERROR(
10897 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:5310898 return error::kNoError;
10899 }
[email protected]882ba1e22012-03-08 19:02:5310900
[email protected]8ebd46c2014-01-08 12:06:1310901 QueryManager::Query* query = it->second.get();
10902 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:3610903 return error::kOutOfBounds;
10904 }
10905
[email protected]fe8d73c2013-02-16 22:37:3210906 query_manager_->ProcessPendingTransferQueries();
10907
[email protected]8ebd46c2014-01-08 12:06:1310908 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:5310909 return error::kNoError;
10910}
10911
[email protected]944b62f32012-09-27 02:20:4610912bool GLES2DecoderImpl::GenVertexArraysOESHelper(
10913 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610914 for (GLsizei ii = 0; ii < n; ++ii) {
10915 if (GetVertexAttribManager(client_ids[ii])) {
10916 return false;
10917 }
10918 }
[email protected]ab4fd7282012-10-12 16:25:5710919
[email protected]62e155e2012-10-23 22:43:1510920 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710921 // Emulated VAO
10922 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810923 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5710924 }
10925 } else {
[email protected]40d90a22013-04-09 03:39:5510926 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5710927
10928 glGenVertexArraysOES(n, service_ids.get());
10929 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810930 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5710931 }
[email protected]944b62f32012-09-27 02:20:4610932 }
[email protected]ab4fd7282012-10-12 16:25:5710933
[email protected]944b62f32012-09-27 02:20:4610934 return true;
10935}
10936
10937void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
10938 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610939 for (GLsizei ii = 0; ii < n; ++ii) {
10940 VertexAttribManager* vao =
10941 GetVertexAttribManager(client_ids[ii]);
10942 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1110943 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1110944 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4610945 }
10946 RemoveVertexAttribManager(client_ids[ii]);
10947 }
10948 }
10949}
10950
10951void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610952 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4610953 if (client_id != 0) {
10954 vao = GetVertexAttribManager(client_id);
10955 if (!vao) {
10956 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10957 // only allows names that have been previously generated. As such, we do
10958 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110959 LOCAL_SET_GL_ERROR(
10960 GL_INVALID_OPERATION,
10961 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610962 current_decoder_error_ = error::kNoError;
10963 return;
[email protected]944b62f32012-09-27 02:20:4610964 }
[email protected]944b62f32012-09-27 02:20:4610965 } else {
[email protected]81f20a622014-04-18 01:54:5210966 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610967 }
10968
[email protected]ab4fd7282012-10-12 16:25:5710969 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110970 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410971 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510972 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710973 EmulateVertexArrayState();
10974 } else {
[email protected]da364812014-05-09 21:39:4810975 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710976 glBindVertexArrayOES(service_id);
10977 }
10978 }
10979}
10980
10981// Used when OES_vertex_array_object isn't natively supported
10982void GLES2DecoderImpl::EmulateVertexArrayState() {
10983 // Setup the Vertex attribute state
10984 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310985 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710986 }
10987
10988 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110989 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410990 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710991 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10992 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610993}
10994
10995bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610996 const VertexAttribManager* vao =
10997 GetVertexAttribManager(client_id);
10998 return vao && vao->IsValid() && !vao->IsDeleted();
10999}
11000
[email protected]e51bdf32011-11-23 22:21:4611001#if defined(OS_MACOSX)
11002void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
11003 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
11004 texture_id);
11005 if (it != texture_to_io_surface_map_.end()) {
11006 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5311007 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4611008 CFRelease(surface);
11009 texture_to_io_surface_map_.erase(it);
11010 }
11011}
11012#endif
11013
11014void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
11015 GLenum target, GLsizei width, GLsizei height,
11016 GLuint io_surface_id, GLuint plane) {
11017#if defined(OS_MACOSX)
11018 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5111019 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311020 GL_INVALID_OPERATION,
11021 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4611022 return;
11023 }
11024
[email protected]e51bdf32011-11-23 22:21:4611025 if (target != GL_TEXTURE_RECTANGLE_ARB) {
11026 // This might be supported in the future, and if we could require
11027 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
11028 // could delete a lot of code. For now, perform strict validation so we
11029 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5111030 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4611031 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4311032 "glTexImageIOSurface2DCHROMIUM",
11033 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4611034 return;
11035 }
11036
[email protected]09d50362012-10-18 20:54:3711037 // Default target might be conceptually valid, but disallow it to avoid
11038 // accidents.
[email protected]c986af502013-08-14 01:04:4411039 TextureRef* texture_ref =
11040 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911041 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111042 LOCAL_SET_GL_ERROR(
11043 GL_INVALID_OPERATION,
11044 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4611045 return;
11046 }
[email protected]e51bdf32011-11-23 22:21:4611047
11048 // Look up the new IOSurface. Note that because of asynchrony
11049 // between processes this might fail; during live resizing the
11050 // plugin process might allocate and release an IOSurface before
11051 // this process gets a chance to look it up. Hold on to any old
11052 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5311053 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4611054 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5111055 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311056 GL_INVALID_OPERATION,
11057 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4611058 return;
11059 }
11060
11061 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4911062 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4611063
11064 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
11065 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4911066 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4611067
11068 CGLContextObj context =
11069 static_cast<CGLContextObj>(context_->GetHandle());
11070
[email protected]c3a6b4a2014-06-04 09:25:5311071 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4611072 context,
11073 target,
11074 GL_RGBA,
11075 width,
11076 height,
11077 GL_BGRA,
11078 GL_UNSIGNED_INT_8_8_8_8_REV,
11079 surface,
11080 plane);
11081
11082 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5111083 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4611084 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4311085 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4611086 return;
11087 }
11088
11089 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911090 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4611091 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
11092
11093#else
[email protected]ab09b612013-03-11 22:11:5111094 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4311095 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4611096#endif
11097}
11098
[email protected]97dc7cbe2011-12-06 17:26:1711099static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
11100 switch (internalformat) {
11101 case GL_RGB565:
11102 return GL_RGB;
11103 case GL_RGBA4:
11104 return GL_RGBA;
11105 case GL_RGB5_A1:
11106 return GL_RGBA;
11107 case GL_RGB8_OES:
11108 return GL_RGB;
11109 case GL_RGBA8_OES:
11110 return GL_RGBA;
11111 case GL_LUMINANCE8_ALPHA8_EXT:
11112 return GL_LUMINANCE_ALPHA;
11113 case GL_LUMINANCE8_EXT:
11114 return GL_LUMINANCE;
11115 case GL_ALPHA8_EXT:
11116 return GL_ALPHA;
11117 case GL_RGBA32F_EXT:
11118 return GL_RGBA;
11119 case GL_RGB32F_EXT:
11120 return GL_RGB;
11121 case GL_ALPHA32F_EXT:
11122 return GL_ALPHA;
11123 case GL_LUMINANCE32F_EXT:
11124 return GL_LUMINANCE;
11125 case GL_LUMINANCE_ALPHA32F_EXT:
11126 return GL_LUMINANCE_ALPHA;
11127 case GL_RGBA16F_EXT:
11128 return GL_RGBA;
11129 case GL_RGB16F_EXT:
11130 return GL_RGB;
11131 case GL_ALPHA16F_EXT:
11132 return GL_ALPHA;
11133 case GL_LUMINANCE16F_EXT:
11134 return GL_LUMINANCE;
11135 case GL_LUMINANCE_ALPHA16F_EXT:
11136 return GL_LUMINANCE_ALPHA;
11137 case GL_BGRA8_EXT:
11138 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5911139 case GL_SRGB8_ALPHA8_EXT:
11140 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1711141 default:
11142 return GL_NONE;
11143 }
11144}
11145
dongseong.hwang46305b12015-03-05 18:28:0411146bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUM(
11147 const char* function_name,
11148 GLenum target,
11149 TextureRef* source_texture_ref,
11150 TextureRef* dest_texture_ref,
11151 GLenum dest_internal_format) {
[email protected]370eaf12013-05-18 09:19:4911152 if (!source_texture_ref || !dest_texture_ref) {
dongseong.hwang46305b12015-03-05 18:28:0411153 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown texture id");
11154 return false;
[email protected]43410e92012-04-20 17:06:2811155 }
11156
11157 if (GL_TEXTURE_2D != target) {
dongseong.hwang46305b12015-03-05 18:28:0411158 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
11159 "invalid texture target");
11160 return false;
[email protected]43410e92012-04-20 17:06:2811161 }
11162
[email protected]370eaf12013-05-18 09:19:4911163 Texture* source_texture = source_texture_ref->texture();
11164 Texture* dest_texture = dest_texture_ref->texture();
dongseong.hwang46305b12015-03-05 18:28:0411165 if (source_texture == dest_texture) {
11166 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11167 "source and destination textures are the same");
11168 return false;
11169 }
11170
[email protected]02965c22013-03-09 02:40:0711171 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2511172 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3411173 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
11174 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
dongseong.hwang46305b12015-03-05 18:28:0411175 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name,
[email protected]3ecc1052013-09-26 08:59:0011176 "invalid texture target binding");
dongseong.hwang46305b12015-03-05 18:28:0411177 return false;
[email protected]0a1e9ad2012-05-04 21:13:0311178 }
11179
dongseong.hwang46305b12015-03-05 18:28:0411180 GLenum source_type = 0;
11181 GLenum source_internal_format = 0;
11182 source_texture->GetLevelType(source_texture->target(), 0, &source_type,
11183 &source_internal_format);
[email protected]43410e92012-04-20 17:06:2811184
dongseong.hwang46305b12015-03-05 18:28:0411185 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
11186 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
11187 // renderable on some platforms.
11188 bool valid_dest_format = dest_internal_format == GL_RGB ||
11189 dest_internal_format == GL_RGBA ||
11190 dest_internal_format == GL_BGRA_EXT;
11191 bool valid_source_format = source_internal_format == GL_ALPHA ||
11192 source_internal_format == GL_RGB ||
11193 source_internal_format == GL_RGBA ||
11194 source_internal_format == GL_LUMINANCE ||
11195 source_internal_format == GL_LUMINANCE_ALPHA ||
11196 source_internal_format == GL_BGRA_EXT;
11197 if (!valid_source_format || !valid_dest_format) {
11198 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
11199 "invalid internal format");
11200 return false;
11201 }
11202 return true;
11203}
11204
11205void GLES2DecoderImpl::DoCopyTextureCHROMIUM(GLenum target,
11206 GLuint source_id,
11207 GLuint dest_id,
11208 GLenum internal_format,
11209 GLenum dest_type) {
11210 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
11211
11212 TextureRef* source_texture_ref = GetTexture(source_id);
11213 TextureRef* dest_texture_ref = GetTexture(dest_id);
11214 Texture* source_texture = source_texture_ref->texture();
11215 Texture* dest_texture = dest_texture_ref->texture();
11216 int source_width = 0;
11217 int source_height = 0;
[email protected]3e0dfd72014-02-21 06:28:4111218 gfx::GLImage* image =
11219 source_texture->GetLevelImage(source_texture->target(), 0);
11220 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5511221 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5611222 source_width = size.width();
11223 source_height = size.height();
11224 if (source_width <= 0 || source_height <= 0) {
11225 LOCAL_SET_GL_ERROR(
11226 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5511227 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5611228 return;
11229 }
[email protected]3ecc1052013-09-26 08:59:0011230 } else {
11231 if (!source_texture->GetLevelSize(
11232 source_texture->target(), 0, &source_width, &source_height)) {
11233 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
11234 "glCopyTextureChromium",
11235 "source texture has no level 0");
11236 return;
11237 }
11238
11239 // Check that this type of texture is allowed.
dongseong.hwang46305b12015-03-05 18:28:0411240 if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
11241 source_width, source_height, 1)) {
[email protected]3ecc1052013-09-26 08:59:0011242 LOCAL_SET_GL_ERROR(
11243 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
11244 return;
11245 }
[email protected]377976552013-05-14 23:32:5611246 }
11247
[email protected]a6e3d282014-08-22 22:20:4411248 GLenum source_type = 0;
11249 GLenum source_internal_format = 0;
11250 source_texture->GetLevelType(
11251 source_texture->target(), 0, &source_type, &source_internal_format);
11252
dongseong.hwang46305b12015-03-05 18:28:0411253 if (dest_texture->IsImmutable()) {
11254 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyTextureCHROMIUM",
11255 "texture is immutable");
11256 return;
11257 }
11258
11259 if (!ValidateCopyTextureCHROMIUM("glCopyTextureCHROMIUM", target,
11260 source_texture_ref, dest_texture_ref,
11261 internal_format)) {
11262 return;
11263 }
11264
11265 // Clear the source texture if necessary.
11266 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
11267 source_texture->target(), 0)) {
11268 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM",
11269 "dimensions too big");
[email protected]a6e3d282014-08-22 22:20:4411270 return;
11271 }
11272
[email protected]cf6b8f62012-05-25 21:43:3711273 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
11274 // needed because it takes 10s of milliseconds to initialize.
11275 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5111276 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3711277 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2711278 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3711279 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5111280 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3711281 return;
11282 }
11283
[email protected]efc87712014-07-09 00:22:4711284 GLenum dest_type_previous = dest_type;
11285 GLenum dest_internal_format = internal_format;
dongseong.hwang46305b12015-03-05 18:28:0411286 int dest_width = 0;
11287 int dest_height = 0;
11288 bool dest_level_defined =
11289 dest_texture->GetLevelSize(GL_TEXTURE_2D, 0, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2811290
[email protected]0a1e9ad2012-05-04 21:13:0311291 if (dest_level_defined) {
dongseong.hwang46305b12015-03-05 18:28:0411292 dest_texture->GetLevelType(GL_TEXTURE_2D, 0, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0711293 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0311294 }
11295
11296 // Resize the destination texture to the dimensions of the source texture.
11297 if (!dest_level_defined || dest_width != source_width ||
11298 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5411299 dest_internal_format != internal_format ||
11300 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2811301 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5111302 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0711303 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
dongseong.hwang46305b12015-03-05 18:28:0411304 glTexImage2D(GL_TEXTURE_2D, 0, internal_format, source_width, source_height,
11305 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5111306 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0311307 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0211308 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2811309 return;
[email protected]0a1e9ad2012-05-04 21:13:0311310 }
[email protected]43410e92012-04-20 17:06:2811311
11312 texture_manager()->SetLevelInfo(
dongseong.hwang46305b12015-03-05 18:28:0411313 dest_texture_ref, GL_TEXTURE_2D, 0, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0311314 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2511315 } else {
dongseong.hwang46305b12015-03-05 18:28:0411316 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
11317 true);
[email protected]43410e92012-04-20 17:06:2811318 }
11319
[email protected]00c2cf92014-03-14 00:08:3711320 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5411321
revemance8fbe82014-09-05 02:19:5211322 // Try using GLImage::CopyTexImage when possible.
11323 bool unpack_premultiply_alpha_change =
11324 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
dongseong.hwang46305b12015-03-05 18:28:0411325 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change) {
revemance8fbe82014-09-05 02:19:5211326 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
11327 if (image->CopyTexImage(GL_TEXTURE_2D))
11328 return;
11329 }
11330
11331 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
11332
[email protected]5394a4102013-04-18 05:41:3711333 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
11334 // before presenting.
11335 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
11336 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
dongseong.hwang46305b12015-03-05 18:28:0411337 // instead of using kIdentityMatrix crbug.com/226218.
[email protected]5394a4102013-04-18 05:41:3711338 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
dongseong.hwang46305b12015-03-05 18:28:0411339 this, source_texture->target(), source_texture->service_id(),
11340 dest_texture->service_id(), source_width, source_height, unpack_flip_y_,
11341 unpack_premultiply_alpha_, unpack_unpremultiply_alpha_,
11342 kIdentityMatrix);
[email protected]5394a4102013-04-18 05:41:3711343 } else {
dongseong.hwang46305b12015-03-05 18:28:0411344 copy_texture_CHROMIUM_->DoCopyTexture(
11345 this, source_texture->target(), source_texture->service_id(),
11346 source_internal_format, dest_texture->service_id(), internal_format,
11347 source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
11348 unpack_unpremultiply_alpha_);
11349 }
11350
11351 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
11352}
11353
11354void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(GLenum target,
11355 GLuint source_id,
11356 GLuint dest_id,
11357 GLint xoffset,
11358 GLint yoffset) {
11359 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM");
11360
11361 TextureRef* source_texture_ref = GetTexture(source_id);
11362 TextureRef* dest_texture_ref = GetTexture(dest_id);
11363 Texture* source_texture = source_texture_ref->texture();
11364 Texture* dest_texture = dest_texture_ref->texture();
11365 int source_width = 0;
11366 int source_height = 0;
11367 gfx::GLImage* image =
11368 source_texture->GetLevelImage(source_texture->target(), 0);
11369 if (image) {
11370 gfx::Size size = image->GetSize();
11371 source_width = size.width();
11372 source_height = size.height();
11373 if (source_width <= 0 || source_height <= 0) {
11374 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11375 "invalid image size");
11376 return;
11377 }
11378 } else {
11379 if (!source_texture->GetLevelSize(source_texture->target(), 0,
11380 &source_width, &source_height)) {
11381 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11382 "source texture has no level 0");
11383 return;
11384 }
11385
11386 // Check that this type of texture is allowed.
11387 if (!texture_manager()->ValidForTarget(source_texture->target(), 0,
11388 source_width, source_height, 1)) {
11389 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11390 "source texture bad dimensions");
11391 return;
11392 }
11393 }
11394
11395 GLenum source_type = 0;
11396 GLenum source_internal_format = 0;
11397 source_texture->GetLevelType(source_texture->target(), 0, &source_type,
11398 &source_internal_format);
11399 GLenum dest_type = 0;
11400 GLenum dest_internal_format = 0;
11401 bool dest_level_defined = dest_texture->GetLevelType(
11402 dest_texture->target(), 0, &dest_type, &dest_internal_format);
11403 if (!dest_level_defined) {
11404 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopySubTextureCHROMIUM",
11405 "destination texture is not defined");
11406 return;
11407 }
11408 if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset,
11409 yoffset, source_width, source_height,
11410 dest_type)) {
11411 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
11412 "destination texture bad dimensions.");
11413 return;
11414 }
11415
11416 if (!ValidateCopyTextureCHROMIUM("glCopySubTextureCHROMIUM", target,
11417 source_texture_ref, dest_texture_ref,
11418 dest_internal_format)) {
11419 return;
11420 }
11421
11422 // Clear the source texture if necessary.
11423 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
11424 source_texture->target(), 0)) {
11425 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
11426 "source texture dimensions too big");
11427 return;
11428 }
11429
11430 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
11431 // needed because it takes 10s of milliseconds to initialize.
11432 if (!copy_texture_CHROMIUM_.get()) {
11433 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopySubTextureCHROMIUM");
11434 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
11435 copy_texture_CHROMIUM_->Initialize(this);
11436 RestoreCurrentFramebufferBindings();
11437 if (LOCAL_PEEK_GL_ERROR("glCopySubTextureCHROMIUM") != GL_NO_ERROR)
11438 return;
11439 }
11440
11441 int dest_width = 0;
11442 int dest_height = 0;
11443 bool ok =
11444 dest_texture->GetLevelSize(GL_TEXTURE_2D, 0, &dest_width, &dest_height);
11445 DCHECK(ok);
11446 if (xoffset != 0 || yoffset != 0 || source_width != dest_width ||
11447 source_height != dest_height) {
11448 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target,
11449 0)) {
11450 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
11451 "destination texture dimensions too big");
11452 return;
11453 }
11454 } else {
11455 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0,
11456 true);
11457 }
11458
11459 ScopedModifyPixels modify(dest_texture_ref);
11460
11461 // Try using GLImage::CopyTexSubImage when possible.
11462 bool unpack_premultiply_alpha_change =
11463 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
11464 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change &&
11465 !xoffset && !yoffset) {
11466 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
11467 if (image->CopyTexImage(GL_TEXTURE_2D))
11468 return;
11469 }
11470
11471 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
11472
11473 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
11474 // before presenting.
11475 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
11476 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
11477 // instead of using kIdentityMatrix crbug.com/226218.
11478 copy_texture_CHROMIUM_->DoCopySubTextureWithTransform(
11479 this, source_texture->target(), source_texture->service_id(),
11480 dest_texture->service_id(), xoffset, yoffset, dest_width, dest_height,
11481 source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
11482 unpack_unpremultiply_alpha_, kIdentityMatrix);
11483 } else {
11484 copy_texture_CHROMIUM_->DoCopySubTexture(
11485 this, source_texture->target(), source_texture->service_id(),
11486 source_internal_format, dest_texture->service_id(),
11487 dest_internal_format, xoffset, yoffset, dest_width, dest_height,
11488 source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
11489 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3711490 }
[email protected]91c94eb2013-10-22 10:32:5411491
11492 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2811493}
11494
[email protected]97dc7cbe2011-12-06 17:26:1711495static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
11496 switch (internalformat) {
11497 case GL_RGB565:
11498 return GL_UNSIGNED_SHORT_5_6_5;
11499 case GL_RGBA4:
11500 return GL_UNSIGNED_SHORT_4_4_4_4;
11501 case GL_RGB5_A1:
11502 return GL_UNSIGNED_SHORT_5_5_5_1;
11503 case GL_RGB8_OES:
11504 return GL_UNSIGNED_BYTE;
11505 case GL_RGBA8_OES:
11506 return GL_UNSIGNED_BYTE;
11507 case GL_LUMINANCE8_ALPHA8_EXT:
11508 return GL_UNSIGNED_BYTE;
11509 case GL_LUMINANCE8_EXT:
11510 return GL_UNSIGNED_BYTE;
11511 case GL_ALPHA8_EXT:
11512 return GL_UNSIGNED_BYTE;
11513 case GL_RGBA32F_EXT:
11514 return GL_FLOAT;
11515 case GL_RGB32F_EXT:
11516 return GL_FLOAT;
11517 case GL_ALPHA32F_EXT:
11518 return GL_FLOAT;
11519 case GL_LUMINANCE32F_EXT:
11520 return GL_FLOAT;
11521 case GL_LUMINANCE_ALPHA32F_EXT:
11522 return GL_FLOAT;
11523 case GL_RGBA16F_EXT:
11524 return GL_HALF_FLOAT_OES;
11525 case GL_RGB16F_EXT:
11526 return GL_HALF_FLOAT_OES;
11527 case GL_ALPHA16F_EXT:
11528 return GL_HALF_FLOAT_OES;
11529 case GL_LUMINANCE16F_EXT:
11530 return GL_HALF_FLOAT_OES;
11531 case GL_LUMINANCE_ALPHA16F_EXT:
11532 return GL_HALF_FLOAT_OES;
11533 case GL_BGRA8_EXT:
11534 return GL_UNSIGNED_BYTE;
11535 default:
11536 return GL_NONE;
11537 }
11538}
11539
11540void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4411541 GLenum target,
11542 GLint levels,
11543 GLenum internal_format,
11544 GLsizei width,
11545 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1311546 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
11547 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4111548 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0011549 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5111550 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311551 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1711552 return;
11553 }
[email protected]c986af502013-08-14 01:04:4411554 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11555 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911556 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111557 LOCAL_SET_GL_ERROR(
11558 GL_INVALID_OPERATION,
11559 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1711560 return;
11561 }
[email protected]370eaf12013-05-18 09:19:4911562 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0711563 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4411564 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1711565 }
[email protected]02965c22013-03-09 02:40:0711566 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5111567 LOCAL_SET_GL_ERROR(
11568 GL_INVALID_OPERATION,
11569 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1711570 return;
11571 }
[email protected]7989c9e2013-01-23 06:39:2611572
11573 GLenum format = ExtractFormatFromStorageFormat(internal_format);
11574 GLenum type = ExtractTypeFromStorageFormat(internal_format);
11575
11576 {
11577 GLsizei level_width = width;
11578 GLsizei level_height = height;
11579 uint32 estimated_size = 0;
11580 for (int ii = 0; ii < levels; ++ii) {
11581 uint32 level_size = 0;
11582 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211583 level_width, level_height, 1, format, type, state_.unpack_alignment,
[email protected]7989c9e2013-01-23 06:39:2611584 &estimated_size, NULL, NULL) ||
11585 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111586 LOCAL_SET_GL_ERROR(
11587 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2611588 return;
11589 }
11590 level_width = std::max(1, level_width >> 1);
11591 level_height = std::max(1, level_height >> 1);
11592 }
11593 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111594 LOCAL_SET_GL_ERROR(
11595 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611596 return;
11597 }
11598 }
11599
[email protected]ab09b612013-03-11 22:11:5111600 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3811601 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5111602 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1711603 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1511604 GLsizei level_width = width;
11605 GLsizei level_height = height;
11606 for (int ii = 0; ii < levels; ++ii) {
11607 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911608 texture_ref, target, ii, format,
11609 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1511610 level_width = std::max(1, level_width >> 1);
11611 level_height = std::max(1, level_height >> 1);
11612 }
[email protected]02965c22013-03-09 02:40:0711613 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1711614 }
[email protected]97dc7cbe2011-12-06 17:26:1711615}
[email protected]e51bdf32011-11-23 22:21:4611616
[email protected]78b514b2012-05-01 21:50:5911617error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3411618 uint32 immediate_data_size,
11619 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3511620 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5911621}
11622
11623void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711624 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211625 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211626 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711627 "mailbox[0]", static_cast<unsigned char>(data[0]));
11628
[email protected]43f253da2014-06-10 17:51:2211629 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11630 &state_, target);
11631 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
11632}
11633
11634void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
11635 GLenum target, const GLbyte* data) {
11636 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
11637 "context", logger_.GetLogPrefix(),
11638 "mailbox[0]", static_cast<unsigned char>(data[0]));
11639
11640 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
11641 target, data);
11642}
11643
11644void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
11645 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3711646 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2211647 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3711648 "mailbox that was not generated by "
11649 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211650
[email protected]370eaf12013-05-18 09:19:4911651 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111652 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211653 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911654 return;
11655 }
11656
[email protected]62e65f02013-05-29 22:28:1011657 Texture* produced = texture_manager()->Produce(texture_ref);
11658 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5111659 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211660 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
11661 return;
11662 }
11663
11664 if (produced->target() != target) {
11665 LOCAL_SET_GL_ERROR(
11666 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5911667 return;
11668 }
11669
sievers8b373ec52014-10-24 23:04:0611670 group_->mailbox_manager()->ProduceTexture(mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5911671}
11672
11673void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711674 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211675 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211676 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711677 "mailbox[0]", static_cast<unsigned char>(data[0]));
11678 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11679 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
11680 "mailbox that was not generated by "
11681 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211682
[email protected]62e65f02013-05-29 22:28:1011683 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4411684 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1111685 if (!texture_ref.get()) {
11686 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11687 "glConsumeTextureCHROMIUM",
11688 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911689 return;
11690 }
[email protected]62e65f02013-05-29 22:28:1011691 GLuint client_id = texture_ref->client_id();
11692 if (!client_id) {
11693 LOCAL_SET_GL_ERROR(
11694 GL_INVALID_OPERATION,
11695 "glConsumeTextureCHROMIUM", "unknown texture for target");
11696 return;
11697 }
sievers8b373ec52014-10-24 23:04:0611698 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]62e65f02013-05-29 22:28:1011699 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5111700 LOCAL_SET_GL_ERROR(
11701 GL_INVALID_OPERATION,
11702 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5911703 return;
11704 }
[email protected]62e65f02013-05-29 22:28:1011705 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5111706 LOCAL_SET_GL_ERROR(
11707 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1011708 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5911709 return;
11710 }
[email protected]62e65f02013-05-29 22:28:1011711
11712 DeleteTexturesHelper(1, &client_id);
11713 texture_ref = texture_manager()->Consume(client_id, texture);
11714 glBindTexture(target, texture_ref->service_id());
11715
11716 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
11717 unit.bind_target = target;
11718 switch (target) {
11719 case GL_TEXTURE_2D:
11720 unit.bound_texture_2d = texture_ref;
11721 break;
11722 case GL_TEXTURE_CUBE_MAP:
11723 unit.bound_texture_cube_map = texture_ref;
11724 break;
11725 case GL_TEXTURE_EXTERNAL_OES:
11726 unit.bound_texture_external_oes = texture_ref;
11727 break;
11728 case GL_TEXTURE_RECTANGLE_ARB:
11729 unit.bound_texture_rectangle_arb = texture_ref;
11730 break;
11731 default:
11732 NOTREACHED(); // Validation should prevent us getting here.
11733 break;
11734 }
[email protected]78b514b2012-05-01 21:50:5911735}
11736
bajonesd8388be02015-04-04 00:15:4311737void GLES2DecoderImpl::EnsureTextureForClientId(
11738 GLenum target,
11739 GLuint client_id) {
11740 TextureRef* texture_ref = GetTexture(client_id);
11741 if (!texture_ref) {
11742 GLuint service_id;
11743 glGenTextures(1, &service_id);
11744 DCHECK_NE(0u, service_id);
11745 texture_ref = CreateTexture(client_id, service_id);
11746 texture_manager()->SetTarget(texture_ref, target);
11747 glBindTexture(target, service_id);
11748 RestoreCurrentTextureBindings(&state_, target);
11749 }
11750}
11751
11752// If CreateAndConsumeTexture fails we still need to ensure that the client_id
11753// provided is associated with a service_id/TextureRef for consistency, even if
11754// the resulting texture is incomplete.
[email protected]43f253da2014-06-10 17:51:2211755error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
11756 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3411757 const void* cmd_data) {
11758 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
11759 *static_cast<
11760 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
11761 cmd_data);
[email protected]43f253da2014-06-10 17:51:2211762 GLenum target = static_cast<GLenum>(c.target);
11763 uint32_t data_size;
11764 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
11765 return error::kOutOfBounds;
11766 }
11767 if (data_size > immediate_data_size) {
11768 return error::kOutOfBounds;
11769 }
11770 const GLbyte* mailbox =
11771 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
11772 if (!validators_->texture_bind_target.IsValid(target)) {
11773 LOCAL_SET_GL_ERROR_INVALID_ENUM(
11774 "glCreateAndConsumeTextureCHROMIUM", target, "target");
11775 return error::kNoError;
11776 }
11777 if (mailbox == NULL) {
11778 return error::kOutOfBounds;
11779 }
11780 uint32_t client_id = c.client_id;
11781 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
11782 return error::kNoError;
11783}
11784
11785void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
11786 const GLbyte* data, GLuint client_id) {
11787 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
11788 "context", logger_.GetLogPrefix(),
11789 "mailbox[0]", static_cast<unsigned char>(data[0]));
11790 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11791 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
11792 "passed a mailbox that was not "
11793 "generated by GenMailboxCHROMIUM.";
11794
11795 TextureRef* texture_ref = GetTexture(client_id);
11796 if (texture_ref) {
bajonesd8388be02015-04-04 00:15:4311797 // No need to call EnsureTextureForClientId here, the client_id already has
11798 // an associated texture.
[email protected]43f253da2014-06-10 17:51:2211799 LOCAL_SET_GL_ERROR(
11800 GL_INVALID_OPERATION,
11801 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
11802 return;
11803 }
sievers8b373ec52014-10-24 23:04:0611804 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]43f253da2014-06-10 17:51:2211805 if (!texture) {
bajonesd8388be02015-04-04 00:15:4311806 EnsureTextureForClientId(target, client_id);
[email protected]43f253da2014-06-10 17:51:2211807 LOCAL_SET_GL_ERROR(
11808 GL_INVALID_OPERATION,
11809 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
11810 return;
11811 }
bajonesd8388be02015-04-04 00:15:4311812
[email protected]43f253da2014-06-10 17:51:2211813 if (texture->target() != target) {
bajonesd8388be02015-04-04 00:15:4311814 EnsureTextureForClientId(target, client_id);
[email protected]43f253da2014-06-10 17:51:2211815 LOCAL_SET_GL_ERROR(
11816 GL_INVALID_OPERATION,
11817 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
11818 return;
11819 }
11820
[email protected]43f253da2014-06-10 17:51:2211821 texture_ref = texture_manager()->Consume(client_id, texture);
11822}
11823
orglofchcad5a6742014-11-07 19:51:1211824bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
11825 const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
11826 return valuebuffer && valuebuffer->IsValid();
11827}
11828
11829void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
11830 GLuint client_id) {
11831 Valuebuffer* valuebuffer = NULL;
11832 if (client_id != 0) {
11833 valuebuffer = GetValuebuffer(client_id);
11834 if (!valuebuffer) {
11835 if (!group_->bind_generates_resource()) {
11836 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
11837 "id not generated by glBindValuebufferCHROMIUM");
11838 return;
11839 }
11840
11841 // It's a new id so make a valuebuffer for it.
11842 CreateValuebuffer(client_id);
11843 valuebuffer = GetValuebuffer(client_id);
11844 }
11845 valuebuffer->MarkAsValid();
11846 }
11847 state_.bound_valuebuffer = valuebuffer;
11848}
11849
11850void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
11851 GLenum subscription) {
11852 if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
11853 return;
11854 }
11855 state_.bound_valuebuffer.get()->AddSubscription(subscription);
11856}
11857
11858void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
11859 if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
11860 return;
11861 }
11862 valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
11863}
11864
11865void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
11866 GLenum target,
11867 GLenum subscription) {
11868 if (!CheckCurrentValuebufferForSubscription(
11869 subscription, "glPopulateSubscribedValuesCHROMIUM")) {
11870 return;
11871 }
11872 if (!CheckSubscriptionTarget(location, subscription,
11873 "glPopulateSubscribedValuesCHROMIUM")) {
11874 return;
11875 }
11876 const ValueState* state =
11877 state_.bound_valuebuffer.get()->GetState(subscription);
11878 if (state) {
11879 switch (subscription) {
11880 case GL_MOUSE_POSITION_CHROMIUM:
11881 DoUniform2iv(location, 1, state->int_value);
11882 break;
11883 default:
11884 NOTREACHED() << "Unhandled uniform subscription target "
11885 << subscription;
11886 break;
11887 }
11888 }
11889}
11890
[email protected]d2a0e1a2012-08-12 02:25:0111891void GLES2DecoderImpl::DoInsertEventMarkerEXT(
11892 GLsizei length, const GLchar* marker) {
11893 if (!marker) {
11894 marker = "";
11895 }
11896 debug_marker_manager_.SetMarker(
11897 length ? std::string(marker, length) : std::string(marker));
11898}
11899
11900void GLES2DecoderImpl::DoPushGroupMarkerEXT(
11901 GLsizei length, const GLchar* marker) {
11902 if (!marker) {
11903 marker = "";
11904 }
[email protected]cac16542014-01-15 17:53:5111905 std::string name = length ? std::string(marker, length) : std::string(marker);
11906 debug_marker_manager_.PushGroup(name);
dyen4bb43282015-01-08 01:09:5611907 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_group_marker"), name,
11908 kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111909}
11910
11911void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
11912 debug_marker_manager_.PopGroup();
dyen4bb43282015-01-08 01:09:5611913 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111914}
11915
[email protected]09d50362012-10-18 20:54:3711916void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
11917 GLenum target, GLint image_id) {
11918 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711919
[email protected]bc26e8d2014-01-29 00:40:3011920 if (target == GL_TEXTURE_CUBE_MAP) {
11921 LOCAL_SET_GL_ERROR(
11922 GL_INVALID_ENUM,
11923 "glBindTexImage2DCHROMIUM", "invalid target");
11924 return;
11925 }
11926
[email protected]09d50362012-10-18 20:54:3711927 // Default target might be conceptually valid, but disallow it to avoid
11928 // accidents.
[email protected]c986af502013-08-14 01:04:4411929 TextureRef* texture_ref =
11930 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911931 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111932 LOCAL_SET_GL_ERROR(
11933 GL_INVALID_OPERATION,
11934 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711935 return;
11936 }
11937
11938 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11939 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111940 LOCAL_SET_GL_ERROR(
11941 GL_INVALID_OPERATION,
11942 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711943 return;
11944 }
11945
[email protected]b8160812013-04-09 00:41:0411946 {
11947 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011948 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611949 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0411950 LOCAL_SET_GL_ERROR(
11951 GL_INVALID_OPERATION,
11952 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
11953 return;
11954 }
[email protected]09d50362012-10-18 20:54:3711955 }
11956
11957 gfx::Size size = gl_image->GetSize();
11958 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911959 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3711960 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4911961 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3711962}
11963
11964void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
11965 GLenum target, GLint image_id) {
11966 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711967
11968 // Default target might be conceptually valid, but disallow it to avoid
11969 // accidents.
[email protected]c986af502013-08-14 01:04:4411970 TextureRef* texture_ref =
11971 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911972 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111973 LOCAL_SET_GL_ERROR(
11974 GL_INVALID_OPERATION,
11975 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711976 return;
11977 }
11978
11979 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11980 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111981 LOCAL_SET_GL_ERROR(
11982 GL_INVALID_OPERATION,
11983 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711984 return;
11985 }
11986
11987 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4911988 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3711989 return;
11990
[email protected]b8160812013-04-09 00:41:0411991 {
11992 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011993 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611994 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0411995 }
[email protected]09d50362012-10-18 20:54:3711996
11997 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911998 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3711999 GL_RGBA, GL_UNSIGNED_BYTE, false);
12000}
[email protected]d2a0e1a2012-08-12 02:25:0112001
[email protected]94307712012-11-16 23:26:1112002error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3412003 uint32 immediate_data_size,
12004 const void* cmd_data) {
12005 const gles2::cmds::TraceBeginCHROMIUM& c =
12006 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
dyencb86f2f2014-12-09 18:35:4112007 Bucket* category_bucket = GetBucket(c.category_bucket_id);
12008 Bucket* name_bucket = GetBucket(c.name_bucket_id);
12009 if (!category_bucket || category_bucket->size() == 0 ||
12010 !name_bucket || name_bucket->size() == 0) {
[email protected]94307712012-11-16 23:26:1112011 return error::kInvalidArguments;
12012 }
dyencb86f2f2014-12-09 18:35:4112013
12014 std::string category_name;
12015 std::string trace_name;
12016 if (!category_bucket->GetAsString(&category_name) ||
12017 !name_bucket->GetAsString(&trace_name)) {
[email protected]94307712012-11-16 23:26:1112018 return error::kInvalidArguments;
12019 }
dyencb86f2f2014-12-09 18:35:4112020
dyencb86f2f2014-12-09 18:35:4112021 if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5112022 LOCAL_SET_GL_ERROR(
12023 GL_INVALID_OPERATION,
12024 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1412025 return error::kNoError;
12026 }
[email protected]94307712012-11-16 23:26:1112027 return error::kNoError;
12028}
12029
12030void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
dyen4bb43282015-01-08 01:09:5612031 if (!gpu_tracer_->End(kTraceCHROMIUM)) {
12032 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
12033 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1112034 return;
12035 }
[email protected]94307712012-11-16 23:26:1112036}
12037
[email protected]2f143d482013-03-14 18:04:4912038void GLES2DecoderImpl::DoDrawBuffersEXT(
12039 GLsizei count, const GLenum* bufs) {
12040 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
12041 LOCAL_SET_GL_ERROR(
12042 GL_INVALID_VALUE,
12043 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
12044 return;
12045 }
12046
12047 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
12048 if (framebuffer) {
12049 for (GLsizei i = 0; i < count; ++i) {
12050 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
12051 bufs[i] != GL_NONE) {
12052 LOCAL_SET_GL_ERROR(
12053 GL_INVALID_OPERATION,
12054 "glDrawBuffersEXT",
12055 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
12056 return;
12057 }
12058 }
12059 glDrawBuffersARB(count, bufs);
12060 framebuffer->SetDrawBuffers(count, bufs);
12061 } else { // backbuffer
12062 if (count > 1 ||
12063 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
12064 LOCAL_SET_GL_ERROR(
12065 GL_INVALID_OPERATION,
12066 "glDrawBuffersEXT",
12067 "more than one buffer or bufs not GL_NONE or GL_BACK");
12068 return;
12069 }
12070 GLenum mapped_buf = bufs[0];
12071 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
12072 bufs[0] == GL_BACK) {
12073 mapped_buf = GL_COLOR_ATTACHMENT0;
12074 }
12075 glDrawBuffersARB(count, &mapped_buf);
12076 group_->set_draw_buffer(bufs[0]);
12077 }
12078}
12079
[email protected]a6a09f852014-05-23 13:05:0312080void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
12081 group_->LoseContexts(other);
12082 reset_status_ = current;
12083 current_decoder_error_ = error::kLostContext;
12084}
12085
kkinnunen337d59632014-08-26 10:19:5712086void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
12087 const GLfloat* matrix) {
12088 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
12089 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
12090 if (!features().chromium_path_rendering) {
12091 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
12092 "glMatrixLoadfCHROMIUM",
12093 "function not available");
12094 return;
12095 }
12096
12097 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
12098 ? state_.projection_matrix
12099 : state_.modelview_matrix;
12100 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
12101 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
12102 // since the values of the _NV and _CHROMIUM tokens match.
12103 glMatrixLoadfEXT(matrix_mode, matrix);
12104}
12105
12106void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
12107 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
12108 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
12109
12110 if (!features().chromium_path_rendering) {
12111 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
12112 "glMatrixLoadIdentityCHROMIUM",
12113 "function not available");
12114 return;
12115 }
12116
kkinnunen337d59632014-08-26 10:19:5712117 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
12118 ? state_.projection_matrix
12119 : state_.modelview_matrix;
12120 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
12121 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
12122 // since the values of the _NV and _CHROMIUM tokens match.
12123 glMatrixLoadIdentityEXT(matrix_mode);
12124}
12125
[email protected]32145a92012-12-17 09:01:5912126bool GLES2DecoderImpl::ValidateAsyncTransfer(
12127 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4712128 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5912129 GLenum target,
12130 GLint level,
12131 const void * data) {
12132 // We only support async uploads to 2D textures for now.
12133 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5112134 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5912135 return false;
12136 }
12137 // We only support uploads to level zero for now.
12138 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5112139 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5912140 return false;
12141 }
12142 // A transfer buffer must be bound, even for asyncTexImage2D.
12143 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5112144 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5912145 return false;
12146 }
12147 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4712148 if (!texture_ref ||
12149 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5112150 LOCAL_SET_GL_ERROR(
12151 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5912152 function_name, "transfer already in progress");
12153 return false;
12154 }
12155 return true;
12156}
12157
[email protected]e3c4a9ab2014-03-31 09:07:0212158base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
12159 uint32 async_upload_token,
12160 uint32 sync_data_shm_id,
12161 uint32 sync_data_shm_offset) {
12162 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2512163 if (!buffer.get() ||
12164 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0212165 return base::Closure();
12166
12167 AsyncMemoryParams mem_params(buffer,
12168 sync_data_shm_offset,
12169 sizeof(AsyncUploadSync));
12170
12171 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
12172 new AsyncUploadTokenCompletionObserver(async_upload_token));
12173
12174 return base::Bind(
12175 &AsyncPixelTransferManager::AsyncNotifyCompletion,
12176 base::Unretained(GetAsyncPixelTransferManager()),
12177 mem_params,
12178 observer);
12179}
12180
[email protected]69023942012-11-30 19:57:1612181error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412182 uint32 immediate_data_size,
12183 const void* cmd_data) {
12184 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
12185 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1612186 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1612187 GLenum target = static_cast<GLenum>(c.target);
12188 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4412189 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1612190 GLsizei width = static_cast<GLsizei>(c.width);
12191 GLsizei height = static_cast<GLsizei>(c.height);
12192 GLint border = static_cast<GLint>(c.border);
12193 GLenum format = static_cast<GLenum>(c.format);
12194 GLenum type = static_cast<GLenum>(c.type);
12195 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
12196 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
12197 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0212198 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
12199 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
12200 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
12201
12202 base::ScopedClosureRunner scoped_completion_callback;
12203 if (async_upload_token) {
12204 base::Closure completion_closure =
12205 AsyncUploadTokenCompletionClosure(async_upload_token,
12206 sync_data_shm_id,
12207 sync_data_shm_offset);
12208 if (completion_closure.is_null())
12209 return error::kInvalidArguments;
12210
12211 scoped_completion_callback.Reset(completion_closure);
12212 }
[email protected]32145a92012-12-17 09:01:5912213
12214 // TODO(epenner): Move this and copies of this memory validation
12215 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1612216 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4212217 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
12218 NULL, NULL)) {
[email protected]69023942012-11-30 19:57:1612219 return error::kOutOfBounds;
12220 }
12221 const void* pixels = NULL;
12222 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
12223 pixels = GetSharedMemoryAs<const void*>(
12224 pixels_shm_id, pixels_shm_offset, pixels_size);
12225 if (!pixels) {
12226 return error::kOutOfBounds;
12227 }
12228 }
12229
[email protected]c986af502013-08-14 01:04:4412230 TextureManager::DoTextImage2DArguments args = {
12231 target, level, internal_format, width, height, border, format, type,
12232 pixels, pixels_size};
12233 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5912234 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4412235 if (!texture_manager()->ValidateTexImage2D(
12236 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5912237 return error::kNoError;
12238 }
12239
12240 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4912241 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5912242 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4712243 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5912244 return error::kNoError;
12245
12246 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0712247 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5112248 LOCAL_SET_GL_ERROR(
12249 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5912250 "glAsyncTexImage2DCHROMIUM", "already defined");
12251 return error::kNoError;
12252 }
12253
[email protected]7989c9e2013-01-23 06:39:2612254 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5112255 LOCAL_SET_GL_ERROR(
12256 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2612257 return error::kNoError;
12258 }
12259
[email protected]5b3a8e02013-03-13 05:36:4412260 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3812261 AsyncTexImage2DParams tex_params = {
12262 target, level, static_cast<GLenum>(internal_format),
12263 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1212264 AsyncMemoryParams mem_params(
12265 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5912266
[email protected]5b3a8e02013-03-13 05:36:4412267 // Set up the async state if needed, and make the texture
12268 // immutable so the async state stays valid. The level info
12269 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1812270 AsyncPixelTransferDelegate* delegate =
12271 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
12272 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4412273 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5912274
[email protected]896425e2013-06-12 17:27:1812275 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4412276 tex_params,
12277 mem_params,
12278 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4912279 // The callback is only invoked if the transfer delegate still
12280 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4412281 // ownership that both of these pointers are valid.
12282 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4912283 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4412284 tex_params));
[email protected]f598f422012-12-07 08:30:0312285 return error::kNoError;
[email protected]69023942012-11-30 19:57:1612286}
12287
12288error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412289 uint32 immediate_data_size,
12290 const void* cmd_data) {
12291 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
12292 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1612293 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1612294 GLenum target = static_cast<GLenum>(c.target);
12295 GLint level = static_cast<GLint>(c.level);
12296 GLint xoffset = static_cast<GLint>(c.xoffset);
12297 GLint yoffset = static_cast<GLint>(c.yoffset);
12298 GLsizei width = static_cast<GLsizei>(c.width);
12299 GLsizei height = static_cast<GLsizei>(c.height);
12300 GLenum format = static_cast<GLenum>(c.format);
12301 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0212302 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
12303 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
12304 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
12305
12306 base::ScopedClosureRunner scoped_completion_callback;
12307 if (async_upload_token) {
12308 base::Closure completion_closure =
12309 AsyncUploadTokenCompletionClosure(async_upload_token,
12310 sync_data_shm_id,
12311 sync_data_shm_offset);
12312 if (completion_closure.is_null())
12313 return error::kInvalidArguments;
12314
12315 scoped_completion_callback.Reset(completion_closure);
12316 }
[email protected]32145a92012-12-17 09:01:5912317
12318 // TODO(epenner): Move this and copies of this memory validation
12319 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1612320 uint32 data_size;
12321 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4212322 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]69023942012-11-30 19:57:1612323 NULL, NULL)) {
12324 return error::kOutOfBounds;
12325 }
12326 const void* pixels = GetSharedMemoryAs<const void*>(
12327 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5912328
12329 // All the normal glTexSubImage2D validation.
12330 error::Error error = error::kNoError;
12331 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
12332 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
12333 return error;
[email protected]69023942012-11-30 19:57:1612334 }
12335
[email protected]32145a92012-12-17 09:01:5912336 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4412337 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
12338 &state_, target);
[email protected]370eaf12013-05-18 09:19:4912339 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5912340 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4712341 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5912342 return error::kNoError;
12343
12344 // Guarantee async textures are always 'cleared' as follows:
12345 // - AsyncTexImage2D can not redefine an existing texture
12346 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
12347 // - AsyncTexSubImage2D clears synchronously if not already cleared.
12348 // - Textures become immutable after an async call.
12349 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0712350 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4912351 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
12352 target, level)) {
[email protected]ab09b612013-03-11 22:11:5112353 LOCAL_SET_GL_ERROR(
12354 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2512355 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5912356 return error::kNoError;
12357 }
12358 }
12359
[email protected]5b3a8e02013-03-13 05:36:4412360 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0312361 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5912362 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1212363 AsyncMemoryParams mem_params(
12364 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1812365 AsyncPixelTransferDelegate* delegate =
12366 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
12367 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4412368 // TODO(epenner): We may want to enforce exclusive use
12369 // of async APIs in which case this should become an error,
12370 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0312371 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4412372 0, 0, 0, 0, 0, 0};
12373 texture->GetLevelSize(target, level, &define_params.width,
12374 &define_params.height);
12375 texture->GetLevelType(target, level, &define_params.type,
12376 &define_params.internal_format);
12377 // Set up the async state if needed, and make the texture
12378 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1812379 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4712380 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4412381 texture->SetImmutable(true);
12382 }
12383
[email protected]896425e2013-06-12 17:27:1812384 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5912385 return error::kNoError;
[email protected]69023942012-11-30 19:57:1612386}
12387
[email protected]a00c1f742013-03-05 17:02:1612388error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412389 uint32 immediate_data_size,
12390 const void* cmd_data) {
12391 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
12392 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1612393 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
12394 GLenum target = static_cast<GLenum>(c.target);
12395
12396 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5112397 LOCAL_SET_GL_ERROR(
12398 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1612399 return error::kNoError;
12400 }
[email protected]c986af502013-08-14 01:04:4412401 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
12402 &state_, target);
[email protected]370eaf12013-05-18 09:19:4912403 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5112404 LOCAL_SET_GL_ERROR(
12405 GL_INVALID_OPERATION,
12406 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1612407 return error::kNoError;
12408 }
[email protected]896425e2013-06-12 17:27:1812409 AsyncPixelTransferDelegate* delegate =
12410 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
12411 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4912412 LOCAL_SET_GL_ERROR(
12413 GL_INVALID_OPERATION,
12414 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
12415 return error::kNoError;
12416 }
[email protected]896425e2013-06-12 17:27:1812417 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0912418 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1612419 return error::kNoError;
12420}
12421
[email protected]e3c4a9ab2014-03-31 09:07:0212422error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3412423 uint32 immediate_data_size,
12424 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0212425 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
12426
12427 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
12428 ProcessFinishedAsyncTransfers();
12429 return error::kNoError;
12430}
12431
zmo8fab00c2015-02-07 02:45:0512432error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
12433 uint32_t immediate_data_size, const void* cmd_data) {
12434 if (!unsafe_es3_apis_enabled())
12435 return error::kUnknownCommand;
12436 const gles2::cmds::UniformBlockBinding& c =
12437 *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data);
12438 GLuint client_id = c.program;
12439 GLuint index = static_cast<GLuint>(c.index);
12440 GLuint binding = static_cast<GLuint>(c.binding);
12441 Program* program = GetProgramInfoNotShader(
12442 client_id, "glUniformBlockBinding");
12443 if (!program) {
12444 return error::kNoError;
12445 }
12446 GLuint service_id = program->service_id();
12447 glUniformBlockBinding(service_id, index, binding);
12448 return error::kNoError;
12449}
12450
zmo3366957e2015-02-18 23:40:0712451error::Error GLES2DecoderImpl::HandleClientWaitSync(
12452 uint32_t immediate_data_size, const void* cmd_data) {
12453 if (!unsafe_es3_apis_enabled())
12454 return error::kUnknownCommand;
12455 const gles2::cmds::ClientWaitSync& c =
12456 *static_cast<const gles2::cmds::ClientWaitSync*>(cmd_data);
12457 GLuint sync = static_cast<GLuint>(c.sync);
12458 GLbitfield flags = static_cast<GLbitfield>(c.flags);
12459 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1);
12460 typedef cmds::ClientWaitSync::Result Result;
12461 Result* result_dst = GetSharedMemoryAs<Result*>(
12462 c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
12463 if (!result_dst) {
12464 return error::kOutOfBounds;
12465 }
12466 if (*result_dst != GL_WAIT_FAILED) {
12467 return error::kInvalidArguments;
12468 }
12469 GLsync service_sync = 0;
12470 if (!group_->GetSyncServiceId(sync, &service_sync)) {
12471 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "ClientWaitSync", "invalid sync");
12472 return error::kNoError;
12473 }
12474 *result_dst = glClientWaitSync(service_sync, flags, timeout);
12475 return error::kNoError;
12476}
12477
zmo41e40582015-02-19 02:13:3012478error::Error GLES2DecoderImpl::HandleWaitSync(
12479 uint32_t immediate_data_size, const void* cmd_data) {
12480 if (!unsafe_es3_apis_enabled())
12481 return error::kUnknownCommand;
12482 const gles2::cmds::WaitSync& c =
12483 *static_cast<const gles2::cmds::WaitSync*>(cmd_data);
12484 GLuint sync = static_cast<GLuint>(c.sync);
12485 GLbitfield flags = static_cast<GLbitfield>(c.flags);
12486 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1);
12487 GLsync service_sync = 0;
12488 if (!group_->GetSyncServiceId(sync, &service_sync)) {
12489 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "WaitSync", "invalid sync");
12490 return error::kNoError;
12491 }
12492 glWaitSync(service_sync, flags, timeout);
12493 return error::kNoError;
12494}
12495
zmoa06b9882015-03-10 20:50:3412496error::Error GLES2DecoderImpl::HandleMapBufferRange(
12497 uint32_t immediate_data_size, const void* cmd_data) {
12498 if (!unsafe_es3_apis_enabled()) {
12499 return error::kUnknownCommand;
12500 }
12501 const gles2::cmds::MapBufferRange& c =
12502 *static_cast<const gles2::cmds::MapBufferRange*>(cmd_data);
12503 GLenum target = static_cast<GLenum>(c.target);
12504 GLbitfield access = static_cast<GLbitfield>(c.access);
12505 GLintptr offset = static_cast<GLintptr>(c.offset);
12506 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
12507
12508 typedef cmds::MapBufferRange::Result Result;
12509 Result* result = GetSharedMemoryAs<Result*>(
12510 c.result_shm_id, c.result_shm_offset, sizeof(*result));
12511 if (!result) {
12512 return error::kOutOfBounds;
12513 }
12514 if (*result != 0) {
12515 *result = 0;
12516 return error::kInvalidArguments;
12517 }
12518 int8_t* mem =
12519 GetSharedMemoryAs<int8_t*>(c.data_shm_id, c.data_shm_offset, size);
12520 if (!mem) {
12521 return error::kOutOfBounds;
12522 }
12523
12524 GLbitfield mask = GL_MAP_INVALIDATE_BUFFER_BIT;
12525 if ((access & mask) == mask) {
12526 // TODO(zmo): To be on the safe side, always map
12527 // GL_MAP_INVALIDATE_BUFFER_BIT to GL_MAP_INVALIDATE_RANGE_BIT.
12528 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT);
12529 access = (access | GL_MAP_INVALIDATE_RANGE_BIT);
12530 }
12531 // TODO(zmo): Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of
12532 // undefined behaviors.
12533 mask = GL_MAP_READ_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
12534 if ((access & mask) == mask) {
12535 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "MapBufferRange",
12536 "incompatible access bits");
12537 return error::kNoError;
12538 }
12539 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT);
12540 if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT &&
12541 (access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
12542 access = (access | GL_MAP_READ_BIT);
12543 }
12544 void* ptr = glMapBufferRange(target, offset, size, access);
12545 if (ptr == nullptr) {
12546 return error::kNoError;
12547 }
12548 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
12549 DCHECK(buffer);
zmo2a09dc052015-03-12 00:48:2512550 buffer->SetMappedRange(offset, size, access, ptr,
12551 GetSharedMemoryBuffer(c.data_shm_id));
zmoa06b9882015-03-10 20:50:3412552 if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) {
12553 memcpy(mem, ptr, size);
12554 }
12555 *result = 1;
12556 return error::kNoError;
12557}
12558
zmo2a09dc052015-03-12 00:48:2512559error::Error GLES2DecoderImpl::HandleUnmapBuffer(
12560 uint32_t immediate_data_size, const void* cmd_data) {
12561 if (!unsafe_es3_apis_enabled()) {
12562 return error::kUnknownCommand;
12563 }
12564 const gles2::cmds::UnmapBuffer& c =
12565 *static_cast<const gles2::cmds::UnmapBuffer*>(cmd_data);
12566 GLenum target = static_cast<GLenum>(c.target);
12567
12568 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target);
12569 if (!buffer) {
12570 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", "no buffer bound");
12571 return error::kNoError;
12572 }
12573 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange();
12574 if (!mapped_range) {
12575 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer",
12576 "buffer is unmapped");
12577 return error::kNoError;
12578 }
12579 if ((mapped_range->access & GL_MAP_WRITE_BIT) == 0 ||
12580 (mapped_range->access & GL_MAP_FLUSH_EXPLICIT_BIT) ==
12581 GL_MAP_FLUSH_EXPLICIT_BIT) {
12582 // If we don't need to write back, or explict flush is required, no copying
12583 // back is needed.
12584 } else {
12585 void* mem = mapped_range->GetShmPointer();
12586 if (!mem) {
12587 return error::kOutOfBounds;
12588 }
12589 DCHECK(mapped_range->pointer);
12590 memcpy(mapped_range->pointer, mem, mapped_range->size);
12591 }
12592 buffer->RemoveMappedRange();
12593 GLboolean rt = glUnmapBuffer(target);
12594 if (rt == GL_FALSE) {
12595 // At this point, we have already done the necessary validation, so
12596 // GL_FALSE indicates data corruption.
12597 // TODO(zmo): We could redo the map / copy data / unmap to recover, but
12598 // the second unmap could still return GL_FALSE. For now, we simply lose
12599 // the contexts in the share group.
12600 LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE";
12601 group_->LoseContexts(GL_INNOCENT_CONTEXT_RESET_ARB);
12602 reset_status_ = GL_GUILTY_CONTEXT_RESET_ARB;
12603 return error::kLostContext;
12604 }
12605 return error::kNoError;
12606}
12607
[email protected]91c94eb2013-10-22 10:32:5412608void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
12609 TextureRef* texture_ref) {
12610 Texture* texture = texture_ref->texture();
12611 DoDidUseTexImageIfNeeded(texture, texture->target());
12612}
12613
oetuaho37cc50e2014-10-31 11:19:2012614void GLES2DecoderImpl::OnContextLostError() {
12615 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
12616}
12617
[email protected]828a3932014-04-02 14:43:1312618void GLES2DecoderImpl::OnOutOfMemoryError() {
12619 if (lose_context_when_out_of_memory_) {
12620 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]828a3932014-04-02 14:43:1312621 }
12622}
12623
[email protected]96449d2c2009-11-25 00:01:3212624// Include the auto-generated part of this file. We split this because it means
12625// we can easily edit the non-auto generated parts right here in this file
12626// instead of having to edit some template or the code generator.
12627#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
12628
12629} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2512630} // namespace gpu