blob: 01d20c7f1ae22eee9befd13b556137b244c59028 [file] [log] [blame]
[email protected]529c6672012-01-04 02:18:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]96449d2c2009-11-25 00:01:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8a837bb2010-01-05 00:21:245#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
[email protected]74470702010-01-06 18:51:166
7#include <stdio.h>
8
[email protected]1aef98132010-02-23 18:00:079#include <algorithm>
[email protected]f39f4b3f2010-05-12 17:04:0810#include <list>
[email protected]96449d2c2009-11-25 00:01:3211#include <map>
[email protected]94307712012-11-16 23:26:1112#include <stack>
[email protected]f39f4b3f2010-05-12 17:04:0813#include <string>
14#include <vector>
[email protected]5a6db6c2010-04-22 18:32:0615
[email protected]00eb49a2010-08-12 20:46:5716#include "base/at_exit.h"
[email protected]9d37f062011-11-22 01:24:5217#include "base/bind.h"
[email protected]e3c4a9ab2014-03-31 09:07:0218#include "base/callback_helpers.h"
[email protected]e844ae22012-01-14 03:36:2619#include "base/command_line.h"
[email protected]1078f912011-12-23 13:12:1420#include "base/debug/trace_event.h"
[email protected]b2e92592014-01-10 15:47:1521#include "base/debug/trace_event_synthetic_delay.h"
[email protected]5aa95ac2014-08-14 15:20:5622#include "base/float_util.h"
[email protected]3b63f8f42011-03-28 01:54:1523#include "base/memory/scoped_ptr.h"
[email protected]e3c4a9ab2014-03-31 09:07:0224#include "base/numerics/safe_math.h"
[email protected]f4390962013-06-11 07:29:2225#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1226#include "base/strings/string_split.h"
[email protected]d37231fa2010-04-09 21:16:0227#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3228#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2229#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3230#include "gpu/command_buffer/common/gles2_cmd_format.h"
31#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1032#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5133#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2234#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
35#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5036#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3237#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5038#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2439#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5040#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1141#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5842#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3243#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2844#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4645#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1346#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2647#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1448#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3749#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5950#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2551#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4752#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5353#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5854#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4755#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4556#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0457#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4758#include "gpu/command_buffer/service/texture_manager.h"
[email protected]944b62f32012-09-27 02:20:4659#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2260#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]6896d7f2014-04-28 20:24:1561#include "third_party/smhasher/src/City.h"
[email protected]5a36dc132013-07-23 23:17:5562#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3763#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2764#include "ui/gl/gl_implementation.h"
65#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2766
[email protected]e51bdf32011-11-23 22:21:4667#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:5368#include <IOSurface/IOSurfaceAPI.h>
69// Note that this must be included after gl_bindings.h to avoid conflicts.
70#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4671#endif
[email protected]de17df392010-04-23 21:09:4172
[email protected]6eb775352013-08-27 05:57:1673#if defined(OS_WIN)
74#include "base/win/win_util.h"
75#endif
76
[email protected]a7a27ace2009-12-12 00:11:2577namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3278namespace gles2 {
79
[email protected]f0d74742011-10-03 16:31:0480namespace {
[email protected]693ca512012-11-13 18:09:1381
[email protected]f0d74742011-10-03 16:31:0482static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4983static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1384static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]93c2fd82014-04-16 02:46:0685static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
[email protected]693ca512012-11-13 18:09:1386
[email protected]448e459e2013-06-12 17:00:4187static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
88 GLint rangeMax,
89 GLint precision) {
90 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
91}
92
[email protected]8dc1bf92013-03-12 03:58:2193static void GetShaderPrecisionFormatImpl(GLenum shader_type,
94 GLenum precision_type,
95 GLint *range, GLint *precision) {
96 switch (precision_type) {
97 case GL_LOW_INT:
98 case GL_MEDIUM_INT:
99 case GL_HIGH_INT:
100 // These values are for a 32-bit twos-complement integer format.
101 range[0] = 31;
102 range[1] = 30;
103 *precision = 0;
104 break;
105 case GL_LOW_FLOAT:
106 case GL_MEDIUM_FLOAT:
107 case GL_HIGH_FLOAT:
108 // These values are for an IEEE single-precision floating-point format.
109 range[0] = 127;
110 range[1] = 127;
111 *precision = 23;
112 break;
113 default:
114 NOTREACHED();
115 break;
116 }
117
[email protected]8af4d5e2013-03-15 23:55:33118 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
119 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21120 // This function is sometimes defined even though it's really just
121 // a stub, so we need to set range and precision as if it weren't
122 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44123 // On Mac OS with some GPUs, calling this generates a
124 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
125 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21126 glGetShaderPrecisionFormat(shader_type, precision_type,
127 range, precision);
[email protected]448e459e2013-06-12 17:00:41128
129 // TODO(brianderson): Make the following official workarounds.
130
131 // Some drivers have bugs where they report the ranges as a negative number.
132 // Taking the absolute value here shouldn't hurt because negative numbers
133 // aren't expected anyway.
134 range[0] = abs(range[0]);
135 range[1] = abs(range[1]);
136
137 // If the driver reports a precision for highp float that isn't actually
138 // highp, don't pretend like it's supported because shader compilation will
139 // fail anyway.
140 if (precision_type == GL_HIGH_FLOAT &&
141 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
142 range[0] = 0;
143 range[1] = 0;
144 *precision = 0;
145 }
[email protected]8dc1bf92013-03-12 03:58:21146 }
147}
148
[email protected]d286ebbc2014-07-03 17:19:10149static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
150 switch (plane_transform) {
151 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
152 return gfx::OVERLAY_TRANSFORM_NONE;
153 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
154 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
155 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
156 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
157 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
158 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
159 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
160 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
161 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
162 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
163 default:
164 return gfx::OVERLAY_TRANSFORM_INVALID;
165 }
166}
167
[email protected]b04e24c2013-01-08 18:35:25168} // namespace
[email protected]f0d74742011-10-03 16:31:04169
[email protected]6217d392010-03-25 22:08:35170class GLES2DecoderImpl;
171
[email protected]ab09b612013-03-11 22:11:51172// Local versions of the SET_GL_ERROR macros
173#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50174 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51175#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50176 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
177 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51178#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50179 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
180 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51181#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50182 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
183 function_name)
[email protected]ab09b612013-03-11 22:11:51184#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50185 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51186#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50187 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51188#define LOCAL_PERFORMANCE_WARNING(msg) \
189 PerformanceWarning(__FILE__, __LINE__, msg)
190#define LOCAL_RENDER_WARNING(msg) \
191 RenderWarning(__FILE__, __LINE__, msg)
192
[email protected]07f54fcc2009-12-22 02:46:30193// Check that certain assumptions the code makes are true. There are places in
194// the code where shared memory is passed direclty to GL. Example, glUniformiv,
195// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
196// a few others) are 32bits. If they are not 32bits the code will have to change
197// to call those GL functions with service side memory and then copy the results
198// to shared memory, converting the sizes.
199COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
200 GLint_not_same_size_as_uint32);
201COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
202 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37203COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
204 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30205
[email protected]43f28f832010-02-03 02:28:48206// TODO(kbr): the use of this anonymous namespace core dumps the
207// linker on Mac OS X 10.6 when the symbol ordering file is used
208// namespace {
[email protected]96449d2c2009-11-25 00:01:32209
210// Returns the address of the first byte after a struct.
211template <typename T>
212const void* AddressAfterStruct(const T& pod) {
213 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
214}
215
[email protected]07f54fcc2009-12-22 02:46:30216// Returns the address of the frst byte after the struct or NULL if size >
217// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32218template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30219RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
220 uint32 size,
221 uint32 immediate_data_size) {
222 return (size <= immediate_data_size) ?
223 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
224 NULL;
[email protected]96449d2c2009-11-25 00:01:32225}
226
[email protected]07f54fcc2009-12-22 02:46:30227// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18228bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32229 GLuint count,
230 size_t size,
[email protected]a76b0052010-03-05 00:33:18231 unsigned int elements_per_unit,
232 uint32* dst) {
233 uint32 value;
234 if (!SafeMultiplyUint32(count, size, &value)) {
235 return false;
236 }
237 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
238 return false;
239 }
240 *dst = value;
241 return true;
[email protected]96449d2c2009-11-25 00:01:32242}
243
[email protected]258a3313f2011-10-18 20:13:57244// Return true if a character belongs to the ASCII subset as defined in
245// GLSL ES 1.0 spec section 3.1.
246static bool CharacterIsValidForGLES(unsigned char c) {
247 // Printing characters are valid except " $ ` @ \ ' DEL.
248 if (c >= 32 && c <= 126 &&
249 c != '"' &&
250 c != '$' &&
251 c != '`' &&
252 c != '@' &&
253 c != '\\' &&
254 c != '\'') {
255 return true;
256 }
257 // Horizontal tab, line feed, vertical tab, form feed, carriage return
258 // are also valid.
259 if (c >= 9 && c <= 13) {
260 return true;
261 }
262
263 return false;
264}
265
266static bool StringIsValidForGLES(const char* str) {
267 for (; *str; ++str) {
268 if (!CharacterIsValidForGLES(*str)) {
269 return false;
270 }
271 }
272 return true;
273}
274
[email protected]6217d392010-03-25 22:08:35275// This class prevents any GL errors that occur when it is in scope from
276// being reported to the client.
277class ScopedGLErrorSuppressor {
278 public:
[email protected]ab09b612013-03-11 22:11:51279 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30280 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35281 ~ScopedGLErrorSuppressor();
282 private:
[email protected]ab09b612013-03-11 22:11:51283 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30284 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35285 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
286};
287
[email protected]2b10c02d2014-01-29 16:43:02288// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35289// object goes out of scope. Also temporarily switches to using active texture
290// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02291class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35292 public:
[email protected]00c2cf92014-03-14 00:08:37293 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02294 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35295
296 private:
[email protected]ce296892013-10-24 22:04:36297 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02298 GLenum target_;
299 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35300};
301
302// Temporarily changes a decoder's bound render buffer and restore it when this
303// object goes out of scope.
304class ScopedRenderBufferBinder {
305 public:
[email protected]00c2cf92014-03-14 00:08:37306 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35307 ~ScopedRenderBufferBinder();
308
309 private:
[email protected]18e785a2013-10-09 03:29:41310 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35311 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
312};
313
314// Temporarily changes a decoder's bound frame buffer and restore it when this
315// object goes out of scope.
316class ScopedFrameBufferBinder {
317 public:
[email protected]00c2cf92014-03-14 00:08:37318 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35319 ~ScopedFrameBufferBinder();
320
321 private:
322 GLES2DecoderImpl* decoder_;
323 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
324};
325
[email protected]34ff8b0c2010-10-01 20:06:02326// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52327// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27328// if it is bound or enforce_internal_framebuffer is true. If internal is
329// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02330class ScopedResolvedFrameBufferBinder {
331 public:
[email protected]00c2cf92014-03-14 00:08:37332 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
333 bool enforce_internal_framebuffer,
334 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02335 ~ScopedResolvedFrameBufferBinder();
336
337 private:
338 GLES2DecoderImpl* decoder_;
339 bool resolve_and_bind_;
340 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
341};
342
[email protected]00c2cf92014-03-14 00:08:37343class ScopedModifyPixels {
344 public:
345 explicit ScopedModifyPixels(TextureRef* ref);
346 ~ScopedModifyPixels();
347
348 private:
349 TextureRef* ref_;
350};
351
352ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
353 if (ref_)
354 ref_->texture()->OnWillModifyPixels();
355}
356
357ScopedModifyPixels::~ScopedModifyPixels() {
358 if (ref_)
359 ref_->texture()->OnDidModifyPixels();
360}
361
362class ScopedRenderTo {
363 public:
364 explicit ScopedRenderTo(Framebuffer* framebuffer);
365 ~ScopedRenderTo();
366
367 private:
368 const Framebuffer* framebuffer_;
369};
370
371ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
372 : framebuffer_(framebuffer) {
373 if (framebuffer)
374 framebuffer_->OnWillRenderTo();
375}
376
377ScopedRenderTo::~ScopedRenderTo() {
378 if (framebuffer_)
379 framebuffer_->OnDidRenderTo();
380}
381
[email protected]6217d392010-03-25 22:08:35382// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35383class BackTexture {
[email protected]6217d392010-03-25 22:08:35384 public:
[email protected]ce296892013-10-24 22:04:36385 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35386 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35387
388 // Create a new render texture.
389 void Create();
390
391 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09392 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35393
394 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58395 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35396
397 // Destroy the render texture. This must be explicitly called before
398 // destroying this object.
399 void Destroy();
400
[email protected]97872062010-11-03 19:07:05401 // Invalidate the texture. This can be used when a context is lost and it is
402 // not possible to make it current in order to free the resource.
403 void Invalidate();
404
[email protected]6217d392010-03-25 22:08:35405 GLuint id() const {
406 return id_;
407 }
408
[email protected]d37231fa2010-04-09 21:16:02409 gfx::Size size() const {
410 return size_;
411 }
412
[email protected]6217d392010-03-25 22:08:35413 private:
[email protected]ff6493f2012-07-31 19:52:25414 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36415 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48416 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35417 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02418 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35419 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35420};
421
422// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35423class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35424 public:
[email protected]d5a28e452013-10-10 01:01:40425 explicit BackRenderbuffer(
426 RenderbufferManager* renderbuffer_manager,
427 MemoryTracker* memory_tracker,
428 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35429 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35430
431 // Create a new render buffer.
432 void Create();
433
434 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18435 bool AllocateStorage(const FeatureInfo* feature_info,
436 const gfx::Size& size,
437 GLenum format,
438 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35439
440 // Destroy the render buffer. This must be explicitly called before destroying
441 // this object.
442 void Destroy();
443
[email protected]97872062010-11-03 19:07:05444 // Invalidate the render buffer. This can be used when a context is lost and
445 // it is not possible to make it current in order to free the resource.
446 void Invalidate();
447
[email protected]6217d392010-03-25 22:08:35448 GLuint id() const {
449 return id_;
450 }
451
452 private:
[email protected]d5a28e452013-10-10 01:01:40453 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25454 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40455 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48456 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35457 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35458 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35459};
460
461// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35462class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35463 public:
[email protected]ed9f9cd2013-02-27 21:12:35464 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
465 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35466
467 // Create a new frame buffer.
468 void Create();
469
470 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35471 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35472
[email protected]b9363b22010-06-09 22:06:15473 // Attach a render buffer to a frame buffer. Note that this unbinds any
474 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35475 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35476
[email protected]6217d392010-03-25 22:08:35477 // Destroy the frame buffer. This must be explicitly called before destroying
478 // this object.
479 void Destroy();
480
[email protected]97872062010-11-03 19:07:05481 // Invalidate the frame buffer. This can be used when a context is lost and it
482 // is not possible to make it current in order to free the resource.
483 void Invalidate();
484
[email protected]6217d392010-03-25 22:08:35485 // See glCheckFramebufferStatusEXT.
486 GLenum CheckStatus();
487
488 GLuint id() const {
489 return id_;
490 }
491
492 private:
493 GLES2DecoderImpl* decoder_;
494 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35495 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35496};
[email protected]34ff8b0c2010-10-01 20:06:02497
[email protected]5a36dc132013-07-23 23:17:55498struct FenceCallback {
499 explicit FenceCallback()
500 : fence(gfx::GLFence::Create()) {
501 DCHECK(fence);
502 }
[email protected]5a36dc132013-07-23 23:17:55503 std::vector<base::Closure> callbacks;
504 scoped_ptr<gfx::GLFence> fence;
505};
506
[email protected]e3c4a9ab2014-03-31 09:07:02507class AsyncUploadTokenCompletionObserver
508 : public AsyncPixelTransferCompletionObserver {
509 public:
510 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
511 : async_upload_token_(async_upload_token) {
512 }
513
dcheng1f4d1d72014-10-21 16:21:58514 void DidComplete(const AsyncMemoryParams& mem_params) override {
dcheng6ef3c5552014-08-30 05:34:19515 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02516 void* data = mem_params.GetDataAddress();
517 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
518 sync->SetAsyncUploadToken(async_upload_token_);
519 }
520
521 private:
dcheng1f4d1d72014-10-21 16:21:58522 ~AsyncUploadTokenCompletionObserver() override {}
[email protected]e3c4a9ab2014-03-31 09:07:02523
524 uint32 async_upload_token_;
525
526 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
527};
528
[email protected]43f28f832010-02-03 02:28:48529// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32530
[email protected]efc87712014-07-09 00:22:47531// static
532const unsigned int GLES2Decoder::kDefaultStencilMask =
533 static_cast<unsigned int>(-1);
534
[email protected]ddb1e5a2010-12-13 20:10:45535bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
536 uint32* service_texture_id) {
537 return false;
538}
539
[email protected]a3ded6d2010-10-19 06:44:39540GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06541 : initialized_(false),
542 debug_(false),
[email protected]1d82e822013-04-10 21:32:32543 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32544}
545
[email protected]3916c97e2010-02-25 03:20:50546GLES2Decoder::~GLES2Decoder() {
547}
548
[email protected]cac16542014-01-15 17:53:51549void GLES2Decoder::BeginDecoding() {}
550
551void GLES2Decoder::EndDecoding() {}
552
[email protected]f39f4b3f2010-05-12 17:04:08553// This class implements GLES2Decoder so we don't have to expose all the GLES2
554// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54555class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13556 public FramebufferManager::TextureDetachObserver,
557 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08558 public:
[email protected]aa7666122011-09-02 19:45:52559 explicit GLES2DecoderImpl(ContextGroup* group);
dcheng1f4d1d72014-10-21 16:21:58560 ~GLES2DecoderImpl() override;
[email protected]f39f4b3f2010-05-12 17:04:08561
[email protected]96449d2c2009-11-25 00:01:32562 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58563 Error DoCommand(unsigned int command,
564 unsigned int arg_count,
565 const void* args) override;
[email protected]96449d2c2009-11-25 00:01:32566
dcheng1f4d1d72014-10-21 16:21:58567 error::Error DoCommands(unsigned int num_commands,
568 const void* buffer,
569 int num_entries,
570 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00571
vmiura1c2b1de2014-09-19 19:03:24572 template <bool DebugImpl>
573 error::Error DoCommandsImpl(unsigned int num_commands,
574 const void* buffer,
575 int num_entries,
576 int* entries_processed);
577
[email protected]96449d2c2009-11-25 00:01:32578 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58579 const char* GetCommandName(unsigned int command_id) const override;
[email protected]96449d2c2009-11-25 00:01:32580
581 // Overridden from GLES2Decoder.
dcheng1f4d1d72014-10-21 16:21:58582 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
583 const scoped_refptr<gfx::GLContext>& context,
584 bool offscreen,
585 const gfx::Size& size,
586 const DisallowedFeatures& disallowed_features,
587 const std::vector<int32>& attribs) override;
588 void Destroy(bool have_context) override;
589 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
590 void ProduceFrontBuffer(const Mailbox& mailbox) override;
591 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39592 void UpdateParentTextureInfo();
dcheng1f4d1d72014-10-21 16:21:58593 bool MakeCurrent() override;
594 GLES2Util* GetGLES2Util() override { return &util_; }
595 gfx::GLContext* GetGLContext() override { return context_.get(); }
596 ContextGroup* GetContextGroup() override { return group_.get(); }
597 Capabilities GetCapabilities() override;
598 void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06599
dcheng1f4d1d72014-10-21 16:21:58600 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
601 void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17602 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16603 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55604 }
dcheng1f4d1d72014-10-21 16:21:58605 void RestoreActiveTextureUnitBinding(unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27606 state_.RestoreActiveTextureUnitBinding(target);
607 }
dcheng1f4d1d72014-10-21 16:21:58608 void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06609 state_.RestoreBufferBindings();
610 }
dcheng1f4d1d72014-10-21 16:21:58611 void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
612 void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06613 state_.RestoreProgramBindings();
614 }
dcheng1f4d1d72014-10-21 16:21:58615 void RestoreTextureUnitBindings(unsigned unit) const override {
[email protected]5baa86bc2014-01-16 04:33:16616 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06617 }
dcheng1f4d1d72014-10-21 16:21:58618 void RestoreFramebufferBindings() const override;
619 void RestoreRenderbufferBindings() override;
620 void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06621
dcheng1f4d1d72014-10-21 16:21:58622 void ClearAllAttributes() const override;
623 void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03624
dcheng1f4d1d72014-10-21 16:21:58625 QueryManager* GetQueryManager() override { return query_manager_.get(); }
626 VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46627 return vertex_array_manager_.get();
628 }
dcheng1f4d1d72014-10-21 16:21:58629 ImageManager* GetImageManager() override { return image_manager_.get(); }
630 bool ProcessPendingQueries() override;
631 bool HasMoreIdleWork() override;
632 void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48633
dcheng1f4d1d72014-10-21 16:21:58634 void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55635
dcheng1f4d1d72014-10-21 16:21:58636 void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17637 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00638
dcheng1f4d1d72014-10-21 16:21:58639 Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51640
dcheng1f4d1d72014-10-21 16:21:58641 void BeginDecoding() override;
642 void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51643
dcheng1f4d1d72014-10-21 16:21:58644 ErrorState* GetErrorState() override;
645 const ContextState* GetContextState() override { return &state_; }
[email protected]1d82e822013-04-10 21:32:32646
dcheng1f4d1d72014-10-21 16:21:58647 void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
648 void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00649
dcheng1f4d1d72014-10-21 16:21:58650 AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
651 void ResetAsyncPixelTransferManagerForTest() override;
652 void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17653 AsyncPixelTransferManager* manager) override;
dcheng1f4d1d72014-10-21 16:21:58654 void SetIgnoreCachedStateForTest(bool ignore) override;
[email protected]69a8701e2013-03-07 21:31:09655 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59656
dcheng1f4d1d72014-10-21 16:21:58657 bool GetServiceTextureId(uint32 client_texture_id,
658 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48659
dcheng1f4d1d72014-10-21 16:21:58660 uint32 GetTextureUploadCount() override;
661 base::TimeDelta GetTotalTextureUploadTime() override;
662 base::TimeDelta GetTotalProcessingCommandsTime() override;
663 void AddProcessingCommandsTime(base::TimeDelta) override;
[email protected]63b465922012-09-06 02:04:52664
[email protected]8e3e0662010-08-23 18:46:30665 // Restores the current state to the user's settings.
666 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30667
[email protected]297ca1c2011-06-20 23:08:46668 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
669 void ApplyDirtyState();
670
671 // These check the state of the currently bound framebuffer or the
672 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54673 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
674 // check with all attached and enabled color attachments.
675 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46676 bool BoundFramebufferHasDepthAttachment();
677 bool BoundFramebufferHasStencilAttachment();
678
dcheng1f4d1d72014-10-21 16:21:58679 error::ContextLostReason GetContextLostReason() override;
[email protected]38d139d2011-07-14 00:38:43680
[email protected]91c94eb2013-10-22 10:32:54681 // Overridden from FramebufferManager::TextureDetachObserver:
dcheng1f4d1d72014-10-21 16:21:58682 void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54683
[email protected]828a3932014-04-02 14:43:13684 // Overriden from ErrorStateClient.
dcheng1f4d1d72014-10-21 16:21:58685 void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13686
[email protected]8875a5f2014-06-27 08:33:47687 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
688 void EnsureRenderbufferBound();
689
[email protected]f42f05b2013-11-15 21:46:18690 // Helpers to facilitate calling into compatible extensions.
691 static void RenderbufferStorageMultisampleHelper(
692 const FeatureInfo* feature_info,
693 GLenum target,
694 GLsizei samples,
695 GLenum internal_format,
696 GLsizei width,
697 GLsizei height);
698
699 void BlitFramebufferHelper(GLint srcX0,
700 GLint srcY0,
701 GLint srcX1,
702 GLint srcY1,
703 GLint dstX0,
704 GLint dstY0,
705 GLint dstX1,
706 GLint dstY1,
707 GLbitfield mask,
708 GLenum filter);
[email protected]345ba902013-11-14 21:39:00709
[email protected]96449d2c2009-11-25 00:01:32710 private:
[email protected]70d34263c2013-01-09 00:27:45711 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02712 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35713 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35714
[email protected]c2f8c8402010-12-06 18:07:24715 // Initialize or re-initialize the shader translator.
716 bool InitializeShaderTranslator();
717
[email protected]302ce6d2011-07-07 23:28:11718 void UpdateCapabilities();
719
[email protected]ae51d192010-04-27 00:48:03720 // Helpers for the glGen and glDelete functions.
721 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
722 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
723 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
724 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
725 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
726 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
727 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
728 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53729 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
730 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46731 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
732 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47733
[email protected]e3c4a9ab2014-03-31 09:07:02734 // Helper for async upload token completion notification callback.
735 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
736 uint32 sync_data_shm_id,
737 uint32 sync_data_shm_offset);
738
739
740
[email protected]70d34263c2013-01-09 00:27:45741 // Workarounds
742 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51743 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45744
[email protected]3916c97e2010-02-25 03:20:50745 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50746 BufferManager* buffer_manager() {
747 return group_->buffer_manager();
748 }
749
[email protected]a25fa872010-03-25 02:57:58750 RenderbufferManager* renderbuffer_manager() {
751 return group_->renderbuffer_manager();
752 }
753
754 FramebufferManager* framebuffer_manager() {
755 return group_->framebuffer_manager();
756 }
757
[email protected]3916c97e2010-02-25 03:20:50758 ProgramManager* program_manager() {
759 return group_->program_manager();
760 }
761
762 ShaderManager* shader_manager() {
763 return group_->shader_manager();
764 }
765
[email protected]03cef9b2014-04-03 15:58:14766 ShaderTranslatorCache* shader_translator_cache() {
767 return group_->shader_translator_cache();
768 }
769
[email protected]29a4d902013-02-26 20:18:06770 const TextureManager* texture_manager() const {
771 return group_->texture_manager();
772 }
773
[email protected]3916c97e2010-02-25 03:20:50774 TextureManager* texture_manager() {
775 return group_->texture_manager();
776 }
777
[email protected]78b514b2012-05-01 21:50:59778 MailboxManager* mailbox_manager() {
779 return group_->mailbox_manager();
780 }
781
[email protected]b63f1d62014-07-18 15:40:59782 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37783
[email protected]944b62f32012-09-27 02:20:46784 VertexArrayManager* vertex_array_manager() {
785 return vertex_array_manager_.get();
786 }
787
[email protected]7989c9e2013-01-23 06:39:26788 MemoryTracker* memory_tracker() {
789 return group_->memory_tracker();
790 }
791
792 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
793 MemoryTracker* tracker = memory_tracker();
794 if (tracker) {
795 return tracker->EnsureGPUMemoryAvailable(estimated_size);
796 }
797 return true;
798 }
799
[email protected]34ff8b0c2010-10-01 20:06:02800 bool IsOffscreenBufferMultisampled() const {
801 return offscreen_target_samples_ > 1;
802 }
803
[email protected]ed9f9cd2013-02-27 21:12:35804 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49805 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03806 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35807 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47808 }
809
810 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49811 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07812 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47813 }
814
815 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35816 void RemoveTexture(GLuint client_id) {
817 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50818 }
[email protected]a93bb842010-02-16 23:03:47819
[email protected]d37231fa2010-04-09 21:16:02820 // Get the size (in pixels) of the currently bound frame buffer (either FBO
821 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30822 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02823
[email protected]9edc6b22010-12-23 02:00:26824 // Get the format of the currently bound frame buffer (either FBO or regular
825 // back buffer)
[email protected]68586372013-12-11 01:27:59826 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26827 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46828 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26829
[email protected]a93bb842010-02-16 23:03:47830 // Wrapper for CompressedTexImage2D commands.
831 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37832 GLenum target,
833 GLint level,
834 GLenum internal_format,
835 GLsizei width,
836 GLsizei height,
837 GLint border,
838 GLsizei image_size,
839 const void* data);
[email protected]a93bb842010-02-16 23:03:47840
[email protected]cadde4a2010-07-31 17:10:43841 // Wrapper for CompressedTexSubImage2D.
842 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37843 GLenum target,
844 GLint level,
845 GLint xoffset,
846 GLint yoffset,
847 GLsizei width,
848 GLsizei height,
849 GLenum format,
850 GLsizei imageSize,
851 const void * data);
[email protected]cadde4a2010-07-31 17:10:43852
853 // Wrapper for CopyTexImage2D.
854 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37855 GLenum target,
856 GLint level,
857 GLenum internal_format,
858 GLint x,
859 GLint y,
860 GLsizei width,
861 GLsizei height,
862 GLint border);
[email protected]cadde4a2010-07-31 17:10:43863
[email protected]6d792ee12013-05-15 00:40:56864 // Wrapper for SwapBuffers.
865 void DoSwapBuffers();
866
[email protected]cadde4a2010-07-31 17:10:43867 // Wrapper for CopyTexSubImage2D.
868 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37869 GLenum target,
870 GLint level,
871 GLint xoffset,
872 GLint yoffset,
873 GLint x,
874 GLint y,
875 GLsizei width,
876 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43877
[email protected]f598f422012-12-07 08:30:03878 // Validation for TexSubImage2D.
879 bool ValidateTexSubImage2D(
880 error::Error* error,
881 const char* function_name,
882 GLenum target,
883 GLint level,
884 GLint xoffset,
885 GLint yoffset,
886 GLsizei width,
887 GLsizei height,
888 GLenum format,
889 GLenum type,
890 const void * data);
891
[email protected]cadde4a2010-07-31 17:10:43892 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03893 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37894 GLenum target,
895 GLint level,
896 GLint xoffset,
897 GLint yoffset,
898 GLsizei width,
899 GLsizei height,
900 GLenum format,
901 GLenum type,
902 const void * data);
[email protected]cadde4a2010-07-31 17:10:43903
[email protected]32145a92012-12-17 09:01:59904 // Extra validation for async tex(Sub)Image2D.
905 bool ValidateAsyncTransfer(
906 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47907 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59908 GLenum target,
909 GLint level,
910 const void * data);
911
[email protected]e51bdf32011-11-23 22:21:46912 // Wrapper for TexImageIOSurface2DCHROMIUM.
913 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37914 GLenum target,
915 GLsizei width,
916 GLsizei height,
917 GLuint io_surface_id,
918 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46919
[email protected]43410e92012-04-20 17:06:28920 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37921 GLenum target,
922 GLuint source_id,
923 GLuint target_id,
924 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54925 GLenum internal_format,
926 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28927
[email protected]97dc7cbe2011-12-06 17:26:17928 // Wrapper for TexStorage2DEXT.
929 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37930 GLenum target,
931 GLint levels,
932 GLenum internal_format,
933 GLsizei width,
934 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17935
[email protected]78b514b2012-05-01 21:50:59936 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22937 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
938 const GLbyte* key);
939 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
940 GLenum target, const GLbyte* data);
941
[email protected]78b514b2012-05-01 21:50:59942 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22943 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
944 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59945
[email protected]09d50362012-10-18 20:54:37946 void DoBindTexImage2DCHROMIUM(
947 GLenum target,
948 GLint image_id);
949 void DoReleaseTexImage2DCHROMIUM(
950 GLenum target,
951 GLint image_id);
952
[email protected]94307712012-11-16 23:26:11953 void DoTraceEndCHROMIUM(void);
954
[email protected]2f143d482013-03-14 18:04:49955 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
956
[email protected]a6a09f852014-05-23 13:05:03957 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
958
kkinnunen337d59632014-08-26 10:19:57959 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
960 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
961
[email protected]ed9f9cd2013-02-27 21:12:35962 // Creates a Program for the given program.
963 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57964 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35965 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47966 }
967
[email protected]07f54fcc2009-12-22 02:46:30968 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35969 Program* GetProgram(GLuint client_id) {
970 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46971 }
[email protected]07f54fcc2009-12-22 02:46:30972
[email protected]cae20172012-12-07 00:06:19973#if defined(NDEBUG)
974 void LogClientServiceMapping(
975 const char* /* function_name */,
976 GLuint /* client_id */,
977 GLuint /* service_id */) {
978 }
979 template<typename T>
980 void LogClientServiceForInfo(
981 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
982 }
983#else
984 void LogClientServiceMapping(
985 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26986 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:47987 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
988 << ": client_id = " << client_id
989 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:26990 }
[email protected]cae20172012-12-07 00:06:19991 }
992 template<typename T>
993 void LogClientServiceForInfo(
994 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26995 if (info) {
[email protected]cae20172012-12-07 00:06:19996 LogClientServiceMapping(function_name, client_id, info->service_id());
997 }
998 }
999#endif
1000
[email protected]6b8cf1a2010-05-06 16:13:581001 // Gets the program info for the given program. If it's not a program
1002 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351003 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581004 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421005 Program* program = GetProgram(client_id);
1006 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351007 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511008 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431009 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581010 } else {
[email protected]ab09b612013-03-11 22:11:511011 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581012 }
1013 }
[email protected]df37b9932013-03-08 05:21:421014 LogClientServiceForInfo(program, client_id, function_name);
1015 return program;
[email protected]6b8cf1a2010-05-06 16:13:581016 }
1017
1018
[email protected]ed9f9cd2013-02-27 21:12:351019 // Creates a Shader for the given shader.
1020 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571021 GLuint client_id,
1022 GLuint service_id,
1023 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351024 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571025 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311026 }
1027
1028 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351029 Shader* GetShader(GLuint client_id) {
1030 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311031 }
1032
[email protected]6b8cf1a2010-05-06 16:13:581033 // Gets the shader info for the given shader. If it's not a shader generates a
1034 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351035 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581036 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421037 Shader* shader = GetShader(client_id);
1038 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351039 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511040 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431041 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581042 } else {
[email protected]ab09b612013-03-11 22:11:511043 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431044 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581045 }
1046 }
[email protected]df37b9932013-03-08 05:21:421047 LogClientServiceForInfo(shader, client_id, function_name);
1048 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581049 }
1050
[email protected]a93bb842010-02-16 23:03:471051 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351052 void CreateBuffer(GLuint client_id, GLuint service_id) {
1053 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471054 }
1055
[email protected]07f54fcc2009-12-22 02:46:301056 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211057 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071058 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1059 return buffer;
[email protected]1d32bc82010-01-13 22:06:461060 }
[email protected]07f54fcc2009-12-22 02:46:301061
[email protected]a93bb842010-02-16 23:03:471062 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1063 // on glDeleteBuffers so we can make sure the user does not try to render
1064 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351065 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471066
[email protected]a25fa872010-03-25 02:57:581067 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351068 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1069 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581070 }
1071
1072 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061073 Framebuffer* GetFramebuffer(GLuint client_id) {
1074 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581075 }
1076
1077 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351078 void RemoveFramebuffer(GLuint client_id) {
1079 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581080 }
1081
1082 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351083 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1084 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031085 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581086 }
1087
1088 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271089 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1090 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581091 }
1092
1093 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351094 void RemoveRenderbuffer(GLuint client_id) {
1095 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581096 }
1097
[email protected]944b62f32012-09-27 02:20:461098 // Gets the vertex attrib manager for the given vertex array.
1099 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1100 VertexAttribManager* info =
1101 vertex_array_manager()->GetVertexAttribManager(client_id);
1102 return info;
1103 }
1104
1105 // Removes the vertex attrib manager for the given vertex array.
1106 void RemoveVertexAttribManager(GLuint client_id) {
1107 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1108 }
1109
1110 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481111 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1112 GLuint client_id,
1113 GLuint service_id,
1114 bool client_visible) {
1115 return vertex_array_manager()->CreateVertexAttribManager(
1116 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461117 }
1118
[email protected]258a3313f2011-10-18 20:13:571119 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331120 void DoBindUniformLocationCHROMIUM(
1121 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571122
[email protected]558847a2010-03-24 07:02:541123 error::Error GetAttribLocationHelper(
1124 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1125 const std::string& name_str);
1126
1127 error::Error GetUniformLocationHelper(
1128 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1129 const std::string& name_str);
1130
[email protected]3916c97e2010-02-25 03:20:501131 // Helper for glShaderSource.
1132 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031133 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301134
[email protected]0d6bfdc2011-11-02 01:32:201135 // Clear any textures used by the current program.
1136 bool ClearUnclearedTextures();
1137
[email protected]0d6bfdc2011-11-02 01:32:201138 // Clears any uncleared attachments attached to the given frame buffer.
1139 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061140 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281141
[email protected]0d6bfdc2011-11-02 01:32:201142 // overridden from GLES2Decoder
dcheng1f4d1d72014-10-21 16:21:581143 bool ClearLevel(unsigned service_id,
1144 unsigned bind_target,
1145 unsigned target,
1146 int level,
1147 unsigned internal_format,
1148 unsigned format,
1149 unsigned type,
1150 int width,
1151 int height,
1152 bool is_texture_immutable) override;
[email protected]0d6bfdc2011-11-02 01:32:201153
[email protected]c007aa02010-09-02 22:22:401154 // Restore all GL state that affects clearing.
1155 void RestoreClearState();
1156
[email protected]3a2e7c7b2010-08-06 01:12:281157 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461158 // Returns: true if glEnable/glDisable should actually be called.
1159 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281160
[email protected]0d6bfdc2011-11-02 01:32:201161 // Check that the currently bound framebuffers are valid.
1162 // Generates GL error if not.
1163 bool CheckBoundFramebuffersValid(const char* func_name);
1164
[email protected]2ea5950d2014-07-09 18:20:341165 // Check that the currently bound read framebuffer has a color image
1166 // attached. Generates GL error if not.
1167 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1168
zmo383512cf2014-10-14 00:11:001169 // Check that the currently bound read framebuffer's color image
1170 // isn't the target texture of the glCopyTex{Sub}Image2D.
1171 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1172
[email protected]0d6bfdc2011-11-02 01:32:201173 // Check if a framebuffer meets our requirements.
1174 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351175 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201176 GLenum target,
1177 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271178
[email protected]939e7362010-05-13 20:49:101179 // Checks if the current program exists and is valid. If not generates the
1180 // appropriate GL error. Returns true if the current program is in a usable
1181 // state.
1182 bool CheckCurrentProgram(const char* function_name);
1183
1184 // Checks if the current program exists and is valid and that location is not
1185 // -1. If the current program is not valid generates the appropriate GL
1186 // error. Returns true if the current program is in a usable state and
1187 // location is not -1.
1188 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1189
zmof9a81360f2014-10-17 00:06:141190 // Checks if the current program samples a texture that is also the color
1191 // image of the current bound framebuffer, i.e., the source and destination
1192 // of the draw operation are the same.
1193 bool CheckDrawingFeedbackLoops();
1194
[email protected]939e7362010-05-13 20:49:101195 // Gets the type of a uniform for a location in the current program. Sets GL
1196 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361197 // program is valid and the location exists. Adjusts count so it
1198 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131199 bool PrepForSetUniformByLocation(GLint fake_location,
1200 const char* function_name,
1201 Program::UniformApiType api_type,
1202 GLint* real_location,
1203 GLenum* type,
1204 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101205
[email protected]b177ae22011-11-01 03:29:111206 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021207 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111208
[email protected]b273e432010-04-12 17:23:581209 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1210 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1211
[email protected]ac77603c72013-03-08 13:52:061212 // Helper for glGetVertexAttrib
1213 void GetVertexAttribHelper(
1214 const VertexAttrib* attrib, GLenum pname, GLint* param);
1215
[email protected]96449d2c2009-11-25 00:01:321216 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031217 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321218
1219 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031220 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321221
[email protected]3916c97e2010-02-25 03:20:501222 // Wrapper for glActiveTexture
1223 void DoActiveTexture(GLenum texture_unit);
1224
[email protected]ae51d192010-04-27 00:48:031225 // Wrapper for glAttachShader
1226 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1227
[email protected]96449d2c2009-11-25 00:01:321228 // Wrapper for glBindBuffer since we need to track the current targets.
1229 void DoBindBuffer(GLenum target, GLuint buffer);
1230
[email protected]86093972010-03-11 00:13:561231 // Wrapper for glBindFramebuffer since we need to track the current targets.
1232 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1233
1234 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1235 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1236
[email protected]a93bb842010-02-16 23:03:471237 // Wrapper for glBindTexture since we need to track the current targets.
1238 void DoBindTexture(GLenum target, GLuint texture);
1239
[email protected]944b62f32012-09-27 02:20:461240 // Wrapper for glBindVertexArrayOES
1241 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571242 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461243
[email protected]49cabed2013-11-13 18:15:181244 // Wrapper for glBlitFramebufferCHROMIUM.
1245 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301246 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1247 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1248 GLbitfield mask, GLenum filter);
1249
[email protected]36cef8ce2010-03-16 07:34:451250 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111251 void DoBufferSubData(
1252 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1253
[email protected]36cef8ce2010-03-16 07:34:451254 // Wrapper for glCheckFramebufferStatus
1255 GLenum DoCheckFramebufferStatus(GLenum target);
1256
[email protected]3a03a8f2011-03-19 00:51:271257 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081258 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271259
[email protected]88a61bf2012-10-27 13:00:421260 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421261 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251262 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281263
[email protected]45bf5152010-02-12 00:11:311264 // Wrapper for glCompileShader.
1265 void DoCompileShader(GLuint shader);
1266
[email protected]ae51d192010-04-27 00:48:031267 // Wrapper for glDetachShader
1268 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1269
[email protected]3a2e7c7b2010-08-06 01:12:281270 // Wrapper for glDisable
1271 void DoDisable(GLenum cap);
1272
[email protected]07f54fcc2009-12-22 02:46:301273 // Wrapper for glDisableVertexAttribArray.
1274 void DoDisableVertexAttribArray(GLuint index);
1275
[email protected]60f22d32012-12-12 00:31:581276 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1277 // attachments.
1278 void DoDiscardFramebufferEXT(GLenum target,
1279 GLsizei numAttachments,
1280 const GLenum* attachments);
1281
[email protected]3a2e7c7b2010-08-06 01:12:281282 // Wrapper for glEnable
1283 void DoEnable(GLenum cap);
1284
[email protected]07f54fcc2009-12-22 02:46:301285 // Wrapper for glEnableVertexAttribArray.
1286 void DoEnableVertexAttribArray(GLuint index);
1287
[email protected]882ba1e22012-03-08 19:02:531288 // Wrapper for glFinish.
1289 void DoFinish();
1290
1291 // Wrapper for glFlush.
1292 void DoFlush();
1293
[email protected]36cef8ce2010-03-16 07:34:451294 // Wrapper for glFramebufferRenderbufffer.
1295 void DoFramebufferRenderbuffer(
1296 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1297 GLuint renderbuffer);
1298
1299 // Wrapper for glFramebufferTexture2D.
1300 void DoFramebufferTexture2D(
1301 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1302 GLint level);
1303
[email protected]7d3c36e2013-07-12 14:13:161304 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1305 void DoFramebufferTexture2DMultisample(
1306 GLenum target, GLenum attachment, GLenum textarget,
1307 GLuint texture, GLint level, GLsizei samples);
1308
1309 // Common implementation for both DoFramebufferTexture2D wrappers.
1310 void DoFramebufferTexture2DCommon(const char* name,
1311 GLenum target, GLenum attachment, GLenum textarget,
1312 GLuint texture, GLint level, GLsizei samples);
1313
[email protected]a93bb842010-02-16 23:03:471314 // Wrapper for glGenerateMipmap
1315 void DoGenerateMipmap(GLenum target);
1316
[email protected]7d3c36e2013-07-12 14:13:161317 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1318 // to account for different pname values defined in different extension
1319 // variants.
1320 GLenum AdjustGetPname(GLenum pname);
1321
[email protected]b273e432010-04-12 17:23:581322 // Wrapper for DoGetBooleanv.
1323 void DoGetBooleanv(GLenum pname, GLboolean* params);
1324
1325 // Wrapper for DoGetFloatv.
1326 void DoGetFloatv(GLenum pname, GLfloat* params);
1327
[email protected]36cef8ce2010-03-16 07:34:451328 // Wrapper for glGetFramebufferAttachmentParameteriv.
1329 void DoGetFramebufferAttachmentParameteriv(
1330 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1331
[email protected]a0c3e972010-04-21 00:49:131332 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581333 void DoGetIntegerv(GLenum pname, GLint* params);
1334
[email protected]29a9eb52010-04-13 09:04:231335 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061336 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231337 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1338
[email protected]17cfbe0e2013-03-07 01:26:081339 // Wrapper for glGetBufferParameteriv.
1340 void DoGetBufferParameteriv(
1341 GLenum target, GLenum pname, GLint* params);
1342
[email protected]a0c3e972010-04-21 00:49:131343 // Wrapper for glGetProgramiv.
1344 void DoGetProgramiv(
1345 GLuint program_id, GLenum pname, GLint* params);
1346
[email protected]36cef8ce2010-03-16 07:34:451347 // Wrapper for glRenderbufferParameteriv.
1348 void DoGetRenderbufferParameteriv(
1349 GLenum target, GLenum pname, GLint* params);
1350
[email protected]ddd968b82010-03-02 00:44:291351 // Wrapper for glGetShaderiv
1352 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1353
[email protected]4c6f5462014-03-05 00:26:561354 // Wrappers for glGetTexParameter.
1355 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1356 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1357 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1358
[email protected]b1122982010-05-17 23:04:241359 // Wrappers for glGetVertexAttrib.
1360 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1361 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1362
[email protected]1958e0e2010-04-22 05:17:151363 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241364 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151365 bool DoIsBuffer(GLuint client_id);
1366 bool DoIsFramebuffer(GLuint client_id);
1367 bool DoIsProgram(GLuint client_id);
1368 bool DoIsRenderbuffer(GLuint client_id);
1369 bool DoIsShader(GLuint client_id);
1370 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461371 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151372
[email protected]07f54fcc2009-12-22 02:46:301373 // Wrapper for glLinkProgram
1374 void DoLinkProgram(GLuint program);
1375
[email protected]36cef8ce2010-03-16 07:34:451376 // Wrapper for glRenderbufferStorage.
1377 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031378 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451379
[email protected]49cabed2013-11-13 18:15:181380 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1381 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301382 GLenum target, GLsizei samples, GLenum internalformat,
1383 GLsizei width, GLsizei height);
1384
[email protected]49cabed2013-11-13 18:15:181385 // Handler for glRenderbufferStorageMultisampleEXT
1386 // (multisampled_render_to_texture).
1387 void DoRenderbufferStorageMultisampleEXT(
1388 GLenum target, GLsizei samples, GLenum internalformat,
1389 GLsizei width, GLsizei height);
1390
1391 // Common validation for multisample extensions.
1392 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1393 GLenum internalformat,
1394 GLsizei width,
1395 GLsizei height);
1396
[email protected]4a4c18b2013-09-13 22:50:101397 // Verifies that the currently bound multisample renderbuffer is valid
1398 // Very slow! Only done on platforms with driver bugs that return invalid
1399 // buffers under memory pressure
1400 bool VerifyMultisampleRenderbufferIntegrity(
1401 GLuint renderbuffer, GLenum format);
1402
[email protected]b273e432010-04-12 17:23:581403 // Wrapper for glReleaseShaderCompiler.
1404 void DoReleaseShaderCompiler() { }
1405
[email protected]3916c97e2010-02-25 03:20:501406 // Wrappers for glTexParameter functions.
1407 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1408 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1409 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1410 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1411
1412 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1413 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121414 void DoUniform1i(GLint fake_location, GLint v0);
1415 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1416 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1417 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1418 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101419
1420 // Wrappers for glUniformfv because some drivers don't correctly accept
1421 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121422 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1423 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1424 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1425 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501426
[email protected]43c2f1f2011-03-25 18:35:361427 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121428 GLint fake_location, GLsizei count, GLboolean transpose,
1429 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361430 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121431 GLint fake_location, GLsizei count, GLboolean transpose,
1432 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361433 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121434 GLint fake_location, GLsizei count, GLboolean transpose,
1435 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361436
[email protected]af6380962012-11-29 23:24:131437 bool SetVertexAttribValue(
1438 const char* function_name, GLuint index, const GLfloat* value);
1439
[email protected]b1122982010-05-17 23:04:241440 // Wrappers for glVertexAttrib??
1441 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1442 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1443 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1444 void DoVertexAttrib4f(
1445 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1446 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1447 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1448 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1449 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1450
[email protected]43410e92012-04-20 17:06:281451 // Wrapper for glViewport
1452 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1453
[email protected]07f54fcc2009-12-22 02:46:301454 // Wrapper for glUseProgram
1455 void DoUseProgram(GLuint program);
1456
[email protected]ae51d192010-04-27 00:48:031457 // Wrapper for glValidateProgram.
1458 void DoValidateProgram(GLuint program_client_id);
1459
[email protected]d2a0e1a2012-08-12 02:25:011460 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1461 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1462 void DoPopGroupMarkerEXT(void);
1463
[email protected]4e8a5b122010-05-08 22:00:101464 // Gets the number of values that will be returned by glGetXXX. Returns
1465 // false if pname is unknown.
1466 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1467
[email protected]07f54fcc2009-12-22 02:46:301468 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431469 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101470 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1471 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301472
[email protected]c13e1da62011-09-09 21:48:301473 // Returns true if successful, simulated will be true if attrib0 was
1474 // simulated.
[email protected]c6aef902012-02-14 03:31:421475 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431476 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231477 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241478
[email protected]91c94eb2013-10-22 10:32:541479 // If an image is bound to texture, this will call Will/DidUseTexImage
1480 // if needed.
1481 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1482 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1483
1484 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111485 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541486 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501487
[email protected]8fbedc02010-11-18 18:43:401488 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421489 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431490 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421491 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401492 void RestoreStateForSimulatedFixedAttribs();
1493
[email protected]c6aef902012-02-14 03:31:421494 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101495 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421496 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431497 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421498 bool instanced, GLenum mode, GLint first, GLsizei count,
1499 GLsizei primcount);
1500 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431501 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421502 bool instanced, GLenum mode, GLsizei count, GLenum type,
1503 int32 offset, GLsizei primcount);
1504
[email protected]61eeb33f2011-07-26 15:30:311505 GLenum GetBindTargetForSamplerType(GLenum type) {
1506 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461507 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1508 switch (type) {
1509 case GL_SAMPLER_2D:
1510 return GL_TEXTURE_2D;
1511 case GL_SAMPLER_CUBE:
1512 return GL_TEXTURE_CUBE_MAP;
1513 case GL_SAMPLER_EXTERNAL_OES:
1514 return GL_TEXTURE_EXTERNAL_OES;
1515 case GL_SAMPLER_2D_RECT_ARB:
1516 return GL_TEXTURE_RECTANGLE_ARB;
1517 }
1518
1519 NOTREACHED();
1520 return 0;
[email protected]61eeb33f2011-07-26 15:30:311521 }
1522
[email protected]8e3e0662010-08-23 18:46:301523 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061524 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1525 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301526 switch (target) {
1527 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451528 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341529 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301530 break;
[email protected]ebfb73c2012-08-15 02:37:451531 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341532 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301533 break;
1534 default:
1535 NOTREACHED();
1536 break;
1537 }
[email protected]4d8f0dd2013-03-09 14:37:061538 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301539 }
1540
[email protected]ed9f9cd2013-02-27 21:12:351541 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201542 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271543 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201544 switch (target) {
1545 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111546 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201547 break;
1548 default:
1549 NOTREACHED();
1550 break;
1551 }
[email protected]ee2a79c32013-03-10 03:50:271552 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201553 }
1554
[email protected]f7b85372010-02-03 01:11:371555 // Validates the program and location for a glGetUniform call and returns
1556 // a SizeResult setup to receive the result. Returns true if glGetUniform
1557 // should be called.
1558 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121559 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371560 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121561 error::Error* error, GLint* real_location, GLuint* service_id,
1562 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371563
jbauman7a059312014-10-16 19:30:541564 void MaybeExitOnContextLost();
dcheng1f4d1d72014-10-21 16:21:581565 bool WasContextLost() override;
1566 bool WasContextLostByRobustnessExtension() override;
1567 void LoseContext(uint32 reset_status) override;
[email protected]38d139d2011-07-14 00:38:431568
[email protected]e51bdf32011-11-23 22:21:461569#if defined(OS_MACOSX)
1570 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1571#endif
1572
[email protected]ad84a3a2012-06-08 21:42:431573 bool ValidateCompressedTexDimensions(
1574 const char* function_name,
1575 GLint level, GLsizei width, GLsizei height, GLenum format);
1576 bool ValidateCompressedTexFuncData(
1577 const char* function_name,
1578 GLsizei width, GLsizei height, GLenum format, size_t size);
1579 bool ValidateCompressedTexSubDimensions(
1580 const char* function_name,
1581 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1582 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351583 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431584
[email protected]ab09b612013-03-11 22:11:511585 void RenderWarning(const char* filename, int line, const std::string& msg);
1586 void PerformanceWarning(
1587 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011588
[email protected]62e155e2012-10-23 22:43:151589 const FeatureInfo::FeatureFlags& features() const {
1590 return feature_info_->feature_flags();
1591 }
1592
1593 const FeatureInfo::Workarounds& workarounds() const {
1594 return feature_info_->workarounds();
1595 }
1596
[email protected]a7266a92012-06-28 02:11:081597 bool ShouldDeferDraws() {
1598 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341599 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081600 surface_->DeferDraws();
1601 }
1602
[email protected]09e17272012-11-30 10:30:441603 bool ShouldDeferReads() {
1604 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341605 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441606 surface_->DeferDraws();
1607 }
1608
[email protected]c76fe672013-12-13 23:30:221609 error::Error WillAccessBoundFramebufferForDraw() {
1610 if (ShouldDeferDraws())
1611 return error::kDeferCommandUntilLater;
1612 if (!offscreen_target_frame_buffer_.get() &&
1613 !framebuffer_state_.bound_draw_framebuffer.get() &&
1614 !surface_->SetBackbufferAllocation(true))
1615 return error::kLostContext;
1616 return error::kNoError;
1617 }
1618
1619 error::Error WillAccessBoundFramebufferForRead() {
1620 if (ShouldDeferReads())
1621 return error::kDeferCommandUntilLater;
1622 if (!offscreen_target_frame_buffer_.get() &&
1623 !framebuffer_state_.bound_read_framebuffer.get() &&
1624 !surface_->SetBackbufferAllocation(true))
1625 return error::kLostContext;
1626 return error::kNoError;
1627 }
1628
vmiura8266ca72014-09-09 21:37:001629 // Set remaining commands to process to 0 to force DoCommands to return
1630 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1631 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1632
[email protected]5a36dc132013-07-23 23:17:551633 void ProcessPendingReadPixels();
1634 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1635
[email protected]96449d2c2009-11-25 00:01:321636 // Generate a member function prototype for each command in an automated and
1637 // typesafe way.
vmiuracd108592014-09-08 14:36:341638#define GLES2_CMD_OP(name) \
1639 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321640
1641 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1642
1643 #undef GLES2_CMD_OP
1644
[email protected]2f2d7042010-04-14 21:45:581645 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381646 scoped_refptr<gfx::GLSurface> surface_;
1647 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021648
[email protected]a3ded6d2010-10-19 06:44:391649 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351650 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391651
[email protected]1d82e822013-04-10 21:32:321652 DebugMarkerManager debug_marker_manager_;
1653 Logger logger_;
1654
[email protected]e259eb412012-10-13 05:47:241655 // All the state for this context.
1656 ContextState state_;
1657
[email protected]34ff8b0c2010-10-01 20:06:021658 // Current width and height of the offscreen frame buffer.
1659 gfx::Size offscreen_size_;
1660
[email protected]96449d2c2009-11-25 00:01:321661 // Util to help with GL.
1662 GLES2Util util_;
1663
[email protected]43410e92012-04-20 17:06:281664 // unpack flip y as last set by glPixelStorei
1665 bool unpack_flip_y_;
1666
[email protected]6c75c712012-06-19 15:43:171667 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281668 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171669 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281670
[email protected]b1122982010-05-17 23:04:241671 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1672 GLuint attrib_0_buffer_id_;
1673
1674 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131675 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241676
[email protected]fc753442011-02-04 19:49:491677 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1678 bool attrib_0_buffer_matches_value_;
1679
[email protected]b1122982010-05-17 23:04:241680 // The size of attrib 0.
1681 GLsizei attrib_0_size_;
1682
[email protected]8fbedc02010-11-18 18:43:401683 // The buffer used to simulate GL_FIXED attribs.
1684 GLuint fixed_attrib_buffer_id_;
1685
1686 // The size of fiixed attrib buffer.
1687 GLsizei fixed_attrib_buffer_size_;
1688
[email protected]b9363b22010-06-09 22:06:151689 // The offscreen frame buffer that the client renders to. With EGL, the
1690 // depth and stencil buffers are separate. With regular GL there is a single
1691 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1692 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351693 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1694 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1695 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1696 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1697 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021698 GLenum offscreen_target_color_format_;
1699 GLenum offscreen_target_depth_format_;
1700 GLenum offscreen_target_stencil_format_;
1701 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561702 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351703
[email protected]de26b3c2011-08-03 21:54:271704 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351705 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1706 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491707 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351708 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271709
1710 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351711 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1712 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051713 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351714
[email protected]882ba1e22012-03-08 19:02:531715 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531716
[email protected]944b62f32012-09-27 02:20:461717 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1718
[email protected]b63f1d62014-07-18 15:40:591719 scoped_ptr<ImageManager> image_manager_;
1720
[email protected]729c0b42013-05-26 02:05:071721 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001722
[email protected]840a7e462013-02-27 01:29:511723 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481724
[email protected]e3932abb2013-03-13 00:01:371725 ShaderCacheCallback shader_cache_callback_;
1726
[email protected]85a4ac22013-05-31 01:58:471727 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421728
[email protected]32fe9aa2011-01-21 23:47:131729 // The format of the back buffer_
1730 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461731 bool back_buffer_has_depth_;
1732 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131733
achaulkcf5316f2014-09-26 19:28:421734 bool surfaceless_;
1735
[email protected]60f22d32012-12-12 00:31:581736 // Backbuffer attachments that are currently undefined.
1737 uint32 backbuffer_needs_clear_bits_;
1738
[email protected]a6a09f852014-05-23 13:05:031739 // The current decoder error communicates the decoder error through command
1740 // processing functions that do not return the error value. Should be set only
1741 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561742 error::Error current_decoder_error_;
1743
[email protected]b1d2dcb2010-05-17 19:24:181744 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041745 scoped_refptr<ShaderTranslator> vertex_translator_;
1746 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181747
[email protected]e82fb792011-09-22 00:33:291748 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411749
[email protected]915a59a12010-09-30 21:29:111750 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051751 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351752 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051753
[email protected]65225772011-05-12 21:10:241754 int frame_number_;
1755
vmiura8266ca72014-09-09 21:37:001756 // Number of commands remaining to be processed in DoCommands().
1757 int commands_to_process_;
1758
[email protected]706b69f2012-07-27 04:59:301759 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431760 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221761 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431762 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431763
[email protected]f0d74742011-10-03 16:31:041764 // These flags are used to override the state of the shared feature_info_
1765 // member. Because the same FeatureInfo instance may be shared among many
1766 // contexts, the assumptions on the availablity of extensions in WebGL
1767 // contexts may be broken. These flags override the shared state to preserve
1768 // WebGL semantics.
1769 bool force_webgl_glsl_validation_;
1770 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491771 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131772 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061773 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041774
[email protected]062c38b2012-01-18 03:25:101775 bool compile_shader_always_succeeds_;
1776
[email protected]828a3932014-04-02 14:43:131777 // An optional behaviour to lose the context and group when OOM.
1778 bool lose_context_when_out_of_memory_;
1779
[email protected]cae20172012-12-07 00:06:191780 // Log extra info.
1781 bool service_logging_;
1782
[email protected]e51bdf32011-11-23 22:21:461783#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531784 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461785 TextureToIOSurfaceMap texture_to_io_surface_map_;
1786#endif
1787
[email protected]43410e92012-04-20 17:06:281788 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1789
[email protected]1868a342012-11-07 15:56:021790 // Cached values of the currently assigned viewport dimensions.
1791 GLsizei viewport_max_width_;
1792 GLsizei viewport_max_height_;
1793
[email protected]63b465922012-09-06 02:04:521794 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521795 base::TimeDelta total_processing_commands_time_;
1796
[email protected]c986af502013-08-14 01:04:441797 // States related to each manager.
1798 DecoderTextureState texture_state_;
1799 DecoderFramebufferState framebuffer_state_;
1800
[email protected]fb97b662013-02-20 23:02:141801 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131802 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241803 const unsigned char* cb_command_trace_category_;
[email protected]cac16542014-01-15 17:53:511804 int gpu_trace_level_;
1805 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241806 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111807
[email protected]5a36dc132013-07-23 23:17:551808 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1809
[email protected]4a4c18b2013-09-13 22:50:101810 // Used to validate multisample renderbuffers if needed
1811 GLuint validation_texture_;
1812 GLuint validation_fbo_multisample_;
1813 GLuint validation_fbo_;
1814
vmiuracd108592014-09-08 14:36:341815 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1816 uint32 immediate_data_size,
1817 const void* data);
1818
1819 // A struct to hold info about each command.
1820 struct CommandInfo {
1821 CmdHandler cmd_handler;
1822 uint8 arg_flags; // How to handle the arguments for this command
1823 uint8 cmd_flags; // How to handle this command
1824 uint16 arg_count; // How many arguments are expected for this command.
1825 };
1826
1827 // A table of CommandInfo for all the commands.
1828 static const CommandInfo command_info[kNumCommands - kStartPoint];
1829
[email protected]96449d2c2009-11-25 00:01:321830 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1831};
1832
vmiuracd108592014-09-08 14:36:341833const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1834#define GLES2_CMD_OP(name) \
1835 { \
1836 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1837 cmds::name::cmd_flags, \
1838 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1839 } \
1840 , /* NOLINT */
1841 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1842#undef GLES2_CMD_OP
1843};
1844
[email protected]ab09b612013-03-11 22:11:511845ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301846 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511847 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301848 error_state_(error_state) {
1849 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351850}
1851
1852ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301853 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351854}
1855
[email protected]2b10c02d2014-01-29 16:43:021856static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361857 TextureUnit& info = state->texture_units[0];
1858 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021859 scoped_refptr<TextureRef> texture_ref;
1860 switch (target) {
1861 case GL_TEXTURE_2D:
1862 texture_ref = info.bound_texture_2d;
1863 break;
1864 case GL_TEXTURE_CUBE_MAP:
1865 texture_ref = info.bound_texture_cube_map;
1866 break;
1867 case GL_TEXTURE_EXTERNAL_OES:
1868 texture_ref = info.bound_texture_external_oes;
1869 break;
1870 case GL_TEXTURE_RECTANGLE_ARB:
1871 texture_ref = info.bound_texture_rectangle_arb;
1872 break;
1873 default:
1874 NOTREACHED();
1875 break;
1876 }
1877 if (texture_ref.get()) {
1878 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361879 } else {
1880 last_id = 0;
1881 }
1882
[email protected]2b10c02d2014-01-29 16:43:021883 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361884 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1885}
1886
[email protected]2b10c02d2014-01-29 16:43:021887ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1888 GLuint id,
1889 GLenum target)
1890 : state_(state),
1891 target_(target) {
[email protected]ab09b612013-03-11 22:11:511892 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021893 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351894
1895 // TODO(apatrick): Check if there are any other states that need to be reset
1896 // before binding a new texture.
1897 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021898 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351899}
1900
[email protected]2b10c02d2014-01-29 16:43:021901ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511902 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021903 "ScopedTextureBinder::dtor", state_->GetErrorState());
1904 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351905}
1906
[email protected]18e785a2013-10-09 03:29:411907ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351908 GLuint id)
[email protected]18e785a2013-10-09 03:29:411909 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511910 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411911 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351912 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1913}
1914
1915ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511916 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411917 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1918 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351919}
1920
1921ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1922 GLuint id)
1923 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511924 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301925 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351926 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451927 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351928}
1929
1930ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511931 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301932 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301933 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351934}
1935
[email protected]34ff8b0c2010-10-01 20:06:021936ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271937 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521938 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341939 resolve_and_bind_ = (
1940 decoder_->offscreen_target_frame_buffer_.get() &&
1941 decoder_->IsOffscreenBufferMultisampled() &&
1942 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1943 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021944 if (!resolve_and_bind_)
1945 return;
1946
[email protected]ab09b612013-03-11 22:11:511947 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301948 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021949 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1950 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271951 GLuint targetid;
1952 if (internal) {
1953 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1954 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351955 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271956 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351957 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:361958 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:271959 decoder_->offscreen_resolved_color_texture_->Create();
1960
1961 DCHECK(decoder_->offscreen_saved_color_format_);
1962 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091963 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1964 false);
[email protected]de26b3c2011-08-03 21:54:271965 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1966 decoder_->offscreen_resolved_color_texture_.get());
1967 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1968 GL_FRAMEBUFFER_COMPLETE) {
1969 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1970 << "because offscreen resolved FBO was incomplete.";
1971 return;
1972 }
1973 }
1974 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1975 } else {
1976 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1977 }
1978 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021979 const int width = decoder_->offscreen_size_.width();
1980 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:451981 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:181982 decoder->BlitFramebufferHelper(0,
1983 0,
1984 width,
1985 height,
1986 0,
1987 0,
1988 width,
1989 height,
1990 GL_COLOR_BUFFER_BIT,
1991 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:271992 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021993}
1994
1995ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1996 if (!resolve_and_bind_)
1997 return;
1998
[email protected]ab09b612013-03-11 22:11:511999 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302000 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022001 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222002 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452003 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182004 }
[email protected]34ff8b0c2010-10-01 20:06:022005}
2006
[email protected]ce296892013-10-24 22:04:362007BackTexture::BackTexture(
2008 MemoryTracker* memory_tracker,
2009 ContextState* state)
2010 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2011 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482012 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252013 id_(0) {
[email protected]6217d392010-03-25 22:08:352014}
2015
[email protected]ed9f9cd2013-02-27 21:12:352016BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352017 // This does not destroy the render texture because that would require that
2018 // the associated GL context was current. Just check that it was explicitly
2019 // destroyed.
2020 DCHECK_EQ(id_, 0u);
2021}
2022
[email protected]ed9f9cd2013-02-27 21:12:352023void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302024 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362025 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352026 Destroy();
2027 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022028 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262029 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2030 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582031 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2032 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162033
2034 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2035 // never called on an offscreen context, no data will ever be uploaded to the
2036 // saved offscreen color texture (it is deferred until to when SwapBuffers
2037 // is called). My idea is that some nvidia drivers might have a bug where
2038 // deleting a texture that has never been populated might cause a
2039 // crash.
2040 glTexImage2D(
2041 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482042
2043 bytes_allocated_ = 16u * 16u * 4u;
2044 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352045}
2046
[email protected]ed9f9cd2013-02-27 21:12:352047bool BackTexture::AllocateStorage(
2048 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352049 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302050 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362051 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022052 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092053 uint32 image_size = 0;
2054 GLES2Util::ComputeImageDataSizes(
2055 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
2056 NULL, NULL);
2057
[email protected]7989c9e2013-01-23 06:39:262058 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2059 return false;
2060 }
2061
[email protected]40d90a22013-04-09 03:39:552062 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092063 if (zero) {
2064 zero_data.reset(new char[image_size]);
2065 memset(zero_data.get(), 0, image_size);
2066 }
[email protected]6217d392010-03-25 22:08:352067
[email protected]8f1d2aa2013-05-10 23:45:382068 glTexImage2D(GL_TEXTURE_2D,
2069 0, // mip level
2070 format,
2071 size.width(),
2072 size.height(),
2073 0, // border
2074 format,
2075 GL_UNSIGNED_BYTE,
2076 zero_data.get());
[email protected]6217d392010-03-25 22:08:352077
[email protected]d37231fa2010-04-09 21:16:022078 size_ = size;
2079
[email protected]1078f912011-12-23 13:12:142080 bool success = glGetError() == GL_NO_ERROR;
2081 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482082 memory_tracker_.TrackMemFree(bytes_allocated_);
2083 bytes_allocated_ = image_size;
2084 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142085 }
2086 return success;
[email protected]6217d392010-03-25 22:08:352087}
2088
[email protected]ed9f9cd2013-02-27 21:12:352089void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352090 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302091 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362092 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022093 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352094 glCopyTexImage2D(GL_TEXTURE_2D,
2095 0, // level
[email protected]3a4d0c52011-06-29 23:11:582096 format,
[email protected]6217d392010-03-25 22:08:352097 0, 0,
2098 size.width(),
2099 size.height(),
2100 0); // border
2101}
2102
[email protected]ed9f9cd2013-02-27 21:12:352103void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352104 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302105 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362106 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352107 glDeleteTextures(1, &id_);
2108 id_ = 0;
2109 }
[email protected]68e81a4a62012-12-13 01:16:482110 memory_tracker_.TrackMemFree(bytes_allocated_);
2111 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352112}
2113
[email protected]ed9f9cd2013-02-27 21:12:352114void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052115 id_ = 0;
2116}
2117
[email protected]d5a28e452013-10-10 01:01:402118BackRenderbuffer::BackRenderbuffer(
2119 RenderbufferManager* renderbuffer_manager,
2120 MemoryTracker* memory_tracker,
2121 ContextState* state)
2122 : renderbuffer_manager_(renderbuffer_manager),
2123 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2124 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482125 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252126 id_(0) {
[email protected]6217d392010-03-25 22:08:352127}
2128
[email protected]ed9f9cd2013-02-27 21:12:352129BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352130 // This does not destroy the render buffer because that would require that
2131 // the associated GL context was current. Just check that it was explicitly
2132 // destroyed.
2133 DCHECK_EQ(id_, 0u);
2134}
2135
[email protected]ed9f9cd2013-02-27 21:12:352136void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302137 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402138 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352139 Destroy();
2140 glGenRenderbuffersEXT(1, &id_);
2141}
2142
[email protected]f42f05b2013-11-15 21:46:182143bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2144 const gfx::Size& size,
2145 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352146 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512147 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402148 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2149 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262150
2151 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402152 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232153 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262154 return false;
2155 }
2156
2157 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2158 return false;
2159 }
2160
[email protected]34ff8b0c2010-10-01 20:06:022161 if (samples <= 1) {
2162 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2163 format,
2164 size.width(),
2165 size.height());
2166 } else {
[email protected]f42f05b2013-11-15 21:46:182167 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2168 GL_RENDERBUFFER,
2169 samples,
2170 format,
2171 size.width(),
2172 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022173 }
[email protected]1078f912011-12-23 13:12:142174 bool success = glGetError() == GL_NO_ERROR;
2175 if (success) {
[email protected]d5a28e452013-10-10 01:01:402176 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482177 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262178 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402179 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482180 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142181 }
2182 return success;
[email protected]6217d392010-03-25 22:08:352183}
2184
[email protected]ed9f9cd2013-02-27 21:12:352185void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352186 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302187 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402188 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352189 glDeleteRenderbuffersEXT(1, &id_);
2190 id_ = 0;
2191 }
[email protected]68e81a4a62012-12-13 01:16:482192 memory_tracker_.TrackMemFree(bytes_allocated_);
2193 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352194}
2195
[email protected]ed9f9cd2013-02-27 21:12:352196void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052197 id_ = 0;
2198}
2199
[email protected]ed9f9cd2013-02-27 21:12:352200BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352201 : decoder_(decoder),
2202 id_(0) {
2203}
2204
[email protected]ed9f9cd2013-02-27 21:12:352205BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352206 // This does not destroy the frame buffer because that would require that
2207 // the associated GL context was current. Just check that it was explicitly
2208 // destroyed.
2209 DCHECK_EQ(id_, 0u);
2210}
2211
[email protected]ed9f9cd2013-02-27 21:12:352212void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302213 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2214 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352215 Destroy();
2216 glGenFramebuffersEXT(1, &id_);
2217}
2218
[email protected]ed9f9cd2013-02-27 21:12:352219void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352220 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512221 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302222 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352223 ScopedFrameBufferBinder binder(decoder_, id_);
2224 GLuint attach_id = texture ? texture->id() : 0;
2225 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2226 GL_COLOR_ATTACHMENT0,
2227 GL_TEXTURE_2D,
2228 attach_id,
2229 0);
2230}
2231
[email protected]ed9f9cd2013-02-27 21:12:352232void BackFramebuffer::AttachRenderBuffer(GLenum target,
2233 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352234 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512235 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302236 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352237 ScopedFrameBufferBinder binder(decoder_, id_);
2238 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2239 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152240 target,
[email protected]6217d392010-03-25 22:08:352241 GL_RENDERBUFFER,
2242 attach_id);
2243}
2244
[email protected]ed9f9cd2013-02-27 21:12:352245void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352246 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302247 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2248 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352249 glDeleteFramebuffersEXT(1, &id_);
2250 id_ = 0;
2251 }
2252}
2253
[email protected]ed9f9cd2013-02-27 21:12:352254void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052255 id_ = 0;
2256}
2257
[email protected]ed9f9cd2013-02-27 21:12:352258GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352259 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302260 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2261 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352262 ScopedFrameBufferBinder binder(decoder_, id_);
2263 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2264}
2265
[email protected]aa7666122011-09-02 19:45:522266GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2267 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322268}
2269
[email protected]aa7666122011-09-02 19:45:522270GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392271 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572272 group_(group),
[email protected]1d82e822013-04-10 21:32:322273 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132274 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282275 unpack_flip_y_(false),
2276 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172277 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242278 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492279 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242280 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402281 fixed_attrib_buffer_id_(0),
2282 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022283 offscreen_target_color_format_(0),
2284 offscreen_target_depth_format_(0),
2285 offscreen_target_stencil_format_(0),
2286 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562287 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052288 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132289 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462290 back_buffer_has_depth_(false),
2291 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422292 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582293 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562294 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052295 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112296 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002297 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432298 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302299 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512300 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222301 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432302 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042303 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102304 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492305 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132306 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062307 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282308 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132309 lose_context_when_out_of_memory_(false),
[email protected]cae20172012-12-07 00:06:192310 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2311 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022312 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102313 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002314 texture_state_(group_->feature_info()
2315 ->workarounds()
2316 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242317 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2318 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
2319 gpu_trace_level_(2),
2320 gpu_trace_commands_(false),
2321 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102322 validation_texture_(0),
2323 validation_fbo_multisample_(0),
2324 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572325 DCHECK(group);
2326
[email protected]b1122982010-05-17 23:04:242327 attrib_0_value_.v[0] = 0.0f;
2328 attrib_0_value_.v[1] = 0.0f;
2329 attrib_0_value_.v[2] = 0.0f;
2330 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152331
[email protected]c2f8c8402010-12-06 18:07:242332 // The shader translator is used for WebGL even when running on EGL
2333 // because additional restrictions are needed (like only enabling
2334 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562335 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2336 // the empty string to CompileShader and this is not a valid shader.
2337 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002338 CommandLine::ForCurrentProcess()->HasSwitch(
2339 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152340 use_shader_translator_ = false;
2341 }
[email protected]96449d2c2009-11-25 00:01:322342}
2343
[email protected]80eb6b52012-01-19 00:14:412344GLES2DecoderImpl::~GLES2DecoderImpl() {
2345}
2346
[email protected]c410da802011-03-14 19:17:412347bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382348 const scoped_refptr<gfx::GLSurface>& surface,
2349 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232350 bool offscreen,
[email protected]c410da802011-03-14 19:17:412351 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292352 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242353 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322354 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382355 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302356 DCHECK(!context_.get());
2357
jbaumana7604692014-10-17 02:00:392358 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422359
[email protected]55e136f2013-04-03 18:50:062360 set_initialized();
[email protected]b4af07d2014-08-20 00:11:572361 gpu_tracer_.reset(new GPUTracer(this));
[email protected]8f9b8dd2013-09-12 18:05:132362 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142363
[email protected]e844ae22012-01-14 03:36:262364 if (CommandLine::ForCurrentProcess()->HasSwitch(
2365 switches::kEnableGPUDebugging)) {
2366 set_debug(true);
2367 }
2368
[email protected]39ba4f02012-03-26 01:16:002369 if (CommandLine::ForCurrentProcess()->HasSwitch(
2370 switches::kEnableGPUCommandLogging)) {
2371 set_log_commands(true);
2372 }
2373
[email protected]062c38b2012-01-18 03:25:102374 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2375 switches::kCompileShaderAlwaysSucceeds);
2376
[email protected]f62a5ab2011-05-23 20:34:152377
[email protected]63c9b052012-05-17 18:27:382378 // Take ownership of the context and surface. The surface can be replaced with
2379 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382380 context_ = context;
[email protected]63c9b052012-05-17 18:27:382381 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182382
[email protected]65f7efe2013-11-28 03:11:472383 ContextCreationAttribHelper attrib_parser;
2384 if (!attrib_parser.Parse(attribs))
2385 return false;
2386
[email protected]828a3932014-04-02 14:43:132387 // Save the loseContextWhenOutOfMemory context creation attribute.
2388 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402389 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132390
[email protected]65f7efe2013-11-28 03:11:472391 // If the failIfMajorPerformanceCaveat context creation attribute was true
2392 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402393 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472394 feature_info_->feature_flags().is_swiftshader) {
2395 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2396 Destroy(true);
2397 return false;
2398 }
2399
[email protected]956aec52013-09-05 15:41:192400 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222401 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392402 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422403 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382404 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032405 return false;
[email protected]a3ded6d2010-10-19 06:44:392406 }
[email protected]b64c24952012-04-19 03:20:272407 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282408
[email protected]e82fb792011-09-22 00:33:292409 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502410
[email protected]af6380962012-11-29 23:24:132411 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482412 vertex_array_manager_.reset(new VertexArrayManager());
2413
2414 GLuint default_vertex_attrib_service_id = 0;
2415 if (features().native_vertex_array_object) {
2416 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2417 glBindVertexArrayOES(default_vertex_attrib_service_id);
2418 }
2419
2420 state_.default_vertex_attrib_manager =
2421 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2422
[email protected]81f20a622014-04-18 01:54:522423 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002424 group_->max_vertex_attribs(),
2425 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462426
[email protected]81f20a622014-04-18 01:54:522427 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572428 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322429
[email protected]7cd76fd2013-06-02 21:11:112430 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532431
[email protected]b63f1d62014-07-18 15:40:592432 image_manager_.reset(new ImageManager);
2433
[email protected]302ce6d2011-07-07 23:28:112434 util_.set_num_compressed_texture_formats(
2435 validators_->compressed_texture_format.GetValues().size());
2436
[email protected]1071e572011-02-09 20:00:122437 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2438 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2439 // OpenGL ES 2.0 does not have this issue.
2440 glEnableVertexAttribArray(0);
2441 }
[email protected]b1122982010-05-17 23:04:242442 glGenBuffersARB(1, &attrib_0_buffer_id_);
2443 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2444 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2445 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402446 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082447
[email protected]1868a342012-11-07 15:56:022448 state_.texture_units.resize(group_->max_texture_units());
2449 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492450 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312451 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492452 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152453 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492454 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072455 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492456 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572457 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312458 }
[email protected]62e155e2012-10-23 22:43:152459 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492460 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072461 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492462 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572463 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462464 }
[email protected]370eaf12013-05-18 09:19:492465 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2466 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572467 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492468 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2469 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572470 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152471 }
[email protected]00f893d2010-08-24 18:55:492472 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502473 CHECK_GL_ERROR();
2474
[email protected]069944672012-04-25 20:52:232475 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402476 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542477 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022478 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432479 // max_sample_count must be initialized to a sane value. If
2480 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2481 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022482 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402483 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022484 max_sample_count);
2485 } else {
2486 offscreen_target_samples_ = 1;
2487 }
[email protected]845c4e32014-08-13 11:50:402488 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022489
2490 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2491 const bool rgb8_supported =
2492 context_->HasExtension("GL_OES_rgb8_rgba8");
2493 // The only available default render buffer formats in GLES2 have very
2494 // little precision. Don't enable multisampling unless 8-bit render
2495 // buffer formats are available--instead fall back to 8-bit textures.
2496 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402497 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022498 GL_RGBA8 : GL_RGB8;
2499 } else {
2500 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402501 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022502 GL_RGBA : GL_RGB;
2503 }
2504
2505 // ANGLE only supports packed depth/stencil formats, so use it if it is
2506 // available.
2507 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182508 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272509 VLOG(1) << "GL_OES_packed_depth_stencil "
2510 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402511 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002512 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022513 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2514 offscreen_target_stencil_format_ = 0;
2515 } else {
2516 // It may be the case that this depth/stencil combination is not
2517 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402518 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022519 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402520 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022521 GL_STENCIL_INDEX8 : 0;
2522 }
2523 } else {
[email protected]845c4e32014-08-13 11:50:402524 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022525 GL_RGBA : GL_RGB;
2526
2527 // If depth is requested at all, use the packed depth stencil format if
2528 // it's available, as some desktop GL drivers don't support any non-packed
2529 // formats for depth attachments.
2530 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182531 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272532 VLOG(1) << "GL_EXT_packed_depth_stencil "
2533 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022534
[email protected]845c4e32014-08-13 11:50:402535 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002536 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022537 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2538 offscreen_target_stencil_format_ = 0;
2539 } else {
[email protected]845c4e32014-08-13 11:50:402540 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022541 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402542 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022543 GL_STENCIL_INDEX : 0;
2544 }
2545 }
2546
[email protected]845c4e32014-08-13 11:50:402547 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052548 GL_RGBA : GL_RGB;
2549
[email protected]6217d392010-03-25 22:08:352550 // Create the target frame buffer. This is the one that the client renders
2551 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352552 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352553 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022554 // Due to GLES2 format limitations, either the color texture (for
2555 // non-multisampling) or the color render buffer (for multisampling) will be
2556 // attached to the offscreen frame buffer. The render buffer has more
2557 // limited formats available to it, but the texture can't do multisampling.
2558 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402559 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2560 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022561 offscreen_target_color_render_buffer_->Create();
2562 } else {
[email protected]ce296892013-10-24 22:04:362563 offscreen_target_color_texture_.reset(new BackTexture(
2564 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022565 offscreen_target_color_texture_->Create();
2566 }
[email protected]d5a28e452013-10-10 01:01:402567 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2568 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152569 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402570 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2571 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152572 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352573
2574 // Create the saved offscreen texture. The target frame buffer is copied
2575 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352576 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022577 offscreen_saved_frame_buffer_->Create();
2578 //
[email protected]ce296892013-10-24 22:04:362579 offscreen_saved_color_texture_.reset(new BackTexture(
2580 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352581 offscreen_saved_color_texture_->Create();
2582
[email protected]6217d392010-03-25 22:08:352583 // Allocate the render buffers at their initial size and check the status
2584 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592585 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012586 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382587 Destroy(true);
[email protected]6217d392010-03-25 22:08:352588 return false;
2589 }
2590
[email protected]678a73f2012-12-19 19:22:092591 // Allocate the offscreen saved color texture.
2592 DCHECK(offscreen_saved_color_format_);
2593 offscreen_saved_color_texture_->AllocateStorage(
2594 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2595
2596 offscreen_saved_frame_buffer_->AttachRenderTexture(
2597 offscreen_saved_color_texture_.get());
2598 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2599 GL_FRAMEBUFFER_COMPLETE) {
2600 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2601 Destroy(true);
2602 return false;
2603 }
2604
[email protected]6217d392010-03-25 22:08:352605 // Bind to the new default frame buffer (the offscreen target frame buffer).
2606 // This should now be associated with ID zero.
2607 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102608 } else {
2609 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2610 // These are NOT if the back buffer has these proprorties. They are
2611 // if we want the command buffer to enforce them regardless of what
2612 // the real backbuffer is assuming the real back buffer gives us more than
2613 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2614 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2615 // can't do anything about that.
2616
achaulkcf5316f2014-09-26 19:28:422617 if (!surfaceless_) {
2618 GLint v = 0;
2619 glGetIntegerv(GL_ALPHA_BITS, &v);
2620 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2621 // the user requested RGB then RGB. If the user did not specify a
2622 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2623 back_buffer_color_format_ =
2624 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2625 glGetIntegerv(GL_DEPTH_BITS, &v);
2626 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2627 glGetIntegerv(GL_STENCIL_BITS, &v);
2628 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2629 }
[email protected]6217d392010-03-25 22:08:352630 }
2631
[email protected]76a0ee102010-04-07 21:03:042632 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2633 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2634 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372635 // mailing list archives. It also implicitly enables the desktop GL
2636 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2637 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152638 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2639 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372640 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152641 }
[email protected]de17df392010-04-23 21:09:412642
[email protected]706b69f2012-07-27 04:59:302643 has_robustness_extension_ =
2644 context->HasExtension("GL_ARB_robustness") ||
2645 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432646
[email protected]c2f8c8402010-12-06 18:07:242647 if (!InitializeShaderTranslator()) {
2648 return false;
[email protected]de17df392010-04-23 21:09:412649 }
[email protected]76a0ee102010-04-07 21:03:042650
[email protected]e259eb412012-10-13 05:47:242651 state_.viewport_width = size.width();
2652 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282653
[email protected]5904806b2012-05-08 18:10:222654 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282655 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022656 viewport_max_width_ = viewport_params[0];
2657 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282658
[email protected]88a61bf2012-10-27 13:00:422659 state_.scissor_width = state_.viewport_width;
2660 state_.scissor_height = state_.viewport_height;
2661
[email protected]11f3e702012-06-19 19:00:012662 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342663 state_.InitCapabilities(NULL);
2664 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242665 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012666
2667 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2668 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2669 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2670 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2671
achaulkcf5316f2014-09-26 19:28:422672 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002673#if defined(OS_ANDROID)
2674 // Temporary workaround for Android WebView because this clear ignores the
2675 // clip and corrupts that external UI of the App. Not calling glClear is ok
2676 // because the system already clears the buffer before each draw. Proper
2677 // fix might be setting the scissor clip properly before initialize. See
2678 // crbug.com/259023 for details.
2679 call_gl_clear = surface_->GetHandle();
2680#endif
2681 if (call_gl_clear) {
2682 // Clear the backbuffer.
2683 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2684 }
[email protected]561cc0a62013-05-07 18:34:452685
[email protected]b381ee32014-03-22 02:43:432686 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2687 if (feature_info_->workarounds()
2688 .disable_post_sub_buffers_for_onscreen_surfaces &&
2689 !surface->IsOffscreen())
2690 supports_post_sub_buffer_ = false;
2691
[email protected]62e155e2012-10-23 22:43:152692 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462693 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2694 }
[email protected]dd289a5d62012-06-30 22:05:462695
[email protected]9b753992013-04-27 02:04:412696 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2697 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242698 }
[email protected]85cb4682013-04-20 00:54:242699
[email protected]97419c02013-04-10 02:52:382700 // Only compositor contexts are known to use only the subset of GL
2701 // that can be safely migrated between the iGPU and the dGPU. Mark
2702 // those contexts as safe to forcibly transition between the GPUs.
2703 // http://crbug.com/180876, http://crbug.com/227228
2704 if (!offscreen)
2705 context_->SetSafeToForceGpuSwitch();
2706
[email protected]85a4ac22013-05-31 01:58:472707 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072708 AsyncPixelTransferManager::Create(context.get()));
2709 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592710
[email protected]91c94eb2013-10-22 10:32:542711 framebuffer_manager()->AddObserver(this);
2712
[email protected]246a70452010-03-05 21:53:502713 return true;
[email protected]96449d2c2009-11-25 00:01:322714}
2715
[email protected]6d668892013-12-04 21:37:122716Capabilities GLES2DecoderImpl::GetCapabilities() {
2717 DCHECK(initialized());
2718
2719 Capabilities caps;
2720
[email protected]6d668892013-12-04 21:37:122721 caps.egl_image_external =
2722 feature_info_->feature_flags().oes_egl_image_external;
2723 caps.texture_format_bgra8888 =
2724 feature_info_->feature_flags().ext_texture_format_bgra8888;
2725 caps.texture_format_etc1 =
2726 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202727 caps.texture_format_etc1_npot =
2728 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122729 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2730 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2731 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2732 caps.discard_framebuffer =
2733 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352734 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122735
2736#if defined(OS_MACOSX)
2737 // This is unconditionally true on mac, no need to test for it at runtime.
2738 caps.iosurface = true;
2739#endif
2740
[email protected]b381ee32014-03-22 02:43:432741 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452742 caps.image = true;
[email protected]6d668892013-12-04 21:37:122743
edfad658b2014-10-10 08:59:522744 caps.blend_minmax = feature_info_->feature_flags().ext_blend_minmax;
ed9198b422014-10-23 15:01:372745 caps.blend_equation_advanced =
2746 feature_info_->feature_flags().blend_equation_advanced;
2747 caps.blend_equation_advanced_coherent =
2748 feature_info_->feature_flags().blend_equation_advanced_coherent;
[email protected]6d668892013-12-04 21:37:122749 return caps;
2750}
2751
[email protected]302ce6d2011-07-07 23:28:112752void GLES2DecoderImpl::UpdateCapabilities() {
2753 util_.set_num_compressed_texture_formats(
2754 validators_->compressed_texture_format.GetValues().size());
2755 util_.set_num_shader_binary_formats(
2756 validators_->shader_binary_format.GetValues().size());
2757}
2758
[email protected]c2f8c8402010-12-06 18:07:242759bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442760 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2761
[email protected]c2f8c8402010-12-06 18:07:242762 if (!use_shader_translator_) {
2763 return true;
2764 }
2765 ShBuiltInResources resources;
2766 ShInitBuiltInResources(&resources);
2767 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2768 resources.MaxVertexUniformVectors =
2769 group_->max_vertex_uniform_vectors();
2770 resources.MaxVaryingVectors = group_->max_varying_vectors();
2771 resources.MaxVertexTextureImageUnits =
2772 group_->max_vertex_texture_image_units();
2773 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2774 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2775 resources.MaxFragmentUniformVectors =
2776 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492777 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242778 resources.MaxExpressionComplexity = 256;
2779 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042780
[email protected]46c86752013-05-21 05:08:392781 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212782 GLint precision = 0;
2783 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2784 range, &precision);
[email protected]448e459e2013-06-12 17:00:412785 resources.FragmentPrecisionHigh =
2786 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142787
[email protected]f0d74742011-10-03 16:31:042788 if (force_webgl_glsl_validation_) {
2789 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492790 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132791 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442792 if (!draw_buffers_explicitly_enabled_)
2793 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062794 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:462795 resources.NV_draw_buffers =
2796 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:042797 } else {
2798 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152799 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462800 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152801 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062802 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152803 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492804 resources.EXT_draw_buffers =
2805 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492806 resources.EXT_frag_depth =
2807 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062808 resources.EXT_shader_texture_lod =
2809 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:462810 resources.NV_draw_buffers =
2811 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042812 }
2813
[email protected]26b61442013-03-17 16:12:012814 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2815 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052816 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022817 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:052818 else
2819 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122820 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2821 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2822 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212823 int driver_bug_workarounds = 0;
2824 if (workarounds().needs_glsl_built_in_function_emulation)
2825 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542826 if (workarounds().init_gl_position_in_vertex_shader)
2827 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112828 if (workarounds().unfold_short_circuit_as_ternary_operation)
2829 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052830 if (workarounds().init_varyings_without_static_use)
2831 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062832 if (workarounds().unroll_for_loop_with_sampler_array_index)
2833 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:252834 if (workarounds().scalarize_vec_and_mat_constructor_args)
2835 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:272836 if (workarounds().regenerate_struct_names)
2837 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:042838
[email protected]03cef9b2014-04-03 15:58:142839 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262840 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:142841 shader_spec,
2842 &resources,
[email protected]a6739bc2013-09-07 04:45:212843 implementation_type,
2844 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042845 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242846 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382847 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242848 return false;
2849 }
[email protected]87fb6ab2012-06-13 22:28:042850
[email protected]03cef9b2014-04-03 15:58:142851 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262852 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:142853 shader_spec,
2854 &resources,
[email protected]a6739bc2013-09-07 04:45:212855 implementation_type,
2856 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042857 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242858 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382859 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242860 return false;
2861 }
2862 return true;
2863}
2864
[email protected]ae51d192010-04-27 00:48:032865bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472866 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352867 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032868 return false;
2869 }
2870 }
[email protected]40d90a22013-04-09 03:39:552871 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032872 glGenBuffersARB(n, service_ids.get());
2873 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352874 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032875 }
2876 return true;
2877}
2878
2879bool GLES2DecoderImpl::GenFramebuffersHelper(
2880 GLsizei n, const GLuint* client_ids) {
2881 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352882 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032883 return false;
2884 }
2885 }
[email protected]40d90a22013-04-09 03:39:552886 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032887 glGenFramebuffersEXT(n, service_ids.get());
2888 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352889 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032890 }
2891 return true;
2892}
2893
2894bool GLES2DecoderImpl::GenRenderbuffersHelper(
2895 GLsizei n, const GLuint* client_ids) {
2896 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352897 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032898 return false;
2899 }
2900 }
[email protected]40d90a22013-04-09 03:39:552901 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032902 glGenRenderbuffersEXT(n, service_ids.get());
2903 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352904 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032905 }
2906 return true;
2907}
2908
2909bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2910 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352911 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032912 return false;
2913 }
2914 }
[email protected]40d90a22013-04-09 03:39:552915 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032916 glGenTextures(n, service_ids.get());
2917 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352918 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032919 }
2920 return true;
2921}
2922
2923void GLES2DecoderImpl::DeleteBuffersHelper(
2924 GLsizei n, const GLuint* client_ids) {
2925 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212926 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102927 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242928 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112929 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242930 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102931 }
[email protected]ed9f9cd2013-02-27 21:12:352932 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032933 }
[email protected]a93bb842010-02-16 23:03:472934 }
[email protected]07f54fcc2009-12-22 02:46:302935}
2936
[email protected]ae51d192010-04-27 00:48:032937void GLES2DecoderImpl::DeleteFramebuffersHelper(
2938 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452939 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152940 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112941
[email protected]a25fa872010-03-25 02:57:582942 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352943 Framebuffer* framebuffer =
2944 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102945 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:342946 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2947 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442948 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452949 GLenum target = supports_separate_framebuffer_binds ?
2950 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112951 glBindFramebufferEXT(target, GetBackbufferServiceId());
2952 }
[email protected]9d3b2e12013-10-02 01:04:342953 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2954 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452955 GLenum target = supports_separate_framebuffer_binds ?
2956 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112957 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462958 }
[email protected]70d34263c2013-01-09 00:27:452959 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352960 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032961 }
[email protected]a25fa872010-03-25 02:57:582962 }
[email protected]07f54fcc2009-12-22 02:46:302963}
2964
[email protected]ae51d192010-04-27 00:48:032965void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2966 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452967 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152968 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582969 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352970 Renderbuffer* renderbuffer =
2971 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102972 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112973 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242974 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102975 }
2976 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452977 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342978 if (framebuffer_state_.bound_read_framebuffer.get()) {
2979 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112980 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102981 }
[email protected]9d3b2e12013-10-02 01:04:342982 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2983 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112984 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102985 }
2986 } else {
[email protected]9d3b2e12013-10-02 01:04:342987 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2988 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112989 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102990 }
2991 }
[email protected]c986af502013-08-14 01:04:442992 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:352993 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032994 }
[email protected]a25fa872010-03-25 02:57:582995 }
[email protected]07f54fcc2009-12-22 02:46:302996}
2997
[email protected]ae51d192010-04-27 00:48:032998void GLES2DecoderImpl::DeleteTexturesHelper(
2999 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453000 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153001 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473002 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493003 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3004 if (texture_ref) {
3005 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103006 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443007 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463008 }
[email protected]370eaf12013-05-18 09:19:493009 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023010 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493011 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103012 }
3013 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453014 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343015 if (framebuffer_state_.bound_read_framebuffer.get()) {
3016 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113017 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103018 }
[email protected]9d3b2e12013-10-02 01:04:343019 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3020 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113021 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103022 }
3023 } else {
[email protected]9d3b2e12013-10-02 01:04:343024 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3025 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113026 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103027 }
3028 }
[email protected]e51bdf32011-11-23 22:21:463029#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073030 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463031 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3032 ReleaseIOSurfaceForTexture(service_id);
3033 }
3034#endif
[email protected]ed9f9cd2013-02-27 21:12:353035 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033036 }
[email protected]a93bb842010-02-16 23:03:473037 }
[email protected]07f54fcc2009-12-22 02:46:303038}
3039
[email protected]43f28f832010-02-03 02:28:483040// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323041
[email protected]eb54a562010-01-20 21:55:183042bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343043 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383044 return false;
3045
[email protected]177d1342013-12-07 04:20:343046 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433047 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293048
jbauman7a059312014-10-16 19:30:543049 MaybeExitOnContextLost();
[email protected]e9f0ca82013-04-01 23:52:293050
[email protected]63c9b052012-05-17 18:27:383051 return false;
[email protected]38d139d2011-07-14 00:38:433052 }
3053
[email protected]69a8701e2013-03-07 21:31:093054 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093055
[email protected]9b753992013-04-27 02:04:413056 // Rebind the FBO if it was unbound by the context.
3057 if (workarounds().unbind_fbo_on_context_switch)
3058 RestoreFramebufferBindings();
3059
[email protected]c986af502013-08-14 01:04:443060 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493061
[email protected]69a8701e2013-03-07 21:31:093062 return true;
3063}
3064
3065void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553066 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323067 if (engine() && query_manager_.get())
3068 query_manager_->ProcessPendingTransferQueries();
3069
[email protected]5b3a8e02013-03-13 05:36:443070 // TODO(epenner): Is there a better place to do this?
3071 // This needs to occur before we execute any batch of commands
3072 // from the client, as the client may have recieved an async
3073 // completion while issuing those commands.
3074 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483075 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183076}
3077
[email protected]8e3e0662010-08-23 18:46:303078static void RebindCurrentFramebuffer(
3079 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063080 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243081 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063082 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463083
[email protected]a3783712012-01-20 22:18:243084 if (framebuffer_id == 0) {
3085 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303086 }
[email protected]297ca1c2011-06-20 23:08:463087
[email protected]8e3e0662010-08-23 18:46:303088 glBindFramebufferEXT(target, framebuffer_id);
3089}
3090
3091void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443092 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463093
[email protected]62e155e2012-10-23 22:43:153094 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303095 RebindCurrentFramebuffer(
3096 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343097 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243098 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303099 } else {
3100 RebindCurrentFramebuffer(
3101 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343102 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243103 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303104 RebindCurrentFramebuffer(
3105 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343106 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243107 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303108 }
[email protected]70d34263c2013-01-09 00:27:453109 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303110}
3111
[email protected]0d6bfdc2011-11-02 01:32:203112bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353113 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203114 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103115 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423116 if (surfaceless_)
3117 return false;
[email protected]60f22d32012-12-12 00:31:583118 if (backbuffer_needs_clear_bits_) {
3119 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323120 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453121 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583122 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473123 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3124 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583125 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453126 state_.SetDeviceDepthMask(GL_TRUE);
3127 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423128 bool reset_draw_buffer = false;
3129 if ((backbuffer_needs_clear_bits_ | GL_COLOR_BUFFER_BIT) != 0 &&
3130 group_->draw_buffer() == GL_NONE) {
3131 reset_draw_buffer = true;
3132 GLenum buf = GL_BACK;
3133 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3134 buf = GL_COLOR_ATTACHMENT0;
3135 glDrawBuffersARB(1, &buf);
3136 }
[email protected]60f22d32012-12-12 00:31:583137 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423138 if (reset_draw_buffer) {
3139 GLenum buf = GL_NONE;
3140 glDrawBuffersARB(1, &buf);
3141 }
[email protected]60f22d32012-12-12 00:31:583142 backbuffer_needs_clear_bits_ = 0;
3143 RestoreClearState();
3144 }
[email protected]0d6bfdc2011-11-02 01:32:203145 return true;
3146 }
3147
[email protected]968351b2011-12-20 08:26:513148 if (framebuffer_manager()->IsComplete(framebuffer)) {
3149 return true;
3150 }
3151
[email protected]0d6bfdc2011-11-02 01:32:203152 GLenum completeness = framebuffer->IsPossiblyComplete();
3153 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513154 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433155 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273156 return false;
3157 }
[email protected]0d6bfdc2011-11-02 01:32:203158
3159 // Are all the attachments cleared?
3160 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3161 texture_manager()->HaveUnclearedMips()) {
3162 if (!framebuffer->IsCleared()) {
3163 // Can we clear them?
[email protected]73276522012-11-09 05:50:203164 if (framebuffer->GetStatus(texture_manager(), target) !=
3165 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513166 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433167 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3168 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203169 return false;
3170 }
3171 ClearUnclearedAttachments(target, framebuffer);
3172 }
3173 }
3174
[email protected]968351b2011-12-20 08:26:513175 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203176 if (framebuffer->GetStatus(texture_manager(), target) !=
3177 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513178 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433179 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3180 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513181 return false;
3182 }
3183 framebuffer_manager()->MarkAsComplete(framebuffer);
3184 }
3185
[email protected]0d6bfdc2011-11-02 01:32:203186 // NOTE: At this point we don't know if the framebuffer is complete but
3187 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273188 return true;
3189}
3190
[email protected]0d6bfdc2011-11-02 01:32:203191bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153192 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513193 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343194 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3195 func_name);
[email protected]28718a92013-04-04 12:12:513196
3197 if (valid)
3198 OnUseFramebuffer();
3199
3200 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203201 }
[email protected]9d3b2e12013-10-02 01:04:343202 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113203 GL_DRAW_FRAMEBUFFER_EXT,
3204 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343205 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113206 GL_READ_FRAMEBUFFER_EXT,
3207 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203208}
3209
[email protected]2ea5950d2014-07-09 18:20:343210bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3211 const char* func_name) {
3212 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3213 framebuffer_state_.bound_read_framebuffer.get() :
3214 framebuffer_state_.bound_draw_framebuffer.get();
3215 if (!framebuffer)
3216 return true;
3217 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3218 LOCAL_SET_GL_ERROR(
3219 GL_INVALID_OPERATION, func_name, "no color image attached");
3220 return false;
3221 }
3222 return true;
3223}
3224
zmo383512cf2014-10-14 00:11:003225bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3226 TextureRef* texture, GLint level) {
3227 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3228 framebuffer_state_.bound_read_framebuffer.get() :
3229 framebuffer_state_.bound_draw_framebuffer.get();
3230 if (!framebuffer)
3231 return false;
3232 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3233 GL_COLOR_ATTACHMENT0);
3234 if (!attachment)
3235 return false;
3236 return attachment->FormsFeedbackLoop(texture, level);
3237}
3238
[email protected]8e3e0662010-08-23 18:46:303239gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353240 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453241 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203242 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353243 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203244 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263245 if (attachment) {
3246 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503247 }
[email protected]9edc6b22010-12-23 02:00:263248 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023249 } else if (offscreen_target_frame_buffer_.get()) {
3250 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353251 } else {
[email protected]f62a5ab2011-05-23 20:34:153252 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023253 }
[email protected]246a70452010-03-05 21:53:503254}
3255
[email protected]68586372013-12-11 01:27:593256GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3257 Framebuffer* framebuffer =
3258 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3259 if (framebuffer != NULL) {
3260 return framebuffer->GetColorAttachmentTextureType();
3261 } else {
3262 return GL_UNSIGNED_BYTE;
3263 }
3264}
3265
[email protected]9edc6b22010-12-23 02:00:263266GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353267 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453268 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203269 if (framebuffer != NULL) {
3270 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463271 } else if (offscreen_target_frame_buffer_.get()) {
3272 return offscreen_target_color_format_;
3273 } else {
3274 return back_buffer_color_format_;
3275 }
3276}
3277
3278GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353279 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453280 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203281 if (framebuffer != NULL) {
3282 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263283 } else if (offscreen_target_frame_buffer_.get()) {
3284 return offscreen_target_color_format_;
3285 } else {
[email protected]32fe9aa2011-01-21 23:47:133286 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263287 }
3288}
3289
[email protected]9a5afa432011-07-22 18:16:393290void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513291 if (!offscreen_saved_color_texture_info_.get())
3292 return;
3293 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3294 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3295 texture_manager()->SetLevelInfo(
3296 offscreen_saved_color_texture_info_.get(),
3297 GL_TEXTURE_2D,
3298 0, // level
3299 GL_RGBA,
3300 offscreen_size_.width(),
3301 offscreen_size_.height(),
3302 1, // depth
3303 0, // border
3304 GL_RGBA,
3305 GL_UNSIGNED_BYTE,
3306 true);
[email protected]737191ee72014-03-09 08:02:423307 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513308 "UpdateParentTextureInfo",
3309 GetErrorState(),
3310 offscreen_saved_color_texture_info_.get(),
3311 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263312 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423313 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513314 "UpdateParentTextureInfo",
3315 GetErrorState(),
3316 offscreen_saved_color_texture_info_.get(),
3317 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263318 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423319 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513320 "UpdateParentTextureInfo",
3321 GetErrorState(),
3322 offscreen_saved_color_texture_info_.get(),
3323 GL_TEXTURE_WRAP_S,
3324 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423325 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513326 "UpdateParentTextureInfo",
3327 GetErrorState(),
3328 offscreen_saved_color_texture_info_.get(),
3329 GL_TEXTURE_WRAP_T,
3330 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443331 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3332 &state_, target);
[email protected]2ad674132013-06-05 07:48:513333 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353334}
3335
[email protected]799b4b22011-08-22 17:09:593336void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073337 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523338 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003339}
3340
[email protected]1d82e822013-04-10 21:32:323341Logger* GLES2DecoderImpl::GetLogger() {
3342 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523343}
3344
[email protected]cac16542014-01-15 17:53:513345void GLES2DecoderImpl::BeginDecoding() {
3346 gpu_tracer_->BeginDecoding();
3347 gpu_trace_commands_ = gpu_tracer_->IsTracing();
vmiura1c2b1de2014-09-19 19:03:243348 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3349 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513350}
3351
3352void GLES2DecoderImpl::EndDecoding() {
3353 gpu_tracer_->EndDecoding();
3354}
3355
[email protected]d3eba342013-04-18 21:11:503356ErrorState* GLES2DecoderImpl::GetErrorState() {
3357 return state_.GetErrorState();
3358}
3359
[email protected]e3932abb2013-03-13 00:01:373360void GLES2DecoderImpl::SetShaderCacheCallback(
3361 const ShaderCacheCallback& callback) {
3362 shader_cache_callback_ = callback;
3363}
3364
[email protected]840a7e462013-02-27 01:29:513365void GLES2DecoderImpl::SetWaitSyncPointCallback(
3366 const WaitSyncPointCallback& callback) {
3367 wait_sync_point_callback_ = callback;
3368}
3369
[email protected]85a4ac22013-05-31 01:58:473370AsyncPixelTransferManager*
3371 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3372 return async_pixel_transfer_manager_.get();
3373}
3374
3375void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3376 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593377}
3378
[email protected]498b5c072013-06-04 19:30:073379void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3380 AsyncPixelTransferManager* manager) {
3381 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3382}
3383
[email protected]1318e922010-09-17 22:03:163384bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3385 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493386 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3387 if (texture_ref) {
3388 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163389 return true;
3390 }
3391 return false;
3392}
3393
[email protected]63b465922012-09-06 02:04:523394uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443395 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483396 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523397}
3398
3399base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443400 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483401 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523402}
3403
3404base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3405 return total_processing_commands_time_;
3406}
3407
[email protected]dc25dda2012-09-27 21:36:303408void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3409 total_processing_commands_time_ += time;
3410}
3411
[email protected]63c9b052012-05-17 18:27:383412void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063413 if (!initialized())
3414 return;
3415
[email protected]63c9b052012-05-17 18:27:383416 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053417
[email protected]80eb6b52012-01-19 00:14:413418 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243419 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523420 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023421 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243422 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133423 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343424 framebuffer_state_.bound_read_framebuffer = NULL;
3425 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243426 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413427
[email protected]cadac622013-06-11 16:46:363428 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513429 DCHECK(offscreen_target_color_texture_);
3430 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3431 offscreen_saved_color_texture_->id());
3432 offscreen_saved_color_texture_->Invalidate();
3433 offscreen_saved_color_texture_info_ = NULL;
3434 }
[email protected]eadc96792010-10-27 19:39:393435 if (have_context) {
[email protected]c322e882012-05-23 18:06:183436 if (copy_texture_CHROMIUM_.get()) {
3437 copy_texture_CHROMIUM_->Destroy();
3438 copy_texture_CHROMIUM_.reset();
3439 }
[email protected]43410e92012-04-20 17:06:283440
[email protected]7cd76fd2013-06-02 21:11:113441 if (state_.current_program.get()) {
3442 program_manager()->UnuseProgram(shader_manager(),
3443 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143444 }
3445
[email protected]b1122982010-05-17 23:04:243446 if (attrib_0_buffer_id_) {
3447 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3448 }
[email protected]8fbedc02010-11-18 18:43:403449 if (fixed_attrib_buffer_id_) {
3450 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3451 }
[email protected]b1122982010-05-17 23:04:243452
[email protected]4a4c18b2013-09-13 22:50:103453 if (validation_texture_) {
3454 glDeleteTextures(1, &validation_texture_);
3455 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3456 glDeleteFramebuffersEXT(1, &validation_fbo_);
3457 }
3458
[email protected]97872062010-11-03 19:07:053459 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543460 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053461 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543462 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053463 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023464 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053465 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153466 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053467 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153468 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053469 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023470 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053471 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543472 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273473 if (offscreen_resolved_frame_buffer_.get())
3474 offscreen_resolved_frame_buffer_->Destroy();
3475 if (offscreen_resolved_color_texture_.get())
3476 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053477 } else {
3478 if (offscreen_target_frame_buffer_.get())
3479 offscreen_target_frame_buffer_->Invalidate();
3480 if (offscreen_target_color_texture_.get())
3481 offscreen_target_color_texture_->Invalidate();
3482 if (offscreen_target_color_render_buffer_.get())
3483 offscreen_target_color_render_buffer_->Invalidate();
3484 if (offscreen_target_depth_render_buffer_.get())
3485 offscreen_target_depth_render_buffer_->Invalidate();
3486 if (offscreen_target_stencil_render_buffer_.get())
3487 offscreen_target_stencil_render_buffer_->Invalidate();
3488 if (offscreen_saved_frame_buffer_.get())
3489 offscreen_saved_frame_buffer_->Invalidate();
3490 if (offscreen_saved_color_texture_.get())
3491 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273492 if (offscreen_resolved_frame_buffer_.get())
3493 offscreen_resolved_frame_buffer_->Invalidate();
3494 if (offscreen_resolved_color_texture_.get())
3495 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023496 }
[email protected]83a52d032013-07-24 10:30:373497
3498 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3499 // Otherwise, we can leak objects. http://crbug.com/258772.
3500 // state_.current_program must be reset before group_ is reset because
3501 // the later deletes the ProgramManager object that referred by
3502 // state_.current_program object.
3503 state_.current_program = NULL;
3504
[email protected]43410e92012-04-20 17:06:283505 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053506
[email protected]882ba1e22012-03-08 19:02:533507 if (query_manager_.get()) {
3508 query_manager_->Destroy(have_context);
3509 query_manager_.reset();
3510 }
3511
[email protected]944b62f32012-09-27 02:20:463512 if (vertex_array_manager_ .get()) {
3513 vertex_array_manager_->Destroy(have_context);
3514 vertex_array_manager_.reset();
3515 }
3516
[email protected]d2eaf52f2014-07-31 15:01:243517 if (image_manager_.get()) {
3518 image_manager_->Destroy(have_context);
3519 image_manager_.reset();
3520 }
3521
[email protected]97872062010-11-03 19:07:053522 offscreen_target_frame_buffer_.reset();
3523 offscreen_target_color_texture_.reset();
3524 offscreen_target_color_render_buffer_.reset();
3525 offscreen_target_depth_render_buffer_.reset();
3526 offscreen_target_stencil_render_buffer_.reset();
3527 offscreen_saved_frame_buffer_.reset();
3528 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273529 offscreen_resolved_frame_buffer_.reset();
3530 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463531
[email protected]03cef9b2014-04-03 15:58:143532 // Need to release these before releasing |group_| which may own the
3533 // ShaderTranslatorCache.
3534 fragment_translator_ = NULL;
3535 vertex_translator_ = NULL;
3536
[email protected]85a4ac22013-05-31 01:58:473537 // Should destroy the transfer manager before the texture manager held
3538 // by the context group.
3539 async_pixel_transfer_manager_.reset();
3540
[email protected]7cd76fd2013-06-02 21:11:113541 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393542 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233543 group_->Destroy(this, have_context);
3544 group_ = NULL;
3545 }
3546
3547 if (context_.get()) {
3548 context_->ReleaseCurrent(NULL);
3549 context_ = NULL;
3550 }
3551
[email protected]e51bdf32011-11-23 22:21:463552#if defined(OS_MACOSX)
3553 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3554 it != texture_to_io_surface_map_.end(); ++it) {
3555 CFRelease(it->second);
3556 }
3557 texture_to_io_surface_map_.clear();
3558#endif
[email protected]96449d2c2009-11-25 00:01:323559}
3560
[email protected]63c9b052012-05-17 18:27:383561void GLES2DecoderImpl::SetSurface(
3562 const scoped_refptr<gfx::GLSurface>& surface) {
3563 DCHECK(context_->IsCurrent(NULL));
3564 DCHECK(surface_.get());
3565 surface_ = surface;
3566 RestoreCurrentFramebufferBindings();
3567}
3568
[email protected]aba551b2014-02-08 03:38:323569void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3570 if (!offscreen_saved_color_texture_.get()) {
3571 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3572 return;
3573 }
[email protected]2ad674132013-06-05 07:48:513574 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243575 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073576 offscreen_saved_color_texture_info_ = TextureRef::Create(
3577 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513578 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3579 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393580 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243581 }
[email protected]aba551b2014-02-08 03:38:323582 mailbox_manager()->ProduceTexture(
3583 GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243584}
3585
[email protected]799b4b22011-08-22 17:09:593586bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3587 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3588 if (!is_offscreen) {
3589 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3590 << " with an onscreen framebuffer.";
3591 return false;
3592 }
3593
3594 if (offscreen_size_ == size)
3595 return true;
3596
3597 offscreen_size_ = size;
3598 int w = offscreen_size_.width();
3599 int h = offscreen_size_.height();
3600 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3601 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3602 << "to allocate storage due to excessive dimensions.";
3603 return false;
3604 }
3605
3606 // Reallocate the offscreen target buffers.
3607 DCHECK(offscreen_target_color_format_);
3608 if (IsOffscreenBufferMultisampled()) {
3609 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253610 feature_info_.get(),
3611 offscreen_size_,
3612 offscreen_target_color_format_,
3613 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593614 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3615 << "to allocate storage for offscreen target color buffer.";
3616 return false;
3617 }
3618 } else {
3619 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093620 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593621 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3622 << "to allocate storage for offscreen target color texture.";
3623 return false;
3624 }
3625 }
3626 if (offscreen_target_depth_format_ &&
3627 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253628 feature_info_.get(),
3629 offscreen_size_,
3630 offscreen_target_depth_format_,
3631 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593632 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3633 << "to allocate storage for offscreen target depth buffer.";
3634 return false;
3635 }
3636 if (offscreen_target_stencil_format_ &&
3637 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253638 feature_info_.get(),
3639 offscreen_size_,
3640 offscreen_target_stencil_format_,
3641 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593642 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3643 << "to allocate storage for offscreen target stencil buffer.";
3644 return false;
3645 }
3646
3647 // Attach the offscreen target buffers to the target frame buffer.
3648 if (IsOffscreenBufferMultisampled()) {
3649 offscreen_target_frame_buffer_->AttachRenderBuffer(
3650 GL_COLOR_ATTACHMENT0,
3651 offscreen_target_color_render_buffer_.get());
3652 } else {
3653 offscreen_target_frame_buffer_->AttachRenderTexture(
3654 offscreen_target_color_texture_.get());
3655 }
3656 if (offscreen_target_depth_format_) {
3657 offscreen_target_frame_buffer_->AttachRenderBuffer(
3658 GL_DEPTH_ATTACHMENT,
3659 offscreen_target_depth_render_buffer_.get());
3660 }
3661 const bool packed_depth_stencil =
3662 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3663 if (packed_depth_stencil) {
3664 offscreen_target_frame_buffer_->AttachRenderBuffer(
3665 GL_STENCIL_ATTACHMENT,
3666 offscreen_target_depth_render_buffer_.get());
3667 } else if (offscreen_target_stencil_format_) {
3668 offscreen_target_frame_buffer_->AttachRenderBuffer(
3669 GL_STENCIL_ATTACHMENT,
3670 offscreen_target_stencil_render_buffer_.get());
3671 }
3672
3673 if (offscreen_target_frame_buffer_->CheckStatus() !=
3674 GL_FRAMEBUFFER_COMPLETE) {
3675 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3676 << "because offscreen FBO was incomplete.";
3677 return false;
3678 }
3679
3680 // Clear the target frame buffer.
3681 {
3682 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3683 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323684 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453685 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593686 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473687 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3688 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593689 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453690 state_.SetDeviceDepthMask(GL_TRUE);
3691 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593692 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3693 RestoreClearState();
3694 }
[email protected]d85ef76d2011-09-08 22:21:433695
3696 // Destroy the offscreen resolved framebuffers.
3697 if (offscreen_resolved_frame_buffer_.get())
3698 offscreen_resolved_frame_buffer_->Destroy();
3699 if (offscreen_resolved_color_texture_.get())
3700 offscreen_resolved_color_texture_->Destroy();
3701 offscreen_resolved_color_texture_.reset();
3702 offscreen_resolved_frame_buffer_.reset();
3703
[email protected]799b4b22011-08-22 17:09:593704 return true;
[email protected]6217d392010-03-25 22:08:353705}
3706
vmiuracd108592014-09-08 14:36:343707error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3708 const void* cmd_data) {
3709 const gles2::cmds::ResizeCHROMIUM& c =
3710 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:443711 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023712 return error::kDeferCommandUntilLater;
3713
[email protected]799b4b22011-08-22 17:09:593714 GLuint width = static_cast<GLuint>(c.width);
3715 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073716 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593717 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413718
3719 width = std::max(1U, width);
3720 height = std::max(1U, height);
3721
[email protected]a0d989162011-11-22 13:15:073722#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3723 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003724 // Make sure that we are done drawing to the back buffer before resizing.
3725 glFinish();
3726#endif
[email protected]799b4b22011-08-22 17:09:593727 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3728 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493729 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3730 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3731 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593732 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493733 }
[email protected]7ff86b92010-11-25 17:50:003734 }
[email protected]799b4b22011-08-22 17:09:593735
[email protected]9d37f062011-11-22 01:24:523736 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073737 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443738 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493739 if (!context_->IsCurrent(surface_.get())) {
3740 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3741 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053742 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493743 }
[email protected]658f7562011-09-09 05:24:053744 }
[email protected]799b4b22011-08-22 17:09:593745
3746 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393747}
3748
[email protected]96449d2c2009-11-25 00:01:323749const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3750 if (command_id > kStartPoint && command_id < kNumCommands) {
3751 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3752 }
3753 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3754}
3755
vmiura8266ca72014-09-09 21:37:003756// Decode a command, and call the corresponding GL functions.
3757// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3758// of commands at once, and is now only used for tests that need to track
3759// individual commands.
3760error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3761 unsigned int arg_count,
3762 const void* cmd_data) {
3763 return DoCommands(1, cmd_data, arg_count + 1, 0);
3764}
3765
3766// Decode multiple commands, and call the corresponding GL functions.
3767// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3768// changed by a (malicious) client at any time, so if validation has to happen,
3769// it should operate on a copy of them.
3770// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3771// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:243772template <bool DebugImpl>
3773error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3774 const void* buffer,
3775 int num_entries,
3776 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:003777 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:143778 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:003779 const CommandBufferEntry* cmd_data =
3780 static_cast<const CommandBufferEntry*>(buffer);
3781 int process_pos = 0;
3782 unsigned int command = 0;
3783
3784 while (process_pos < num_entries && result == error::kNoError &&
3785 commands_to_process_--) {
3786 const unsigned int size = cmd_data->value_header.size;
3787 command = cmd_data->value_header.command;
3788
3789 if (size == 0) {
3790 result = error::kInvalidSize;
3791 break;
3792 }
3793
3794 if (static_cast<int>(size) + process_pos > num_entries) {
3795 result = error::kOutOfBounds;
3796 break;
3797 }
3798
vmiura1c2b1de2014-09-19 19:03:243799 if (DebugImpl) {
3800 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3801 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:003802
vmiura1c2b1de2014-09-19 19:03:243803 if (log_commands()) {
3804 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
3805 << "cmd: " << GetCommandName(command);
3806 }
vmiura8266ca72014-09-09 21:37:003807 }
3808
3809 const unsigned int arg_count = size - 1;
3810 unsigned int command_index = command - kStartPoint - 1;
3811 if (command_index < arraysize(command_info)) {
3812 const CommandInfo& info = command_info[command_index];
3813 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3814 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3815 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3816 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:243817 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:003818 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3819 doing_gpu_trace = true;
3820 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3821 }
[email protected]cac16542014-01-15 17:53:513822 }
[email protected]cac16542014-01-15 17:53:513823
vmiura8266ca72014-09-09 21:37:003824 uint32 immediate_data_size = (arg_count - info_arg_count) *
3825 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323826
vmiura8266ca72014-09-09 21:37:003827 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:513828
vmiura1c2b1de2014-09-19 19:03:243829 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:003830 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:513831
vmiura1c2b1de2014-09-19 19:03:243832 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:003833 GLenum error;
3834 while ((error = glGetError()) != GL_NO_ERROR) {
3835 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
3836 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
3837 << " : " << GetCommandName(command);
3838 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
3839 }
[email protected]b9849abf2009-11-25 19:13:193840 }
vmiura8266ca72014-09-09 21:37:003841 } else {
3842 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323843 }
3844 } else {
vmiura8266ca72014-09-09 21:37:003845 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323846 }
vmiura1c2b1de2014-09-19 19:03:243847
3848 if (DebugImpl) {
3849 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3850 GetCommandName(command));
3851 }
3852
vmiura8266ca72014-09-09 21:37:003853 if (result == error::kNoError &&
3854 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:563855 result = current_decoder_error_;
3856 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:003857 }
3858
3859 if (result != error::kDeferCommandUntilLater) {
3860 process_pos += size;
3861 cmd_data += size;
3862 }
[email protected]a3a93e7b2010-08-28 00:48:563863 }
vmiura8266ca72014-09-09 21:37:003864
3865 if (entries_processed)
3866 *entries_processed = process_pos;
3867
3868 if (error::IsError(result)) {
3869 LOG(ERROR) << "Error: " << result << " for Command "
3870 << GetCommandName(command);
3871 }
3872
[email protected]b9849abf2009-11-25 19:13:193873 return result;
[email protected]96449d2c2009-11-25 00:01:323874}
3875
vmiura1c2b1de2014-09-19 19:03:243876error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
3877 const void* buffer,
3878 int num_entries,
3879 int* entries_processed) {
3880 if (gpu_debug_commands_) {
3881 return DoCommandsImpl<true>(
3882 num_commands, buffer, num_entries, entries_processed);
3883 } else {
3884 return DoCommandsImpl<false>(
3885 num_commands, buffer, num_entries, entries_processed);
3886 }
3887}
3888
[email protected]ed9f9cd2013-02-27 21:12:353889void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3890 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503891}
3892
[email protected]ae51d192010-04-27 00:48:033893bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353894 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033895 return false;
3896 }
[email protected]96449d2c2009-11-25 00:01:323897 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033898 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353899 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323900 }
[email protected]ae51d192010-04-27 00:48:033901 return true;
[email protected]96449d2c2009-11-25 00:01:323902}
3903
[email protected]ae51d192010-04-27 00:48:033904bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353905 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033906 return false;
[email protected]96449d2c2009-11-25 00:01:323907 }
[email protected]ae51d192010-04-27 00:48:033908 GLuint service_id = glCreateShader(type);
3909 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353910 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033911 }
3912 return true;
[email protected]96449d2c2009-11-25 00:01:323913}
3914
[email protected]882ba1e22012-03-08 19:02:533915void GLES2DecoderImpl::DoFinish() {
3916 glFinish();
[email protected]5a36dc132013-07-23 23:17:553917 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193918 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533919}
3920
3921void GLES2DecoderImpl::DoFlush() {
3922 glFlush();
[email protected]22e3f552012-03-13 01:54:193923 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533924}
3925
[email protected]3916c97e2010-02-25 03:20:503926void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453927 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023928 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513929 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533930 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503931 return;
3932 }
[email protected]e259eb412012-10-13 05:47:243933 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453934 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503935}
3936
[email protected]051b1372010-04-12 02:42:083937void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073938 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083939 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033940 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073941 buffer = GetBuffer(client_id);
3942 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353943 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:223944 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3945 "glBindBuffer",
3946 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:353947 return;
3948 }
3949
[email protected]b10492f2013-03-08 05:24:073950 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033951 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353952 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073953 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:033954 }
[email protected]051b1372010-04-12 02:42:083955 }
[email protected]b10492f2013-03-08 05:24:073956 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3957 if (buffer) {
3958 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513959 LOCAL_SET_GL_ERROR(
3960 GL_INVALID_OPERATION,
3961 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473962 return;
3963 }
[email protected]b10492f2013-03-08 05:24:073964 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473965 }
[email protected]96449d2c2009-11-25 00:01:323966 switch (target) {
3967 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073968 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323969 break;
3970 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073971 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323972 break;
3973 default:
[email protected]a93bb842010-02-16 23:03:473974 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323975 break;
3976 }
[email protected]051b1372010-04-12 02:42:083977 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323978}
3979
[email protected]f3b191b2013-06-19 03:43:543980bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3981 bool all_draw_buffers) {
3982 Framebuffer* framebuffer =
3983 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3984 if (!all_draw_buffers || !framebuffer) {
3985 return (GLES2Util::GetChannelsForFormat(
3986 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3987 }
3988 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463989}
3990
3991bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353992 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453993 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203994 if (framebuffer) {
3995 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463996 }
3997 if (offscreen_target_frame_buffer_.get()) {
3998 return offscreen_target_depth_format_ != 0;
3999 }
4000 return back_buffer_has_depth_;
4001}
4002
4003bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354004 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454005 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204006 if (framebuffer) {
4007 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464008 }
4009 if (offscreen_target_frame_buffer_.get()) {
4010 return offscreen_target_stencil_format_ != 0 ||
4011 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4012 }
4013 return back_buffer_has_stencil_;
4014}
4015
4016void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444017 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454018 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4019 state_.SetDeviceColorMask(state_.color_mask_red,
4020 state_.color_mask_green,
4021 state_.color_mask_blue,
4022 state_.color_mask_alpha && have_alpha);
4023
[email protected]297ca1c2011-06-20 23:08:464024 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454025 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4026
[email protected]297ca1c2011-06-20 23:08:464027 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454028 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424029 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454030 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424031 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454032
4033 state_.SetDeviceCapabilityState(
4034 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4035 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224036 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444037 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464038 }
4039}
4040
[email protected]1868a342012-11-07 15:56:024041GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114042 return (offscreen_target_frame_buffer_.get())
4043 ? offscreen_target_frame_buffer_->id()
4044 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024045}
4046
[email protected]8875a5f2014-06-27 08:33:474047void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144048 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4049 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064050 // Restore the Framebuffer first because of bugs in Intel drivers.
4051 // Intel drivers incorrectly clip the viewport settings to
4052 // the size of the current framebuffer object.
4053 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164054 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064055}
4056
4057void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344058 GLuint service_id =
4059 framebuffer_state_.bound_draw_framebuffer.get()
4060 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4061 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064062 if (!features().chromium_framebuffer_multisample) {
4063 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4064 } else {
4065 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344066 service_id = framebuffer_state_.bound_read_framebuffer.get()
4067 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114068 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064069 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4070 }
[email protected]70d34263c2013-01-09 00:27:454071 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064072}
4073
[email protected]8875a5f2014-06-27 08:33:474074void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4075 state_.RestoreRenderbufferBindings();
4076}
4077
[email protected]29a4d902013-02-26 20:18:064078void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104079 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4080 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254081 GLenum target = texture->target();
4082 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064083 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254084 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064085 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254086 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064087 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254088 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064089 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254090 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064091 RestoreTextureUnitBindings(state_.active_texture_unit);
4092 }
[email protected]70d34263c2013-01-09 00:27:454093}
4094
[email protected]cd2ef752014-02-12 23:16:034095void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524096 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4097 // other VAOs.
4098 if (feature_info_->feature_flags().native_vertex_array_object)
4099 glBindVertexArrayOES(0);
4100
[email protected]cd2ef752014-02-12 23:16:034101 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4102 if (i != 0) // Never disable attribute 0
4103 glDisableVertexAttribArray(i);
4104 if(features().angle_instanced_arrays)
4105 glVertexAttribDivisorANGLE(i, 0);
4106 }
4107}
4108
4109void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524110 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034111}
4112
[email protected]454157e2014-05-03 02:49:454113void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4114 state_.SetIgnoreCachedStateForTest(ignore);
4115}
4116
[email protected]70d34263c2013-01-09 00:27:454117void GLES2DecoderImpl::OnFboChanged() const {
4118 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514119 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
4120}
4121
4122// Called after the FBO is checked for completeness.
4123void GLES2DecoderImpl::OnUseFramebuffer() const {
4124 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4125 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324126 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514127 glScissor(state_.scissor_x,
4128 state_.scissor_y,
4129 state_.scissor_width,
4130 state_.scissor_height);
4131
4132 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4133 // it's unclear how this bug works.
4134 glFlush();
4135 }
[email protected]b177ae22011-11-01 03:29:114136}
4137
[email protected]051b1372010-04-12 02:42:084138void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064139 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084140 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034141 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064142 framebuffer = GetFramebuffer(client_id);
4143 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354144 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224145 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4146 "glBindFramebuffer",
4147 "id not generated by glGenFramebuffers");
4148 return;
[email protected]bf5a8d132011-08-16 08:39:354149 }
4150
[email protected]4d8f0dd2013-03-09 14:37:064151 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034152 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354153 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064154 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034155 } else {
[email protected]4d8f0dd2013-03-09 14:37:064156 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084157 }
[email protected]4d8f0dd2013-03-09 14:37:064158 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084159 }
[email protected]4d8f0dd2013-03-09 14:37:064160 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304161
4162 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344163 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304164 }
[email protected]cac16542014-01-15 17:53:514165
4166 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304167 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344168 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304169 }
[email protected]6217d392010-03-25 22:08:354170
[email protected]c986af502013-08-14 01:04:444171 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464172
[email protected]b177ae22011-11-01 03:29:114173 // If we are rendering to the backbuffer get the FBO id for any simulated
4174 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064175 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114176 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464177 }
[email protected]6217d392010-03-25 22:08:354178
[email protected]051b1372010-04-12 02:42:084179 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454180 OnFboChanged();
[email protected]86093972010-03-11 00:13:564181}
4182
[email protected]051b1372010-04-12 02:42:084183void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274184 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084185 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034186 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274187 renderbuffer = GetRenderbuffer(client_id);
4188 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354189 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224190 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4191 "glBindRenderbuffer",
4192 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354193 return;
4194 }
4195
[email protected]8875a5f2014-06-27 08:33:474196 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034197 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354198 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274199 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034200 } else {
[email protected]ee2a79c32013-03-10 03:50:274201 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084202 }
[email protected]ee2a79c32013-03-10 03:50:274203 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084204 }
[email protected]caa13ed2014-02-17 11:29:204205 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274206 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474207 state_.bound_renderbuffer_valid = true;
4208 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564209}
4210
[email protected]051b1372010-04-12 02:42:084211void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494212 TextureRef* texture_ref = 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]370eaf12013-05-18 09:19:494215 texture_ref = GetTexture(client_id);
4216 if (!texture_ref) {
[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 "glBindTexture",
4220 "id not generated by glGenTextures");
4221 return;
[email protected]bf5a8d132011-08-16 08:39:354222 }
4223
[email protected]02965c22013-03-09 02:40:074224 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034225 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414226 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354227 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494228 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034229 }
4230 } else {
[email protected]370eaf12013-05-18 09:19:494231 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084232 }
[email protected]ae51d192010-04-27 00:48:034233
[email protected]1958e0e2010-04-22 05:17:154234 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574235 if (texture_ref) {
4236 Texture* texture = texture_ref->texture();
4237 // Check that we are not trying to bind it to a different target.
4238 if (texture->target() != 0 && texture->target() != target) {
4239 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4240 "glBindTexture",
4241 "texture bound to more than 1 target.");
4242 return;
4243 }
4244 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4245 if (texture->target() == 0) {
4246 texture_manager()->SetTarget(texture_ref, target);
4247 }
4248 glBindTexture(target, texture->service_id());
4249 } else {
4250 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154251 }
[email protected]32145a92012-12-17 09:01:594252
[email protected]e259eb412012-10-13 05:47:244253 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504254 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474255 switch (target) {
4256 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494257 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474258 break;
4259 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494260 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474261 break;
[email protected]61eeb33f2011-07-26 15:30:314262 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494263 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314264 break;
[email protected]e51bdf32011-11-23 22:21:464265 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494266 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464267 break;
[email protected]a93bb842010-02-16 23:03:474268 default:
4269 NOTREACHED(); // Validation should prevent us getting here.
4270 break;
4271 }
4272}
4273
[email protected]07f54fcc2009-12-22 02:46:304274void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244275 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124276 if (index != 0 ||
4277 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244278 glDisableVertexAttribArray(index);
4279 }
[email protected]07f54fcc2009-12-22 02:46:304280 } else {
[email protected]ab09b612013-03-11 22:11:514281 LOCAL_SET_GL_ERROR(
4282 GL_INVALID_VALUE,
4283 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304284 }
4285}
4286
[email protected]60f22d32012-12-12 00:31:584287void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4288 GLsizei numAttachments,
4289 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354290 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584291 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4292
4293 // Validates the attachments. If one of them fails
4294 // the whole command fails.
4295 for (GLsizei i = 0; i < numAttachments; ++i) {
4296 if ((framebuffer &&
4297 !validators_->attachment.IsValid(attachments[i])) ||
4298 (!framebuffer &&
4299 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514300 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4301 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584302 return;
4303 }
4304 }
4305
4306 // Marks each one of them as not cleared
4307 for (GLsizei i = 0; i < numAttachments; ++i) {
4308 if (framebuffer) {
4309 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4310 texture_manager(),
4311 attachments[i],
4312 false);
4313 } else {
4314 switch (attachments[i]) {
4315 case GL_COLOR_EXT:
4316 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4317 break;
4318 case GL_DEPTH_EXT:
4319 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4320 case GL_STENCIL_EXT:
4321 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4322 break;
4323 default:
4324 NOTREACHED();
4325 break;
4326 }
4327 }
4328 }
4329
[email protected]d49c5402013-09-11 15:39:024330 // If the default framebuffer is bound but we are still rendering to an
4331 // FBO, translate attachment names that refer to default framebuffer
4332 // channels to corresponding framebuffer attachments.
4333 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4334 for (GLsizei i = 0; i < numAttachments; ++i) {
4335 GLenum attachment = attachments[i];
4336 if (!framebuffer && GetBackbufferServiceId()) {
4337 switch (attachment) {
4338 case GL_COLOR_EXT:
4339 attachment = GL_COLOR_ATTACHMENT0;
4340 break;
4341 case GL_DEPTH_EXT:
4342 attachment = GL_DEPTH_ATTACHMENT;
4343 break;
4344 case GL_STENCIL_EXT:
4345 attachment = GL_STENCIL_ATTACHMENT;
4346 break;
4347 default:
4348 NOTREACHED();
4349 return;
4350 }
4351 }
4352 translated_attachments[i] = attachment;
4353 }
4354
boliu2e7d8a7a2014-10-16 20:35:204355 ScopedRenderTo do_render(framebuffer);
[email protected]d49c5402013-09-11 15:39:024356 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584357}
4358
[email protected]07f54fcc2009-12-22 02:46:304359void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244360 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304361 glEnableVertexAttribArray(index);
4362 } else {
[email protected]ab09b612013-03-11 22:11:514363 LOCAL_SET_GL_ERROR(
4364 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304365 }
4366}
4367
[email protected]a93bb842010-02-16 23:03:474368void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444369 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4370 &state_, target);
[email protected]370eaf12013-05-18 09:19:494371 if (!texture_ref ||
4372 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514373 LOCAL_SET_GL_ERROR(
4374 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474375 return;
4376 }
[email protected]38c0a972012-05-12 00:48:024377
[email protected]12d95352012-12-14 07:23:544378 if (target == GL_TEXTURE_CUBE_MAP) {
4379 for (int i = 0; i < 6; ++i) {
4380 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494381 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514382 LOCAL_SET_GL_ERROR(
4383 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544384 return;
4385 }
4386 }
4387 } else {
[email protected]370eaf12013-05-18 09:19:494388 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514389 LOCAL_SET_GL_ERROR(
4390 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544391 return;
4392 }
[email protected]7687479c2012-05-14 23:54:044393 }
4394
[email protected]ab09b612013-03-11 22:11:514395 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194396 // Workaround for Mac driver bug. In the large scheme of things setting
4397 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564398 // hit so there's probably no need to make this conditional. The bug appears
4399 // to be that if the filtering mode is set to something that doesn't require
4400 // mipmaps for rendering, or is never set to something other than the default,
4401 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154402 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194403 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4404 }
[email protected]a93bb842010-02-16 23:03:474405 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154406 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494407 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4408 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194409 }
[email protected]ab09b612013-03-11 22:11:514410 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024411 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494412 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024413 }
[email protected]a93bb842010-02-16 23:03:474414}
4415
[email protected]b273e432010-04-12 17:23:584416bool GLES2DecoderImpl::GetHelper(
4417 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584418 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154419 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4420 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434421 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4422 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214423 // Return the GL implementation's preferred format and (see below type)
4424 // if we have the GL extension that exposes this. This allows the GPU
4425 // client to use the implementation's preferred format for glReadPixels
4426 // for optimisation.
4427 //
4428 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4429 // case when requested on integer/floating point buffers but which is
4430 // acceptable on GLES2 and with the GL_OES_read_format extension.
4431 //
4432 // Therefore if an error occurs we swallow the error and use the
4433 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434434 if (params) {
[email protected]c959a09a2014-03-27 11:44:214435 if (context_->HasExtension("GL_OES_read_format")) {
4436 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4437 GetErrorState());
4438 glGetIntegerv(pname, params);
4439 if (glGetError() == GL_NO_ERROR)
4440 return true;
4441 }
[email protected]68586372013-12-11 01:27:594442 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4443 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434444 }
4445 return true;
4446 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4447 *num_written = 1;
4448 if (params) {
[email protected]c959a09a2014-03-27 11:44:214449 if (context_->HasExtension("GL_OES_read_format")) {
4450 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4451 GetErrorState());
4452 glGetIntegerv(pname, params);
4453 if (glGetError() == GL_NO_ERROR)
4454 return true;
4455 }
[email protected]68586372013-12-11 01:27:594456 *params = GLES2Util::GetPreferredGLReadPixelsType(
4457 GetBoundReadFrameBufferInternalFormat(),
4458 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434459 }
4460 return true;
4461 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4462 *num_written = 1;
4463 if (params) {
4464 *params = group_->max_fragment_uniform_vectors();
4465 }
4466 return true;
4467 case GL_MAX_VARYING_VECTORS:
4468 *num_written = 1;
4469 if (params) {
4470 *params = group_->max_varying_vectors();
4471 }
4472 return true;
4473 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4474 *num_written = 1;
4475 if (params) {
4476 *params = group_->max_vertex_uniform_vectors();
4477 }
4478 return true;
[email protected]4e8a5b122010-05-08 22:00:104479 }
[email protected]5cb735d2011-10-13 01:37:234480 }
4481 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244482 case GL_MAX_VIEWPORT_DIMS:
4483 if (offscreen_target_frame_buffer_.get()) {
4484 *num_written = 2;
4485 if (params) {
4486 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4487 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4488 }
4489 return true;
4490 }
[email protected]5cb735d2011-10-13 01:37:234491 return false;
[email protected]84afefa2011-10-19 21:45:534492 case GL_MAX_SAMPLES:
4493 *num_written = 1;
4494 if (params) {
4495 params[0] = renderbuffer_manager()->max_samples();
4496 }
4497 return true;
4498 case GL_MAX_RENDERBUFFER_SIZE:
4499 *num_written = 1;
4500 if (params) {
4501 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4502 }
4503 return true;
[email protected]5cb735d2011-10-13 01:37:234504 case GL_MAX_TEXTURE_SIZE:
4505 *num_written = 1;
4506 if (params) {
4507 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4508 }
4509 return true;
4510 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4511 *num_written = 1;
4512 if (params) {
4513 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4514 }
4515 return true;
[email protected]2f143d482013-03-14 18:04:494516 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4517 *num_written = 1;
4518 if (params) {
4519 params[0] = group_->max_color_attachments();
4520 }
4521 return true;
4522 case GL_MAX_DRAW_BUFFERS_ARB:
4523 *num_written = 1;
4524 if (params) {
4525 params[0] = group_->max_draw_buffers();
4526 }
4527 return true;
[email protected]297ca1c2011-06-20 23:08:464528 case GL_ALPHA_BITS:
4529 *num_written = 1;
4530 if (params) {
4531 GLint v = 0;
4532 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544533 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464534 }
4535 return true;
4536 case GL_DEPTH_BITS:
4537 *num_written = 1;
4538 if (params) {
4539 GLint v = 0;
4540 glGetIntegerv(GL_DEPTH_BITS, &v);
4541 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4542 }
4543 return true;
4544 case GL_STENCIL_BITS:
4545 *num_written = 1;
4546 if (params) {
4547 GLint v = 0;
4548 glGetIntegerv(GL_STENCIL_BITS, &v);
4549 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4550 }
4551 return true;
[email protected]656dcaad2010-05-07 17:18:374552 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114553 *num_written = validators_->compressed_texture_format.GetValues().size();
4554 if (params) {
4555 for (GLint ii = 0; ii < *num_written; ++ii) {
4556 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4557 }
4558 }
[email protected]656dcaad2010-05-07 17:18:374559 return true;
[email protected]b273e432010-04-12 17:23:584560 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4561 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104562 if (params) {
[email protected]302ce6d2011-07-07 23:28:114563 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104564 }
[email protected]b273e432010-04-12 17:23:584565 return true;
4566 case GL_NUM_SHADER_BINARY_FORMATS:
4567 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104568 if (params) {
[email protected]302ce6d2011-07-07 23:28:114569 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104570 }
[email protected]b273e432010-04-12 17:23:584571 return true;
4572 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114573 *num_written = validators_->shader_binary_format.GetValues().size();
4574 if (params) {
4575 for (GLint ii = 0; ii < *num_written; ++ii) {
4576 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4577 }
4578 }
4579 return true;
[email protected]b273e432010-04-12 17:23:584580 case GL_SHADER_COMPILER:
4581 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104582 if (params) {
4583 *params = GL_TRUE;
4584 }
[email protected]b273e432010-04-12 17:23:584585 return true;
[email protected]6b8cf1a2010-05-06 16:13:584586 case GL_ARRAY_BUFFER_BINDING:
4587 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104588 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114589 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104590 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244591 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104592 &client_id);
4593 *params = client_id;
4594 } else {
4595 *params = 0;
4596 }
[email protected]6b8cf1a2010-05-06 16:13:584597 }
4598 return true;
4599 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4600 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104601 if (params) {
[email protected]e259eb412012-10-13 05:47:244602 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104603 GLuint client_id = 0;
4604 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254605 state_.vertex_attrib_manager->element_array_buffer()->
4606 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104607 *params = client_id;
4608 } else {
4609 *params = 0;
4610 }
[email protected]6b8cf1a2010-05-06 16:13:584611 }
4612 return true;
4613 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304614 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584615 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104616 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354617 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454618 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204619 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104620 GLuint client_id = 0;
4621 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204622 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304623 *params = client_id;
4624 } else {
4625 *params = 0;
4626 }
4627 }
4628 return true;
[email protected]ebfb73c2012-08-15 02:37:454629 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304630 *num_written = 1;
4631 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354632 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454633 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204634 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304635 GLuint client_id = 0;
4636 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204637 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104638 *params = client_id;
4639 } else {
4640 *params = 0;
4641 }
[email protected]6b8cf1a2010-05-06 16:13:584642 }
4643 return true;
4644 case GL_RENDERBUFFER_BINDING:
4645 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104646 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354647 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204648 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4649 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104650 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104651 } else {
4652 *params = 0;
4653 }
[email protected]6b8cf1a2010-05-06 16:13:584654 }
4655 return true;
4656 case GL_CURRENT_PROGRAM:
4657 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104658 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114659 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104660 GLuint client_id = 0;
4661 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244662 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104663 *params = client_id;
4664 } else {
4665 *params = 0;
4666 }
[email protected]6b8cf1a2010-05-06 16:13:584667 }
4668 return true;
[email protected]bf835842012-11-19 15:21:514669 case GL_VERTEX_ARRAY_BINDING_OES:
4670 *num_written = 1;
4671 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114672 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524673 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514674 GLuint client_id = 0;
4675 vertex_array_manager_->GetClientId(
4676 state_.vertex_attrib_manager->service_id(), &client_id);
4677 *params = client_id;
4678 } else {
4679 *params = 0;
4680 }
4681 }
4682 return true;
[email protected]4e8a5b122010-05-08 22:00:104683 case GL_TEXTURE_BINDING_2D:
4684 *num_written = 1;
4685 if (params) {
[email protected]e259eb412012-10-13 05:47:244686 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114687 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104688 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584689 } else {
4690 *params = 0;
4691 }
[email protected]6b8cf1a2010-05-06 16:13:584692 }
[email protected]4e8a5b122010-05-08 22:00:104693 return true;
4694 case GL_TEXTURE_BINDING_CUBE_MAP:
4695 *num_written = 1;
4696 if (params) {
[email protected]e259eb412012-10-13 05:47:244697 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114698 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104699 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584700 } else {
4701 *params = 0;
4702 }
[email protected]6b8cf1a2010-05-06 16:13:584703 }
[email protected]4e8a5b122010-05-08 22:00:104704 return true;
[email protected]61eeb33f2011-07-26 15:30:314705 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4706 *num_written = 1;
4707 if (params) {
[email protected]e259eb412012-10-13 05:47:244708 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114709 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104710 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314711 } else {
4712 *params = 0;
4713 }
4714 }
4715 return true;
[email protected]e51bdf32011-11-23 22:21:464716 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4717 *num_written = 1;
4718 if (params) {
[email protected]e259eb412012-10-13 05:47:244719 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114720 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104721 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464722 } else {
4723 *params = 0;
4724 }
4725 }
4726 return true;
[email protected]6c75c712012-06-19 15:43:174727 case GL_UNPACK_FLIP_Y_CHROMIUM:
4728 *num_written = 1;
4729 if (params) {
4730 params[0] = unpack_flip_y_;
4731 }
4732 return true;
4733 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4734 *num_written = 1;
4735 if (params) {
4736 params[0] = unpack_premultiply_alpha_;
4737 }
4738 return true;
4739 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4740 *num_written = 1;
4741 if (params) {
4742 params[0] = unpack_unpremultiply_alpha_;
4743 }
4744 return true;
[email protected]6eda6822014-04-03 23:00:504745 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4746 *num_written = 1;
4747 if (params) {
4748 params[0] = group_->bind_generates_resource() ? 1 : 0;
4749 }
4750 return true;
[email protected]b273e432010-04-12 17:23:584751 default:
[email protected]2f143d482013-03-14 18:04:494752 if (pname >= GL_DRAW_BUFFER0_ARB &&
4753 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4754 *num_written = 1;
4755 if (params) {
4756 Framebuffer* framebuffer =
4757 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4758 if (framebuffer) {
4759 params[0] = framebuffer->GetDrawBuffer(pname);
4760 } else { // backbuffer
4761 if (pname == GL_DRAW_BUFFER0_ARB)
4762 params[0] = group_->draw_buffer();
4763 else
4764 params[0] = GL_NONE;
4765 }
4766 }
4767 return true;
4768 }
[email protected]4e8a5b122010-05-08 22:00:104769 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534770 return false;
[email protected]b273e432010-04-12 17:23:584771 }
4772}
4773
[email protected]4e8a5b122010-05-08 22:00:104774bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4775 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264776 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534777 return true;
4778 }
[email protected]4e8a5b122010-05-08 22:00:104779 return GetHelper(pname, NULL, num_values);
4780}
4781
[email protected]7d3c36e2013-07-12 14:13:164782GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4783 if (GL_MAX_SAMPLES == pname &&
4784 features().use_img_for_multisampled_render_to_texture) {
4785 return GL_MAX_SAMPLES_IMG;
4786 }
4787 return pname;
4788}
4789
[email protected]b273e432010-04-12 17:23:584790void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4791 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104792 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534793 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554794 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264795 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534796 GetHelper(pname, values.get(), &num_written);
4797 }
[email protected]b273e432010-04-12 17:23:584798 for (GLsizei ii = 0; ii < num_written; ++ii) {
4799 params[ii] = static_cast<GLboolean>(values[ii]);
4800 }
4801 } else {
[email protected]7d3c36e2013-07-12 14:13:164802 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584803 glGetBooleanv(pname, params);
4804 }
4805}
4806
4807void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4808 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104809 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264810 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534811 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554812 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534813 GetHelper(pname, values.get(), &num_written);
4814 for (GLsizei ii = 0; ii < num_written; ++ii) {
4815 params[ii] = static_cast<GLfloat>(values[ii]);
4816 }
4817 } else {
[email protected]7d3c36e2013-07-12 14:13:164818 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534819 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584820 }
[email protected]b273e432010-04-12 17:23:584821 }
4822}
4823
4824void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4825 DCHECK(params);
4826 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264827 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534828 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164829 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584830 glGetIntegerv(pname, params);
4831 }
4832}
4833
[email protected]a0c3e972010-04-21 00:49:134834void GLES2DecoderImpl::DoGetProgramiv(
4835 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424836 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4837 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134838 return;
4839 }
[email protected]df37b9932013-03-08 05:21:424840 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134841}
4842
[email protected]17cfbe0e2013-03-07 01:26:084843void GLES2DecoderImpl::DoGetBufferParameteriv(
4844 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134845 // Just delegate it. Some validation is actually done before this.
4846 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4847 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084848}
4849
[email protected]258a3313f2011-10-18 20:13:574850void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424851 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574852 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514853 LOCAL_SET_GL_ERROR(
4854 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574855 return;
4856 }
[email protected]68dcb1f2012-04-07 00:14:564857 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514858 LOCAL_SET_GL_ERROR(
4859 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564860 return;
4861 }
4862 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514863 LOCAL_SET_GL_ERROR(
4864 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564865 return;
4866 }
[email protected]df37b9932013-03-08 05:21:424867 Program* program = GetProgramInfoNotShader(
4868 program_id, "glBindAttribLocation");
4869 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574870 return;
[email protected]558847a2010-03-24 07:02:544871 }
zmo460b593e2014-10-13 23:07:454872 // At this point, the program's shaders may not be translated yet,
4873 // therefore, we may not find the hashed attribute name.
4874 // glBindAttribLocation call with original name is useless.
4875 // So instead, we should simply cache the binding, and then call
4876 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:424877 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:454878 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:424879 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574880}
4881
[email protected]558847a2010-03-24 07:02:544882error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:344883 uint32 immediate_data_size,
4884 const void* cmd_data) {
4885 const gles2::cmds::BindAttribLocationBucket& c =
4886 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:584887 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544888 GLuint index = static_cast<GLuint>(c.index);
4889 Bucket* bucket = GetBucket(c.name_bucket_id);
4890 if (!bucket || bucket->size() == 0) {
4891 return error::kInvalidArguments;
4892 }
4893 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184894 if (!bucket->GetAsString(&name_str)) {
4895 return error::kInvalidArguments;
4896 }
[email protected]258a3313f2011-10-18 20:13:574897 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544898 return error::kNoError;
4899}
4900
[email protected]2be6abf32012-06-26 00:28:334901void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424902 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334903 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514904 LOCAL_SET_GL_ERROR(
4905 GL_INVALID_VALUE,
4906 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334907 return;
4908 }
4909 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514910 LOCAL_SET_GL_ERROR(
4911 GL_INVALID_OPERATION,
4912 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334913 return;
4914 }
4915 if (location < 0 || static_cast<uint32>(location) >=
4916 (group_->max_fragment_uniform_vectors() +
4917 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514918 LOCAL_SET_GL_ERROR(
4919 GL_INVALID_VALUE,
4920 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334921 return;
4922 }
[email protected]df37b9932013-03-08 05:21:424923 Program* program = GetProgramInfoNotShader(
4924 program_id, "glBindUniformLocationCHROMIUM");
4925 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334926 return;
4927 }
[email protected]df37b9932013-03-08 05:21:424928 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514929 LOCAL_SET_GL_ERROR(
4930 GL_INVALID_VALUE,
4931 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334932 }
4933}
4934
[email protected]2be6abf32012-06-26 00:28:334935error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4936 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:344937 const void* cmd_data) {
4938 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
4939 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
4940 cmd_data);
[email protected]2be6abf32012-06-26 00:28:334941 GLuint program = static_cast<GLuint>(c.program);
4942 GLint location = static_cast<GLint>(c.location);
4943 Bucket* bucket = GetBucket(c.name_bucket_id);
4944 if (!bucket || bucket->size() == 0) {
4945 return error::kInvalidArguments;
4946 }
4947 std::string name_str;
4948 if (!bucket->GetAsString(&name_str)) {
4949 return error::kInvalidArguments;
4950 }
4951 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4952 return error::kNoError;
4953}
4954
vmiuracd108592014-09-08 14:36:344955error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
4956 const void* cmd_data) {
4957 const gles2::cmds::DeleteShader& c =
4958 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:034959 GLuint client_id = c.shader;
4960 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424961 Shader* shader = GetShader(client_id);
4962 if (shader) {
4963 if (!shader->IsDeleted()) {
4964 glDeleteShader(shader->service_id());
4965 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144966 }
[email protected]ae51d192010-04-27 00:48:034967 } else {
[email protected]ab09b612013-03-11 22:11:514968 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034969 }
[email protected]96449d2c2009-11-25 00:01:324970 }
[email protected]f7a64ee2010-02-01 22:24:144971 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324972}
4973
vmiuracd108592014-09-08 14:36:344974error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
4975 const void* cmd_data) {
4976 const gles2::cmds::DeleteProgram& c =
4977 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:034978 GLuint client_id = c.program;
4979 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424980 Program* program = GetProgram(client_id);
4981 if (program) {
4982 if (!program->IsDeleted()) {
4983 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144984 }
[email protected]ae51d192010-04-27 00:48:034985 } else {
[email protected]ab09b612013-03-11 22:11:514986 LOCAL_SET_GL_ERROR(
4987 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034988 }
[email protected]96449d2c2009-11-25 00:01:324989 }
[email protected]f7a64ee2010-02-01 22:24:144990 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324991}
4992
[email protected]a7266a92012-06-28 02:11:084993error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444994 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204995 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:464996 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:204997 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]3a03a8f2011-03-19 00:51:274998 glClear(mask);
4999 }
[email protected]a7266a92012-06-28 02:11:085000 return error::kNoError;
5001}
5002
[email protected]36cef8ce2010-03-16 07:34:455003void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5004 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035005 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065006 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5007 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515008 LOCAL_SET_GL_ERROR(
5009 GL_INVALID_OPERATION,
5010 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455011 return;
5012 }
[email protected]ae51d192010-04-27 00:48:035013 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275014 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035015 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275016 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5017 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515018 LOCAL_SET_GL_ERROR(
5019 GL_INVALID_OPERATION,
5020 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035021 return;
5022 }
[email protected]ee2a79c32013-03-10 03:50:275023 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035024 }
[email protected]ab09b612013-03-11 22:11:515025 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035026 glFramebufferRenderbufferEXT(
5027 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515028 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265029 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275030 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285031 }
[email protected]9d3b2e12013-10-02 01:04:345032 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445033 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465034 }
[email protected]81fc9d02013-03-14 23:53:325035 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285036}
5037
[email protected]3a2e7c7b2010-08-06 01:12:285038void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465039 if (SetCapabilityState(cap, false)) {
5040 glDisable(cap);
5041 }
[email protected]3a2e7c7b2010-08-06 01:12:285042}
5043
5044void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465045 if (SetCapabilityState(cap, true)) {
5046 glEnable(cap);
5047 }
[email protected]3a2e7c7b2010-08-06 01:12:285048}
5049
[email protected]88a61bf2012-10-27 13:00:425050void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5051 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5052 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5053 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285054}
5055
[email protected]b04e24c2013-01-08 18:35:255056void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425057 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5058 state_.sample_coverage_invert = (invert != 0);
5059 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285060}
5061
[email protected]0d6bfdc2011-11-02 01:32:205062// Assumes framebuffer is complete.
5063void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065064 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305065 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205066 // bind this to the DRAW point, clear then bind back to READ
5067 // TODO(gman): I don't think there is any guarantee that an FBO that
5068 // is complete on the READ attachment will be complete as a DRAW
5069 // attachment.
5070 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065071 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305072 }
[email protected]3a2e7c7b2010-08-06 01:12:285073 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425074 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465075 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205076 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465077 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065078 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5079 1.0f);
[email protected]454157e2014-05-03 02:49:455080 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285081 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535082 if (feature_info_->feature_flags().ext_draw_buffers)
5083 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285084 }
5085
[email protected]4d8f0dd2013-03-09 14:37:065086 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5087 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285088 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475089 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5090 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285091 clear_bits |= GL_STENCIL_BUFFER_BIT;
5092 }
5093
[email protected]4d8f0dd2013-03-09 14:37:065094 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5095 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285096 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455097 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285098 clear_bits |= GL_DEPTH_BUFFER_BIT;
5099 }
5100
[email protected]454157e2014-05-03 02:49:455101 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285102 glClear(clear_bits);
5103
[email protected]0e58af82014-08-08 14:02:535104 if ((clear_bits | GL_COLOR_BUFFER_BIT) != 0 &&
5105 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425106 framebuffer->RestoreDrawBuffersAfterClear();
5107
[email protected]968351b2011-12-20 08:26:515108 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065109 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285110
[email protected]c007aa02010-09-02 22:22:405111 RestoreClearState();
5112
5113 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065114 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5115 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485116 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065117 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5118 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485119 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405120 }
5121}
5122
5123void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445124 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245125 glClearColor(
5126 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5127 state_.color_clear_alpha);
5128 glClearStencil(state_.stencil_clear);
5129 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225130 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455131 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285132 }
[email protected]36cef8ce2010-03-16 07:34:455133}
5134
5135GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355136 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305137 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205138 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455139 return GL_FRAMEBUFFER_COMPLETE;
5140 }
[email protected]0d6bfdc2011-11-02 01:32:205141 GLenum completeness = framebuffer->IsPossiblyComplete();
5142 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5143 return completeness;
5144 }
[email protected]73276522012-11-09 05:50:205145 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455146}
5147
5148void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035149 GLenum target, GLenum attachment, GLenum textarget,
5150 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165151 DoFramebufferTexture2DCommon(
5152 "glFramebufferTexture2D", target, attachment,
5153 textarget, client_texture_id, level, 0);
5154}
5155
5156void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5157 GLenum target, GLenum attachment, GLenum textarget,
5158 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165159 DoFramebufferTexture2DCommon(
5160 "glFramebufferTexture2DMultisample", target, attachment,
5161 textarget, client_texture_id, level, samples);
5162}
5163
5164void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5165 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5166 GLuint client_texture_id, GLint level, GLsizei samples) {
5167 if (samples > renderbuffer_manager()->max_samples()) {
5168 LOCAL_SET_GL_ERROR(
5169 GL_INVALID_VALUE,
5170 "glFramebufferTexture2DMultisample", "samples too large");
5171 return;
5172 }
[email protected]4d8f0dd2013-03-09 14:37:065173 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5174 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515175 LOCAL_SET_GL_ERROR(
5176 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165177 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455178 return;
5179 }
[email protected]ae51d192010-04-27 00:48:035180 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495181 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035182 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495183 texture_ref = GetTexture(client_texture_id);
5184 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515185 LOCAL_SET_GL_ERROR(
5186 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165187 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035188 return;
5189 }
[email protected]370eaf12013-05-18 09:19:495190 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035191 }
[email protected]0d6bfdc2011-11-02 01:32:205192
[email protected]80eb6b52012-01-19 00:14:415193 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515194 LOCAL_SET_GL_ERROR(
5195 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165196 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205197 return;
5198 }
5199
[email protected]91c94eb2013-10-22 10:32:545200 if (texture_ref)
5201 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5202
[email protected]7d3c36e2013-07-12 14:13:165203 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5204 if (0 == samples) {
5205 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5206 } else {
5207 if (features().use_img_for_multisampled_render_to_texture) {
5208 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5209 service_id, level, samples);
5210 } else {
5211 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5212 service_id, level, samples);
5213 }
5214 }
5215 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265216 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165217 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5218 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285219 }
[email protected]9d3b2e12013-10-02 01:04:345220 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445221 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465222 }
[email protected]91c94eb2013-10-22 10:32:545223
5224 if (texture_ref)
5225 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5226
[email protected]81fc9d02013-03-14 23:53:325227 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455228}
5229
5230void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5231 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065232 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5233 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515234 LOCAL_SET_GL_ERROR(
5235 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205236 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455237 return;
5238 }
[email protected]74c1ec42010-08-12 01:55:575239 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105240 const Framebuffer::Attachment* attachment_object =
5241 framebuffer->GetAttachment(attachment);
5242 *params = attachment_object ? attachment_object->object_name() : 0;
5243 } else {
[email protected]7d3c36e2013-07-12 14:13:165244 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5245 features().use_img_for_multisampled_render_to_texture) {
5246 pname = GL_TEXTURE_SAMPLES_IMG;
5247 }
[email protected]62e65f02013-05-29 22:28:105248 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575249 }
[email protected]36cef8ce2010-03-16 07:34:455250}
5251
5252void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5253 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355254 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205255 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5256 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515257 LOCAL_SET_GL_ERROR(
5258 GL_INVALID_OPERATION,
5259 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455260 return;
5261 }
[email protected]8875a5f2014-06-27 08:33:475262
5263 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275264 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435265 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5266 *params = renderbuffer->internal_format();
5267 break;
5268 case GL_RENDERBUFFER_WIDTH:
5269 *params = renderbuffer->width();
5270 break;
5271 case GL_RENDERBUFFER_HEIGHT:
5272 *params = renderbuffer->height();
5273 break;
[email protected]7d3c36e2013-07-12 14:13:165274 case GL_RENDERBUFFER_SAMPLES_EXT:
5275 if (features().use_img_for_multisampled_render_to_texture) {
5276 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5277 params);
5278 } else {
5279 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5280 params);
5281 }
[email protected]ad84a3a2012-06-08 21:42:435282 default:
5283 glGetRenderbufferParameterivEXT(target, pname, params);
5284 break;
[email protected]b71f52c2010-06-18 22:20:205285 }
[email protected]36cef8ce2010-03-16 07:34:455286}
5287
[email protected]49cabed2013-11-13 18:15:185288void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305289 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5290 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5291 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445292 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165293
[email protected]49cabed2013-11-13 18:15:185294 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165295 return;
5296 }
5297
[email protected]454157e2014-05-03 02:49:455298 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205299 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185300 BlitFramebufferHelper(
5301 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455302 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5303 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185304}
5305
[email protected]8875a5f2014-06-27 08:33:475306void GLES2DecoderImpl::EnsureRenderbufferBound() {
5307 if (!state_.bound_renderbuffer_valid) {
5308 state_.bound_renderbuffer_valid = true;
5309 glBindRenderbufferEXT(GL_RENDERBUFFER,
5310 state_.bound_renderbuffer.get()
5311 ? state_.bound_renderbuffer->service_id()
5312 : 0);
5313 }
5314}
5315
[email protected]f42f05b2013-11-15 21:46:185316void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5317 const FeatureInfo* feature_info,
5318 GLenum target,
5319 GLsizei samples,
5320 GLenum internal_format,
5321 GLsizei width,
5322 GLsizei height) {
5323 // TODO(sievers): This could be resolved at the GL binding level, but the
5324 // binding process is currently a bit too 'brute force'.
5325 if (feature_info->feature_flags().is_angle) {
5326 glRenderbufferStorageMultisampleANGLE(
5327 target, samples, internal_format, width, height);
5328 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5329 glRenderbufferStorageMultisample(
5330 target, samples, internal_format, width, height);
5331 } else {
5332 glRenderbufferStorageMultisampleEXT(
5333 target, samples, internal_format, width, height);
5334 }
5335}
5336
5337void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5338 GLint srcY0,
5339 GLint srcX1,
5340 GLint srcY1,
5341 GLint dstX0,
5342 GLint dstY0,
5343 GLint dstX1,
5344 GLint dstY1,
5345 GLbitfield mask,
5346 GLenum filter) {
5347 // TODO(sievers): This could be resolved at the GL binding level, but the
5348 // binding process is currently a bit too 'brute force'.
5349 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245350 glBlitFramebufferANGLE(
5351 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185352 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5353 glBlitFramebuffer(
5354 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245355 } else {
5356 glBlitFramebufferEXT(
5357 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5358 }
[email protected]8e3e0662010-08-23 18:46:305359}
5360
[email protected]49cabed2013-11-13 18:15:185361bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5362 GLsizei samples,
5363 GLenum internalformat,
5364 GLsizei width,
5365 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535366 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515367 LOCAL_SET_GL_ERROR(
5368 GL_INVALID_VALUE,
5369 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185370 return false;
[email protected]84afefa2011-10-19 21:45:535371 }
5372
5373 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5374 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515375 LOCAL_SET_GL_ERROR(
5376 GL_INVALID_VALUE,
5377 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185378 return false;
[email protected]84afefa2011-10-19 21:45:535379 }
5380
[email protected]7989c9e2013-01-23 06:39:265381 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235382 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5383 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515384 LOCAL_SET_GL_ERROR(
5385 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205386 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185387 return false;
[email protected]8e3e0662010-08-23 18:46:305388 }
5389
[email protected]7989c9e2013-01-23 06:39:265390 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515391 LOCAL_SET_GL_ERROR(
5392 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205393 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185394 return false;
5395 }
5396
5397 return true;
5398}
5399
5400void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5401 GLenum target, GLsizei samples, GLenum internalformat,
5402 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185403 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5404 if (!renderbuffer) {
5405 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5406 "glRenderbufferStorageMultisampleCHROMIUM",
5407 "no renderbuffer bound");
5408 return;
5409 }
5410
5411 if (!ValidateRenderbufferStorageMultisample(
5412 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265413 return;
5414 }
5415
[email protected]8875a5f2014-06-27 08:33:475416 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235417 GLenum impl_format =
5418 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5419 internalformat);
[email protected]49cabed2013-11-13 18:15:185420 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5421 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185422 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255423 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185424 GLenum error =
5425 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265426 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105427
5428 if (workarounds().validate_multisample_buffer_allocation) {
5429 if (!VerifyMultisampleRenderbufferIntegrity(
5430 renderbuffer->service_id(), impl_format)) {
5431 LOCAL_SET_GL_ERROR(
5432 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185433 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105434 return;
5435 }
5436 }
5437
[email protected]968351b2011-12-20 08:26:515438 // TODO(gman): If renderbuffers tracked which framebuffers they were
5439 // attached to we could just mark those framebuffers as not complete.
5440 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205441 renderbuffer_manager()->SetInfo(
5442 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265443 }
[email protected]8e3e0662010-08-23 18:46:305444}
5445
[email protected]49cabed2013-11-13 18:15:185446// This is the handler for multisampled_render_to_texture extensions.
5447void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5448 GLenum target, GLsizei samples, GLenum internalformat,
5449 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185450 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5451 if (!renderbuffer) {
5452 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5453 "glRenderbufferStorageMultisampleEXT",
5454 "no renderbuffer bound");
5455 return;
5456 }
5457
5458 if (!ValidateRenderbufferStorageMultisample(
5459 samples, internalformat, width, height)) {
5460 return;
5461 }
5462
[email protected]8875a5f2014-06-27 08:33:475463 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185464 GLenum impl_format =
5465 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5466 internalformat);
5467 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5468 if (features().use_img_for_multisampled_render_to_texture) {
5469 glRenderbufferStorageMultisampleIMG(
5470 target, samples, impl_format, width, height);
5471 } else {
5472 glRenderbufferStorageMultisampleEXT(
5473 target, samples, impl_format, width, height);
5474 }
5475 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5476 if (error == GL_NO_ERROR) {
5477 // TODO(gman): If renderbuffers tracked which framebuffers they were
5478 // attached to we could just mark those framebuffers as not complete.
5479 framebuffer_manager()->IncFramebufferStateChangeCount();
5480 renderbuffer_manager()->SetInfo(
5481 renderbuffer, samples, internalformat, width, height);
5482 }
5483}
5484
[email protected]4a4c18b2013-09-13 22:50:105485// This function validates the allocation of a multisampled renderbuffer
5486// by clearing it to a key color, blitting the contents to a texture, and
5487// reading back the color to ensure it matches the key.
5488bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5489 GLuint renderbuffer, GLenum format) {
5490
5491 // Only validate color buffers.
5492 // These formats have been selected because they are very common or are known
5493 // to be used by the WebGL backbuffer. If problems are observed with other
5494 // color formats they can be added here.
5495 switch(format) {
5496 case GL_RGB:
5497 case GL_RGB8:
5498 case GL_RGBA:
5499 case GL_RGBA8:
5500 break;
5501 default:
5502 return true;
5503 }
5504
5505 GLint draw_framebuffer, read_framebuffer;
5506
5507 // Cache framebuffer and texture bindings.
5508 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5509 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5510
5511 if (!validation_texture_) {
5512 GLint bound_texture;
5513 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5514
5515 // Create additional resources needed for the verification.
5516 glGenTextures(1, &validation_texture_);
5517 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5518 glGenFramebuffersEXT(1, &validation_fbo_);
5519
5520 // Texture only needs to be 1x1.
5521 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5522 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5523 GL_UNSIGNED_BYTE, NULL);
5524
5525 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5526 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5527 GL_TEXTURE_2D, validation_texture_, 0);
5528
5529 glBindTexture(GL_TEXTURE_2D, bound_texture);
5530 }
5531
5532 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5533 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5534 GL_RENDERBUFFER, renderbuffer);
5535
5536 // Cache current state and reset it to the values we require.
5537 GLboolean scissor_enabled = false;
5538 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5539 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455540 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105541
[email protected]454157e2014-05-03 02:49:455542 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105543 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455544 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105545
5546 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5547 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5548 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5549
5550 // Clear the buffer to the desired key color.
5551 glClear(GL_COLOR_BUFFER_BIT);
5552
5553 // Blit from the multisample buffer to a standard texture.
5554 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5555 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5556
[email protected]f42f05b2013-11-15 21:46:185557 BlitFramebufferHelper(
5558 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105559
5560 // Read a pixel from the buffer.
5561 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5562
5563 unsigned char pixel[3] = {0, 0, 0};
5564 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5565
5566 // Detach the renderbuffer.
5567 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5568 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5569 GL_RENDERBUFFER, 0);
5570
5571 // Restore cached state.
5572 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455573 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105574
[email protected]454157e2014-05-03 02:49:455575 state_.SetDeviceColorMask(
5576 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105577 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5578 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5579 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5580
5581 // Return true if the pixel matched the desired key color.
5582 return (pixel[0] == 0xFF &&
5583 pixel[1] == 0x00 &&
5584 pixel[2] == 0xFF);
5585}
5586
[email protected]36cef8ce2010-03-16 07:34:455587void GLES2DecoderImpl::DoRenderbufferStorage(
5588 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355589 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205590 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5591 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515592 LOCAL_SET_GL_ERROR(
5593 GL_INVALID_OPERATION,
5594 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455595 return;
5596 }
[email protected]876f6fee2010-08-02 23:10:325597
[email protected]84afefa2011-10-19 21:45:535598 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5599 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515600 LOCAL_SET_GL_ERROR(
5601 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535602 return;
5603 }
5604
[email protected]7989c9e2013-01-23 06:39:265605 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235606 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5607 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515608 LOCAL_SET_GL_ERROR(
5609 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265610 return;
5611 }
5612
5613 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515614 LOCAL_SET_GL_ERROR(
5615 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265616 return;
[email protected]b71f52c2010-06-18 22:20:205617 }
[email protected]876f6fee2010-08-02 23:10:325618
[email protected]8875a5f2014-06-27 08:33:475619 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515620 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265621 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235622 target,
5623 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5624 internalformat),
5625 width,
5626 height);
[email protected]ab09b612013-03-11 22:11:515627 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265628 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515629 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5630 // we could just mark those framebuffers as not complete.
5631 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205632 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265633 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265634 }
[email protected]36cef8ce2010-03-16 07:34:455635}
5636
[email protected]df37b9932013-03-08 05:21:425637void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385638 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425639 Program* program = GetProgramInfoNotShader(
5640 program_id, "glLinkProgram");
5641 if (!program) {
[email protected]a93bb842010-02-16 23:03:475642 return;
5643 }
[email protected]05afda12011-01-20 00:17:345644
[email protected]df37b9932013-03-08 05:21:425645 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395646 ShaderTranslator* vertex_translator = NULL;
5647 ShaderTranslator* fragment_translator = NULL;
5648 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115649 vertex_translator = vertex_translator_.get();
5650 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395651 }
[email protected]df37b9932013-03-08 05:21:425652 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115653 vertex_translator,
5654 fragment_translator,
[email protected]008401532014-02-07 00:10:505655 workarounds().count_all_in_varyings_packing ?
5656 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115657 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425658 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185659 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425660 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185661 if (workarounds().clear_uniforms_before_first_program_use)
5662 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545663 }
5664 }
vmiura8266ca72014-09-09 21:37:005665
5666 // LinkProgram can be very slow. Exit command processing to allow for
5667 // context preemption and GPU watchdog checks.
5668 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305669};
5670
[email protected]3916c97e2010-02-25 03:20:505671void GLES2DecoderImpl::DoTexParameterf(
5672 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445673 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5674 &state_, target);
[email protected]02965c22013-03-09 02:40:075675 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515676 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245677 return;
[email protected]07f54fcc2009-12-22 02:46:305678 }
[email protected]cbb22e42011-05-12 23:36:245679
[email protected]737191ee72014-03-09 08:02:425680 texture_manager()->SetParameterf(
5681 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305682}
5683
[email protected]3916c97e2010-02-25 03:20:505684void GLES2DecoderImpl::DoTexParameteri(
5685 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445686 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5687 &state_, target);
[email protected]02965c22013-03-09 02:40:075688 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515689 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245690 return;
[email protected]3916c97e2010-02-25 03:20:505691 }
[email protected]cbb22e42011-05-12 23:36:245692
[email protected]737191ee72014-03-09 08:02:425693 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505694 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505695}
5696
5697void GLES2DecoderImpl::DoTexParameterfv(
5698 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445699 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5700 &state_, target);
[email protected]02965c22013-03-09 02:40:075701 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515702 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245703 return;
[email protected]3916c97e2010-02-25 03:20:505704 }
[email protected]cbb22e42011-05-12 23:36:245705
[email protected]737191ee72014-03-09 08:02:425706 texture_manager()->SetParameterf(
5707 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505708}
5709
5710void GLES2DecoderImpl::DoTexParameteriv(
5711 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445712 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5713 &state_, target);
[email protected]02965c22013-03-09 02:40:075714 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515715 LOCAL_SET_GL_ERROR(
5716 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245717 return;
[email protected]3916c97e2010-02-25 03:20:505718 }
[email protected]cbb22e42011-05-12 23:36:245719
[email protected]737191ee72014-03-09 08:02:425720 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505721 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505722}
5723
[email protected]939e7362010-05-13 20:49:105724bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115725 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435726 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515727 LOCAL_SET_GL_ERROR(
5728 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435729 return false;
[email protected]939e7362010-05-13 20:49:105730 }
[email protected]e259eb412012-10-13 05:47:245731 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515732 LOCAL_SET_GL_ERROR(
5733 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105734 return false;
5735 }
5736 return true;
5737}
5738
5739bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5740 GLint location, const char* function_name) {
5741 if (!CheckCurrentProgram(function_name)) {
5742 return false;
5743 }
5744 return location != -1;
5745}
5746
zmof9a81360f2014-10-17 00:06:145747bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
5748 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
5749 if (!framebuffer)
5750 return false;
5751 const Framebuffer::Attachment* attachment =
5752 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
5753 if (!attachment)
5754 return false;
5755
5756 DCHECK(state_.current_program.get());
5757 const Program::SamplerIndices& sampler_indices =
5758 state_.current_program->sampler_indices();
5759 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
5760 const Program::UniformInfo* uniform_info =
5761 state_.current_program->GetUniformInfo(sampler_indices[ii]);
5762 DCHECK(uniform_info);
5763 if (uniform_info->type != GL_SAMPLER_2D)
5764 continue;
5765 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5766 GLuint texture_unit_index = uniform_info->texture_units[jj];
5767 if (texture_unit_index >= state_.texture_units.size())
5768 continue;
5769 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
5770 TextureRef* texture_ref =
5771 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
5772 if (attachment->IsTexture(texture_ref))
5773 return true;
5774 }
5775 }
5776 return false;
5777}
5778
[email protected]43c2f1f2011-03-25 18:35:365779bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:135780 GLint fake_location,
5781 const char* function_name,
5782 Program::UniformApiType api_type,
5783 GLint* real_location,
5784 GLenum* type,
5785 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365786 DCHECK(type);
5787 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125788 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525789
[email protected]1b0a6752012-02-22 03:44:125790 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105791 return false;
5792 }
[email protected]43c2f1f2011-03-25 18:35:365793 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355794 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245795 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125796 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365797 if (!info) {
[email protected]ab09b612013-03-11 22:11:515798 LOCAL_SET_GL_ERROR(
5799 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105800 return false;
5801 }
[email protected]9b1f1b52014-03-12 10:40:135802
5803 if ((api_type & info->accepts_api_type) == 0) {
[email protected]ab09b612013-03-11 22:11:515804 LOCAL_SET_GL_ERROR(
5805 GL_INVALID_OPERATION, function_name,
5806 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525807 return false;
5808 }
[email protected]43c2f1f2011-03-25 18:35:365809 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515810 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435811 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365812 return false;
5813 }
5814 *count = std::min(info->size - array_index, *count);
5815 if (*count <= 0) {
5816 return false;
5817 }
5818 *type = info->type;
[email protected]939e7362010-05-13 20:49:105819 return true;
5820}
5821
[email protected]1b0a6752012-02-22 03:44:125822void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5823 GLenum type = 0;
5824 GLsizei count = 1;
5825 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135826 if (!PrepForSetUniformByLocation(fake_location,
5827 "glUniform1i",
5828 Program::kUniform1i,
5829 &real_location,
5830 &type,
5831 &count)) {
[email protected]3916c97e2010-02-25 03:20:505832 return;
5833 }
[email protected]e259eb412012-10-13 05:47:245834 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025835 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515836 LOCAL_SET_GL_ERROR(
5837 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465838 return;
5839 }
[email protected]1b0a6752012-02-22 03:44:125840 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505841}
5842
5843void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125844 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365845 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125846 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135847 if (!PrepForSetUniformByLocation(fake_location,
5848 "glUniform1iv",
5849 Program::kUniform1i,
5850 &real_location,
5851 &type,
5852 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365853 return;
5854 }
[email protected]74727112012-06-13 21:18:085855 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5856 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245857 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025858 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515859 LOCAL_SET_GL_ERROR(
5860 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465861 return;
5862 }
[email protected]43c2f1f2011-03-25 18:35:365863 }
[email protected]1b0a6752012-02-22 03:44:125864 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505865}
5866
[email protected]939e7362010-05-13 20:49:105867void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125868 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365869 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125870 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135871 if (!PrepForSetUniformByLocation(fake_location,
5872 "glUniform1fv",
5873 Program::kUniform1f,
5874 &real_location,
5875 &type,
5876 &count)) {
[email protected]939e7362010-05-13 20:49:105877 return;
5878 }
5879 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555880 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105881 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535882 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105883 }
[email protected]1b0a6752012-02-22 03:44:125884 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105885 } else {
[email protected]1b0a6752012-02-22 03:44:125886 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105887 }
5888}
5889
5890void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125891 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365892 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125893 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135894 if (!PrepForSetUniformByLocation(fake_location,
5895 "glUniform2fv",
5896 Program::kUniform2f,
5897 &real_location,
5898 &type,
5899 &count)) {
[email protected]939e7362010-05-13 20:49:105900 return;
5901 }
5902 if (type == GL_BOOL_VEC2) {
5903 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555904 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105905 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535906 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105907 }
[email protected]1b0a6752012-02-22 03:44:125908 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105909 } else {
[email protected]1b0a6752012-02-22 03:44:125910 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105911 }
5912}
5913
5914void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125915 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365916 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125917 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135918 if (!PrepForSetUniformByLocation(fake_location,
5919 "glUniform3fv",
5920 Program::kUniform3f,
5921 &real_location,
5922 &type,
5923 &count)) {
[email protected]939e7362010-05-13 20:49:105924 return;
5925 }
5926 if (type == GL_BOOL_VEC3) {
5927 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555928 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105929 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535930 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105931 }
[email protected]1b0a6752012-02-22 03:44:125932 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105933 } else {
[email protected]1b0a6752012-02-22 03:44:125934 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105935 }
5936}
5937
5938void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125939 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365940 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125941 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135942 if (!PrepForSetUniformByLocation(fake_location,
5943 "glUniform4fv",
5944 Program::kUniform4f,
5945 &real_location,
5946 &type,
5947 &count)) {
[email protected]939e7362010-05-13 20:49:105948 return;
5949 }
5950 if (type == GL_BOOL_VEC4) {
5951 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555952 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105953 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535954 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105955 }
[email protected]1b0a6752012-02-22 03:44:125956 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105957 } else {
[email protected]1b0a6752012-02-22 03:44:125958 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105959 }
5960}
5961
[email protected]43c2f1f2011-03-25 18:35:365962void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125963 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365964 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125965 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135966 if (!PrepForSetUniformByLocation(fake_location,
5967 "glUniform2iv",
5968 Program::kUniform2i,
5969 &real_location,
5970 &type,
5971 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365972 return;
5973 }
[email protected]1b0a6752012-02-22 03:44:125974 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365975}
5976
5977void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125978 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365979 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125980 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135981 if (!PrepForSetUniformByLocation(fake_location,
5982 "glUniform3iv",
5983 Program::kUniform3i,
5984 &real_location,
5985 &type,
5986 &count)) {
[email protected]43c2f1f2011-03-25 18:35:365987 return;
5988 }
[email protected]1b0a6752012-02-22 03:44:125989 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365990}
5991
5992void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125993 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365994 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125995 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:135996 if (!PrepForSetUniformByLocation(fake_location,
5997 "glUniform4iv",
5998 Program::kUniform4i,
5999 &real_location,
6000 &type,
6001 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366002 return;
6003 }
[email protected]1b0a6752012-02-22 03:44:126004 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366005}
6006
6007void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126008 GLint fake_location, GLsizei count, GLboolean transpose,
6009 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366010 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126011 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136012 if (!PrepForSetUniformByLocation(fake_location,
6013 "glUniformMatrix2fv",
6014 Program::kUniformMatrix2f,
6015 &real_location,
6016 &type,
6017 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366018 return;
6019 }
[email protected]1b0a6752012-02-22 03:44:126020 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366021}
6022
6023void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126024 GLint fake_location, GLsizei count, GLboolean transpose,
6025 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366026 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126027 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136028 if (!PrepForSetUniformByLocation(fake_location,
6029 "glUniformMatrix3fv",
6030 Program::kUniformMatrix3f,
6031 &real_location,
6032 &type,
6033 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366034 return;
6035 }
[email protected]1b0a6752012-02-22 03:44:126036 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366037}
6038
6039void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126040 GLint fake_location, GLsizei count, GLboolean transpose,
6041 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366042 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126043 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136044 if (!PrepForSetUniformByLocation(fake_location,
6045 "glUniformMatrix4fv",
6046 Program::kUniformMatrix4f,
6047 &real_location,
6048 &type,
6049 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366050 return;
6051 }
[email protected]1b0a6752012-02-22 03:44:126052 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366053}
6054
[email protected]df37b9932013-03-08 05:21:426055void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036056 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426057 Program* program = NULL;
6058 if (program_id) {
6059 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6060 if (!program) {
[email protected]ae51d192010-04-27 00:48:036061 return;
6062 }
[email protected]df37b9932013-03-08 05:21:426063 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506064 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516065 LOCAL_SET_GL_ERROR(
6066 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506067 return;
6068 }
[email protected]df37b9932013-03-08 05:21:426069 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506070 }
[email protected]7cd76fd2013-06-02 21:11:116071 if (state_.current_program.get()) {
6072 program_manager()->UnuseProgram(shader_manager(),
6073 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146074 }
[email protected]df37b9932013-03-08 05:21:426075 state_.current_program = program;
6076 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546077 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116078 if (state_.current_program.get()) {
6079 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186080 if (workarounds().clear_uniforms_before_first_program_use)
6081 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146082 }
[email protected]3916c97e2010-02-25 03:20:506083}
6084
[email protected]ab09b612013-03-11 22:11:516085void GLES2DecoderImpl::RenderWarning(
6086 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326087 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016088}
6089
[email protected]ab09b612013-03-11 22:11:516090void GLES2DecoderImpl::PerformanceWarning(
6091 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506092 logger_.LogMessage(filename, line,
6093 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016094}
6095
[email protected]91c94eb2013-10-22 10:32:546096void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6097 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546098 // Image is already in use if texture is attached to a framebuffer.
6099 if (texture && !texture->IsAttachedToFramebuffer()) {
6100 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6101 if (image) {
6102 ScopedGLErrorSuppressor suppressor(
6103 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6104 GetErrorState());
6105 glBindTexture(textarget, texture->service_id());
6106 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026107 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546108 }
6109 }
6110}
6111
6112void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6113 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546114 // Image is still in use if texture is attached to a framebuffer.
6115 if (texture && !texture->IsAttachedToFramebuffer()) {
6116 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6117 if (image) {
6118 ScopedGLErrorSuppressor suppressor(
6119 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6120 GetErrorState());
6121 glBindTexture(textarget, texture->service_id());
6122 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026123 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546124 }
6125 }
6126}
6127
[email protected]e56131d22013-07-28 16:14:116128bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116129 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546130 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556131 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116132 return true;
[email protected]ef526492010-06-02 23:12:256133 }
[email protected]e2367b42013-05-31 03:37:216134
[email protected]ef526492010-06-02 23:12:256135 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356136 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246137 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506138 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356139 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246140 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506141 DCHECK(uniform_info);
6142 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6143 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026144 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246145 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546146 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366147 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546148 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6149 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256150 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506151 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6152 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546153 textarget,
[email protected]00f893d2010-08-24 18:55:496154 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:516155 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:016156 std::string("texture bound to texture unit ") +
6157 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:296158 " is not renderable. It maybe non-power-of-2 and have"
6159 " incompatible texture filtering or is not"
6160 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:546161 continue;
[email protected]3916c97e2010-02-25 03:20:506162 }
[email protected]91c94eb2013-10-22 10:32:546163
[email protected]4e7b89202014-01-28 01:44:066164 if (textarget != GL_TEXTURE_CUBE_MAP) {
6165 Texture* texture = texture_ref->texture();
6166 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6167 if (image && !texture->IsAttachedToFramebuffer()) {
6168 ScopedGLErrorSuppressor suppressor(
6169 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6170 textures_set = true;
6171 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6172 image->WillUseTexImage();
6173 continue;
6174 }
[email protected]91c94eb2013-10-22 10:32:546175 }
[email protected]3916c97e2010-02-25 03:20:506176 }
6177 // else: should this be an error?
6178 }
6179 }
[email protected]e56131d22013-07-28 16:14:116180 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506181}
6182
[email protected]91c94eb2013-10-22 10:32:546183void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116184 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356185 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116186 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506187 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356188 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246189 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506190 DCHECK(uniform_info);
6191 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6192 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026193 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246194 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116195 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546196 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496197 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506198 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496199 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116200 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6201 ? texture_unit.bound_texture_2d.get()
6202 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506203 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496204 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546205 continue;
6206 }
6207
[email protected]4e7b89202014-01-28 01:44:066208 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6209 Texture* texture = texture_ref->texture();
6210 gfx::GLImage* image =
6211 texture->GetLevelImage(texture_unit.bind_target, 0);
6212 if (image && !texture->IsAttachedToFramebuffer()) {
6213 ScopedGLErrorSuppressor suppressor(
6214 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6215 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6216 image->DidUseTexImage();
6217 continue;
6218 }
[email protected]3916c97e2010-02-25 03:20:506219 }
6220 }
6221 }
6222 }
6223 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246224 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306225}
6226
[email protected]0d6bfdc2011-11-02 01:32:206227bool GLES2DecoderImpl::ClearUnclearedTextures() {
6228 // Only check if there are some uncleared textures.
6229 if (!texture_manager()->HaveUnsafeTextures()) {
6230 return true;
6231 }
6232
6233 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116234 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356235 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116236 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206237 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356238 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246239 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206240 DCHECK(uniform_info);
6241 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6242 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026243 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246244 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496245 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366246 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496247 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6248 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206249 return false;
6250 }
6251 }
6252 }
6253 }
6254 }
6255 }
6256 return true;
6257}
6258
[email protected]c6aef902012-02-14 03:31:426259bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106260 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6261 GLsizei primcount) {
6262 DCHECK(instanced || primcount == 1);
6263
[email protected]689fa1c52010-06-09 18:35:036264 // NOTE: We specifically do not check current_program->IsValid() because
6265 // it could never be invalid since glUseProgram would have failed. While
6266 // glLinkProgram could later mark the program as invalid the previous
6267 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116268 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506269 // The program does not exist.
6270 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516271 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506272 return false;
6273 }
[email protected]c6aef902012-02-14 03:31:426274
zmof9a81360f2014-10-17 00:06:146275 if (CheckDrawingFeedbackLoops()) {
6276 LOCAL_SET_GL_ERROR(
6277 GL_INVALID_OPERATION, function_name,
6278 "Source and destination textures of the draw are the same.");
6279 return false;
6280 }
6281
[email protected]7cd76fd2013-06-02 21:11:116282 return state_.vertex_attrib_manager
6283 ->ValidateBindings(function_name,
6284 this,
6285 feature_info_.get(),
6286 state_.current_program.get(),
6287 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106288 instanced,
[email protected]7cd76fd2013-06-02 21:11:116289 primcount);
[email protected]b1122982010-05-17 23:04:246290}
6291
[email protected]c13e1da62011-09-09 21:48:306292bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436293 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306294 DCHECK(simulated);
6295 *simulated = false;
6296
[email protected]876f6fee2010-08-02 23:10:326297 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306298 return true;
[email protected]876f6fee2010-08-02 23:10:326299
[email protected]ac77603c72013-03-08 13:52:066300 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356301 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246302 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246303 bool attrib_0_used =
6304 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066305 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306306 return true;
[email protected]b1122982010-05-17 23:04:246307 }
6308
[email protected]b1122982010-05-17 23:04:246309 // Make a buffer with a single repeated vec4 value enough to
6310 // simulate the constant value that is supposed to be here.
6311 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306312 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476313 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306314
6315 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476316 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306317 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516318 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306319 return false;
6320 }
6321
[email protected]ab09b612013-03-11 22:11:516322 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016323 "Attribute 0 is disabled. This has signficant performance penalty");
6324
[email protected]ab09b612013-03-11 22:11:516325 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306326 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6327
[email protected]8f0b86c2f2012-04-10 05:48:286328 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6329 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496330 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306331 GLenum error = glGetError();
6332 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516333 LOCAL_SET_GL_ERROR(
6334 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306335 return false;
6336 }
[email protected]fc753442011-02-04 19:49:496337 }
[email protected]af6380962012-11-29 23:24:136338
6339 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286340 if (new_buffer ||
6341 (attrib_0_used &&
6342 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136343 (value.v[0] != attrib_0_value_.v[0] ||
6344 value.v[1] != attrib_0_value_.v[1] ||
6345 value.v[2] != attrib_0_value_.v[2] ||
6346 value.v[3] != attrib_0_value_.v[3])))) {
6347 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496348 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6349 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136350 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246351 attrib_0_size_ = size_needed;
6352 }
6353
6354 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6355
[email protected]ac77603c72013-03-08 13:52:066356 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426357 glVertexAttribDivisorANGLE(0, 0);
6358
[email protected]c13e1da62011-09-09 21:48:306359 *simulated = true;
[email protected]b1122982010-05-17 23:04:246360 return true;
[email protected]b1122982010-05-17 23:04:246361}
6362
[email protected]3fc38e22014-05-30 00:13:236363void GLES2DecoderImpl::RestoreStateForAttrib(
6364 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066365 const VertexAttrib* attrib =
6366 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236367 if (restore_array_binding) {
6368 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6369 Buffer* buffer = attrib->buffer();
6370 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6371 glVertexAttribPointer(
6372 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6373 attrib->gl_stride(), ptr);
6374 }
[email protected]ac77603c72013-03-08 13:52:066375 if (attrib->divisor())
6376 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246377 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236378 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6379 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286380
[email protected]265f8992012-07-20 01:03:146381 // Never touch vertex attribute 0's state (in particular, never
6382 // disable it) when running on desktop GL because it will never be
6383 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066384 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146385 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066386 if (attrib->enabled()) {
6387 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146388 } else {
[email protected]ac77603c72013-03-08 13:52:066389 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146390 }
[email protected]43410e92012-04-20 17:06:286391 }
[email protected]b1122982010-05-17 23:04:246392}
[email protected]07f54fcc2009-12-22 02:46:306393
[email protected]8fbedc02010-11-18 18:43:406394bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436395 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426396 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406397 DCHECK(simulated);
6398 *simulated = false;
6399 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6400 return true;
6401
[email protected]e259eb412012-10-13 05:47:246402 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406403 return true;
6404 }
6405
[email protected]ab09b612013-03-11 22:11:516406 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016407 "GL_FIXED attributes have a signficant performance penalty");
6408
[email protected]8fbedc02010-11-18 18:43:406409 // NOTE: we could be smart and try to check if a buffer is used
6410 // twice in 2 different attribs, find the overlapping parts and therefore
6411 // duplicate the minimum amount of data but this whole code path is not meant
6412 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6413 // tests so we just add to the buffer attrib used.
6414
[email protected]c13e1da62011-09-09 21:48:306415 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066416 const VertexAttribManager::VertexAttribList& enabled_attribs =
6417 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6418 for (VertexAttribManager::VertexAttribList::const_iterator it =
6419 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6420 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356421 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066422 state_.current_program->GetAttribInfoByLocation(attrib->index());
6423 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6424 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426425 GLuint num_vertices = max_accessed + 1;
6426 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516427 LOCAL_SET_GL_ERROR(
6428 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426429 return false;
6430 }
[email protected]8fbedc02010-11-18 18:43:406431 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066432 attrib->CanAccess(max_accessed) &&
6433 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476434 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066435 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476436 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516437 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436438 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406439 return false;
6440 }
6441 }
6442 }
6443
[email protected]3aad1a32012-09-07 20:54:476444 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6445 uint32 size_needed = 0;
6446 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306447 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516448 LOCAL_SET_GL_ERROR(
6449 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406450 return false;
6451 }
6452
[email protected]ab09b612013-03-11 22:11:516453 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406454
6455 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306456 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406457 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306458 GLenum error = glGetError();
6459 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516460 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436461 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306462 return false;
6463 }
[email protected]8fbedc02010-11-18 18:43:406464 }
6465
6466 // Copy the elements and convert to float
6467 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066468 for (VertexAttribManager::VertexAttribList::const_iterator it =
6469 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6470 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356471 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066472 state_.current_program->GetAttribInfoByLocation(attrib->index());
6473 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426474 max_vertex_accessed);
6475 GLuint num_vertices = max_accessed + 1;
6476 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516477 LOCAL_SET_GL_ERROR(
6478 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426479 return false;
6480 }
[email protected]8fbedc02010-11-18 18:43:406481 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066482 attrib->CanAccess(max_accessed) &&
6483 attrib->type() == GL_FIXED) {
6484 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406485 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556486 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406487 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066488 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406489 const int32* end = src + num_elements;
6490 float* dst = data.get();
6491 while (src != end) {
6492 *dst++ = static_cast<float>(*src++) / 65536.0f;
6493 }
6494 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6495 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066496 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406497 reinterpret_cast<GLvoid*>(offset));
6498 offset += size;
6499 }
6500 }
6501 *simulated = true;
6502 return true;
6503}
6504
6505void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6506 // There's no need to call glVertexAttribPointer because we shadow all the
6507 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246508 glBindBuffer(
6509 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116510 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6511 : 0);
[email protected]8fbedc02010-11-18 18:43:406512}
6513
[email protected]ad84a3a2012-06-08 21:42:436514error::Error GLES2DecoderImpl::DoDrawArrays(
6515 const char* function_name,
6516 bool instanced,
6517 GLenum mode,
6518 GLint first,
6519 GLsizei count,
6520 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226521 error::Error error = WillAccessBoundFramebufferForDraw();
6522 if (error != error::kNoError)
6523 return error;
[email protected]38d139d2011-07-14 00:38:436524 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516525 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436526 return error::kNoError;
6527 }
6528 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516529 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436530 return error::kNoError;
6531 }
[email protected]c6aef902012-02-14 03:31:426532 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516533 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426534 return error::kNoError;
6535 }
[email protected]ad84a3a2012-06-08 21:42:436536 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436537 return error::kNoError;
6538 }
6539 // We have to check this here because the prototype for glDrawArrays
6540 // is GLint not GLsizei.
6541 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516542 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436543 return error::kNoError;
6544 }
6545
[email protected]ac6904d62014-07-30 12:00:106546 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516547 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436548 return error::kNoError;
6549 }
6550
6551 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106552 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206553 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516554 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206555 return error::kNoError;
6556 }
[email protected]c13e1da62011-09-09 21:48:306557 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436558 if (!SimulateAttrib0(
6559 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306560 return error::kNoError;
6561 }
[email protected]38d139d2011-07-14 00:38:436562 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436563 if (SimulateFixedAttribs(
6564 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6565 primcount)) {
[email protected]e56131d22013-07-28 16:14:116566 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436567 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376568 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426569 if (!instanced) {
6570 glDrawArrays(mode, first, count);
6571 } else {
6572 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6573 }
[email protected]38d139d2011-07-14 00:38:436574 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546575 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436576 }
6577 if (simulated_fixed_attribs) {
6578 RestoreStateForSimulatedFixedAttribs();
6579 }
6580 }
6581 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236582 // We don't have to restore attrib 0 generic data at the end of this
6583 // function even if it is simulated. This is because we will simulate
6584 // it in each draw call, and attrib 0 generic data queries use cached
6585 // values instead of passing down to the underlying driver.
6586 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436587 }
[email protected]38d139d2011-07-14 00:38:436588 }
6589 return error::kNoError;
6590}
6591
vmiuracd108592014-09-08 14:36:346592error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6593 const void* cmd_data) {
6594 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436595 return DoDrawArrays("glDrawArrays",
6596 false,
[email protected]c6aef902012-02-14 03:31:426597 static_cast<GLenum>(c.mode),
6598 static_cast<GLint>(c.first),
6599 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106600 1);
[email protected]c6aef902012-02-14 03:31:426601}
6602
6603error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346604 uint32 immediate_data_size,
6605 const void* cmd_data) {
6606 const gles2::cmds::DrawArraysInstancedANGLE& c =
6607 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156608 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516609 LOCAL_SET_GL_ERROR(
6610 GL_INVALID_OPERATION,
6611 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426612 return error::kNoError;
6613 }
[email protected]ad84a3a2012-06-08 21:42:436614 return DoDrawArrays("glDrawArraysIntancedANGLE",
6615 true,
[email protected]c6aef902012-02-14 03:31:426616 static_cast<GLenum>(c.mode),
6617 static_cast<GLint>(c.first),
6618 static_cast<GLsizei>(c.count),
6619 static_cast<GLsizei>(c.primcount));
6620}
6621
[email protected]ad84a3a2012-06-08 21:42:436622error::Error GLES2DecoderImpl::DoDrawElements(
6623 const char* function_name,
6624 bool instanced,
6625 GLenum mode,
6626 GLsizei count,
6627 GLenum type,
6628 int32 offset,
6629 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226630 error::Error error = WillAccessBoundFramebufferForDraw();
6631 if (error != error::kNoError)
6632 return error;
[email protected]e259eb412012-10-13 05:47:246633 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516634 LOCAL_SET_GL_ERROR(
6635 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296636 return error::kNoError;
6637 }
6638
[email protected]8eee29c2010-04-29 03:38:296639 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516640 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296641 return error::kNoError;
6642 }
6643 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516644 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296645 return error::kNoError;
6646 }
[email protected]9438b012010-06-15 22:55:056647 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516648 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296649 return error::kNoError;
6650 }
[email protected]9438b012010-06-15 22:55:056651 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516652 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296653 return error::kNoError;
6654 }
[email protected]c6aef902012-02-14 03:31:426655 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516656 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426657 return error::kNoError;
6658 }
[email protected]8eee29c2010-04-29 03:38:296659
[email protected]ad84a3a2012-06-08 21:42:436660 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276661 return error::kNoError;
6662 }
6663
[email protected]ac6904d62014-07-30 12:00:106664 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316665 return error::kNoError;
6666 }
6667
[email protected]8eee29c2010-04-29 03:38:296668 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086669 Buffer* element_array_buffer =
6670 state_.vertex_attrib_manager->element_array_buffer();
6671
6672 if (!element_array_buffer->GetMaxValueForRange(
6673 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516674 LOCAL_SET_GL_ERROR(
6675 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296676 return error::kNoError;
6677 }
6678
[email protected]ac6904d62014-07-30 12:00:106679 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206680 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516681 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206682 return error::kNoError;
6683 }
[email protected]c13e1da62011-09-09 21:48:306684 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436685 if (!SimulateAttrib0(
6686 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306687 return error::kNoError;
6688 }
[email protected]8fbedc02010-11-18 18:43:406689 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436690 if (SimulateFixedAttribs(
6691 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6692 primcount)) {
[email protected]e56131d22013-07-28 16:14:116693 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466694 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086695 // TODO(gman): Refactor to hide these details in BufferManager or
6696 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406697 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086698 bool used_client_side_array = false;
6699 if (element_array_buffer->IsClientSideArray()) {
6700 used_client_side_array = true;
6701 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6702 indices = element_array_buffer->GetRange(offset, 0);
6703 }
6704
[email protected]00c2cf92014-03-14 00:08:376705 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426706 if (!instanced) {
6707 glDrawElements(mode, count, type, indices);
6708 } else {
6709 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6710 }
[email protected]17cfbe0e2013-03-07 01:26:086711
6712 if (used_client_side_array) {
6713 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6714 element_array_buffer->service_id());
6715 }
6716
[email protected]8fbedc02010-11-18 18:43:406717 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546718 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406719 }
6720 if (simulated_fixed_attribs) {
6721 RestoreStateForSimulatedFixedAttribs();
6722 }
[email protected]ba3176a2009-12-16 18:19:466723 }
[email protected]b1122982010-05-17 23:04:246724 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236725 // We don't have to restore attrib 0 generic data at the end of this
6726 // function even if it is simulated. This is because we will simulate
6727 // it in each draw call, and attrib 0 generic data queries use cached
6728 // values instead of passing down to the underlying driver.
6729 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:246730 }
[email protected]96449d2c2009-11-25 00:01:326731 }
[email protected]f7a64ee2010-02-01 22:24:146732 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326733}
6734
vmiuracd108592014-09-08 14:36:346735error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
6736 const void* cmd_data) {
6737 const gles2::cmds::DrawElements& c =
6738 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436739 return DoDrawElements("glDrawElements",
6740 false,
[email protected]c6aef902012-02-14 03:31:426741 static_cast<GLenum>(c.mode),
6742 static_cast<GLsizei>(c.count),
6743 static_cast<GLenum>(c.type),
6744 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:106745 1);
[email protected]c6aef902012-02-14 03:31:426746}
6747
6748error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:346749 uint32 immediate_data_size,
6750 const void* cmd_data) {
6751 const gles2::cmds::DrawElementsInstancedANGLE& c =
6752 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156753 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516754 LOCAL_SET_GL_ERROR(
6755 GL_INVALID_OPERATION,
6756 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426757 return error::kNoError;
6758 }
[email protected]ad84a3a2012-06-08 21:42:436759 return DoDrawElements("glDrawElementsInstancedANGLE",
6760 true,
[email protected]c6aef902012-02-14 03:31:426761 static_cast<GLenum>(c.mode),
6762 static_cast<GLsizei>(c.count),
6763 static_cast<GLenum>(c.type),
6764 static_cast<int32>(c.index_offset),
6765 static_cast<GLsizei>(c.primcount));
6766}
6767
[email protected]269200b12010-11-18 22:53:066768GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236769 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6770 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076771 Buffer* buffer = GetBuffer(buffer_id);
6772 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036773 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516774 LOCAL_SET_GL_ERROR(
6775 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236776 } else {
[email protected]b10492f2013-03-08 05:24:076777 if (!buffer->GetMaxValueForRange(
6778 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036779 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516780 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066781 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436782 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236783 }
6784 }
6785 return max_vertex_accessed;
6786}
6787
[email protected]96449d2c2009-11-25 00:01:326788// Calls glShaderSource for the various versions of the ShaderSource command.
6789// Assumes that data / data_size points to a piece of memory that is in range
6790// of whatever context it came from (shared memory, immediate memory, bucket
6791// memory.)
[email protected]45bf5152010-02-12 00:11:316792error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036793 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576794 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426795 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6796 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316797 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326798 }
[email protected]45bf5152010-02-12 00:11:316799 // Note: We don't actually call glShaderSource here. We wait until
6800 // the call to glCompileShader.
zmo576a0492014-09-13 01:12:326801 shader->set_source(str);
[email protected]f7a64ee2010-02-01 22:24:146802 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326803}
6804
[email protected]558847a2010-03-24 07:02:546805error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
vmiuracd108592014-09-08 14:36:346806 uint32 immediate_data_size,
6807 const void* cmd_data) {
6808 const gles2::cmds::ShaderSourceBucket& c =
6809 *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data);
[email protected]558847a2010-03-24 07:02:546810 Bucket* bucket = GetBucket(c.data_bucket_id);
6811 if (!bucket || bucket->size() == 0) {
6812 return error::kInvalidArguments;
6813 }
6814 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036815 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546816 bucket->size() - 1);
6817}
6818
[email protected]ae51d192010-04-27 00:48:036819void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386820 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426821 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6822 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316823 return;
6824 }
[email protected]f57bb282010-11-12 00:51:346825 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186826 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426827 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456828 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416829 }
[email protected]de17df392010-04-23 21:09:416830
zmo576a0492014-09-13 01:12:326831 shader->DoCompile(
[email protected]b05955552014-02-06 18:41:186832 translator,
6833 feature_info_->feature_flags().angle_translated_shader_source ?
zmo576a0492014-09-13 01:12:326834 Shader::kANGLE : Shader::kGL);
vmiura8266ca72014-09-09 21:37:006835
6836 // CompileShader can be very slow. Exit command processing to allow for
6837 // context preemption and GPU watchdog checks.
6838 ExitCommandProcessingEarly();
6839}
[email protected]45bf5152010-02-12 00:11:316840
[email protected]ddd968b82010-03-02 00:44:296841void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426842 GLuint shader_id, GLenum pname, GLint* params) {
6843 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6844 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296845 return;
6846 }
[email protected]8f1ccdac2010-05-19 21:01:486847 switch (pname) {
6848 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:326849 *params = shader->source().size();
6850 if (*params)
6851 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:486852 return;
6853 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:326854 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:416855 return;
[email protected]8f1ccdac2010-05-19 21:01:486856 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:326857 *params = shader->log_info().size();
6858 if (*params)
6859 ++(*params);
[email protected]e5186162010-06-14 18:54:416860 return;
[email protected]d6a53e42011-10-05 00:09:366861 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:326862 *params = shader->translated_source().size();
6863 if (*params)
6864 ++(*params);
[email protected]d6a53e42011-10-05 00:09:366865 return;
[email protected]8f1ccdac2010-05-19 21:01:486866 default:
6867 break;
[email protected]ddd968b82010-03-02 00:44:296868 }
[email protected]df37b9932013-03-08 05:21:426869 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296870}
6871
vmiuracd108592014-09-08 14:36:346872error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
6873 const void* cmd_data) {
6874 const gles2::cmds::GetShaderSource& c =
6875 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426876 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036877 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6878 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426879 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:326880 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:296881 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296882 return error::kNoError;
6883 }
zmo576a0492014-09-13 01:12:326884 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:036885 return error::kNoError;
6886}
6887
[email protected]d6a53e42011-10-05 00:09:366888error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6889 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:346890 const void* cmd_data) {
6891 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
6892 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
6893 cmd_data);
[email protected]df37b9932013-03-08 05:21:426894 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366895 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6896 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426897 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:206898 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:426899 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366900 bucket->SetSize(0);
6901 return error::kNoError;
6902 }
6903
zmo576a0492014-09-13 01:12:326904 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:366905 return error::kNoError;
6906}
6907
[email protected]ae51d192010-04-27 00:48:036908error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:346909 uint32 immediate_data_size,
6910 const void* cmd_data) {
6911 const gles2::cmds::GetProgramInfoLog& c =
6912 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426913 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586914 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6915 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426916 Program* program = GetProgramInfoNotShader(
6917 program_id, "glGetProgramInfoLog");
6918 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466919 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036920 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316921 }
[email protected]df37b9932013-03-08 05:21:426922 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036923 return error::kNoError;
6924}
6925
6926error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:346927 uint32 immediate_data_size,
6928 const void* cmd_data) {
6929 const gles2::cmds::GetShaderInfoLog& c =
6930 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:426931 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586932 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6933 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426934 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:326935 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:466936 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036937 return error::kNoError;
6938 }
zmo576a0492014-09-13 01:12:326939 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:036940 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326941}
6942
[email protected]d058bca2012-11-26 10:27:266943bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6944 return state_.GetEnabled(cap);
6945}
6946
[email protected]1958e0e2010-04-22 05:17:156947bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216948 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106949 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156950}
6951
6952bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356953 const Framebuffer* framebuffer =
6954 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106955 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156956}
6957
6958bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366959 // IsProgram is true for programs as soon as they are created, until they are
6960 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356961 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106962 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156963}
6964
6965bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356966 const Renderbuffer* renderbuffer =
6967 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106968 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156969}
6970
6971bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366972 // IsShader is true for shaders as soon as they are created, until they
6973 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356974 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106975 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156976}
6977
6978bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496979 const TextureRef* texture_ref = GetTexture(client_id);
6980 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036981}
6982
6983void GLES2DecoderImpl::DoAttachShader(
6984 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426985 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586986 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426987 if (!program) {
[email protected]ae51d192010-04-27 00:48:036988 return;
[email protected]1958e0e2010-04-22 05:17:156989 }
[email protected]df37b9932013-03-08 05:21:426990 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6991 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036992 return;
6993 }
[email protected]df37b9932013-03-08 05:21:426994 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516995 LOCAL_SET_GL_ERROR(
6996 GL_INVALID_OPERATION,
6997 "glAttachShader",
6998 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316999 return;
7000 }
[email protected]df37b9932013-03-08 05:21:427001 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037002}
7003
7004void GLES2DecoderImpl::DoDetachShader(
7005 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427006 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587007 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427008 if (!program) {
[email protected]ae51d192010-04-27 00:48:037009 return;
7010 }
[email protected]df37b9932013-03-08 05:21:427011 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7012 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037013 return;
7014 }
[email protected]df37b9932013-03-08 05:21:427015 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517016 LOCAL_SET_GL_ERROR(
7017 GL_INVALID_OPERATION,
7018 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227019 return;
7020 }
[email protected]df37b9932013-03-08 05:21:427021 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037022}
7023
7024void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427025 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587026 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427027 if (!program) {
[email protected]ae51d192010-04-27 00:48:037028 return;
7029 }
[email protected]df37b9932013-03-08 05:21:427030 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157031}
7032
[email protected]ac77603c72013-03-08 13:52:067033void GLES2DecoderImpl::GetVertexAttribHelper(
7034 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247035 switch (pname) {
7036 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067037 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247038 if (buffer && !buffer->IsDeleted()) {
7039 GLuint client_id;
7040 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7041 *params = client_id;
7042 }
7043 break;
7044 }
7045 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067046 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247047 break;
7048 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067049 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247050 break;
7051 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067052 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247053 break;
7054 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067055 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247056 break;
7057 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067058 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247059 break;
[email protected]c6aef902012-02-14 03:31:427060 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067061 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427062 break;
[email protected]ac77603c72013-03-08 13:52:067063 default:
7064 NOTREACHED();
7065 break;
7066 }
7067}
7068
[email protected]4c6f5462014-03-05 00:26:567069void GLES2DecoderImpl::DoGetTexParameterfv(
7070 GLenum target, GLenum pname, GLfloat* params) {
7071 InitTextureMaxAnisotropyIfNeeded(target, pname);
7072 glGetTexParameterfv(target, pname, params);
7073}
7074
7075void GLES2DecoderImpl::DoGetTexParameteriv(
7076 GLenum target, GLenum pname, GLint* params) {
7077 InitTextureMaxAnisotropyIfNeeded(target, pname);
7078 glGetTexParameteriv(target, pname, params);
7079}
7080
7081void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7082 GLenum target, GLenum pname) {
7083 if (!workarounds().init_texture_max_anisotropy)
7084 return;
7085 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7086 !validators_->texture_parameter.IsValid(pname)) {
7087 return;
7088 }
7089
7090 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7091 &state_, target);
7092 if (!texture_ref) {
7093 LOCAL_SET_GL_ERROR(
7094 GL_INVALID_OPERATION,
7095 "glGetTexParamter{fi}v", "unknown texture for target");
7096 return;
7097 }
7098 Texture* texture = texture_ref->texture();
7099 texture->InitTextureMaxAnisotropyIfNeeded(target);
7100}
7101
[email protected]ac77603c72013-03-08 13:52:067102void GLES2DecoderImpl::DoGetVertexAttribfv(
7103 GLuint index, GLenum pname, GLfloat* params) {
7104 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7105 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517106 LOCAL_SET_GL_ERROR(
7107 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067108 return;
7109 }
7110 switch (pname) {
7111 case GL_CURRENT_VERTEX_ATTRIB: {
7112 const Vec4& value = state_.attrib_values[index];
7113 params[0] = value.v[0];
7114 params[1] = value.v[1];
7115 params[2] = value.v[2];
7116 params[3] = value.v[3];
7117 break;
7118 }
7119 default: {
7120 GLint value = 0;
7121 GetVertexAttribHelper(attrib, pname, &value);
7122 *params = static_cast<GLfloat>(value);
7123 break;
7124 }
7125 }
7126}
7127
7128void GLES2DecoderImpl::DoGetVertexAttribiv(
7129 GLuint index, GLenum pname, GLint* params) {
7130 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7131 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517132 LOCAL_SET_GL_ERROR(
7133 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067134 return;
7135 }
7136 switch (pname) {
[email protected]af6380962012-11-29 23:24:137137 case GL_CURRENT_VERTEX_ATTRIB: {
7138 const Vec4& value = state_.attrib_values[index];
7139 params[0] = static_cast<GLint>(value.v[0]);
7140 params[1] = static_cast<GLint>(value.v[1]);
7141 params[2] = static_cast<GLint>(value.v[2]);
7142 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247143 break;
[email protected]af6380962012-11-29 23:24:137144 }
[email protected]b1122982010-05-17 23:04:247145 default:
[email protected]ac77603c72013-03-08 13:52:067146 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247147 break;
7148 }
7149}
7150
[email protected]af6380962012-11-29 23:24:137151bool GLES2DecoderImpl::SetVertexAttribValue(
7152 const char* function_name, GLuint index, const GLfloat* value) {
7153 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517154 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137155 return false;
[email protected]b1122982010-05-17 23:04:247156 }
[email protected]af6380962012-11-29 23:24:137157 Vec4& v = state_.attrib_values[index];
7158 v.v[0] = value[0];
7159 v.v[1] = value[1];
7160 v.v[2] = value[2];
7161 v.v[3] = value[3];
7162 return true;
7163}
7164
7165void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7166 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7167 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7168 glVertexAttrib1f(index, v0);
7169 }
[email protected]b1122982010-05-17 23:04:247170}
7171
7172void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137173 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7174 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7175 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247176 }
[email protected]b1122982010-05-17 23:04:247177}
7178
7179void GLES2DecoderImpl::DoVertexAttrib3f(
7180 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137181 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7182 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7183 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247184 }
[email protected]b1122982010-05-17 23:04:247185}
7186
7187void GLES2DecoderImpl::DoVertexAttrib4f(
7188 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137189 GLfloat v[4] = { v0, v1, v2, v3, };
7190 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7191 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247192 }
[email protected]b1122982010-05-17 23:04:247193}
7194
7195void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137196 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7197 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7198 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247199 }
[email protected]b1122982010-05-17 23:04:247200}
7201
7202void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137203 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7204 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7205 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247206 }
[email protected]b1122982010-05-17 23:04:247207}
7208
7209void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137210 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7211 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7212 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247213 }
[email protected]b1122982010-05-17 23:04:247214}
7215
7216void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137217 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7218 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247219 }
[email protected]b1122982010-05-17 23:04:247220}
7221
[email protected]f7a64ee2010-02-01 22:24:147222error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347223 uint32 immediate_data_size,
7224 const void* cmd_data) {
7225 const gles2::cmds::VertexAttribPointer& c =
7226 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467227
[email protected]7cd76fd2013-06-02 21:11:117228 if (!state_.bound_array_buffer.get() ||
7229 state_.bound_array_buffer->IsDeleted()) {
7230 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527231 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517232 LOCAL_SET_GL_ERROR(
7233 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467234 return error::kNoError;
7235 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517236 LOCAL_SET_GL_ERROR(
7237 GL_INVALID_VALUE,
7238 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467239 return error::kNoError;
7240 }
[email protected]96449d2c2009-11-25 00:01:327241 }
[email protected]8eee29c2010-04-29 03:38:297242
7243 GLuint indx = c.indx;
7244 GLint size = c.size;
7245 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327246 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297247 GLsizei stride = c.stride;
7248 GLsizei offset = c.offset;
7249 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057250 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517251 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297252 return error::kNoError;
7253 }
[email protected]9438b012010-06-15 22:55:057254 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517255 LOCAL_SET_GL_ERROR(
7256 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297257 return error::kNoError;
7258 }
7259 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517260 LOCAL_SET_GL_ERROR(
7261 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297262 return error::kNoError;
7263 }
7264 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517265 LOCAL_SET_GL_ERROR(
7266 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297267 return error::kNoError;
7268 }
7269 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517270 LOCAL_SET_GL_ERROR(
7271 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297272 return error::kNoError;
7273 }
7274 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517275 LOCAL_SET_GL_ERROR(
7276 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297277 return error::kNoError;
7278 }
7279 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317280 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127281 // component_size must be a power of two to use & as optimized modulo.
7282 DCHECK(GLES2Util::IsPOT(component_size));
7283 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517284 LOCAL_SET_GL_ERROR(
7285 GL_INVALID_OPERATION,
7286 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317287 return error::kNoError;
7288 }
[email protected]a07a23602014-08-05 11:36:127289 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517290 LOCAL_SET_GL_ERROR(
7291 GL_INVALID_OPERATION,
7292 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297293 return error::kNoError;
7294 }
[email protected]7cd76fd2013-06-02 21:11:117295 state_.vertex_attrib_manager
7296 ->SetAttribInfo(indx,
7297 state_.bound_array_buffer.get(),
7298 size,
7299 type,
7300 normalized,
7301 stride,
7302 stride != 0 ? stride : component_size * size,
7303 offset);
[email protected]8fbedc02010-11-18 18:43:407304 if (type != GL_FIXED) {
7305 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7306 }
[email protected]f7a64ee2010-02-01 22:24:147307 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327308}
7309
[email protected]43410e92012-04-20 17:06:287310void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7311 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247312 state_.viewport_x = x;
7313 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027314 state_.viewport_width = std::min(width, viewport_max_width_);
7315 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287316 glViewport(x, y, width, height);
7317}
7318
[email protected]c6aef902012-02-14 03:31:427319error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347320 uint32 immediate_data_size,
7321 const void* cmd_data) {
7322 const gles2::cmds::VertexAttribDivisorANGLE& c =
7323 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157324 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517325 LOCAL_SET_GL_ERROR(
7326 GL_INVALID_OPERATION,
7327 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537328 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427329 }
7330 GLuint index = c.index;
7331 GLuint divisor = c.divisor;
7332 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517333 LOCAL_SET_GL_ERROR(
7334 GL_INVALID_VALUE,
7335 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427336 return error::kNoError;
7337 }
7338
[email protected]e259eb412012-10-13 05:47:247339 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427340 index,
7341 divisor);
7342 glVertexAttribDivisorANGLE(index, divisor);
7343 return error::kNoError;
7344}
7345
[email protected]68586372013-12-11 01:27:597346template <typename pixel_data_type>
7347static void WriteAlphaData(
7348 void *pixels, uint32 row_count, uint32 channel_count,
7349 uint32 alpha_channel_index, uint32 unpadded_row_size,
7350 uint32 padded_row_size, pixel_data_type alpha_value) {
7351 DCHECK_GT(channel_count, 0U);
7352 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7353 uint32 unpadded_row_size_in_elements =
7354 unpadded_row_size / sizeof(pixel_data_type);
7355 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7356 uint32 padded_row_size_in_elements =
7357 padded_row_size / sizeof(pixel_data_type);
7358 pixel_data_type* dst =
7359 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7360 for (uint32 yy = 0; yy < row_count; ++yy) {
7361 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7362 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7363 *d = alpha_value;
7364 }
7365 dst += padded_row_size_in_elements;
7366 }
7367}
7368
[email protected]5a36dc132013-07-23 23:17:557369void GLES2DecoderImpl::FinishReadPixels(
7370 const cmds::ReadPixels& c,
7371 GLuint buffer) {
7372 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7373 GLsizei width = c.width;
7374 GLsizei height = c.height;
7375 GLenum format = c.format;
7376 GLenum type = c.type;
7377 typedef cmds::ReadPixels::Result Result;
7378 uint32 pixels_size;
7379 Result* result = NULL;
7380 if (c.result_shm_id != 0) {
7381 result = GetSharedMemoryAs<Result*>(
7382 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7383 if (!result) {
7384 if (buffer != 0) {
7385 glDeleteBuffersARB(1, &buffer);
7386 }
7387 return;
7388 }
7389 }
7390 GLES2Util::ComputeImageDataSizes(
7391 width, height, format, type, state_.pack_alignment, &pixels_size,
7392 NULL, NULL);
7393 void* pixels = GetSharedMemoryAs<void*>(
7394 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7395 if (!pixels) {
7396 if (buffer != 0) {
7397 glDeleteBuffersARB(1, &buffer);
7398 }
7399 return;
7400 }
7401
7402 if (buffer != 0) {
7403 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337404 void* data;
7405 if (features().map_buffer_range) {
7406 data = glMapBufferRange(
7407 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7408 } else {
7409 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7410 }
[email protected]5a36dc132013-07-23 23:17:557411 memcpy(pixels, data, pixels_size);
7412 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7413 // have to restore the state.
7414 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7415 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7416 glDeleteBuffersARB(1, &buffer);
7417 }
7418
7419 if (result != NULL) {
7420 *result = true;
7421 }
7422
7423 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7424 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7425 if ((channels_exist & 0x0008) == 0 &&
7426 workarounds().clear_alpha_in_readpixels) {
7427 // Set the alpha to 255 because some drivers are buggy in this regard.
7428 uint32 temp_size;
7429
7430 uint32 unpadded_row_size;
7431 uint32 padded_row_size;
7432 if (!GLES2Util::ComputeImageDataSizes(
7433 width, 2, format, type, state_.pack_alignment, &temp_size,
7434 &unpadded_row_size, &padded_row_size)) {
7435 return;
7436 }
[email protected]68586372013-12-11 01:27:597437
7438 uint32 channel_count = 0;
7439 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557440 switch (format) {
7441 case GL_RGBA:
7442 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597443 channel_count = 4;
7444 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557445 break;
[email protected]68586372013-12-11 01:27:597446 case GL_ALPHA:
7447 channel_count = 1;
7448 alpha_channel = 0;
7449 break;
7450 }
7451
7452 if (channel_count > 0) {
7453 switch (type) {
7454 case GL_UNSIGNED_BYTE:
7455 WriteAlphaData<uint8>(
7456 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7457 padded_row_size, 0xFF);
7458 break;
7459 case GL_FLOAT:
7460 WriteAlphaData<float>(
7461 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7462 padded_row_size, 1.0f);
7463 break;
7464 case GL_HALF_FLOAT:
7465 WriteAlphaData<uint16>(
7466 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7467 padded_row_size, 0x3C00);
7468 break;
[email protected]5a36dc132013-07-23 23:17:557469 }
[email protected]5a36dc132013-07-23 23:17:557470 }
7471 }
7472}
7473
vmiuracd108592014-09-08 14:36:347474error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7475 const void* cmd_data) {
7476 const gles2::cmds::ReadPixels& c =
7477 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217478 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227479 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7480 if (fbo_error != error::kNoError)
7481 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317482 GLint x = c.x;
7483 GLint y = c.y;
7484 GLsizei width = c.width;
7485 GLsizei height = c.height;
7486 GLenum format = c.format;
7487 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327488 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567489 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517490 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567491 return error::kNoError;
7492 }
[email protected]ed9f9cd2013-02-27 21:12:357493 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187494 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347495 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247496 width, height, format, type, state_.pack_alignment, &pixels_size,
7497 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187498 return error::kOutOfBounds;
7499 }
[email protected]612d2f82009-12-08 20:49:317500 void* pixels = GetSharedMemoryAs<void*>(
7501 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107502 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147503 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467504 }
[email protected]de43f082013-04-02 01:16:107505 Result* result = NULL;
7506 if (c.result_shm_id != 0) {
7507 result = GetSharedMemoryAs<Result*>(
7508 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7509 if (!result) {
7510 return error::kOutOfBounds;
7511 }
7512 }
[email protected]a51788e2010-02-24 21:54:257513
[email protected]9438b012010-06-15 22:55:057514 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517515 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297516 return error::kNoError;
7517 }
[email protected]68586372013-12-11 01:27:597518 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517519 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127520 return error::kNoError;
7521 }
[email protected]68586372013-12-11 01:27:597522 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7523 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7524 // format and type are acceptable enums but not guaranteed to be supported
7525 // for this framebuffer. Have to ask gl if they are valid.
7526 GLint preferred_format = 0;
7527 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7528 GLint preferred_type = 0;
7529 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7530 if (format != static_cast<GLenum>(preferred_format) ||
7531 type != static_cast<GLenum>(preferred_type)) {
7532 LOCAL_SET_GL_ERROR(
7533 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7534 "with the current read framebuffer");
7535 return error::kNoError;
7536 }
7537 }
[email protected]57f223832010-03-19 01:57:567538 if (width == 0 || height == 0) {
7539 return error::kNoError;
7540 }
7541
[email protected]57f223832010-03-19 01:57:567542 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307543 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567544
[email protected]3aad1a32012-09-07 20:54:477545 int32 max_x;
7546 int32 max_y;
7547 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517548 LOCAL_SET_GL_ERROR(
7549 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147550 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317551 }
[email protected]57f223832010-03-19 01:57:567552
[email protected]2ea5950d2014-07-09 18:20:347553 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7554 return error::kNoError;
7555 }
7556
[email protected]0d6bfdc2011-11-02 01:32:207557 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7558 return error::kNoError;
7559 }
7560
[email protected]caa13ed2014-02-17 11:29:207561 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107562
7563 ScopedResolvedFrameBufferBinder binder(this, false, true);
7564
[email protected]d37231fa2010-04-09 21:16:027565 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567566 // The user requested an out of range area. Get the results 1 line
7567 // at a time.
7568 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347569 uint32 unpadded_row_size;
7570 uint32 padded_row_size;
7571 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247572 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347573 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517574 LOCAL_SET_GL_ERROR(
7575 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567576 return error::kNoError;
7577 }
7578
7579 GLint dest_x_offset = std::max(-x, 0);
7580 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347581 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247582 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7583 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517584 LOCAL_SET_GL_ERROR(
7585 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567586 return error::kNoError;
7587 }
7588
7589 // Copy each row into the larger dest rect.
7590 int8* dst = static_cast<int8*>(pixels);
7591 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027592 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567593 GLint read_width = read_end_x - read_x;
7594 for (GLint yy = 0; yy < height; ++yy) {
7595 GLint ry = y + yy;
7596
7597 // Clear the row.
7598 memset(dst, 0, unpadded_row_size);
7599
7600 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027601 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567602 glReadPixels(
7603 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7604 }
7605 dst += padded_row_size;
7606 }
7607 } else {
[email protected]5a36dc132013-07-23 23:17:557608 if (async && features().use_async_readpixels) {
7609 GLuint buffer;
7610 glGenBuffersARB(1, &buffer);
7611 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7612 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7613 GLenum error = glGetError();
7614 if (error == GL_NO_ERROR) {
7615 glReadPixels(x, y, width, height, format, type, 0);
7616 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7617 new FenceCallback()));
7618 WaitForReadPixels(base::Bind(
7619 &GLES2DecoderImpl::FinishReadPixels,
7620 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7621 <GLES2DecoderImpl>(this),
7622 c, buffer));
7623 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7624 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597625 } else {
7626 // On error, unbind pack buffer and fall through to sync readpixels
7627 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
[email protected]5a36dc132013-07-23 23:17:557628 }
7629 }
[email protected]57f223832010-03-19 01:57:567630 glReadPixels(x, y, width, height, format, type, pixels);
7631 }
[email protected]ab09b612013-03-11 22:11:517632 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257633 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107634 if (result != NULL) {
7635 *result = true;
7636 }
[email protected]5a36dc132013-07-23 23:17:557637 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257638 }
[email protected]4848b9f82011-03-10 18:37:567639
[email protected]f7a64ee2010-02-01 22:24:147640 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327641}
7642
vmiuracd108592014-09-08 14:36:347643error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7644 const void* cmd_data) {
7645 const gles2::cmds::PixelStorei& c =
7646 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197647 GLenum pname = c.pname;
7648 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057649 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517650 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127651 return error::kNoError;
7652 }
[email protected]222471d2011-11-30 18:06:397653 switch (pname) {
7654 case GL_PACK_ALIGNMENT:
7655 case GL_UNPACK_ALIGNMENT:
7656 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517657 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207658 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397659 return error::kNoError;
7660 }
[email protected]164d6d52012-05-05 00:55:037661 break;
[email protected]0a1e9ad2012-05-04 21:13:037662 case GL_UNPACK_FLIP_Y_CHROMIUM:
7663 unpack_flip_y_ = (param != 0);
7664 return error::kNoError;
7665 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7666 unpack_premultiply_alpha_ = (param != 0);
7667 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177668 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7669 unpack_unpremultiply_alpha_ = (param != 0);
7670 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397671 default:
7672 break;
[email protected]b9849abf2009-11-25 19:13:197673 }
7674 glPixelStorei(pname, param);
7675 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437676 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247677 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437678 break;
7679 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427680 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437681 break;
7682 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247683 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437684 break;
7685 default:
7686 // Validation should have prevented us from getting here.
7687 NOTREACHED();
7688 break;
[email protected]b9849abf2009-11-25 19:13:197689 }
[email protected]f7a64ee2010-02-01 22:24:147690 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197691}
7692
[email protected]1c75a3702011-11-11 14:15:287693error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:347694 uint32 immediate_data_size,
7695 const void* cmd_data) {
7696 const gles2::cmds::PostSubBufferCHROMIUM& c =
7697 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:387698 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:277699 {
7700 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
7701 }
[email protected]b381ee32014-03-22 02:43:437702 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:517703 LOCAL_SET_GL_ERROR(
7704 GL_INVALID_OPERATION,
7705 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287706 return error::kNoError;
7707 }
[email protected]8f9b8dd2013-09-12 18:05:137708 bool is_tracing;
7709 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7710 &is_tracing);
7711 if (is_tracing) {
7712 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7713 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7714 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7715 is_offscreen ? offscreen_size_ : surface_->GetSize());
7716 }
[email protected]7794d512012-04-17 20:36:497717 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287718 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497719 } else {
7720 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287721 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497722 }
[email protected]1c75a3702011-11-11 14:15:287723}
7724
[email protected]957f0642014-04-09 16:50:017725error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
7726 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347727 const void* cmd_data) {
7728 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
7729 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:107730 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
7731 if (!ref) {
7732 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7733 "glScheduleOverlayPlaneCHROMIUM",
7734 "unknown texture");
7735 return error::kNoError;
7736 }
7737 gfx::GLImage* image =
7738 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
7739 if (!image) {
7740 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
7741 "glScheduleOverlayPlaneCHROMIUM",
7742 "unsupported texture format");
7743 return error::kNoError;
7744 }
7745 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
7746 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
7747 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
7748 "glScheduleOverlayPlaneCHROMIUM",
7749 "invalid transform enum");
7750 return error::kNoError;
7751 }
7752 if (!surface_->ScheduleOverlayPlane(
7753 c.plane_z_order,
7754 transform,
7755 image,
7756 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
7757 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
7758 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
7759 "glScheduleOverlayPlaneCHROMIUM",
7760 "failed to schedule overlay");
7761 }
[email protected]957f0642014-04-09 16:50:017762 return error::kNoError;
7763}
7764
[email protected]558847a2010-03-24 07:02:547765error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7766 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7767 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577768 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517769 LOCAL_SET_GL_ERROR(
7770 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577771 return error::kNoError;
7772 }
[email protected]df37b9932013-03-08 05:21:427773 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587774 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427775 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147776 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197777 }
[email protected]df37b9932013-03-08 05:21:427778 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517779 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437780 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257781 return error::kNoError;
7782 }
[email protected]b9849abf2009-11-25 19:13:197783 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547784 location_shm_id, location_shm_offset, sizeof(GLint));
7785 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147786 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197787 }
[email protected]558847a2010-03-24 07:02:547788 // Require the client to init this incase the context is lost and we are no
7789 // longer executing commands.
7790 if (*location != -1) {
7791 return error::kGenericError;
7792 }
[email protected]df37b9932013-03-08 05:21:427793 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147794 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197795}
7796
[email protected]558847a2010-03-24 07:02:547797error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:347798 uint32 immediate_data_size,
7799 const void* cmd_data) {
7800 const gles2::cmds::GetAttribLocation& c =
7801 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547802 Bucket* bucket = GetBucket(c.name_bucket_id);
7803 if (!bucket) {
7804 return error::kInvalidArguments;
7805 }
7806 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187807 if (!bucket->GetAsString(&name_str)) {
7808 return error::kInvalidArguments;
7809 }
[email protected]558847a2010-03-24 07:02:547810 return GetAttribLocationHelper(
7811 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7812}
7813
7814error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7815 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7816 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577817 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517818 LOCAL_SET_GL_ERROR(
7819 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577820 return error::kNoError;
7821 }
[email protected]df37b9932013-03-08 05:21:427822 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:207823 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:427824 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147825 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197826 }
[email protected]df37b9932013-03-08 05:21:427827 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517828 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437829 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257830 return error::kNoError;
7831 }
[email protected]b9849abf2009-11-25 19:13:197832 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547833 location_shm_id, location_shm_offset, sizeof(GLint));
7834 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147835 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197836 }
[email protected]558847a2010-03-24 07:02:547837 // Require the client to init this incase the context is lost an we are no
7838 // longer executing commands.
7839 if (*location != -1) {
7840 return error::kGenericError;
7841 }
[email protected]df37b9932013-03-08 05:21:427842 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147843 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197844}
7845
[email protected]f7a64ee2010-02-01 22:24:147846error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:347847 uint32 immediate_data_size,
7848 const void* cmd_data) {
7849 const gles2::cmds::GetUniformLocation& c =
7850 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:547851 Bucket* bucket = GetBucket(c.name_bucket_id);
7852 if (!bucket) {
7853 return error::kInvalidArguments;
7854 }
7855 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187856 if (!bucket->GetAsString(&name_str)) {
7857 return error::kInvalidArguments;
7858 }
[email protected]558847a2010-03-24 07:02:547859 return GetUniformLocationHelper(
7860 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197861}
7862
vmiuracd108592014-09-08 14:36:347863error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
7864 const void* cmd_data) {
7865 const gles2::cmds::GetString& c =
7866 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:297867 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057868 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517869 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297870 return error::kNoError;
7871 }
[email protected]959e9072013-09-20 16:58:387872 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:047873 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157874 switch (name) {
7875 case GL_VERSION:
7876 str = "OpenGL ES 2.0 Chromium";
7877 break;
7878 case GL_SHADING_LANGUAGE_VERSION:
7879 str = "OpenGL ES GLSL ES 1.0 Chromium";
7880 break;
[email protected]32939602012-05-09 06:25:167881 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:167882 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:387883 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7884 // They are used by WEBGL_debug_renderer_info.
7885 if (!force_webgl_glsl_validation_)
7886 str = "Chromium";
[email protected]32939602012-05-09 06:25:167887 break;
[email protected]1958e0e2010-04-22 05:17:157888 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047889 {
[email protected]70dc60932013-06-04 03:33:497890 // For WebGL contexts, strip out the OES derivatives and
7891 // EXT frag depth extensions if they have not been enabled.
7892 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047893 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497894 if (!derivatives_explicitly_enabled_) {
7895 size_t offset = extensions.find(kOESDerivativeExtension);
7896 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097897 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497898 std::string());
7899 }
7900 }
7901 if (!frag_depth_explicitly_enabled_) {
7902 size_t offset = extensions.find(kEXTFragDepthExtension);
7903 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097904 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497905 std::string());
7906 }
[email protected]f0d74742011-10-03 16:31:047907 }
[email protected]aff39ac82013-06-08 04:53:137908 if (!draw_buffers_explicitly_enabled_) {
7909 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7910 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097911 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137912 std::string());
7913 }
7914 }
[email protected]93c2fd82014-04-16 02:46:067915 if (!shader_texture_lod_explicitly_enabled_) {
7916 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
7917 if (std::string::npos != offset) {
7918 extensions.replace(offset,
7919 arraysize(kEXTShaderTextureLodExtension),
7920 std::string());
7921 }
7922 }
[email protected]f0d74742011-10-03 16:31:047923 } else {
[email protected]6f5fac9d12012-06-26 21:02:457924 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047925 }
[email protected]b381ee32014-03-22 02:43:437926 if (supports_post_sub_buffer_)
7927 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:457928 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047929 }
[email protected]1958e0e2010-04-22 05:17:157930 break;
7931 default:
[email protected]1958e0e2010-04-22 05:17:157932 break;
7933 }
[email protected]ddd968b82010-03-02 00:44:297934 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157935 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297936 return error::kNoError;
7937}
7938
vmiuracd108592014-09-08 14:36:347939error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
7940 const void* cmd_data) {
7941 const gles2::cmds::BufferData& c =
7942 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:117943 GLenum target = static_cast<GLenum>(c.target);
7944 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7945 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7946 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7947 GLenum usage = static_cast<GLenum>(c.usage);
7948 const void* data = NULL;
7949 if (data_shm_id != 0 || data_shm_offset != 0) {
7950 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7951 if (!data) {
7952 return error::kOutOfBounds;
7953 }
7954 }
[email protected]0fbba3732013-07-17 15:40:137955 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147956 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197957}
7958
[email protected]0c86dbf2010-03-05 08:14:117959void GLES2DecoderImpl::DoBufferSubData(
7960 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137961 // Just delegate it. Some validation is actually done before this.
7962 buffer_manager()->ValidateAndDoBufferSubData(
7963 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197964}
7965
[email protected]0d6bfdc2011-11-02 01:32:207966bool GLES2DecoderImpl::ClearLevel(
7967 unsigned service_id,
7968 unsigned bind_target,
7969 unsigned target,
7970 int level,
[email protected]d8e6c9242014-02-20 16:56:257971 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:207972 unsigned format,
7973 unsigned type,
7974 int width,
[email protected]4502e6492011-12-14 19:39:157975 int height,
7976 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007977 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:007978 if (feature_info_->feature_flags().angle_depth_texture &&
7979 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:007980 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7981 // on depth formats.
7982 GLuint fb = 0;
7983 glGenFramebuffersEXT(1, &fb);
7984 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7985
7986 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7987 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7988 GL_DEPTH_ATTACHMENT;
7989
7990 glFramebufferTexture2DEXT(
7991 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7992 // ANGLE promises a depth only attachment ok.
7993 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7994 GL_FRAMEBUFFER_COMPLETE) {
7995 return false;
7996 }
7997 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:477998 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
7999 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008000 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458001 state_.SetDeviceDepthMask(GL_TRUE);
8002 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008003 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8004
8005 RestoreClearState();
8006
8007 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358008 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008009 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8010 GLuint fb_service_id =
8011 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8012 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8013 return true;
8014 }
8015
[email protected]45d15a62012-04-18 14:33:178016 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8017
8018 uint32 size;
8019 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348020 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248021 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178022 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208023 return false;
8024 }
[email protected]45d15a62012-04-18 14:33:178025
[email protected]a5d3dad2012-05-26 04:34:448026 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8027
[email protected]45d15a62012-04-18 14:33:178028 int tile_height;
8029
8030 if (size > kMaxZeroSize) {
8031 if (kMaxZeroSize < padded_row_size) {
8032 // That'd be an awfully large texture.
8033 return false;
8034 }
8035 // We should never have a large total size with a zero row size.
8036 DCHECK_GT(padded_row_size, 0U);
8037 tile_height = kMaxZeroSize / padded_row_size;
8038 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248039 width, tile_height, format, type, state_.unpack_alignment, &size,
8040 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178041 return false;
8042 }
[email protected]4502e6492011-12-14 19:39:158043 } else {
[email protected]45d15a62012-04-18 14:33:178044 tile_height = height;
8045 }
8046
8047 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558048 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178049 memset(zero.get(), 0, size);
8050 glBindTexture(bind_target, service_id);
8051
8052 GLint y = 0;
8053 while (y < height) {
8054 GLint h = y + tile_height > height ? height - y : tile_height;
8055 if (is_texture_immutable || h != height) {
8056 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8057 } else {
[email protected]8f1d2aa2013-05-10 23:45:388058 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258059 target, level, internal_format, width, h, 0, format, type,
8060 zero.get());
[email protected]45d15a62012-04-18 14:33:178061 }
8062 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158063 }
[email protected]c986af502013-08-14 01:04:448064 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
8065 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:078066 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208067 return true;
8068}
8069
[email protected]ad84a3a2012-06-08 21:42:438070namespace {
8071
8072const int kS3TCBlockWidth = 4;
8073const int kS3TCBlockHeight = 4;
8074const int kS3TCDXT1BlockSize = 8;
8075const int kS3TCDXT3AndDXT5BlockSize = 16;
8076
8077bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518078 return (size == 1) ||
8079 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438080}
8081
[email protected]8aec81ec2014-04-29 01:04:518082bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128083 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518084}
8085
[email protected]ad84a3a2012-06-08 21:42:438086} // anonymous namespace.
8087
8088bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8089 const char* function_name,
8090 GLsizei width, GLsizei height, GLenum format, size_t size) {
8091 unsigned int bytes_required = 0;
8092
8093 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518094 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438095 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518096 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8097 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438098 int num_blocks_across =
8099 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8100 int num_blocks_down =
8101 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8102 int num_blocks = num_blocks_across * num_blocks_down;
8103 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8104 break;
8105 }
[email protected]8aec81ec2014-04-29 01:04:518106 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8107 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438108 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8109 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8110 int num_blocks_across =
8111 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8112 int num_blocks_down =
8113 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8114 int num_blocks = num_blocks_across * num_blocks_down;
8115 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8116 break;
8117 }
[email protected]8aec81ec2014-04-29 01:04:518118 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8119 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8120 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8121 break;
8122 }
8123 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8124 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8125 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078126 break;
8127 }
[email protected]ad84a3a2012-06-08 21:42:438128 default:
[email protected]ab09b612013-03-11 22:11:518129 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438130 return false;
8131 }
8132
8133 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518134 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438135 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8136 return false;
8137 }
8138
8139 return true;
8140}
8141
8142bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8143 const char* function_name,
8144 GLint level, GLsizei width, GLsizei height, GLenum format) {
8145 switch (format) {
8146 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8147 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8148 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8149 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8150 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518151 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438152 GL_INVALID_OPERATION, function_name,
8153 "width or height invalid for level");
8154 return false;
8155 }
8156 return true;
8157 }
[email protected]8aec81ec2014-04-29 01:04:518158 case GL_ATC_RGB_AMD:
8159 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8160 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8161 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078162 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518163 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078164 GL_INVALID_OPERATION, function_name,
8165 "width or height invalid for level");
8166 return false;
8167 }
8168 return true;
[email protected]8aec81ec2014-04-29 01:04:518169 }
8170 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8171 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8172 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8173 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8174 if (!IsValidPVRTCSize(level, width) ||
8175 !IsValidPVRTCSize(level, height)) {
8176 LOCAL_SET_GL_ERROR(
8177 GL_INVALID_OPERATION, function_name,
8178 "width or height invalid for level");
8179 return false;
8180 }
8181 return true;
8182 }
[email protected]ad84a3a2012-06-08 21:42:438183 default:
8184 return false;
8185 }
8186}
8187
8188bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8189 const char* function_name,
8190 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8191 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358192 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438193 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518194 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438195 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8196 return false;
8197 }
8198
8199 switch (format) {
8200 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8201 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8202 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8203 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8204 const int kBlockWidth = 4;
8205 const int kBlockHeight = 4;
8206 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518207 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438208 GL_INVALID_OPERATION, function_name,
8209 "xoffset or yoffset not multiple of 4");
8210 return false;
8211 }
8212 GLsizei tex_width = 0;
8213 GLsizei tex_height = 0;
8214 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8215 width - xoffset > tex_width ||
8216 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518217 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438218 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8219 return false;
8220 }
8221 return ValidateCompressedTexDimensions(
8222 function_name, level, width, height, format);
8223 }
[email protected]8aec81ec2014-04-29 01:04:518224 case GL_ATC_RGB_AMD:
8225 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8226 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8227 LOCAL_SET_GL_ERROR(
8228 GL_INVALID_OPERATION, function_name,
8229 "not supported for ATC textures");
8230 return false;
8231 }
[email protected]2d3765b2012-10-03 00:31:078232 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518233 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078234 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208235 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078236 return false;
8237 }
[email protected]8aec81ec2014-04-29 01:04:518238 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8239 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8240 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8241 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8242 if ((xoffset != 0) || (yoffset != 0)) {
8243 LOCAL_SET_GL_ERROR(
8244 GL_INVALID_OPERATION, function_name,
8245 "xoffset and yoffset must be zero");
8246 return false;
8247 }
8248 GLsizei tex_width = 0;
8249 GLsizei tex_height = 0;
8250 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8251 width != tex_width ||
8252 height != tex_height) {
8253 LOCAL_SET_GL_ERROR(
8254 GL_INVALID_OPERATION, function_name,
8255 "dimensions must match existing texture level dimensions");
8256 return false;
8257 }
8258 return ValidateCompressedTexDimensions(
8259 function_name, level, width, height, format);
8260 }
[email protected]ad84a3a2012-06-08 21:42:438261 default:
8262 return false;
8263 }
8264}
8265
[email protected]a93bb842010-02-16 23:03:478266error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8267 GLenum target,
8268 GLint level,
8269 GLenum internal_format,
8270 GLsizei width,
8271 GLsizei height,
8272 GLint border,
8273 GLsizei image_size,
8274 const void* data) {
[email protected]a93bb842010-02-16 23:03:478275 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058276 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518277 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8278 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298279 return error::kNoError;
8280 }
[email protected]9438b012010-06-15 22:55:058281 if (!validators_->compressed_texture_format.IsValid(
8282 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518283 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538284 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478285 return error::kNoError;
8286 }
[email protected]80eb6b52012-01-19 00:14:418287 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478288 border != 0) {
[email protected]ab09b612013-03-11 22:11:518289 LOCAL_SET_GL_ERROR(
8290 GL_INVALID_VALUE,
8291 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478292 return error::kNoError;
8293 }
[email protected]c986af502013-08-14 01:04:448294 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8295 &state_, target);
[email protected]370eaf12013-05-18 09:19:498296 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518297 LOCAL_SET_GL_ERROR(
8298 GL_INVALID_VALUE,
8299 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478300 return error::kNoError;
8301 }
[email protected]370eaf12013-05-18 09:19:498302 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078303 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518304 LOCAL_SET_GL_ERROR(
8305 GL_INVALID_OPERATION,
8306 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438307 return error::kNoError;
8308 }
8309
8310 if (!ValidateCompressedTexDimensions(
8311 "glCompressedTexImage2D", level, width, height, internal_format) ||
8312 !ValidateCompressedTexFuncData(
8313 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178314 return error::kNoError;
8315 }
[email protected]968351b2011-12-20 08:26:518316
[email protected]7989c9e2013-01-23 06:39:268317 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518318 LOCAL_SET_GL_ERROR(
8319 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268320 return error::kNoError;
8321 }
8322
[email protected]02965c22013-03-09 02:40:078323 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448324 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518325 }
8326
[email protected]40d90a22013-04-09 03:39:558327 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478328 if (!data) {
8329 zero.reset(new int8[image_size]);
8330 memset(zero.get(), 0, image_size);
8331 data = zero.get();
8332 }
[email protected]ab09b612013-03-11 22:11:518333 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478334 glCompressedTexImage2D(
8335 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518336 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438337 if (error == GL_NO_ERROR) {
8338 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498339 texture_ref, target, level, internal_format,
8340 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438341 }
vmiura8266ca72014-09-09 21:37:008342
8343 // This may be a slow command. Exit command processing to allow for
8344 // context preemption and GPU watchdog checks.
8345 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478346 return error::kNoError;
8347}
8348
[email protected]f7a64ee2010-02-01 22:24:148349error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348350 uint32 immediate_data_size,
8351 const void* cmd_data) {
8352 const gles2::cmds::CompressedTexImage2D& c =
8353 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198354 GLenum target = static_cast<GLenum>(c.target);
8355 GLint level = static_cast<GLint>(c.level);
8356 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8357 GLsizei width = static_cast<GLsizei>(c.width);
8358 GLsizei height = static_cast<GLsizei>(c.height);
8359 GLint border = static_cast<GLint>(c.border);
8360 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8361 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8362 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8363 const void* data = NULL;
8364 if (data_shm_id != 0 || data_shm_offset != 0) {
8365 data = GetSharedMemoryAs<const void*>(
8366 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468367 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148368 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198369 }
8370 }
[email protected]a93bb842010-02-16 23:03:478371 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198372 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198373}
8374
[email protected]b6140d02010-05-17 14:47:168375error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348376 uint32 immediate_data_size,
8377 const void* cmd_data) {
8378 const gles2::cmds::CompressedTexImage2DBucket& c =
8379 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168380 GLenum target = static_cast<GLenum>(c.target);
8381 GLint level = static_cast<GLint>(c.level);
8382 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8383 GLsizei width = static_cast<GLsizei>(c.width);
8384 GLsizei height = static_cast<GLsizei>(c.height);
8385 GLint border = static_cast<GLint>(c.border);
8386 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288387 if (!bucket) {
8388 return error::kInvalidArguments;
8389 }
8390 uint32 data_size = bucket->size();
8391 GLsizei imageSize = data_size;
8392 const void* data = bucket->GetData(0, data_size);
8393 if (!data) {
8394 return error::kInvalidArguments;
8395 }
[email protected]b6140d02010-05-17 14:47:168396 return DoCompressedTexImage2D(
8397 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288398 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168399}
8400
8401error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8402 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348403 const void* cmd_data) {
8404 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8405 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168406 GLenum target = static_cast<GLenum>(c.target);
8407 GLint level = static_cast<GLint>(c.level);
8408 GLint xoffset = static_cast<GLint>(c.xoffset);
8409 GLint yoffset = static_cast<GLint>(c.yoffset);
8410 GLsizei width = static_cast<GLsizei>(c.width);
8411 GLsizei height = static_cast<GLsizei>(c.height);
8412 GLenum format = static_cast<GLenum>(c.format);
8413 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288414 if (!bucket) {
8415 return error::kInvalidArguments;
8416 }
[email protected]b6140d02010-05-17 14:47:168417 uint32 data_size = bucket->size();
8418 GLsizei imageSize = data_size;
8419 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288420 if (!data) {
8421 return error::kInvalidArguments;
8422 }
[email protected]9438b012010-06-15 22:55:058423 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518424 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538425 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168426 return error::kNoError;
8427 }
[email protected]9438b012010-06-15 22:55:058428 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518429 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8430 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058431 return error::kNoError;
8432 }
[email protected]b6140d02010-05-17 14:47:168433 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518434 LOCAL_SET_GL_ERROR(
8435 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168436 return error::kNoError;
8437 }
8438 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518439 LOCAL_SET_GL_ERROR(
8440 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168441 return error::kNoError;
8442 }
8443 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518444 LOCAL_SET_GL_ERROR(
8445 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168446 return error::kNoError;
8447 }
[email protected]cadde4a2010-07-31 17:10:438448 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168449 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8450 return error::kNoError;
8451}
8452
vmiuracd108592014-09-08 14:36:348453error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8454 const void* cmd_data) {
8455 const gles2::cmds::TexImage2D& c =
8456 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138457 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8458 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448459 // Set as failed for now, but if it successed, this will be set to not failed.
8460 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198461 GLenum target = static_cast<GLenum>(c.target);
8462 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448463 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8464 // for internalformat.
8465 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198466 GLsizei width = static_cast<GLsizei>(c.width);
8467 GLsizei height = static_cast<GLsizei>(c.height);
8468 GLint border = static_cast<GLint>(c.border);
8469 GLenum format = static_cast<GLenum>(c.format);
8470 GLenum type = static_cast<GLenum>(c.type);
8471 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8472 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188473 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348474 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248475 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348476 NULL)) {
[email protected]a76b0052010-03-05 00:33:188477 return error::kOutOfBounds;
8478 }
[email protected]b9849abf2009-11-25 19:13:198479 const void* pixels = NULL;
8480 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8481 pixels = GetSharedMemoryAs<const void*>(
8482 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468483 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148484 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198485 }
8486 }
[email protected]f598f422012-12-07 08:30:038487
[email protected]c986af502013-08-14 01:04:448488 TextureManager::DoTextImage2DArguments args = {
8489 target, level, internal_format, width, height, border, format, type,
8490 pixels, pixels_size};
8491 texture_manager()->ValidateAndDoTexImage2D(
8492 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008493
8494 // This may be a slow command. Exit command processing to allow for
8495 // context preemption and GPU watchdog checks.
8496 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038497 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198498}
8499
[email protected]cadde4a2010-07-31 17:10:438500void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8501 GLenum target,
8502 GLint level,
8503 GLint xoffset,
8504 GLint yoffset,
8505 GLsizei width,
8506 GLsizei height,
8507 GLenum format,
8508 GLsizei image_size,
8509 const void * data) {
[email protected]c986af502013-08-14 01:04:448510 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8511 &state_, target);
[email protected]370eaf12013-05-18 09:19:498512 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518513 LOCAL_SET_GL_ERROR(
8514 GL_INVALID_OPERATION,
8515 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438516 return;
8517 }
[email protected]370eaf12013-05-18 09:19:498518 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438519 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528520 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078521 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518522 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528523 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438524 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528525 return;
8526 }
8527 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518528 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528529 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438530 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528531 return;
8532 }
[email protected]02965c22013-03-09 02:40:078533 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528534 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518535 LOCAL_SET_GL_ERROR(
8536 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438537 return;
8538 }
[email protected]ad84a3a2012-06-08 21:42:438539
8540 if (!ValidateCompressedTexFuncData(
8541 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8542 !ValidateCompressedTexSubDimensions(
8543 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078544 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438545 return;
8546 }
8547
8548
[email protected]0d6bfdc2011-11-02 01:32:208549 // Note: There is no need to deal with texture cleared tracking here
8550 // because the validation above means you can only get here if the level
8551 // is already a matching compressed format and in that case
8552 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438553 glCompressedTexSubImage2D(
8554 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:008555
8556 // This may be a slow command. Exit command processing to allow for
8557 // context preemption and GPU watchdog checks.
8558 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438559}
8560
[email protected]6e288612010-12-21 20:45:038561static void Clip(
8562 GLint start, GLint range, GLint sourceRange,
8563 GLint* out_start, GLint* out_range) {
8564 DCHECK(out_start);
8565 DCHECK(out_range);
8566 if (start < 0) {
8567 range += start;
8568 start = 0;
8569 }
8570 GLint end = start + range;
8571 if (end > sourceRange) {
8572 range -= end - sourceRange;
8573 }
8574 *out_start = start;
8575 *out_range = range;
8576}
8577
[email protected]cadde4a2010-07-31 17:10:438578void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448579 GLenum target,
8580 GLint level,
8581 GLenum internal_format,
8582 GLint x,
8583 GLint y,
8584 GLsizei width,
8585 GLsizei height,
8586 GLint border) {
[email protected]09e17272012-11-30 10:30:448587 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448588 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8589 &state_, target);
[email protected]370eaf12013-05-18 09:19:498590 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518591 LOCAL_SET_GL_ERROR(
8592 GL_INVALID_OPERATION,
8593 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438594 return;
8595 }
[email protected]370eaf12013-05-18 09:19:498596 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078597 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518598 LOCAL_SET_GL_ERROR(
8599 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:538600 return;
[email protected]97dc7cbe2011-12-06 17:26:178601 }
[email protected]80eb6b52012-01-19 00:14:418602 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188603 border != 0) {
[email protected]ab09b612013-03-11 22:11:518604 LOCAL_SET_GL_ERROR(
8605 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188606 return;
8607 }
[email protected]17a961192014-02-14 15:20:528608 if (!texture_manager()->ValidateFormatAndTypeCombination(
8609 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
8610 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:008611 return;
8612 }
[email protected]f5719fb2010-08-04 18:27:188613
[email protected]9edc6b22010-12-23 02:00:268614 // Check we have compatible formats.
8615 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8616 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8617 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8618
8619 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518620 LOCAL_SET_GL_ERROR(
8621 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268622 return;
8623 }
8624
[email protected]81375742012-06-08 00:04:008625 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518626 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008627 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268628 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8629 return;
8630 }
8631
8632 uint32 estimated_size = 0;
8633 if (!GLES2Util::ComputeImageDataSizes(
8634 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8635 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518636 LOCAL_SET_GL_ERROR(
8637 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268638 return;
8639 }
8640
8641 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518642 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008643 return;
8644 }
8645
[email protected]2ea5950d2014-07-09 18:20:348646 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
8647 return;
8648 }
8649
zmo383512cf2014-10-14 00:11:008650 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
8651 LOCAL_SET_GL_ERROR(
8652 GL_INVALID_OPERATION,
8653 "glCopyTexImage2D", "source and destination textures are the same");
8654 return;
8655 }
8656
[email protected]a0b78dc2011-11-11 10:43:108657 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8658 return;
8659 }
8660
[email protected]ab09b612013-03-11 22:11:518661 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278662 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038663 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268664
[email protected]02965c22013-03-09 02:40:078665 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448666 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468667 }
8668
[email protected]9edc6b22010-12-23 02:00:268669 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038670 GLint copyX = 0;
8671 GLint copyY = 0;
8672 GLint copyWidth = 0;
8673 GLint copyHeight = 0;
8674 Clip(x, width, size.width(), &copyX, &copyWidth);
8675 Clip(y, height, size.height(), &copyY, &copyHeight);
8676
8677 if (copyX != x ||
8678 copyY != y ||
8679 copyWidth != width ||
8680 copyHeight != height) {
8681 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208682 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078683 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:258684 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
8685 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518686 LOCAL_SET_GL_ERROR(
8687 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038688 return;
8689 }
[email protected]6e288612010-12-21 20:45:038690 if (copyHeight > 0 && copyWidth > 0) {
8691 GLint dx = copyX - x;
8692 GLint dy = copyY - y;
8693 GLint destX = dx;
8694 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:378695 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038696 glCopyTexSubImage2D(target, level,
8697 destX, destY, copyX, copyY,
8698 copyWidth, copyHeight);
8699 }
8700 } else {
[email protected]00c2cf92014-03-14 00:08:378701 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038702 glCopyTexImage2D(target, level, internal_format,
8703 copyX, copyY, copyWidth, copyHeight, border);
8704 }
[email protected]ab09b612013-03-11 22:11:518705 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438706 if (error == GL_NO_ERROR) {
8707 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498708 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208709 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438710 }
vmiura8266ca72014-09-09 21:37:008711
8712 // This may be a slow command. Exit command processing to allow for
8713 // context preemption and GPU watchdog checks.
8714 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438715}
8716
8717void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448718 GLenum target,
8719 GLint level,
8720 GLint xoffset,
8721 GLint yoffset,
8722 GLint x,
8723 GLint y,
8724 GLsizei width,
8725 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448726 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448727 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8728 &state_, target);
[email protected]370eaf12013-05-18 09:19:498729 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518730 LOCAL_SET_GL_ERROR(
8731 GL_INVALID_OPERATION,
8732 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438733 return;
8734 }
[email protected]370eaf12013-05-18 09:19:498735 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438736 GLenum type = 0;
8737 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078738 if (!texture->GetLevelType(target, level, &type, &format) ||
8739 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528740 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518741 LOCAL_SET_GL_ERROR(
8742 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438743 return;
8744 }
[email protected]85a4ac22013-05-31 01:58:478745 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518746 LOCAL_SET_GL_ERROR(
8747 GL_INVALID_OPERATION,
8748 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598749 return;
8750 }
[email protected]9edc6b22010-12-23 02:00:268751
8752 // Check we have compatible formats.
8753 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8754 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8755 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8756
[email protected]2d3765b2012-10-03 00:31:078757 if (!channels_needed ||
8758 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518759 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438760 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268761 return;
8762 }
8763
[email protected]81375742012-06-08 00:04:008764 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518765 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008766 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438767 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008768 return;
8769 }
8770
[email protected]2ea5950d2014-07-09 18:20:348771 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
8772 return;
8773 }
8774
zmo383512cf2014-10-14 00:11:008775 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
8776 LOCAL_SET_GL_ERROR(
8777 GL_INVALID_OPERATION,
8778 "glCopyTexSubImage2D", "source and destination textures are the same");
8779 return;
8780 }
8781
[email protected]a0b78dc2011-11-11 10:43:108782 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8783 return;
8784 }
8785
[email protected]de26b3c2011-08-03 21:54:278786 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038787 gfx::Size size = GetBoundReadFrameBufferSize();
8788 GLint copyX = 0;
8789 GLint copyY = 0;
8790 GLint copyWidth = 0;
8791 GLint copyHeight = 0;
8792 Clip(x, width, size.width(), &copyX, &copyWidth);
8793 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208794
[email protected]370eaf12013-05-18 09:19:498795 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518796 LOCAL_SET_GL_ERROR(
8797 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208798 return;
8799 }
8800
[email protected]6e288612010-12-21 20:45:038801 if (copyX != x ||
8802 copyY != y ||
8803 copyWidth != width ||
8804 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208805 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038806 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348807 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248808 width, height, format, type, state_.unpack_alignment, &pixels_size,
8809 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518810 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438811 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038812 return;
8813 }
[email protected]40d90a22013-04-09 03:39:558814 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038815 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:378816 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038817 glTexSubImage2D(
8818 target, level, xoffset, yoffset, width, height,
8819 format, type, zero.get());
8820 }
[email protected]0d6bfdc2011-11-02 01:32:208821
[email protected]6e288612010-12-21 20:45:038822 if (copyHeight > 0 && copyWidth > 0) {
8823 GLint dx = copyX - x;
8824 GLint dy = copyY - y;
8825 GLint destX = xoffset + dx;
8826 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:378827 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:038828 glCopyTexSubImage2D(target, level,
8829 destX, destY, copyX, copyY,
8830 copyWidth, copyHeight);
8831 }
vmiura8266ca72014-09-09 21:37:008832
8833 // This may be a slow command. Exit command processing to allow for
8834 // context preemption and GPU watchdog checks.
8835 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438836}
8837
[email protected]f598f422012-12-07 08:30:038838bool GLES2DecoderImpl::ValidateTexSubImage2D(
8839 error::Error* error,
8840 const char* function_name,
8841 GLenum target,
8842 GLint level,
8843 GLint xoffset,
8844 GLint yoffset,
8845 GLsizei width,
8846 GLsizei height,
8847 GLenum format,
8848 GLenum type,
8849 const void * data) {
8850 (*error) = error::kNoError;
8851 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518852 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038853 return false;
8854 }
8855 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518856 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038857 return false;
8858 }
8859 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518860 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038861 return false;
8862 }
[email protected]c986af502013-08-14 01:04:448863 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8864 &state_, target);
[email protected]370eaf12013-05-18 09:19:498865 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518866 LOCAL_SET_GL_ERROR(
8867 GL_INVALID_OPERATION,
8868 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038869 return false;
[email protected]cadde4a2010-07-31 17:10:438870 }
[email protected]370eaf12013-05-18 09:19:498871 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528872 GLenum current_type = 0;
8873 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078874 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518875 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038876 GL_INVALID_OPERATION, function_name, "level does not exist.");
8877 return false;
[email protected]df6cf1ad2011-01-29 01:20:528878 }
[email protected]17a961192014-02-14 15:20:528879 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
8880 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:038881 return false;
[email protected]df6cf1ad2011-01-29 01:20:528882 }
8883 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518884 LOCAL_SET_GL_ERROR(
8885 GL_INVALID_OPERATION,
8886 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038887 return false;
[email protected]df6cf1ad2011-01-29 01:20:528888 }
[email protected]85a4ac22013-05-31 01:58:478889 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518890 LOCAL_SET_GL_ERROR(
8891 GL_INVALID_OPERATION,
8892 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598893 return false;
8894 }
[email protected]02965c22013-03-09 02:40:078895 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528896 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518897 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038898 return false;
[email protected]cadde4a2010-07-31 17:10:438899 }
[email protected]81375742012-06-08 00:04:008900 if ((GLES2Util::GetChannelsForFormat(format) &
8901 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518902 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008903 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038904 function_name, "can not supply data for depth or stencil textures");
8905 return false;
[email protected]81375742012-06-08 00:04:008906 }
[email protected]f598f422012-12-07 08:30:038907 if (data == NULL) {
8908 (*error) = error::kOutOfBounds;
8909 return false;
8910 }
8911 return true;
8912}
[email protected]81375742012-06-08 00:04:008913
[email protected]f598f422012-12-07 08:30:038914error::Error GLES2DecoderImpl::DoTexSubImage2D(
8915 GLenum target,
8916 GLint level,
8917 GLint xoffset,
8918 GLint yoffset,
8919 GLsizei width,
8920 GLsizei height,
8921 GLenum format,
8922 GLenum type,
8923 const void * data) {
8924 error::Error error = error::kNoError;
8925 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8926 xoffset, yoffset, width, height, format, type, data)) {
8927 return error;
8928 }
[email protected]c986af502013-08-14 01:04:448929 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8930 &state_, target);
[email protected]370eaf12013-05-18 09:19:498931 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158932 GLsizei tex_width = 0;
8933 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078934 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158935 DCHECK(ok);
8936 if (xoffset != 0 || yoffset != 0 ||
8937 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498938 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8939 target, level)) {
[email protected]ab09b612013-03-11 22:11:518940 LOCAL_SET_GL_ERROR(
8941 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038942 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308943 }
[email protected]c986af502013-08-14 01:04:448944 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158945 glTexSubImage2D(
8946 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038947 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208948 }
[email protected]4502e6492011-12-14 19:39:158949
[email protected]345ba902013-11-14 21:39:008950 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:448951 !texture->IsImmutable()) {
8952 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:258953 GLenum internal_format;
8954 GLenum tex_type;
8955 texture->GetLevelType(target, level, &tex_type, &internal_format);
8956 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
8957 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:388958 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258959 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:158960 } else {
[email protected]c986af502013-08-14 01:04:448961 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158962 glTexSubImage2D(
8963 target, level, xoffset, yoffset, width, height, format, type, data);
8964 }
[email protected]370eaf12013-05-18 09:19:498965 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:008966
8967 // This may be a slow command. Exit command processing to allow for
8968 // context preemption and GPU watchdog checks.
8969 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038970 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438971}
8972
vmiuracd108592014-09-08 14:36:348973error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
8974 const void* cmd_data) {
8975 const gles2::cmds::TexSubImage2D& c =
8976 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138977 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
8978 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:008979 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448980 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008981 return error::kNoError;
8982
8983 GLenum target = static_cast<GLenum>(c.target);
8984 GLint level = static_cast<GLint>(c.level);
8985 GLint xoffset = static_cast<GLint>(c.xoffset);
8986 GLint yoffset = static_cast<GLint>(c.yoffset);
8987 GLsizei width = static_cast<GLsizei>(c.width);
8988 GLsizei height = static_cast<GLsizei>(c.height);
8989 GLenum format = static_cast<GLenum>(c.format);
8990 GLenum type = static_cast<GLenum>(c.type);
8991 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348992 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248993 width, height, format, type, state_.unpack_alignment, &data_size,
8994 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008995 return error::kOutOfBounds;
8996 }
8997 const void* pixels = GetSharedMemoryAs<const void*>(
8998 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038999 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009000 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009001}
9002
[email protected]f7a64ee2010-02-01 22:24:149003error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349004 uint32 immediate_data_size,
9005 const void* cmd_data) {
9006 const gles2::cmds::GetVertexAttribPointerv& c =
9007 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369008 GLuint index = static_cast<GLuint>(c.index);
9009 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359010 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259011 Result* result = GetSharedMemoryAs<Result*>(
9012 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369013 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149014 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369015 }
[email protected]07d0cc82010-02-17 04:51:409016 // Check that the client initialized the result.
9017 if (result->size != 0) {
9018 return error::kInvalidArguments;
9019 }
[email protected]9438b012010-06-15 22:55:059020 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519021 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9022 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149023 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369024 }
[email protected]3916c97e2010-02-25 03:20:509025 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519026 LOCAL_SET_GL_ERROR(
9027 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149028 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369029 }
[email protected]0bfd9882010-02-05 23:02:259030 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089031 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359032 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149033 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329034}
9035
[email protected]f7b85372010-02-03 01:11:379036bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429037 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379038 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129039 error::Error* error, GLint* real_location,
9040 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109041 DCHECK(error);
9042 DCHECK(service_id);
9043 DCHECK(result_pointer);
9044 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129045 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379046 *error = error::kNoError;
9047 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259048 SizedResult<GLint>* result;
9049 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9050 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9051 if (!result) {
[email protected]f7b85372010-02-03 01:11:379052 *error = error::kOutOfBounds;
9053 return false;
9054 }
[email protected]0bfd9882010-02-05 23:02:259055 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379056 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259057 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429058 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9059 if (!program) {
[email protected]ae51d192010-04-27 00:48:039060 return false;
9061 }
[email protected]df37b9932013-03-08 05:21:429062 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379063 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519064 LOCAL_SET_GL_ERROR(
9065 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379066 return false;
9067 }
[email protected]df37b9932013-03-08 05:21:429068 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369069 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359070 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429071 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129072 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369073 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379074 // No such location.
[email protected]ab09b612013-03-11 22:11:519075 LOCAL_SET_GL_ERROR(
9076 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379077 return false;
9078 }
[email protected]43c2f1f2011-03-25 18:35:369079 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509080 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379081 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519082 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379083 return false;
9084 }
[email protected]0bfd9882010-02-05 23:02:259085 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9086 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9087 if (!result) {
[email protected]f7b85372010-02-03 01:11:379088 *error = error::kOutOfBounds;
9089 return false;
9090 }
[email protected]0bfd9882010-02-05 23:02:259091 result->size = size;
[email protected]939e7362010-05-13 20:49:109092 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379093 return true;
9094}
9095
vmiuracd108592014-09-08 14:36:349096error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9097 const void* cmd_data) {
9098 const gles2::cmds::GetUniformiv& c =
9099 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379100 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339101 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379102 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109103 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129104 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379105 Error error;
[email protected]0bfd9882010-02-05 23:02:259106 void* result;
[email protected]f7b85372010-02-03 01:11:379107 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129108 program, fake_location, c.params_shm_id, c.params_shm_offset,
9109 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259110 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129111 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359112 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379113 }
9114 return error;
[email protected]96449d2c2009-11-25 00:01:329115}
9116
vmiuracd108592014-09-08 14:36:349117error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9118 const void* cmd_data) {
9119 const gles2::cmds::GetUniformfv& c =
9120 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379121 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339122 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379123 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129124 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379125 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359126 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109127 Result* result;
9128 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379129 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129130 program, fake_location, c.params_shm_id, c.params_shm_offset,
9131 &error, &real_location, &service_id,
9132 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109133 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9134 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9135 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559136 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129137 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109138 GLfloat* dst = result->GetData();
9139 for (GLsizei ii = 0; ii < num_values; ++ii) {
9140 dst[ii] = (temp[ii] != 0);
9141 }
9142 } else {
[email protected]1b0a6752012-02-22 03:44:129143 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109144 }
[email protected]f7b85372010-02-03 01:11:379145 }
9146 return error;
[email protected]96449d2c2009-11-25 00:01:329147}
9148
[email protected]f7a64ee2010-02-01 22:24:149149error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349150 uint32 immediate_data_size,
9151 const void* cmd_data) {
9152 const gles2::cmds::GetShaderPrecisionFormat& c =
9153 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259154 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9155 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359156 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259157 Result* result = GetSharedMemoryAs<Result*>(
9158 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9159 if (!result) {
9160 return error::kOutOfBounds;
9161 }
[email protected]07d0cc82010-02-17 04:51:409162 // Check that the client initialized the result.
9163 if (result->success != 0) {
9164 return error::kInvalidArguments;
9165 }
[email protected]9438b012010-06-15 22:55:059166 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519167 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539168 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299169 return error::kNoError;
9170 }
[email protected]9438b012010-06-15 22:55:059171 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519172 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539173 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299174 return error::kNoError;
9175 }
9176
9177 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409178
[email protected]46c86752013-05-21 05:08:399179 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409180 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219181 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409182
9183 result->min_range = range[0];
9184 result->max_range = range[1];
9185 result->precision = precision;
9186
[email protected]f7a64ee2010-02-01 22:24:149187 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329188}
9189
[email protected]f7a64ee2010-02-01 22:24:149190error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349191 uint32 immediate_data_size,
9192 const void* cmd_data) {
9193 const gles2::cmds::GetAttachedShaders& c =
9194 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259195 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429196 GLuint program_id = static_cast<GLuint>(c.program);
9197 Program* program = GetProgramInfoNotShader(
9198 program_id, "glGetAttachedShaders");
9199 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259200 return error::kNoError;
9201 }
[email protected]ed9f9cd2013-02-27 21:12:359202 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259203 uint32 max_count = Result::ComputeMaxResults(result_size);
9204 Result* result = GetSharedMemoryAs<Result*>(
9205 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9206 if (!result) {
9207 return error::kOutOfBounds;
9208 }
[email protected]07d0cc82010-02-17 04:51:409209 // Check that the client initialized the result.
9210 if (result->size != 0) {
9211 return error::kInvalidArguments;
9212 }
[email protected]0bfd9882010-02-05 23:02:259213 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039214 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429215 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259216 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039217 if (!shader_manager()->GetClientId(result->GetData()[ii],
9218 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259219 NOTREACHED();
9220 return error::kGenericError;
9221 }
9222 }
9223 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149224 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329225}
9226
[email protected]f7a64ee2010-02-01 22:24:149227error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349228 uint32 immediate_data_size,
9229 const void* cmd_data) {
9230 const gles2::cmds::GetActiveUniform& c =
9231 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429232 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259233 GLuint index = c.index;
9234 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359235 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259236 Result* result = GetSharedMemoryAs<Result*>(
9237 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9238 if (!result) {
9239 return error::kOutOfBounds;
9240 }
[email protected]07d0cc82010-02-17 04:51:409241 // Check that the client initialized the result.
9242 if (result->success != 0) {
9243 return error::kInvalidArguments;
9244 }
[email protected]df37b9932013-03-08 05:21:429245 Program* program = GetProgramInfoNotShader(
9246 program_id, "glGetActiveUniform");
9247 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259248 return error::kNoError;
9249 }
[email protected]ed9f9cd2013-02-27 21:12:359250 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429251 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259252 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519253 LOCAL_SET_GL_ERROR(
9254 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259255 return error::kNoError;
9256 }
9257 result->success = 1; // true.
9258 result->size = uniform_info->size;
9259 result->type = uniform_info->type;
9260 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299261 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149262 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329263}
9264
vmiuracd108592014-09-08 14:36:349265error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9266 const void* cmd_data) {
9267 const gles2::cmds::GetActiveAttrib& c =
9268 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429269 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259270 GLuint index = c.index;
9271 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359272 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259273 Result* result = GetSharedMemoryAs<Result*>(
9274 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9275 if (!result) {
9276 return error::kOutOfBounds;
9277 }
[email protected]07d0cc82010-02-17 04:51:409278 // Check that the client initialized the result.
9279 if (result->success != 0) {
9280 return error::kInvalidArguments;
9281 }
[email protected]df37b9932013-03-08 05:21:429282 Program* program = GetProgramInfoNotShader(
9283 program_id, "glGetActiveAttrib");
9284 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259285 return error::kNoError;
9286 }
[email protected]ed9f9cd2013-02-27 21:12:359287 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429288 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259289 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519290 LOCAL_SET_GL_ERROR(
9291 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259292 return error::kNoError;
9293 }
9294 result->success = 1; // true.
9295 result->size = attrib_info->size;
9296 result->type = attrib_info->type;
9297 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299298 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149299 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329300}
9301
vmiuracd108592014-09-08 14:36:349302error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
9303 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:589304#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519305 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:589306 return error::kNoError;
9307#else
9308 GLsizei n = static_cast<GLsizei>(c.n);
9309 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:519310 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:589311 return error::kNoError;
9312 }
9313 GLsizei length = static_cast<GLsizei>(c.length);
9314 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:519315 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:589316 return error::kNoError;
9317 }
9318 uint32 data_size;
9319 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9320 return error::kOutOfBounds;
9321 }
9322 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9323 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9324 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9325 const void* binary = GetSharedMemoryAs<const void*>(
9326 c.binary_shm_id, c.binary_shm_offset, length);
9327 if (shaders == NULL || binary == NULL) {
9328 return error::kOutOfBounds;
9329 }
[email protected]0782b14b2014-05-24 13:04:169330 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:589331 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:429332 Shader* shader = GetShader(shaders[ii]);
9333 if (!shader) {
[email protected]ab09b612013-03-11 22:11:519334 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:589335 return error::kNoError;
9336 }
[email protected]df37b9932013-03-08 05:21:429337 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:589338 }
9339 // TODO(gman): call glShaderBinary
9340 return error::kNoError;
9341#endif
9342}
9343
[email protected]6d792ee12013-05-15 00:40:569344void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:499345 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:089346
[email protected]64ace852011-05-19 21:49:499347 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:429348 // TRACE_EVENT for gpu tests:
9349 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:429350 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:429351 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9352 "width", (is_offscreen ? offscreen_size_.width() :
9353 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:569354 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:499355 "offscreen", is_offscreen,
9356 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:159357 {
[email protected]a36ed4832014-04-24 16:40:279358 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:159359 }
9360
[email protected]8f9b8dd2013-09-12 18:05:139361 bool is_tracing;
9362 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9363 &is_tracing);
9364 if (is_tracing) {
9365 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9366 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9367 is_offscreen ? offscreen_size_ : surface_->GetSize());
9368 }
9369
[email protected]6217d392010-03-25 22:08:359370 // If offscreen then don't actually SwapBuffers to the display. Just copy
9371 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499372 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319373 TRACE_EVENT2("gpu", "Offscreen",
9374 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539375 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9376 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9377 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9378 // fix this.
[email protected]62e155e2012-10-23 22:43:159379 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539380 offscreen_saved_frame_buffer_->Create();
9381 glFinish();
9382 }
9383
9384 // Allocate the offscreen saved color texture.
9385 DCHECK(offscreen_saved_color_format_);
9386 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099387 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539388
9389 offscreen_saved_frame_buffer_->AttachRenderTexture(
9390 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059391 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9392 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9393 GL_FRAMEBUFFER_COMPLETE) {
9394 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9395 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569396 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9397 return;
[email protected]f0cfe752013-01-14 01:09:059398 }
[email protected]1fb8c482011-08-31 01:01:539399
[email protected]f0cfe752013-01-14 01:09:059400 // Clear the offscreen color texture.
9401 // TODO(piman): Is this still necessary?
9402 {
9403 ScopedFrameBufferBinder binder(this,
9404 offscreen_saved_frame_buffer_->id());
9405 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:459406 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9407 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:059408 glClear(GL_COLOR_BUFFER_BIT);
9409 RestoreClearState();
9410 }
[email protected]1fb8c482011-08-31 01:01:539411 }
9412
9413 UpdateParentTextureInfo();
9414 }
9415
[email protected]f0cfe752013-01-14 01:09:059416 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:569417 return;
[email protected]ab09b612013-03-11 22:11:519418 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:309419 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:359420
[email protected]34ff8b0c2010-10-01 20:06:029421 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:139422 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:279423 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:489424 } else {
[email protected]069944672012-04-25 20:52:239425 ScopedFrameBufferBinder binder(this,
9426 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:139427
[email protected]069944672012-04-25 20:52:239428 if (offscreen_target_buffer_preserved_) {
9429 // Copy the target frame buffer to the saved offscreen texture.
9430 offscreen_saved_color_texture_->Copy(
9431 offscreen_saved_color_texture_->size(),
9432 offscreen_saved_color_format_);
9433 } else {
9434 // Flip the textures in the parent context via the texture manager.
9435 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499436 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239437 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569438
[email protected]069944672012-04-25 20:52:239439 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9440 offscreen_target_frame_buffer_->AttachRenderTexture(
9441 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489442 }
[email protected]069944672012-04-25 20:52:239443
9444 // Ensure the side effects of the copy are visible to the parent
9445 // context. There is no need to do this for ANGLE because it uses a
9446 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:189447 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:239448 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399449 }
[email protected]6217d392010-03-25 22:08:359450 } else {
[email protected]f62a5ab2011-05-23 20:34:159451 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019452 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569453 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019454 }
[email protected]6217d392010-03-25 22:08:359455 }
vmiura8266ca72014-09-09 21:37:009456
9457 // This may be a slow command. Exit command processing to allow for
9458 // context preemption and GPU watchdog checks.
9459 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:359460}
9461
[email protected]d4239852011-08-12 04:51:229462error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:349463 uint32 immediate_data_size,
9464 const void* cmd_data) {
9465 const gles2::cmds::EnableFeatureCHROMIUM& c =
9466 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:189467 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289468 if (!bucket || bucket->size() == 0) {
9469 return error::kInvalidArguments;
9470 }
[email protected]ed9f9cd2013-02-27 21:12:359471 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189472 Result* result = GetSharedMemoryAs<Result*>(
9473 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9474 if (!result) {
9475 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109476 }
[email protected]b1d2dcb2010-05-17 19:24:189477 // Check that the client initialized the result.
9478 if (*result != 0) {
9479 return error::kInvalidArguments;
9480 }
9481 std::string feature_str;
9482 if (!bucket->GetAsString(&feature_str)) {
9483 return error::kInvalidArguments;
9484 }
9485
9486 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229487 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189488 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229489 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409490 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9491 // TODO(gman): decide how to remove the need for this const_cast.
9492 // I could make validators_ non const but that seems bad as this is the only
9493 // place it is needed. I could make some special friend class of validators
9494 // just to allow this to set them. That seems silly. I could refactor this
9495 // code to use the extension mechanism or the initialization attributes to
9496 // turn this feature on. Given that the only real point of this is to make
9497 // the conformance tests pass and given that there is lots of real work that
9498 // needs to be done it seems like refactoring for one to one of those
9499 // methods is a very low priority.
9500 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049501 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9502 force_webgl_glsl_validation_ = true;
9503 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189504 } else {
9505 return error::kNoError;
9506 }
9507
9508 *result = 1; // true.
9509 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109510}
9511
[email protected]c2f8c8402010-12-06 18:07:249512error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9513 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:349514 const void* cmd_data) {
9515 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
9516 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
9517 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249518 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359519 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199520 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249521 bucket->SetFromString(info->extensions().c_str());
9522 return error::kNoError;
9523}
9524
9525error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:349526 uint32 immediate_data_size,
9527 const void* cmd_data) {
9528 const gles2::cmds::RequestExtensionCHROMIUM& c =
9529 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:249530 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289531 if (!bucket || bucket->size() == 0) {
9532 return error::kInvalidArguments;
9533 }
[email protected]c2f8c8402010-12-06 18:07:249534 std::string feature_str;
9535 if (!bucket->GetAsString(&feature_str)) {
9536 return error::kInvalidArguments;
9537 }
9538
[email protected]4b7eba92013-01-08 02:23:569539 bool desire_webgl_glsl_validation =
9540 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9541 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499542 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139543 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:069544 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:569545 if (force_webgl_glsl_validation_) {
9546 desire_standard_derivatives =
9547 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499548 desire_frag_depth =
9549 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139550 desire_draw_buffers =
9551 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:069552 desire_shader_texture_lod =
9553 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049554 }
9555
[email protected]4b7eba92013-01-08 02:23:569556 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499557 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139558 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9559 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499560 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9561 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9562 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139563 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:069564 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:249565 InitializeShaderTranslator();
9566 }
9567
[email protected]302ce6d2011-07-07 23:28:119568 UpdateCapabilities();
9569
[email protected]c2f8c8402010-12-06 18:07:249570 return error::kNoError;
9571}
9572
[email protected]372e0412011-06-28 16:08:569573error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
vmiuracd108592014-09-08 14:36:349574 uint32 immediate_data_size,
9575 const void* cmd_data) {
9576 const gles2::cmds::GetMultipleIntegervCHROMIUM& c =
9577 *static_cast<const gles2::cmds::GetMultipleIntegervCHROMIUM*>(cmd_data);
[email protected]372e0412011-06-28 16:08:569578 GLuint count = c.count;
9579 uint32 pnames_size;
9580 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9581 return error::kOutOfBounds;
9582 }
9583 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9584 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9585 if (pnames == NULL) {
9586 return error::kOutOfBounds;
9587 }
9588
9589 // We have to copy them since we use them twice so the client
9590 // can't change them between the time we validate them and the time we use
9591 // them.
[email protected]40d90a22013-04-09 03:39:559592 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:569593 memcpy(enums.get(), pnames, pnames_size);
9594
9595 // Count up the space needed for the result.
9596 uint32 num_results = 0;
9597 for (GLuint ii = 0; ii < count; ++ii) {
9598 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9599 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519600 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]caa13ed2014-02-17 11:29:209601 "glGetMultipleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569602 return error::kNoError;
9603 }
9604 // Num will never be more than 4.
9605 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479606 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569607 return error::kOutOfBounds;
9608 }
9609 }
9610
9611 uint32 result_size = 0;
9612 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9613 return error::kOutOfBounds;
9614 }
9615
9616 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519617 LOCAL_SET_GL_ERROR(
9618 GL_INVALID_VALUE,
[email protected]caa13ed2014-02-17 11:29:209619 "glGetMultipleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569620 return error::kNoError;
9621 }
9622
9623 GLint* results = GetSharedMemoryAs<GLint*>(
9624 c.results_shm_id, c.results_shm_offset, result_size);
9625 if (results == NULL) {
9626 return error::kOutOfBounds;
9627 }
9628
9629 // Check the results have been cleared in case the context was lost.
9630 for (uint32 ii = 0; ii < num_results; ++ii) {
9631 if (results[ii]) {
9632 return error::kInvalidArguments;
9633 }
9634 }
9635
9636 // Get each result.
9637 GLint* start = results;
9638 for (GLuint ii = 0; ii < count; ++ii) {
9639 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269640 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539641 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:489642 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:569643 }
9644 results += num_written;
9645 }
9646
9647 // Just to verify. Should this be a DCHECK?
9648 if (static_cast<uint32>(results - start) != num_results) {
9649 return error::kOutOfBounds;
9650 }
9651
9652 return error::kNoError;
9653}
9654
[email protected]2318d342011-07-11 22:27:429655error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:349656 uint32 immediate_data_size,
9657 const void* cmd_data) {
9658 const gles2::cmds::GetProgramInfoCHROMIUM& c =
9659 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429660 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429661 uint32 bucket_id = c.bucket_id;
9662 Bucket* bucket = CreateBucket(bucket_id);
9663 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429664 Program* program = NULL;
9665 program = GetProgram(program_id);
9666 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469667 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429668 }
[email protected]df37b9932013-03-08 05:21:429669 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429670 return error::kNoError;
9671}
9672
[email protected]38d139d2011-07-14 00:38:439673error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9674 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439675 case GL_NO_ERROR:
9676 // TODO(kbr): improve the precision of the error code in this case.
9677 // Consider delegating to context for error code if MakeCurrent fails.
9678 return error::kUnknown;
9679 case GL_GUILTY_CONTEXT_RESET_ARB:
9680 return error::kGuilty;
9681 case GL_INNOCENT_CONTEXT_RESET_ARB:
9682 return error::kInnocent;
9683 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9684 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439685 }
9686
9687 NOTREACHED();
9688 return error::kUnknown;
9689}
9690
jbauman7a059312014-10-16 19:30:549691void GLES2DecoderImpl::MaybeExitOnContextLost() {
9692 // Some D3D drivers cannot recover from device lost in the GPU process
9693 // sandbox. Allow a new GPU process to launch.
9694 if (workarounds().exit_on_context_lost) {
9695 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
9696 << " a D3D device in the Chrome GPU process sandbox.";
9697#if defined(OS_WIN)
9698 base::win::SetShouldCrashOnProcessDetach(false);
9699#endif
9700 exit(0);
9701 }
9702}
9703
[email protected]38d139d2011-07-14 00:38:439704bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099705 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:549706 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:099707 return true;
9708 }
[email protected]706b69f2012-07-27 04:59:309709 if (context_->WasAllocatedUsingRobustnessExtension()) {
9710 GLenum status = GL_NO_ERROR;
9711 if (has_robustness_extension_)
9712 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439713 if (status != GL_NO_ERROR) {
9714 // The graphics card was reset. Signal a lost context to the application.
9715 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229716 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439717 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099718 << " context lost via ARB/EXT_robustness. Reset status = "
9719 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:549720 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:439721 return true;
9722 }
9723 }
9724 return false;
9725}
9726
[email protected]93a7d98f2013-07-11 00:04:229727bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9728 return WasContextLost() && reset_by_robustness_extension_;
9729}
9730
[email protected]c4485aad62012-12-17 10:19:099731void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9732 // Only loses the context once.
9733 if (reset_status_ != GL_NO_ERROR) {
9734 return;
9735 }
9736
9737 // Marks this context as lost.
9738 reset_status_ = reset_status;
9739 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099740}
9741
[email protected]b096d032013-03-08 03:08:019742error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349743 uint32 immediate_data_size,
9744 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:019745 return error::kUnknownCommand;
9746}
9747
[email protected]840a7e462013-02-27 01:29:519748error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:349749 uint32 immediate_data_size,
9750 const void* cmd_data) {
9751 const gles2::cmds::WaitSyncPointCHROMIUM& c =
9752 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:329753 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:519754 if (wait_sync_point_callback_.is_null())
9755 return error::kNoError;
9756
sievers173a20d2014-10-22 18:19:329757 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:519758 error::kNoError : error::kDeferCommandUntilLater;
9759}
9760
[email protected]5dfc457b2013-12-13 11:13:079761error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:349762 uint32 immediate_data_size,
9763 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:079764 if (surface_->DeferDraws())
9765 return error::kDeferCommandUntilLater;
9766 if (!surface_->SetBackbufferAllocation(false))
9767 return error::kLostContext;
9768 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9769 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9770 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9771 return error::kNoError;
9772}
9773
[email protected]882ba1e22012-03-08 19:02:539774bool GLES2DecoderImpl::GenQueriesEXTHelper(
9775 GLsizei n, const GLuint* client_ids) {
9776 for (GLsizei ii = 0; ii < n; ++ii) {
9777 if (query_manager_->GetQuery(client_ids[ii])) {
9778 return false;
9779 }
9780 }
[email protected]4eea7e62014-04-22 21:14:439781 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:539782 return true;
9783}
9784
9785void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9786 GLsizei n, const GLuint* client_ids) {
9787 for (GLsizei ii = 0; ii < n; ++ii) {
9788 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9789 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139790 ContextState::QueryMap::iterator it =
9791 state_.current_queries.find(query->target());
9792 if (it != state_.current_queries.end())
9793 state_.current_queries.erase(it);
9794
[email protected]c45f1972012-03-14 07:27:369795 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539796 }
[email protected]4eea7e62014-04-22 21:14:439797 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:539798 }
9799}
9800
[email protected]22e3f552012-03-13 01:54:199801bool GLES2DecoderImpl::ProcessPendingQueries() {
9802 if (query_manager_.get() == NULL) {
9803 return false;
9804 }
[email protected]c45f1972012-03-14 07:27:369805 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199806 current_decoder_error_ = error::kOutOfBounds;
9807 }
9808 return query_manager_->HavePendingQueries();
9809}
9810
[email protected]5a36dc132013-07-23 23:17:559811// Note that if there are no pending readpixels right now,
9812// this function will call the callback immediately.
9813void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9814 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9815 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9816 } else {
9817 callback.Run();
9818 }
9819}
9820
9821void GLES2DecoderImpl::ProcessPendingReadPixels() {
9822 while (!pending_readpixel_fences_.empty() &&
9823 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9824 std::vector<base::Closure> callbacks =
9825 pending_readpixel_fences_.front()->callbacks;
9826 pending_readpixel_fences_.pop();
9827 for (size_t i = 0; i < callbacks.size(); i++) {
9828 callbacks[i].Run();
9829 }
9830 }
9831}
9832
[email protected]2b1767cf2013-03-16 09:25:059833bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559834 return !pending_readpixel_fences_.empty() ||
9835 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059836}
9837
9838void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559839 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:489840 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059841 return;
[email protected]b68b100752013-06-05 08:34:489842 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059843 ProcessFinishedAsyncTransfers();
9844}
9845
vmiuracd108592014-09-08 14:36:349846error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
9847 const void* cmd_data) {
9848 const gles2::cmds::BeginQueryEXT& c =
9849 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:539850 GLenum target = static_cast<GLenum>(c.target);
9851 GLuint client_id = static_cast<GLuint>(c.id);
9852 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9853 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9854
[email protected]c45f1972012-03-14 07:27:369855 switch (target) {
9856 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559857 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:319858 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9859 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009860 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369861 break;
[email protected]6a25ae422014-04-17 23:48:279862 case GL_COMMANDS_COMPLETED_CHROMIUM:
9863 if (!features().chromium_sync_query) {
9864 LOCAL_SET_GL_ERROR(
9865 GL_INVALID_OPERATION, "glBeginQueryEXT",
9866 "not enabled for commands completed queries");
9867 return error::kNoError;
9868 }
9869 break;
[email protected]c45f1972012-03-14 07:27:369870 default:
[email protected]62e155e2012-10-23 22:43:159871 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519872 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009873 GL_INVALID_OPERATION, "glBeginQueryEXT",
9874 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369875 return error::kNoError;
9876 }
9877 break;
[email protected]882ba1e22012-03-08 19:02:539878 }
9879
[email protected]8ebd46c2014-01-08 12:06:139880 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519881 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439882 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539883 return error::kNoError;
9884 }
9885
9886 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519887 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539888 return error::kNoError;
9889 }
9890
9891 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9892 if (!query) {
[email protected]4eea7e62014-04-22 21:14:439893 if (!query_manager_->IsValidQuery(client_id)) {
9894 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9895 "glBeginQueryEXT",
9896 "id not made by glGenQueriesEXT");
9897 return error::kNoError;
9898 }
[email protected]c45f1972012-03-14 07:27:369899 query = query_manager_->CreateQuery(
9900 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539901 }
9902
[email protected]c45f1972012-03-14 07:27:369903 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519904 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439905 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539906 return error::kNoError;
9907 } else if (query->shm_id() != sync_shm_id ||
9908 query->shm_offset() != sync_shm_offset) {
9909 DLOG(ERROR) << "Shared memory used by query not the same as before";
9910 return error::kInvalidArguments;
9911 }
9912
[email protected]c45f1972012-03-14 07:27:369913 if (!query_manager_->BeginQuery(query)) {
9914 return error::kOutOfBounds;
9915 }
[email protected]882ba1e22012-03-08 19:02:539916
[email protected]8ebd46c2014-01-08 12:06:139917 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:539918 return error::kNoError;
9919}
9920
vmiuracd108592014-09-08 14:36:349921error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
9922 const void* cmd_data) {
9923 const gles2::cmds::EndQueryEXT& c =
9924 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:539925 GLenum target = static_cast<GLenum>(c.target);
9926 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:139927 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:539928
[email protected]8ebd46c2014-01-08 12:06:139929 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519930 LOCAL_SET_GL_ERROR(
9931 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539932 return error::kNoError;
9933 }
[email protected]882ba1e22012-03-08 19:02:539934
[email protected]8ebd46c2014-01-08 12:06:139935 QueryManager::Query* query = it->second.get();
9936 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369937 return error::kOutOfBounds;
9938 }
9939
[email protected]fe8d73c2013-02-16 22:37:329940 query_manager_->ProcessPendingTransferQueries();
9941
[email protected]8ebd46c2014-01-08 12:06:139942 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:539943 return error::kNoError;
9944}
9945
[email protected]944b62f32012-09-27 02:20:469946bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9947 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469948 for (GLsizei ii = 0; ii < n; ++ii) {
9949 if (GetVertexAttribManager(client_ids[ii])) {
9950 return false;
9951 }
9952 }
[email protected]ab4fd7282012-10-12 16:25:579953
[email protected]62e155e2012-10-23 22:43:159954 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579955 // Emulated VAO
9956 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:489957 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:579958 }
9959 } else {
[email protected]40d90a22013-04-09 03:39:559960 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579961
9962 glGenVertexArraysOES(n, service_ids.get());
9963 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:489964 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:579965 }
[email protected]944b62f32012-09-27 02:20:469966 }
[email protected]ab4fd7282012-10-12 16:25:579967
[email protected]944b62f32012-09-27 02:20:469968 return true;
9969}
9970
9971void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9972 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469973 for (GLsizei ii = 0; ii < n; ++ii) {
9974 VertexAttribManager* vao =
9975 GetVertexAttribManager(client_ids[ii]);
9976 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119977 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:119978 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:469979 }
9980 RemoveVertexAttribManager(client_ids[ii]);
9981 }
9982 }
9983}
9984
9985void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469986 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:469987 if (client_id != 0) {
9988 vao = GetVertexAttribManager(client_id);
9989 if (!vao) {
9990 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9991 // only allows names that have been previously generated. As such, we do
9992 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519993 LOCAL_SET_GL_ERROR(
9994 GL_INVALID_OPERATION,
9995 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469996 current_decoder_error_ = error::kNoError;
9997 return;
[email protected]944b62f32012-09-27 02:20:469998 }
[email protected]944b62f32012-09-27 02:20:469999 } else {
[email protected]81f20a622014-04-18 01:54:5210000 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610001 }
10002
[email protected]ab4fd7282012-10-12 16:25:5710003 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110004 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410005 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510006 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710007 EmulateVertexArrayState();
10008 } else {
[email protected]da364812014-05-09 21:39:4810009 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710010 glBindVertexArrayOES(service_id);
10011 }
10012 }
10013}
10014
10015// Used when OES_vertex_array_object isn't natively supported
10016void GLES2DecoderImpl::EmulateVertexArrayState() {
10017 // Setup the Vertex attribute state
10018 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310019 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710020 }
10021
10022 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110023 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410024 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710025 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10026 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610027}
10028
10029bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610030 const VertexAttribManager* vao =
10031 GetVertexAttribManager(client_id);
10032 return vao && vao->IsValid() && !vao->IsDeleted();
10033}
10034
[email protected]e51bdf32011-11-23 22:21:4610035#if defined(OS_MACOSX)
10036void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10037 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10038 texture_id);
10039 if (it != texture_to_io_surface_map_.end()) {
10040 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310041 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610042 CFRelease(surface);
10043 texture_to_io_surface_map_.erase(it);
10044 }
10045}
10046#endif
10047
10048void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10049 GLenum target, GLsizei width, GLsizei height,
10050 GLuint io_surface_id, GLuint plane) {
10051#if defined(OS_MACOSX)
10052 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110053 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310054 GL_INVALID_OPERATION,
10055 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610056 return;
10057 }
10058
[email protected]e51bdf32011-11-23 22:21:4610059 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10060 // This might be supported in the future, and if we could require
10061 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10062 // could delete a lot of code. For now, perform strict validation so we
10063 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110064 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610065 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310066 "glTexImageIOSurface2DCHROMIUM",
10067 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610068 return;
10069 }
10070
[email protected]09d50362012-10-18 20:54:3710071 // Default target might be conceptually valid, but disallow it to avoid
10072 // accidents.
[email protected]c986af502013-08-14 01:04:4410073 TextureRef* texture_ref =
10074 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910075 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110076 LOCAL_SET_GL_ERROR(
10077 GL_INVALID_OPERATION,
10078 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610079 return;
10080 }
[email protected]e51bdf32011-11-23 22:21:4610081
10082 // Look up the new IOSurface. Note that because of asynchrony
10083 // between processes this might fail; during live resizing the
10084 // plugin process might allocate and release an IOSurface before
10085 // this process gets a chance to look it up. Hold on to any old
10086 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310087 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610088 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110089 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310090 GL_INVALID_OPERATION,
10091 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610092 return;
10093 }
10094
10095 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910096 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610097
10098 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10099 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910100 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610101
10102 CGLContextObj context =
10103 static_cast<CGLContextObj>(context_->GetHandle());
10104
[email protected]c3a6b4a2014-06-04 09:25:5310105 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610106 context,
10107 target,
10108 GL_RGBA,
10109 width,
10110 height,
10111 GL_BGRA,
10112 GL_UNSIGNED_INT_8_8_8_8_REV,
10113 surface,
10114 plane);
10115
10116 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110117 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610118 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310119 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610120 return;
10121 }
10122
10123 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910124 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610125 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10126
10127#else
[email protected]ab09b612013-03-11 22:11:5110128 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310129 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610130#endif
10131}
10132
[email protected]97dc7cbe2011-12-06 17:26:1710133static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10134 switch (internalformat) {
10135 case GL_RGB565:
10136 return GL_RGB;
10137 case GL_RGBA4:
10138 return GL_RGBA;
10139 case GL_RGB5_A1:
10140 return GL_RGBA;
10141 case GL_RGB8_OES:
10142 return GL_RGB;
10143 case GL_RGBA8_OES:
10144 return GL_RGBA;
10145 case GL_LUMINANCE8_ALPHA8_EXT:
10146 return GL_LUMINANCE_ALPHA;
10147 case GL_LUMINANCE8_EXT:
10148 return GL_LUMINANCE;
10149 case GL_ALPHA8_EXT:
10150 return GL_ALPHA;
10151 case GL_RGBA32F_EXT:
10152 return GL_RGBA;
10153 case GL_RGB32F_EXT:
10154 return GL_RGB;
10155 case GL_ALPHA32F_EXT:
10156 return GL_ALPHA;
10157 case GL_LUMINANCE32F_EXT:
10158 return GL_LUMINANCE;
10159 case GL_LUMINANCE_ALPHA32F_EXT:
10160 return GL_LUMINANCE_ALPHA;
10161 case GL_RGBA16F_EXT:
10162 return GL_RGBA;
10163 case GL_RGB16F_EXT:
10164 return GL_RGB;
10165 case GL_ALPHA16F_EXT:
10166 return GL_ALPHA;
10167 case GL_LUMINANCE16F_EXT:
10168 return GL_LUMINANCE;
10169 case GL_LUMINANCE_ALPHA16F_EXT:
10170 return GL_LUMINANCE_ALPHA;
10171 case GL_BGRA8_EXT:
10172 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5910173 case GL_SRGB8_ALPHA8_EXT:
10174 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1710175 default:
10176 return GL_NONE;
10177 }
10178}
10179
[email protected]43410e92012-04-20 17:06:2810180void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:0310181 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:5410182 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:0810183 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
10184
[email protected]370eaf12013-05-18 09:19:4910185 TextureRef* dest_texture_ref = GetTexture(dest_id);
10186 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:2810187
[email protected]370eaf12013-05-18 09:19:4910188 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110189 LOCAL_SET_GL_ERROR(
10190 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:2810191 return;
10192 }
10193
10194 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110195 LOCAL_SET_GL_ERROR(
10196 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:2810197 return;
10198 }
10199
[email protected]370eaf12013-05-18 09:19:4910200 Texture* source_texture = source_texture_ref->texture();
10201 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710202 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510203 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410204 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10205 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:0010206 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10207 "glCopyTextureCHROMIUM",
10208 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310209 return;
10210 }
10211
[email protected]43410e92012-04-20 17:06:2810212 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810213
[email protected]3e0dfd72014-02-21 06:28:4110214 gfx::GLImage* image =
10215 source_texture->GetLevelImage(source_texture->target(), 0);
10216 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510217 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610218 source_width = size.width();
10219 source_height = size.height();
10220 if (source_width <= 0 || source_height <= 0) {
10221 LOCAL_SET_GL_ERROR(
10222 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510223 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610224 return;
10225 }
[email protected]3ecc1052013-09-26 08:59:0010226 } else {
10227 if (!source_texture->GetLevelSize(
10228 source_texture->target(), 0, &source_width, &source_height)) {
10229 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10230 "glCopyTextureChromium",
10231 "source texture has no level 0");
10232 return;
10233 }
10234
10235 // Check that this type of texture is allowed.
10236 if (!texture_manager()->ValidForTarget(
10237 source_texture->target(), level, source_width, source_height, 1)) {
10238 LOCAL_SET_GL_ERROR(
10239 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10240 return;
10241 }
[email protected]377976552013-05-14 23:32:5610242 }
10243
[email protected]04b5b37d2014-02-07 02:11:5110244 // Clear the source texture if necessary.
10245 if (!texture_manager()->ClearTextureLevel(
10246 this, source_texture_ref, source_texture->target(), 0)) {
10247 LOCAL_SET_GL_ERROR(
10248 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
10249 return;
10250 }
10251
[email protected]a6e3d282014-08-22 22:20:4410252 GLenum source_type = 0;
10253 GLenum source_internal_format = 0;
10254 source_texture->GetLevelType(
10255 source_texture->target(), 0, &source_type, &source_internal_format);
10256
10257 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
10258 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
10259 // renderable on some platforms.
reveman6b0fbe42014-09-04 00:55:0310260 bool valid_dest_format = internal_format == GL_RGB ||
10261 internal_format == GL_RGBA ||
10262 internal_format == GL_BGRA_EXT;
[email protected]a6e3d282014-08-22 22:20:4410263 bool valid_source_format = source_internal_format == GL_ALPHA ||
10264 source_internal_format == GL_RGB ||
10265 source_internal_format == GL_RGBA ||
10266 source_internal_format == GL_LUMINANCE ||
10267 source_internal_format == GL_LUMINANCE_ALPHA ||
10268 source_internal_format == GL_BGRA_EXT;
10269 if (!valid_source_format || !valid_dest_format) {
10270 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10271 "glCopyTextureCHROMIUM",
10272 "invalid internal format");
10273 return;
10274 }
10275
[email protected]cf6b8f62012-05-25 21:43:3710276 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
10277 // needed because it takes 10s of milliseconds to initialize.
10278 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5110279 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3710280 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2710281 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3710282 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5110283 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3710284 return;
10285 }
10286
[email protected]efc87712014-07-09 00:22:4710287 GLenum dest_type_previous = dest_type;
10288 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0710289 bool dest_level_defined = dest_texture->GetLevelSize(
10290 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2810291
[email protected]0a1e9ad2012-05-04 21:13:0310292 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5410293 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0710294 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0310295 }
10296
10297 // Resize the destination texture to the dimensions of the source texture.
10298 if (!dest_level_defined || dest_width != source_width ||
10299 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5410300 dest_internal_format != internal_format ||
10301 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2810302 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5110303 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0710304 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3810305 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2810306 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0310307 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5110308 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0310309 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0210310 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2810311 return;
[email protected]0a1e9ad2012-05-04 21:13:0310312 }
[email protected]43410e92012-04-20 17:06:2810313
10314 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910315 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0310316 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2510317 } else {
[email protected]02965c22013-03-09 02:40:0710318 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4910319 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2810320 }
10321
[email protected]00c2cf92014-03-14 00:08:3710322 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5410323
revemance8fbe82014-09-05 02:19:5210324 // Try using GLImage::CopyTexImage when possible.
10325 bool unpack_premultiply_alpha_change =
10326 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
10327 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
10328 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
10329 if (image->CopyTexImage(GL_TEXTURE_2D))
10330 return;
10331 }
10332
10333 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
10334
[email protected]5394a4102013-04-18 05:41:3710335 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
10336 // before presenting.
10337 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
10338 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
10339 // instead of using default matrix crbug.com/226218.
10340 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
10341 0.0f, 1.0f, 0.0f, 0.0f,
10342 0.0f, 0.0f, 1.0f, 0.0f,
10343 0.0f, 0.0f, 0.0f, 1.0f};
10344 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
10345 this,
10346 source_texture->target(),
[email protected]5394a4102013-04-18 05:41:3710347 source_texture->service_id(),
[email protected]90f7d30d2014-08-13 02:51:5710348 dest_texture->service_id(),
10349 level,
10350 source_width,
10351 source_height,
[email protected]5394a4102013-04-18 05:41:3710352 unpack_flip_y_,
10353 unpack_premultiply_alpha_,
10354 unpack_unpremultiply_alpha_,
10355 default_matrix);
10356 } else {
[email protected]90f7d30d2014-08-13 02:51:5710357 copy_texture_CHROMIUM_->DoCopyTexture(this,
10358 source_texture->target(),
10359 source_texture->service_id(),
10360 source_internal_format,
10361 dest_texture->service_id(),
10362 level,
10363 internal_format,
10364 source_width,
10365 source_height,
10366 unpack_flip_y_,
10367 unpack_premultiply_alpha_,
10368 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3710369 }
[email protected]91c94eb2013-10-22 10:32:5410370
10371 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810372}
10373
[email protected]97dc7cbe2011-12-06 17:26:1710374static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10375 switch (internalformat) {
10376 case GL_RGB565:
10377 return GL_UNSIGNED_SHORT_5_6_5;
10378 case GL_RGBA4:
10379 return GL_UNSIGNED_SHORT_4_4_4_4;
10380 case GL_RGB5_A1:
10381 return GL_UNSIGNED_SHORT_5_5_5_1;
10382 case GL_RGB8_OES:
10383 return GL_UNSIGNED_BYTE;
10384 case GL_RGBA8_OES:
10385 return GL_UNSIGNED_BYTE;
10386 case GL_LUMINANCE8_ALPHA8_EXT:
10387 return GL_UNSIGNED_BYTE;
10388 case GL_LUMINANCE8_EXT:
10389 return GL_UNSIGNED_BYTE;
10390 case GL_ALPHA8_EXT:
10391 return GL_UNSIGNED_BYTE;
10392 case GL_RGBA32F_EXT:
10393 return GL_FLOAT;
10394 case GL_RGB32F_EXT:
10395 return GL_FLOAT;
10396 case GL_ALPHA32F_EXT:
10397 return GL_FLOAT;
10398 case GL_LUMINANCE32F_EXT:
10399 return GL_FLOAT;
10400 case GL_LUMINANCE_ALPHA32F_EXT:
10401 return GL_FLOAT;
10402 case GL_RGBA16F_EXT:
10403 return GL_HALF_FLOAT_OES;
10404 case GL_RGB16F_EXT:
10405 return GL_HALF_FLOAT_OES;
10406 case GL_ALPHA16F_EXT:
10407 return GL_HALF_FLOAT_OES;
10408 case GL_LUMINANCE16F_EXT:
10409 return GL_HALF_FLOAT_OES;
10410 case GL_LUMINANCE_ALPHA16F_EXT:
10411 return GL_HALF_FLOAT_OES;
10412 case GL_BGRA8_EXT:
10413 return GL_UNSIGNED_BYTE;
10414 default:
10415 return GL_NONE;
10416 }
10417}
10418
10419void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4410420 GLenum target,
10421 GLint levels,
10422 GLenum internal_format,
10423 GLsizei width,
10424 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1310425 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
10426 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4110427 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0010428 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5110429 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310430 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1710431 return;
10432 }
[email protected]c986af502013-08-14 01:04:4410433 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10434 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910435 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110436 LOCAL_SET_GL_ERROR(
10437 GL_INVALID_OPERATION,
10438 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1710439 return;
10440 }
[email protected]370eaf12013-05-18 09:19:4910441 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710442 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410443 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1710444 }
[email protected]02965c22013-03-09 02:40:0710445 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5110446 LOCAL_SET_GL_ERROR(
10447 GL_INVALID_OPERATION,
10448 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1710449 return;
10450 }
[email protected]7989c9e2013-01-23 06:39:2610451
10452 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10453 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10454
10455 {
10456 GLsizei level_width = width;
10457 GLsizei level_height = height;
10458 uint32 estimated_size = 0;
10459 for (int ii = 0; ii < levels; ++ii) {
10460 uint32 level_size = 0;
10461 if (!GLES2Util::ComputeImageDataSizes(
10462 level_width, level_height, format, type, state_.unpack_alignment,
10463 &estimated_size, NULL, NULL) ||
10464 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110465 LOCAL_SET_GL_ERROR(
10466 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2610467 return;
10468 }
10469 level_width = std::max(1, level_width >> 1);
10470 level_height = std::max(1, level_height >> 1);
10471 }
10472 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110473 LOCAL_SET_GL_ERROR(
10474 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610475 return;
10476 }
10477 }
10478
[email protected]ab09b612013-03-11 22:11:5110479 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3810480 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5110481 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710482 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510483 GLsizei level_width = width;
10484 GLsizei level_height = height;
10485 for (int ii = 0; ii < levels; ++ii) {
10486 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910487 texture_ref, target, ii, format,
10488 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1510489 level_width = std::max(1, level_width >> 1);
10490 level_height = std::max(1, level_height >> 1);
10491 }
[email protected]02965c22013-03-09 02:40:0710492 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710493 }
[email protected]97dc7cbe2011-12-06 17:26:1710494}
[email protected]e51bdf32011-11-23 22:21:4610495
[email protected]78b514b2012-05-01 21:50:5910496error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3410497 uint32 immediate_data_size,
10498 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3510499 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910500}
10501
10502void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710503 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210504 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210505 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710506 "mailbox[0]", static_cast<unsigned char>(data[0]));
10507
[email protected]43f253da2014-06-10 17:51:2210508 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10509 &state_, target);
10510 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
10511}
10512
10513void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
10514 GLenum target, const GLbyte* data) {
10515 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
10516 "context", logger_.GetLogPrefix(),
10517 "mailbox[0]", static_cast<unsigned char>(data[0]));
10518
10519 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
10520 target, data);
10521}
10522
10523void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
10524 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3710525 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2210526 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3710527 "mailbox that was not generated by "
10528 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210529
[email protected]370eaf12013-05-18 09:19:4910530 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110531 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210532 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910533 return;
10534 }
10535
[email protected]62e65f02013-05-29 22:28:1010536 Texture* produced = texture_manager()->Produce(texture_ref);
10537 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110538 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2210539 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
10540 return;
10541 }
10542
10543 if (produced->target() != target) {
10544 LOCAL_SET_GL_ERROR(
10545 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5910546 return;
10547 }
10548
[email protected]64ba52f2014-02-15 14:22:3710549 group_->mailbox_manager()->ProduceTexture(target, mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5910550}
10551
10552void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3710553 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0210554 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210555 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3710556 "mailbox[0]", static_cast<unsigned char>(data[0]));
10557 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10558 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
10559 "mailbox that was not generated by "
10560 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0210561
[email protected]62e65f02013-05-29 22:28:1010562 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410563 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110564 if (!texture_ref.get()) {
10565 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10566 "glConsumeTextureCHROMIUM",
10567 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910568 return;
10569 }
[email protected]62e65f02013-05-29 22:28:1010570 GLuint client_id = texture_ref->client_id();
10571 if (!client_id) {
10572 LOCAL_SET_GL_ERROR(
10573 GL_INVALID_OPERATION,
10574 "glConsumeTextureCHROMIUM", "unknown texture for target");
10575 return;
10576 }
[email protected]64ba52f2014-02-15 14:22:3710577 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
[email protected]62e65f02013-05-29 22:28:1010578 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110579 LOCAL_SET_GL_ERROR(
10580 GL_INVALID_OPERATION,
10581 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910582 return;
10583 }
[email protected]62e65f02013-05-29 22:28:1010584 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110585 LOCAL_SET_GL_ERROR(
10586 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010587 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910588 return;
10589 }
[email protected]62e65f02013-05-29 22:28:1010590
10591 DeleteTexturesHelper(1, &client_id);
10592 texture_ref = texture_manager()->Consume(client_id, texture);
10593 glBindTexture(target, texture_ref->service_id());
10594
10595 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10596 unit.bind_target = target;
10597 switch (target) {
10598 case GL_TEXTURE_2D:
10599 unit.bound_texture_2d = texture_ref;
10600 break;
10601 case GL_TEXTURE_CUBE_MAP:
10602 unit.bound_texture_cube_map = texture_ref;
10603 break;
10604 case GL_TEXTURE_EXTERNAL_OES:
10605 unit.bound_texture_external_oes = texture_ref;
10606 break;
10607 case GL_TEXTURE_RECTANGLE_ARB:
10608 unit.bound_texture_rectangle_arb = texture_ref;
10609 break;
10610 default:
10611 NOTREACHED(); // Validation should prevent us getting here.
10612 break;
10613 }
[email protected]78b514b2012-05-01 21:50:5910614}
10615
[email protected]43f253da2014-06-10 17:51:2210616error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
10617 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3410618 const void* cmd_data) {
10619 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
10620 *static_cast<
10621 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
10622 cmd_data);
[email protected]43f253da2014-06-10 17:51:2210623 GLenum target = static_cast<GLenum>(c.target);
10624 uint32_t data_size;
10625 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
10626 return error::kOutOfBounds;
10627 }
10628 if (data_size > immediate_data_size) {
10629 return error::kOutOfBounds;
10630 }
10631 const GLbyte* mailbox =
10632 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
10633 if (!validators_->texture_bind_target.IsValid(target)) {
10634 LOCAL_SET_GL_ERROR_INVALID_ENUM(
10635 "glCreateAndConsumeTextureCHROMIUM", target, "target");
10636 return error::kNoError;
10637 }
10638 if (mailbox == NULL) {
10639 return error::kOutOfBounds;
10640 }
10641 uint32_t client_id = c.client_id;
10642 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
10643 return error::kNoError;
10644}
10645
10646void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
10647 const GLbyte* data, GLuint client_id) {
10648 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
10649 "context", logger_.GetLogPrefix(),
10650 "mailbox[0]", static_cast<unsigned char>(data[0]));
10651 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
10652 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
10653 "passed a mailbox that was not "
10654 "generated by GenMailboxCHROMIUM.";
10655
10656 TextureRef* texture_ref = GetTexture(client_id);
10657 if (texture_ref) {
10658 LOCAL_SET_GL_ERROR(
10659 GL_INVALID_OPERATION,
10660 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
10661 return;
10662 }
10663 Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox);
10664 if (!texture) {
10665 LOCAL_SET_GL_ERROR(
10666 GL_INVALID_OPERATION,
10667 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
10668 return;
10669 }
10670 if (texture->target() != target) {
10671 LOCAL_SET_GL_ERROR(
10672 GL_INVALID_OPERATION,
10673 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
10674 return;
10675 }
10676
[email protected]43f253da2014-06-10 17:51:2210677 texture_ref = texture_manager()->Consume(client_id, texture);
10678}
10679
[email protected]d2a0e1a2012-08-12 02:25:0110680void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10681 GLsizei length, const GLchar* marker) {
10682 if (!marker) {
10683 marker = "";
10684 }
10685 debug_marker_manager_.SetMarker(
10686 length ? std::string(marker, length) : std::string(marker));
10687}
10688
10689void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10690 GLsizei length, const GLchar* marker) {
10691 if (!marker) {
10692 marker = "";
10693 }
[email protected]cac16542014-01-15 17:53:5110694 std::string name = length ? std::string(marker, length) : std::string(marker);
10695 debug_marker_manager_.PushGroup(name);
10696 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110697}
10698
10699void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10700 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110701 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110702}
10703
[email protected]09d50362012-10-18 20:54:3710704void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10705 GLenum target, GLint image_id) {
10706 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710707
[email protected]bc26e8d2014-01-29 00:40:3010708 if (target == GL_TEXTURE_CUBE_MAP) {
10709 LOCAL_SET_GL_ERROR(
10710 GL_INVALID_ENUM,
10711 "glBindTexImage2DCHROMIUM", "invalid target");
10712 return;
10713 }
10714
[email protected]09d50362012-10-18 20:54:3710715 // Default target might be conceptually valid, but disallow it to avoid
10716 // accidents.
[email protected]c986af502013-08-14 01:04:4410717 TextureRef* texture_ref =
10718 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910719 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110720 LOCAL_SET_GL_ERROR(
10721 GL_INVALID_OPERATION,
10722 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710723 return;
10724 }
10725
10726 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10727 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110728 LOCAL_SET_GL_ERROR(
10729 GL_INVALID_OPERATION,
10730 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710731 return;
10732 }
10733
[email protected]b8160812013-04-09 00:41:0410734 {
10735 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010736 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610737 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410738 LOCAL_SET_GL_ERROR(
10739 GL_INVALID_OPERATION,
10740 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10741 return;
10742 }
[email protected]09d50362012-10-18 20:54:3710743 }
10744
10745 gfx::Size size = gl_image->GetSize();
10746 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910747 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710748 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910749 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710750}
10751
10752void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10753 GLenum target, GLint image_id) {
10754 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710755
10756 // Default target might be conceptually valid, but disallow it to avoid
10757 // accidents.
[email protected]c986af502013-08-14 01:04:4410758 TextureRef* texture_ref =
10759 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910760 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110761 LOCAL_SET_GL_ERROR(
10762 GL_INVALID_OPERATION,
10763 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710764 return;
10765 }
10766
10767 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10768 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110769 LOCAL_SET_GL_ERROR(
10770 GL_INVALID_OPERATION,
10771 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710772 return;
10773 }
10774
10775 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910776 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710777 return;
10778
[email protected]b8160812013-04-09 00:41:0410779 {
10780 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010781 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610782 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0410783 }
[email protected]09d50362012-10-18 20:54:3710784
10785 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910786 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710787 GL_RGBA, GL_UNSIGNED_BYTE, false);
10788}
[email protected]d2a0e1a2012-08-12 02:25:0110789
[email protected]94307712012-11-16 23:26:1110790error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3410791 uint32 immediate_data_size,
10792 const void* cmd_data) {
10793 const gles2::cmds::TraceBeginCHROMIUM& c =
10794 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
[email protected]94307712012-11-16 23:26:1110795 Bucket* bucket = GetBucket(c.bucket_id);
10796 if (!bucket || bucket->size() == 0) {
10797 return error::kInvalidArguments;
10798 }
10799 std::string command_name;
10800 if (!bucket->GetAsString(&command_name)) {
10801 return error::kInvalidArguments;
10802 }
[email protected]fb97b662013-02-20 23:02:1410803 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5110804 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5110805 LOCAL_SET_GL_ERROR(
10806 GL_INVALID_OPERATION,
10807 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410808 return error::kNoError;
10809 }
[email protected]94307712012-11-16 23:26:1110810 return error::kNoError;
10811}
10812
10813void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410814 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110815 LOCAL_SET_GL_ERROR(
10816 GL_INVALID_OPERATION,
10817 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110818 return;
10819 }
[email protected]fb97b662013-02-20 23:02:1410820 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5110821 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1110822}
10823
[email protected]2f143d482013-03-14 18:04:4910824void GLES2DecoderImpl::DoDrawBuffersEXT(
10825 GLsizei count, const GLenum* bufs) {
10826 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10827 LOCAL_SET_GL_ERROR(
10828 GL_INVALID_VALUE,
10829 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10830 return;
10831 }
10832
10833 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10834 if (framebuffer) {
10835 for (GLsizei i = 0; i < count; ++i) {
10836 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10837 bufs[i] != GL_NONE) {
10838 LOCAL_SET_GL_ERROR(
10839 GL_INVALID_OPERATION,
10840 "glDrawBuffersEXT",
10841 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10842 return;
10843 }
10844 }
10845 glDrawBuffersARB(count, bufs);
10846 framebuffer->SetDrawBuffers(count, bufs);
10847 } else { // backbuffer
10848 if (count > 1 ||
10849 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10850 LOCAL_SET_GL_ERROR(
10851 GL_INVALID_OPERATION,
10852 "glDrawBuffersEXT",
10853 "more than one buffer or bufs not GL_NONE or GL_BACK");
10854 return;
10855 }
10856 GLenum mapped_buf = bufs[0];
10857 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10858 bufs[0] == GL_BACK) {
10859 mapped_buf = GL_COLOR_ATTACHMENT0;
10860 }
10861 glDrawBuffersARB(count, &mapped_buf);
10862 group_->set_draw_buffer(bufs[0]);
10863 }
10864}
10865
[email protected]a6a09f852014-05-23 13:05:0310866void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
10867 group_->LoseContexts(other);
10868 reset_status_ = current;
10869 current_decoder_error_ = error::kLostContext;
10870}
10871
kkinnunen337d59632014-08-26 10:19:5710872void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
10873 const GLfloat* matrix) {
10874 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
10875 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
10876 if (!features().chromium_path_rendering) {
10877 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10878 "glMatrixLoadfCHROMIUM",
10879 "function not available");
10880 return;
10881 }
10882
10883 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
10884 ? state_.projection_matrix
10885 : state_.modelview_matrix;
10886 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
10887 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
10888 // since the values of the _NV and _CHROMIUM tokens match.
10889 glMatrixLoadfEXT(matrix_mode, matrix);
10890}
10891
10892void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
10893 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
10894 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
10895
10896 if (!features().chromium_path_rendering) {
10897 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10898 "glMatrixLoadIdentityCHROMIUM",
10899 "function not available");
10900 return;
10901 }
10902
10903 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
10904 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
10905 0.0f, 0.0f, 0.0f, 1.0f};
10906
10907 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
10908 ? state_.projection_matrix
10909 : state_.modelview_matrix;
10910 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
10911 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
10912 // since the values of the _NV and _CHROMIUM tokens match.
10913 glMatrixLoadIdentityEXT(matrix_mode);
10914}
10915
[email protected]32145a92012-12-17 09:01:5910916bool GLES2DecoderImpl::ValidateAsyncTransfer(
10917 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710918 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910919 GLenum target,
10920 GLint level,
10921 const void * data) {
10922 // We only support async uploads to 2D textures for now.
10923 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110924 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910925 return false;
10926 }
10927 // We only support uploads to level zero for now.
10928 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110929 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910930 return false;
10931 }
10932 // A transfer buffer must be bound, even for asyncTexImage2D.
10933 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110934 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910935 return false;
10936 }
10937 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710938 if (!texture_ref ||
10939 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110940 LOCAL_SET_GL_ERROR(
10941 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910942 function_name, "transfer already in progress");
10943 return false;
10944 }
10945 return true;
10946}
10947
[email protected]e3c4a9ab2014-03-31 09:07:0210948base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
10949 uint32 async_upload_token,
10950 uint32 sync_data_shm_id,
10951 uint32 sync_data_shm_offset) {
10952 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2510953 if (!buffer.get() ||
10954 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0210955 return base::Closure();
10956
10957 AsyncMemoryParams mem_params(buffer,
10958 sync_data_shm_offset,
10959 sizeof(AsyncUploadSync));
10960
10961 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
10962 new AsyncUploadTokenCompletionObserver(async_upload_token));
10963
10964 return base::Bind(
10965 &AsyncPixelTransferManager::AsyncNotifyCompletion,
10966 base::Unretained(GetAsyncPixelTransferManager()),
10967 mem_params,
10968 observer);
10969}
10970
[email protected]69023942012-11-30 19:57:1610971error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3410972 uint32 immediate_data_size,
10973 const void* cmd_data) {
10974 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
10975 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1610976 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610977 GLenum target = static_cast<GLenum>(c.target);
10978 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4410979 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1610980 GLsizei width = static_cast<GLsizei>(c.width);
10981 GLsizei height = static_cast<GLsizei>(c.height);
10982 GLint border = static_cast<GLint>(c.border);
10983 GLenum format = static_cast<GLenum>(c.format);
10984 GLenum type = static_cast<GLenum>(c.type);
10985 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10986 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10987 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0210988 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
10989 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
10990 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10991
10992 base::ScopedClosureRunner scoped_completion_callback;
10993 if (async_upload_token) {
10994 base::Closure completion_closure =
10995 AsyncUploadTokenCompletionClosure(async_upload_token,
10996 sync_data_shm_id,
10997 sync_data_shm_offset);
10998 if (completion_closure.is_null())
10999 return error::kInvalidArguments;
11000
11001 scoped_completion_callback.Reset(completion_closure);
11002 }
[email protected]32145a92012-12-17 09:01:5911003
11004 // TODO(epenner): Move this and copies of this memory validation
11005 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1611006 if (!GLES2Util::ComputeImageDataSizes(
11007 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
11008 NULL)) {
11009 return error::kOutOfBounds;
11010 }
11011 const void* pixels = NULL;
11012 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
11013 pixels = GetSharedMemoryAs<const void*>(
11014 pixels_shm_id, pixels_shm_offset, pixels_size);
11015 if (!pixels) {
11016 return error::kOutOfBounds;
11017 }
11018 }
11019
[email protected]c986af502013-08-14 01:04:4411020 TextureManager::DoTextImage2DArguments args = {
11021 target, level, internal_format, width, height, border, format, type,
11022 pixels, pixels_size};
11023 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5911024 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4411025 if (!texture_manager()->ValidateTexImage2D(
11026 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5911027 return error::kNoError;
11028 }
11029
11030 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4911031 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911032 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711033 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911034 return error::kNoError;
11035
11036 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0711037 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5111038 LOCAL_SET_GL_ERROR(
11039 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911040 "glAsyncTexImage2DCHROMIUM", "already defined");
11041 return error::kNoError;
11042 }
11043
[email protected]7989c9e2013-01-23 06:39:2611044 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5111045 LOCAL_SET_GL_ERROR(
11046 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611047 return error::kNoError;
11048 }
11049
[email protected]5b3a8e02013-03-13 05:36:4411050 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3811051 AsyncTexImage2DParams tex_params = {
11052 target, level, static_cast<GLenum>(internal_format),
11053 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1211054 AsyncMemoryParams mem_params(
11055 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5911056
[email protected]5b3a8e02013-03-13 05:36:4411057 // Set up the async state if needed, and make the texture
11058 // immutable so the async state stays valid. The level info
11059 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1811060 AsyncPixelTransferDelegate* delegate =
11061 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
11062 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4411063 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5911064
[email protected]896425e2013-06-12 17:27:1811065 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4411066 tex_params,
11067 mem_params,
11068 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4911069 // The callback is only invoked if the transfer delegate still
11070 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4411071 // ownership that both of these pointers are valid.
11072 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4911073 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4411074 tex_params));
[email protected]f598f422012-12-07 08:30:0311075 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611076}
11077
11078error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411079 uint32 immediate_data_size,
11080 const void* cmd_data) {
11081 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
11082 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611083 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611084 GLenum target = static_cast<GLenum>(c.target);
11085 GLint level = static_cast<GLint>(c.level);
11086 GLint xoffset = static_cast<GLint>(c.xoffset);
11087 GLint yoffset = static_cast<GLint>(c.yoffset);
11088 GLsizei width = static_cast<GLsizei>(c.width);
11089 GLsizei height = static_cast<GLsizei>(c.height);
11090 GLenum format = static_cast<GLenum>(c.format);
11091 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0211092 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11093 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11094 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11095
11096 base::ScopedClosureRunner scoped_completion_callback;
11097 if (async_upload_token) {
11098 base::Closure completion_closure =
11099 AsyncUploadTokenCompletionClosure(async_upload_token,
11100 sync_data_shm_id,
11101 sync_data_shm_offset);
11102 if (completion_closure.is_null())
11103 return error::kInvalidArguments;
11104
11105 scoped_completion_callback.Reset(completion_closure);
11106 }
[email protected]32145a92012-12-17 09:01:5911107
11108 // TODO(epenner): Move this and copies of this memory validation
11109 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1611110 uint32 data_size;
11111 if (!GLES2Util::ComputeImageDataSizes(
11112 width, height, format, type, state_.unpack_alignment, &data_size,
11113 NULL, NULL)) {
11114 return error::kOutOfBounds;
11115 }
11116 const void* pixels = GetSharedMemoryAs<const void*>(
11117 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5911118
11119 // All the normal glTexSubImage2D validation.
11120 error::Error error = error::kNoError;
11121 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
11122 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
11123 return error;
[email protected]69023942012-11-30 19:57:1611124 }
11125
[email protected]32145a92012-12-17 09:01:5911126 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4411127 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11128 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911129 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911130 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711131 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911132 return error::kNoError;
11133
11134 // Guarantee async textures are always 'cleared' as follows:
11135 // - AsyncTexImage2D can not redefine an existing texture
11136 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
11137 // - AsyncTexSubImage2D clears synchronously if not already cleared.
11138 // - Textures become immutable after an async call.
11139 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0711140 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4911141 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
11142 target, level)) {
[email protected]ab09b612013-03-11 22:11:5111143 LOCAL_SET_GL_ERROR(
11144 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2511145 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5911146 return error::kNoError;
11147 }
11148 }
11149
[email protected]5b3a8e02013-03-13 05:36:4411150 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0311151 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5911152 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1211153 AsyncMemoryParams mem_params(
11154 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1811155 AsyncPixelTransferDelegate* delegate =
11156 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11157 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4411158 // TODO(epenner): We may want to enforce exclusive use
11159 // of async APIs in which case this should become an error,
11160 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0311161 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4411162 0, 0, 0, 0, 0, 0};
11163 texture->GetLevelSize(target, level, &define_params.width,
11164 &define_params.height);
11165 texture->GetLevelType(target, level, &define_params.type,
11166 &define_params.internal_format);
11167 // Set up the async state if needed, and make the texture
11168 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1811169 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4711170 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4411171 texture->SetImmutable(true);
11172 }
11173
[email protected]896425e2013-06-12 17:27:1811174 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5911175 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611176}
11177
[email protected]a00c1f742013-03-05 17:02:1611178error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411179 uint32 immediate_data_size,
11180 const void* cmd_data) {
11181 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
11182 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1611183 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11184 GLenum target = static_cast<GLenum>(c.target);
11185
11186 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111187 LOCAL_SET_GL_ERROR(
11188 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1611189 return error::kNoError;
11190 }
[email protected]c986af502013-08-14 01:04:4411191 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11192 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911193 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111194 LOCAL_SET_GL_ERROR(
11195 GL_INVALID_OPERATION,
11196 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1611197 return error::kNoError;
11198 }
[email protected]896425e2013-06-12 17:27:1811199 AsyncPixelTransferDelegate* delegate =
11200 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11201 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4911202 LOCAL_SET_GL_ERROR(
11203 GL_INVALID_OPERATION,
11204 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
11205 return error::kNoError;
11206 }
[email protected]896425e2013-06-12 17:27:1811207 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0911208 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1611209 return error::kNoError;
11210}
11211
[email protected]e3c4a9ab2014-03-31 09:07:0211212error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411213 uint32 immediate_data_size,
11214 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0211215 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11216
11217 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
11218 ProcessFinishedAsyncTransfers();
11219 return error::kNoError;
11220}
11221
[email protected]91c94eb2013-10-22 10:32:5411222void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
11223 TextureRef* texture_ref) {
11224 Texture* texture = texture_ref->texture();
11225 DoDidUseTexImageIfNeeded(texture, texture->target());
11226}
11227
[email protected]828a3932014-04-02 14:43:1311228void GLES2DecoderImpl::OnOutOfMemoryError() {
11229 if (lose_context_when_out_of_memory_) {
11230 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
11231 LoseContext(GL_GUILTY_CONTEXT_RESET_ARB);
11232 }
11233}
11234
[email protected]96449d2c2009-11-25 00:01:3211235// Include the auto-generated part of this file. We split this because it means
11236// we can easily edit the non-auto generated parts right here in this file
11237// instead of having to edit some template or the code generator.
11238#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
11239
11240} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2511241} // namespace gpu