| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| index 11bd9153f5daa29a66ac179195cda37464292c20..e041c27570d8dbb3bb56eb40d731838566397432 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -1324,6 +1324,13 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
|
| void ReleaseIOSurfaceForTexture(GLuint texture_id);
|
| #endif
|
|
|
| + // Validates the combination of texture parameters. For example validates that
|
| + // for a given format the specific type, level and targets are valid.
|
| + // Synthesizes the correct GL error if invalid. Returns true if valid.
|
| + bool ValidateTextureParameters(
|
| + const char* function_name,
|
| + GLenum target, GLenum format, GLenum type, GLint level);
|
| +
|
| void LogMessage(const std::string& msg);
|
| void RenderWarning(const std::string& msg);
|
| void PerformanceWarning(const std::string& msg);
|
| @@ -6667,6 +6674,43 @@ bool GLES2DecoderImpl::ClearLevel(
|
| int width,
|
| int height,
|
| bool is_texture_immutable) {
|
| + uint32 channels = GLES2Util::GetChannelsForFormat(format);
|
| + if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
|
| + // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
|
| + // on depth formats.
|
| + GLuint fb = 0;
|
| + glGenFramebuffersEXT(1, &fb);
|
| + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
|
| +
|
| + bool have_stencil = (channels & GLES2Util::kStencil) != 0;
|
| + GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
|
| + GL_DEPTH_ATTACHMENT;
|
| +
|
| + glFramebufferTexture2DEXT(
|
| + GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
|
| + // ANGLE promises a depth only attachment ok.
|
| + if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
|
| + GL_FRAMEBUFFER_COMPLETE) {
|
| + return false;
|
| + }
|
| + glClearStencil(0);
|
| + glStencilMask(-1);
|
| + glClearDepth(1.0f);
|
| + glDepthMask(true);
|
| + glDisable(GL_SCISSOR_TEST);
|
| + glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
|
| +
|
| + RestoreClearState();
|
| +
|
| + glDeleteFramebuffersEXT(1, &fb);
|
| + FramebufferManager::FramebufferInfo* framebuffer =
|
| + GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
|
| + GLuint fb_service_id =
|
| + framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
|
| + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
|
| + return true;
|
| + }
|
| +
|
| static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
|
|
|
| uint32 size;
|
| @@ -6894,6 +6938,28 @@ error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
|
| return error::kNoError;
|
| }
|
|
|
| +bool GLES2DecoderImpl::ValidateTextureParameters(
|
| + const char* function_name,
|
| + GLenum target, GLenum format, GLenum type, GLint level) {
|
| + if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
|
| + SetGLError(GL_INVALID_OPERATION,
|
| + (std::string(function_name) + ": invalid type " +
|
| + GLES2Util::GetStringEnum(type) + " for format " +
|
| + GLES2Util::GetStringEnum(format)).c_str());
|
| + return false;
|
| + }
|
| +
|
| + uint32 channels = GLES2Util::GetChannelsForFormat(format);
|
| + if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
|
| + SetGLError(GL_INVALID_OPERATION,
|
| + (std::string(function_name) + ": invalid type " +
|
| + GLES2Util::GetStringEnum(type) + " for format " +
|
| + GLES2Util::GetStringEnum(format)).c_str());
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| error::Error GLES2DecoderImpl::DoTexImage2D(
|
| GLenum target,
|
| GLint level,
|
| @@ -6926,11 +6992,21 @@ error::Error GLES2DecoderImpl::DoTexImage2D(
|
| SetGLError(GL_INVALID_OPERATION, "glTexImage2D: format != internalFormat");
|
| return error::kNoError;
|
| }
|
| + if (!ValidateTextureParameters("glTexImage2D", target, format, type, level)) {
|
| + return error::kNoError;
|
| + }
|
| if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
|
| border != 0) {
|
| SetGLError(GL_INVALID_VALUE, "glTexImage2D: dimensions out of range");
|
| return error::kNoError;
|
| }
|
| + if ((GLES2Util::GetChannelsForFormat(format) &
|
| + (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
|
| + SetGLError(
|
| + GL_INVALID_OPERATION,
|
| + "glTexImage2D: can not supply data for depth or stencil textures");
|
| + return error::kNoError;
|
| + }
|
| TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
|
| if (!info) {
|
| SetGLError(GL_INVALID_OPERATION,
|
| @@ -7137,6 +7213,10 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
|
| SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D: dimensions out of range");
|
| return;
|
| }
|
| + if (!ValidateTextureParameters(
|
| + "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
|
| + return;
|
| + }
|
|
|
| // Check we have compatible formats.
|
| GLenum read_format = GetBoundReadFrameBufferInternalFormat();
|
| @@ -7148,6 +7228,13 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
|
| return;
|
| }
|
|
|
| + if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
|
| + SetGLError(
|
| + GL_INVALID_OPERATION,
|
| + "glCopyImage2D: can not be used with depth or stencil textures");
|
| + return;
|
| + }
|
| +
|
| if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
|
| return;
|
| }
|
| @@ -7240,6 +7327,13 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D(
|
| return;
|
| }
|
|
|
| + if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
|
| + SetGLError(
|
| + GL_INVALID_OPERATION,
|
| + "glCopySubImage2D: can not be used with depth or stencil textures");
|
| + return;
|
| + }
|
| +
|
| if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
|
| return;
|
| }
|
| @@ -7330,6 +7424,14 @@ void GLES2DecoderImpl::DoTexSubImage2D(
|
| return;
|
| }
|
|
|
| + if ((GLES2Util::GetChannelsForFormat(format) &
|
| + (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
|
| + SetGLError(
|
| + GL_INVALID_OPERATION,
|
| + "glTexSubImage2D: can not supply data for depth or stencil textures");
|
| + return;
|
| + }
|
| +
|
| GLsizei tex_width = 0;
|
| GLsizei tex_height = 0;
|
| bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height);
|
|
|