Commit 036f7e32 authored by zmo's avatar zmo Committed by Commit bot

Remove blink side texture status caching.

We could also remove a bunch of duplicated validation, but let's keep
this CL simple for review purpose.

The tex-storage-and-subimage3d.html failure is due to the command buffer
side handling isn't fully implemented.  Will do it in a separate CL.

BUG=570453
TEST=webgl_conformance,webgl2_conformance
R=kbr@chromium.org,bajones@chromium.org
CQ_INCLUDE_TRYBOTS=tryserver.chromium.win:win_optional_gpu_tests_rel

Review URL: https://codereview.chromium.org/1684973002

Cr-Commit-Position: refs/heads/master@{#374839}
parent ba16f435
...@@ -92,6 +92,10 @@ class WebGL2ConformanceExpectations(WebGLConformanceExpectations): ...@@ -92,6 +92,10 @@ class WebGL2ConformanceExpectations(WebGLConformanceExpectations):
self.Fail('conformance2/textures/misc/tex-input-validation.html', self.Fail('conformance2/textures/misc/tex-input-validation.html',
bug=483282) bug=483282)
# Command buffer side handling of TexSubImage3D is incorrect.
self.Fail('conformance2/textures/misc/tex-storage-and-subimage-3d.html',
bug=570453)
# Windows only. # Windows only.
self.Fail('conformance2/textures/canvas/tex-image-and-sub-image-2d' + self.Fail('conformance2/textures/canvas/tex-image-and-sub-image-2d' +
'-with-canvas-r8-red-unsigned_byte.html', '-with-canvas-r8-red-unsigned_byte.html',
......
...@@ -36,6 +36,10 @@ class WebGLConformanceExpectations(GpuTestExpectations): ...@@ -36,6 +36,10 @@ class WebGLConformanceExpectations(GpuTestExpectations):
bug=478572) bug=478572)
self.Fail('conformance/extensions/ext-sRGB.html', self.Fail('conformance/extensions/ext-sRGB.html',
bug=540900) bug=540900)
# We need to add WebGL 1 check in command buffer that format/type from
# TexSubImage2D have to match the current texture's.
self.Fail('conformance/textures/misc/tex-sub-image-2d-bad-args.html',
bug=570453)
# Fails on multiple platforms # Fails on multiple platforms
......
...@@ -805,10 +805,6 @@ bool WebGL2RenderingContextBase::validateTexStorage(const char* functionName, GL ...@@ -805,10 +805,6 @@ bool WebGL2RenderingContextBase::validateTexStorage(const char* functionName, GL
} }
} }
WebGLTexture* tex = validateTextureBinding(functionName, target, false);
if (!tex)
return false;
if (functionType == TexStorageType3D && target != GL_TEXTURE_2D_ARRAY && m_compressedTextureFormatsETC2EAC.find(internalformat) != m_compressedTextureFormatsETC2EAC.end()) { if (functionType == TexStorageType3D && target != GL_TEXTURE_2D_ARRAY && m_compressedTextureFormatsETC2EAC.find(internalformat) != m_compressedTextureFormatsETC2EAC.end()) {
synthesizeGLError(GL_INVALID_OPERATION, functionName, "target for ETC2/EAC internal formats must be TEXTURE_2D_ARRAY"); synthesizeGLError(GL_INVALID_OPERATION, functionName, "target for ETC2/EAC internal formats must be TEXTURE_2D_ARRAY");
return false; return false;
...@@ -819,11 +815,6 @@ bool WebGL2RenderingContextBase::validateTexStorage(const char* functionName, GL ...@@ -819,11 +815,6 @@ bool WebGL2RenderingContextBase::validateTexStorage(const char* functionName, GL
return false; return false;
} }
if (tex->isImmutable()) {
synthesizeGLError(GL_INVALID_OPERATION, functionName, "attempted to modify immutable texture");
return false;
}
if (width <= 0 || height <= 0 || depth <= 0) { if (width <= 0 || height <= 0 || depth <= 0) {
synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid dimensions"); synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid dimensions");
return false; return false;
...@@ -854,9 +845,7 @@ void WebGL2RenderingContextBase::texStorage2D(GLenum target, GLsizei levels, GLe ...@@ -854,9 +845,7 @@ void WebGL2RenderingContextBase::texStorage2D(GLenum target, GLsizei levels, GLe
if (isContextLost() || !validateTexStorage("texStorage2D", target, levels, internalformat, width, height, 1, TexStorageType2D)) if (isContextLost() || !validateTexStorage("texStorage2D", target, levels, internalformat, width, height, 1, TexStorageType2D))
return; return;
WebGLTexture* tex = validateTextureBinding("texStorage2D", target, false);
webContext()->texStorage2DEXT(target, levels, internalformat, width, height); webContext()->texStorage2DEXT(target, levels, internalformat, width, height);
tex->setTexStorageInfo(target, levels, internalformat, width, height, 1);
} }
void WebGL2RenderingContextBase::texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) void WebGL2RenderingContextBase::texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
...@@ -864,9 +853,7 @@ void WebGL2RenderingContextBase::texStorage3D(GLenum target, GLsizei levels, GLe ...@@ -864,9 +853,7 @@ void WebGL2RenderingContextBase::texStorage3D(GLenum target, GLsizei levels, GLe
if (isContextLost() || !validateTexStorage("texStorage3D", target, levels, internalformat, width, height, depth, TexStorageType3D)) if (isContextLost() || !validateTexStorage("texStorage3D", target, levels, internalformat, width, height, depth, TexStorageType3D))
return; return;
WebGLTexture* tex = validateTextureBinding("texStorage3D", target, false);
webContext()->texStorage3D(target, levels, internalformat, width, height, depth); webContext()->texStorage3D(target, levels, internalformat, width, height, depth);
tex->setTexStorageInfo(target, levels, internalformat, width, height, depth);
} }
void WebGL2RenderingContextBase::texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, DOMArrayBufferView* pixels) void WebGL2RenderingContextBase::texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, DOMArrayBufferView* pixels)
...@@ -884,10 +871,7 @@ void WebGL2RenderingContextBase::texImage3D(GLenum target, GLint level, GLint in ...@@ -884,10 +871,7 @@ void WebGL2RenderingContextBase::texImage3D(GLenum target, GLint level, GLint in
return; return;
} }
WebGLTexture* tex = validateTextureBinding("texImage3D", target, true);
ASSERT(tex);
webContext()->texImage3D(target, level, convertTexInternalFormat(internalformat, type), width, height, depth, border, format, type, data); webContext()->texImage3D(target, level, convertTexInternalFormat(internalformat, type), width, height, depth, border, format, type, data);
tex->setLevelInfo(target, level, internalformat, width, height, depth, type);
} }
void WebGL2RenderingContextBase::texSubImage3DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha) void WebGL2RenderingContextBase::texSubImage3DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha)
...@@ -1002,18 +986,9 @@ void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint ...@@ -1002,18 +986,9 @@ void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint
|| !validateTexFunc("texSubImage3D", TexSubImage, SourceHTMLCanvasElement, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset)) || !validateTexFunc("texSubImage3D", TexSubImage, SourceHTMLCanvasElement, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoffset, yoffset, zoffset))
return; return;
WebGLTexture* texture = validateTextureBinding("texSubImage3D", target, false); // FIXME: Implement GPU-to-GPU copy path.
ASSERT(texture); texSubImage3DImpl(target, level, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
GLenum internalformat = texture->getInternalFormat(target, level); WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerated() || !canUseTexImageCanvasByGPU(internalformat, type)) {
// 2D canvas has only FrontBuffer.
texSubImage3DImpl(target, level, xoffset, yoffset, zoffset, format, type, canvas->copiedImage(FrontBuffer, PreferAcceleration).get(),
WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha);
return;
}
texImageCanvasByGPU(TexSubImage3DByGPU, texture, target, level, GL_RGBA, type, xoffset, yoffset, zoffset, canvas);
} }
void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState) void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
...@@ -1050,12 +1025,6 @@ void WebGL2RenderingContextBase::copyTexSubImage3D(GLenum target, GLint level, G ...@@ -1050,12 +1025,6 @@ void WebGL2RenderingContextBase::copyTexSubImage3D(GLenum target, GLint level, G
return; return;
if (!validateReadBufferAndGetInfo("copyTexSubImage3D", readFramebufferBinding)) if (!validateReadBufferAndGetInfo("copyTexSubImage3D", readFramebufferBinding))
return; return;
WebGLTexture* tex = validateTextureBinding("copyTexSubImage3D", target, true);
ASSERT(tex);
if (!isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(target, level), boundFramebufferColorFormat())) {
synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage3D", "framebuffer is incompatible format");
return;
}
clearIfComposited(); clearIfComposited();
ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding);
webContext()->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); webContext()->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
...@@ -1080,16 +1049,7 @@ void WebGL2RenderingContextBase::compressedTexImage3D(GLenum target, GLint level ...@@ -1080,16 +1049,7 @@ void WebGL2RenderingContextBase::compressedTexImage3D(GLenum target, GLint level
if (!validateCompressedTexFuncData("compressedTexImage3D", width, height, depth, internalformat, data)) if (!validateCompressedTexFuncData("compressedTexImage3D", width, height, depth, internalformat, data))
return; return;
WebGLTexture* tex = validateTextureBinding("compressedTexImage3D", target, true);
if (!tex)
return;
if (tex->isImmutable()) {
synthesizeGLError(GL_INVALID_OPERATION, "compressedTexImage3D", "attempted to modify immutable texture");
return;
}
webContext()->compressedTexImage3D(target, level, internalformat, width, height, depth, border, data->byteLength(), data->baseAddress()); webContext()->compressedTexImage3D(target, level, internalformat, width, height, depth, border, data->byteLength(), data->baseAddress());
tex->setLevelInfo(target, level, internalformat, width, height, depth, GL_UNSIGNED_BYTE);
} }
void WebGL2RenderingContextBase::compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, DOMArrayBufferView* data) void WebGL2RenderingContextBase::compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, DOMArrayBufferView* data)
...@@ -1105,10 +1065,6 @@ void WebGL2RenderingContextBase::compressedTexSubImage3D(GLenum target, GLint le ...@@ -1105,10 +1065,6 @@ void WebGL2RenderingContextBase::compressedTexSubImage3D(GLenum target, GLint le
return; return;
if (!validateCompressedTexFormat("compressedTexSubImage3D", format)) if (!validateCompressedTexFormat("compressedTexSubImage3D", format))
return; return;
if (format != tex->getInternalFormat(target, level)) {
synthesizeGLError(GL_INVALID_OPERATION, "compressedTexSubImage3D", "format does not match texture format");
return;
}
if (!validateCompressedTexSubDimensions("compressedTexSubImage3D", target, level, xoffset, yoffset, zoffset, width, height, depth, format, tex)) if (!validateCompressedTexSubDimensions("compressedTexSubImage3D", target, level, xoffset, yoffset, zoffset, width, height, depth, format, tex))
return; return;
if (!validateCompressedTexFuncData("compressedTexSubImage3D", width, height, depth, format, data)) if (!validateCompressedTexFuncData("compressedTexSubImage3D", width, height, depth, format, data))
...@@ -3465,15 +3421,6 @@ void WebGL2RenderingContextBase::restoreCurrentFramebuffer() ...@@ -3465,15 +3421,6 @@ void WebGL2RenderingContextBase::restoreCurrentFramebuffer()
bindFramebuffer(nullptr, GL_READ_FRAMEBUFFER, m_readFramebufferBinding.get()); bindFramebuffer(nullptr, GL_READ_FRAMEBUFFER, m_readFramebufferBinding.get());
} }
GLenum WebGL2RenderingContextBase::boundFramebufferColorFormat()
{
if (m_readFramebufferBinding && m_readFramebufferBinding->object())
return m_readFramebufferBinding->colorBufferFormat();
if (m_requestedAttributes.alpha())
return GL_RGBA;
return GL_RGB;
}
const WebGLSamplerState* WebGL2RenderingContextBase::getTextureUnitSamplerState(GLenum target, GLuint unit) const const WebGLSamplerState* WebGL2RenderingContextBase::getTextureUnitSamplerState(GLenum target, GLuint unit) const
{ {
ASSERT(unit < m_samplerUnits.size()); ASSERT(unit < m_samplerUnits.size());
......
...@@ -232,7 +232,6 @@ protected: ...@@ -232,7 +232,6 @@ protected:
WebGLFramebuffer* getReadFramebufferBinding() override; WebGLFramebuffer* getReadFramebufferBinding() override;
GLint getMaxTextureLevelForTarget(GLenum target) override; GLint getMaxTextureLevelForTarget(GLenum target) override;
void renderbufferStorageImpl(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, const char* functionName) override; void renderbufferStorageImpl(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, const char* functionName) override;
GLenum boundFramebufferColorFormat() override;
const WebGLSamplerState* getTextureUnitSamplerState(GLenum target, GLuint unit) const override; const WebGLSamplerState* getTextureUnitSamplerState(GLenum target, GLuint unit) const override;
// Helper function to validate the target for compressedTex{Sub}Image3D. // Helper function to validate the target for compressedTex{Sub}Image3D.
......
...@@ -41,16 +41,6 @@ public: ...@@ -41,16 +41,6 @@ public:
public: public:
virtual ~WebGLAttachment(); virtual ~WebGLAttachment();
virtual GLsizei width() const = 0;
virtual GLsizei height() const = 0;
virtual GLsizei depth() const = 0;
virtual GLenum format() const = 0;
// For texture attachment, type() returns the type of the attached texture.
// For renderbuffer attachment, the type of the renderbuffer may vary with GL implementation.
// To avoid confusion, it would be better to not implement type() for renderbuffer attachment and
// we should always use the internalformat of the renderbuffer and avoid using type() API.
virtual GLenum type() const = 0;
virtual bool isCubeComplete() const = 0;
virtual WebGLSharedObject* object() const = 0; virtual WebGLSharedObject* object() const = 0;
virtual bool isSharedObject(WebGLSharedObject*) const = 0; virtual bool isSharedObject(WebGLSharedObject*) const = 0;
virtual bool valid() const = 0; virtual bool valid() const = 0;
...@@ -78,14 +68,6 @@ public: ...@@ -78,14 +68,6 @@ public:
void removeAttachmentFromBoundFramebuffer(GLenum target, GLenum attachment); void removeAttachmentFromBoundFramebuffer(GLenum target, GLenum attachment);
WebGLSharedObject* getAttachmentObject(GLenum) const; WebGLSharedObject* getAttachmentObject(GLenum) const;
GLenum colorBufferFormat() const;
// Software version of glCheckFramebufferStatus(), except that when
// FRAMEBUFFER_COMPLETE is returned, it is still possible for
// glCheckFramebufferStatus() to return FRAMEBUFFER_UNSUPPORTED,
// depending on hardware implementation.
GLenum checkStatus(const char** reason) const;
// WebGL 1 specific: // WebGL 1 specific:
// 1) can't allow depth_stencil for depth/stencil attachments, and vice versa. // 1) can't allow depth_stencil for depth/stencil attachments, and vice versa.
// 2) no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments. // 2) no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments.
...@@ -106,10 +88,6 @@ public: ...@@ -106,10 +88,6 @@ public:
GLenum getReadBuffer() const { return m_readBuffer; } GLenum getReadBuffer() const { return m_readBuffer; }
// If readbuffer is GL_NONE or no image is attached, return false.
// Note: it's ok for format or type to be nullptr.
bool getReadBufferFormatAndType(GLenum* format, GLenum* type) const;
DECLARE_VIRTUAL_TRACE(); DECLARE_VIRTUAL_TRACE();
protected: protected:
...@@ -120,7 +98,6 @@ protected: ...@@ -120,7 +98,6 @@ protected:
private: private:
WebGLAttachment* getAttachment(GLenum attachment) const; WebGLAttachment* getAttachment(GLenum attachment) const;
bool isAttachmentComplete(WebGLAttachment* attachedObject, GLenum attachment, const char** reason) const;
// Check if the framebuffer is currently bound. // Check if the framebuffer is currently bound.
bool isBound(GLenum target) const; bool isBound(GLenum target) const;
......
...@@ -837,9 +837,6 @@ protected: ...@@ -837,9 +837,6 @@ protected:
// is valid. // is valid.
bool isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat); bool isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat);
// Helper function to get the bound framebuffer's color buffer format.
virtual GLenum boundFramebufferColorFormat();
// Helper function to verify limits on the length of uniform and attribute locations. // Helper function to verify limits on the length of uniform and attribute locations.
virtual unsigned getMaxWebGLLocationLength() const { return 256; } virtual unsigned getMaxWebGLLocationLength() const { return 256; }
bool validateLocationLength(const char* functionName, const String&); bool validateLocationLength(const char* functionName, const String&);
......
...@@ -37,13 +37,7 @@ WebGLTexture* WebGLTexture::create(WebGLRenderingContextBase* ctx) ...@@ -37,13 +37,7 @@ WebGLTexture* WebGLTexture::create(WebGLRenderingContextBase* ctx)
WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx) WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx)
: WebGLSharedPlatform3DObject(ctx) : WebGLSharedPlatform3DObject(ctx)
, m_target(0) , m_target(0)
, m_isNPOT(false)
, m_isCubeComplete(false)
, m_isComplete(false)
, m_isFloatType(false)
, m_isHalfFloatType(false)
, m_isWebGL2OrHigher(ctx->isWebGL2OrHigher()) , m_isWebGL2OrHigher(ctx->isWebGL2OrHigher())
, m_immutable(false)
, m_baseLevel(0) , m_baseLevel(0)
, m_maxLevel(1000) , m_maxLevel(1000)
{ {
...@@ -63,21 +57,7 @@ void WebGLTexture::setTarget(GLenum target, GLint maxLevel) ...@@ -63,21 +57,7 @@ void WebGLTexture::setTarget(GLenum target, GLint maxLevel)
// Target is finalized the first time bindTexture() is called. // Target is finalized the first time bindTexture() is called.
if (m_target) if (m_target)
return; return;
switch (target) { m_target = target;
case GL_TEXTURE_2D:
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_3D:
m_target = target;
m_info.resize(1);
m_info[0].resize(maxLevel);
break;
case GL_TEXTURE_CUBE_MAP:
m_target = target;
m_info.resize(6);
for (int ii = 0; ii < 6; ++ii)
m_info[ii].resize(maxLevel);
break;
}
} }
void WebGLTexture::setParameteri(GLenum pname, GLint param) void WebGLTexture::setParameteri(GLenum pname, GLint param)
...@@ -143,7 +123,6 @@ void WebGLTexture::setParameteri(GLenum pname, GLint param) ...@@ -143,7 +123,6 @@ void WebGLTexture::setParameteri(GLenum pname, GLint param)
default: default:
return; return;
} }
update();
} }
void WebGLTexture::setParameterf(GLenum pname, GLfloat param) void WebGLTexture::setParameterf(GLenum pname, GLfloat param)
...@@ -154,129 +133,6 @@ void WebGLTexture::setParameterf(GLenum pname, GLfloat param) ...@@ -154,129 +133,6 @@ void WebGLTexture::setParameterf(GLenum pname, GLfloat param)
setParameteri(pname, iparam); setParameteri(pname, iparam);
} }
void WebGLTexture::setLevelInfo(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum type)
{
ASSERT(!m_immutable);
if (!object() || !m_target)
return;
// We assume level, internalFormat, width, height, depth, and type have all been
// validated already.
int index = mapTargetToIndex(target);
if (index < 0)
return;
m_info[index][level].setInfo(internalFormat, width, height, depth, type);
update();
}
void WebGLTexture::setTexStorageInfo(GLenum target, GLint levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
{
ASSERT(!m_immutable);
// We assume level, internalFormat, width, height, and depth have all been
// validated already.
if (!object() || !m_target || target != m_target)
return;
GLenum type = getValidTypeForInternalFormat(internalFormat);
if (type == GL_NONE)
return;
for (size_t ii = 0; ii < m_info.size(); ++ii) {
GLsizei levelWidth = width;
GLsizei levelHeight = height;
GLsizei levelDepth = depth;
for (GLint level = 0; level < levels; ++level) {
LevelInfo& info = m_info[ii][level];
info.setInfo(internalFormat, levelWidth, levelHeight, levelDepth, type);
levelWidth = std::max(1, levelWidth >> 1);
levelHeight = std::max(1, levelHeight >> 1);
levelDepth = m_target == GL_TEXTURE_2D_ARRAY ? levelDepth : std::max(1, levelDepth >> 1);
}
}
update();
m_immutable = true;
}
void WebGLTexture::generateMipmapLevelInfo()
{
if (!object() || !m_target)
return;
if (!canGenerateMipmaps())
return;
if (!m_isComplete) {
for (size_t ii = 0; ii < m_info.size(); ++ii) {
const LevelInfo& info0 = m_info[ii][m_baseLevel];
GLsizei width = info0.width;
GLsizei height = info0.height;
GLsizei depth = info0.depth;
GLint levelCount = computeLevelCount(width, height, (m_target == GL_TEXTURE_2D_ARRAY ? 0 : depth));
size_t maxLevel = 0;
if (m_baseLevel + levelCount > 0)
maxLevel = m_baseLevel + levelCount - 1;
maxLevel = m_isWebGL2OrHigher ? std::min(m_maxLevel, maxLevel) : maxLevel;
ASSERT(maxLevel < m_info[ii].size());
for (size_t level = m_baseLevel + 1; level <= maxLevel; ++level) {
width = std::max(1, width >> 1);
height = std::max(1, height >> 1);
depth = m_target == GL_TEXTURE_2D_ARRAY ? depth : std::max(1, depth >> 1);
LevelInfo& info = m_info[ii][level];
info.setInfo(info0.internalFormat, width, height, depth, info0.type);
}
}
m_isComplete = true;
}
}
GLenum WebGLTexture::getInternalFormat(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
return 0;
return info->internalFormat;
}
GLenum WebGLTexture::getType(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
return 0;
return info->type;
}
GLsizei WebGLTexture::getWidth(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
return 0;
return info->width;
}
GLsizei WebGLTexture::getHeight(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
return 0;
return info->height;
}
GLsizei WebGLTexture::getDepth(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
return 0;
return info->depth;
}
bool WebGLTexture::isValid(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
return 0;
return info->valid;
}
bool WebGLTexture::isNPOT(GLsizei width, GLsizei height) bool WebGLTexture::isNPOT(GLsizei width, GLsizei height)
{ {
ASSERT(width >= 0 && height >= 0); ASSERT(width >= 0 && height >= 0);
...@@ -287,13 +143,6 @@ bool WebGLTexture::isNPOT(GLsizei width, GLsizei height) ...@@ -287,13 +143,6 @@ bool WebGLTexture::isNPOT(GLsizei width, GLsizei height)
return false; return false;
} }
bool WebGLTexture::isNPOT() const
{
if (!object())
return false;
return m_isNPOT;
}
void WebGLTexture::deleteObjectImpl(WebGraphicsContext3D* context3d) void WebGLTexture::deleteObjectImpl(WebGraphicsContext3D* context3d)
{ {
context3d->deleteTexture(m_object); context3d->deleteTexture(m_object);
...@@ -330,20 +179,6 @@ int WebGLTexture::mapTargetToIndex(GLenum target) const ...@@ -330,20 +179,6 @@ int WebGLTexture::mapTargetToIndex(GLenum target) const
return -1; return -1;
} }
bool WebGLTexture::canGenerateMipmaps()
{
if (!m_isWebGL2OrHigher && isNPOT())
return false;
if (m_baseLevel >= m_info[0].size())
return false;
if (m_info.size() > 1 && !m_isCubeComplete)
return false;
return true;
}
GLint WebGLTexture::computeLevelCount(GLsizei width, GLsizei height, GLsizei depth) GLint WebGLTexture::computeLevelCount(GLsizei width, GLsizei height, GLsizei depth)
{ {
// return 1 + log2Floor(std::max(width, height)); // return 1 + log2Floor(std::max(width, height));
...@@ -364,77 +199,6 @@ GLint WebGLTexture::computeLevelCount(GLsizei width, GLsizei height, GLsizei dep ...@@ -364,77 +199,6 @@ GLint WebGLTexture::computeLevelCount(GLsizei width, GLsizei height, GLsizei dep
return log + 1; return log + 1;
} }
void WebGLTexture::update()
{
m_isNPOT = false;
for (size_t ii = 0; ii < m_info.size(); ++ii) {
if (isNPOT(m_info[ii][0].width, m_info[ii][0].height)) {
m_isNPOT = true;
break;
}
}
m_isComplete = true;
m_isCubeComplete = true;
if (m_baseLevel > m_maxLevel || m_baseLevel >= m_info[0].size()) {
m_isComplete = false;
}
else {
const LevelInfo& base = m_info[0][m_baseLevel];
size_t levelCount = computeLevelCount(base.width, base.height, (m_target == GL_TEXTURE_2D_ARRAY ? 0 : base.depth));
size_t maxLevel = 0;
if (m_baseLevel + levelCount > 0)
maxLevel = m_baseLevel + levelCount - 1;
maxLevel = m_isWebGL2OrHigher ? std::min(m_maxLevel, maxLevel) : maxLevel;
for (size_t ii = 0; ii < m_info.size(); ++ii) {
const LevelInfo& info0 = m_info[ii][m_baseLevel];
if (!info0.valid
|| info0.width != base.width || info0.height != base.height || info0.depth != base.depth
|| info0.internalFormat != base.internalFormat || info0.type != base.type
|| (m_info.size() > 1 && info0.width != info0.height)) {
if (m_info.size() > 1)
m_isCubeComplete = false;
m_isComplete = false;
break;
}
if (!m_isComplete)
continue;
GLsizei width = info0.width;
GLsizei height = info0.height;
GLsizei depth = info0.depth;
ASSERT(maxLevel < m_info[ii].size());
for (size_t level = m_baseLevel + 1; level <= maxLevel; ++level) {
width = std::max(1, width >> 1);
height = std::max(1, height >> 1);
depth = m_target == GL_TEXTURE_2D_ARRAY ? depth : std::max(1, depth >> 1);
const LevelInfo& info = m_info[ii][level];
if (!info.valid
|| info.width != width || info.height != height || info.depth != depth
|| info.internalFormat != info0.internalFormat || info.type != info0.type) {
m_isComplete = false;
break;
}
}
}
}
m_isFloatType = m_info[0][0].type == GL_FLOAT;
m_isHalfFloatType = m_info[0][0].type == GL_HALF_FLOAT_OES;
}
const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(GLenum target, GLint level) const
{
if (!object() || !m_target)
return nullptr;
int targetIndex = mapTargetToIndex(target);
if (targetIndex < 0 || targetIndex >= static_cast<int>(m_info.size()))
return nullptr;
if (level < 0 || level >= static_cast<GLint>(m_info[targetIndex].size()))
return nullptr;
return &(m_info[targetIndex][level]);
}
// TODO(bajones): Logic surrounding relationship of internalFormat, format, and type needs to be revisisted for WebGL 2.0 // TODO(bajones): Logic surrounding relationship of internalFormat, format, and type needs to be revisisted for WebGL 2.0
GLenum WebGLTexture::getValidTypeForInternalFormat(GLenum internalFormat) GLenum WebGLTexture::getValidTypeForInternalFormat(GLenum internalFormat)
{ {
......
...@@ -60,30 +60,11 @@ public: ...@@ -60,30 +60,11 @@ public:
int getMinFilter() const { return m_samplerState.minFilter; } int getMinFilter() const { return m_samplerState.minFilter; }
void setLevelInfo(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum type);
void setTexStorageInfo(GLenum target, GLint levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
bool canGenerateMipmaps();
// Generate all level information.
void generateMipmapLevelInfo();
GLenum getInternalFormat(GLenum target, GLint level) const;
GLenum getType(GLenum target, GLint level) const;
GLsizei getWidth(GLenum target, GLint level) const;
GLsizei getHeight(GLenum target, GLint level) const;
GLsizei getDepth(GLenum target, GLint level) const;
bool isValid(GLenum target, GLint level) const;
bool isImmutable() const { return m_immutable; }
static GLenum getValidFormatForInternalFormat(GLenum); static GLenum getValidFormatForInternalFormat(GLenum);
bool isCubeComplete() const { return m_isCubeComplete; }
// Whether width/height is NotPowerOfTwo. // Whether width/height is NotPowerOfTwo.
static bool isNPOT(GLsizei, GLsizei); static bool isNPOT(GLsizei, GLsizei);
bool isNPOT() const;
bool hasEverBeenBound() const { return object() && m_target; } bool hasEverBeenBound() const { return object() && m_target; }
static GLint computeLevelCount(GLsizei width, GLsizei height, GLsizei depth); static GLint computeLevelCount(GLsizei width, GLsizei height, GLsizei depth);
...@@ -96,57 +77,15 @@ private: ...@@ -96,57 +77,15 @@ private:
void deleteObjectImpl(WebGraphicsContext3D*) override; void deleteObjectImpl(WebGraphicsContext3D*) override;
class LevelInfo {
public:
LevelInfo()
: valid(false)
, internalFormat(0)
, width(0)
, height(0)
, depth(0)
, type(0)
{
}
void setInfo(GLenum internalFmt, GLsizei w, GLsizei h, GLsizei d, GLenum tp)
{
valid = true;
internalFormat = internalFmt;
width = w;
height = h;
depth = d;
type = tp;
}
bool valid;
GLenum internalFormat;
GLsizei width;
GLsizei height;
GLsizei depth;
GLenum type;
};
bool isTexture() const override { return true; } bool isTexture() const override { return true; }
void update();
int mapTargetToIndex(GLenum) const; int mapTargetToIndex(GLenum) const;
const LevelInfo* getLevelInfo(GLenum target, GLint level) const;
GLenum m_target; GLenum m_target;
WebGLSamplerState m_samplerState; WebGLSamplerState m_samplerState;
Vector<Vector<LevelInfo>> m_info;
bool m_isNPOT;
bool m_isCubeComplete;
bool m_isComplete;
bool m_isFloatType;
bool m_isHalfFloatType;
bool m_isWebGL2OrHigher; bool m_isWebGL2OrHigher;
bool m_immutable;
size_t m_baseLevel; size_t m_baseLevel;
size_t m_maxLevel; size_t m_maxLevel;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment