Bug 1063053 - Add stronger types to WebGL texture code for better debug/compile time checking. r=jgilbert,kamidphish

This commit is contained in:
Walter Litwinczyk 2014-09-18 16:14:22 -07:00
parent 303e2ef098
commit a2379a555b
22 changed files with 454 additions and 274 deletions

View File

@ -1,27 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLBindableName.h"
#include "GLConsts.h"
#include "mozilla/Assertions.h"
using namespace mozilla;
WebGLBindableName::WebGLBindableName()
: mGLName(LOCAL_GL_NONE)
, mTarget(LOCAL_GL_NONE)
{ }
void
WebGLBindableName::BindTo(GLenum target)
{
MOZ_ASSERT(target != LOCAL_GL_NONE, "Can't bind to GL_NONE.");
MOZ_ASSERT(mTarget == LOCAL_GL_NONE || mTarget == target, "Rebinding is illegal.");
bool targetChanged = (target != mTarget);
mTarget = target;
if (targetChanged)
OnTargetChanged();
}

View File

@ -8,19 +8,41 @@
#include "WebGLTypes.h"
#include "GLDefs.h"
#include "mozilla/TypeTraits.h"
#include "mozilla/Assertions.h"
namespace mozilla {
/** Represents a GL name that can be bound to a target.
*/
template<typename T>
class WebGLBindableName
{
public:
WebGLBindableName();
void BindTo(GLenum target);
bool HasEverBeenBound() const { return mTarget != 0; }
WebGLBindableName()
: mGLName(0)
, mTarget(LOCAL_GL_NONE)
{ }
void BindTo(T target)
{
MOZ_ASSERT(target != LOCAL_GL_NONE, "Can't bind to GL_NONE.");
MOZ_ASSERT(!HasEverBeenBound() || mTarget == target, "Rebinding is illegal.");
bool targetChanged = (target != mTarget);
mTarget = target;
if (targetChanged)
OnTargetChanged();
}
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
GLuint GLName() const { return mGLName; }
GLenum Target() const { return mTarget; }
T Target() const {
MOZ_ASSERT(HasEverBeenBound());
return mTarget;
}
protected:
@ -28,7 +50,7 @@ protected:
virtual void OnTargetChanged() {}
GLuint mGLName;
GLenum mTarget;
T mTarget;
};
} // namespace mozilla

View File

@ -13,7 +13,7 @@
using namespace mozilla;
WebGLBuffer::WebGLBuffer(WebGLContext *context)
: WebGLBindableName()
: WebGLBindableName<GLenum>()
, WebGLContextBoundObject(context)
, mByteLength(0)
{

View File

@ -20,7 +20,7 @@ class WebGLElementArrayCache;
class WebGLBuffer MOZ_FINAL
: public nsWrapperCache
, public WebGLBindableName
, public WebGLBindableName<GLenum>
, public WebGLRefCountedObject<WebGLBuffer>
, public LinkedListElement<WebGLBuffer>
, public WebGLContextBoundObject

View File

@ -1746,7 +1746,7 @@ WebGLContext::DidRefresh()
}
}
bool WebGLContext::TexImageFromVideoElement(GLenum texImageTarget, GLint level,
bool WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget, GLint level,
GLenum internalformat, GLenum format, GLenum type,
mozilla::dom::Element& elt)
{
@ -1793,9 +1793,9 @@ bool WebGLContext::TexImageFromVideoElement(GLenum texImageTarget, GLint level,
info.Height() == srcImage->GetSize().height;
if (!dimensionsMatch) {
// we need to allocation
gl->fTexImage2D(texImageTarget, level, internalformat, srcImage->GetSize().width, srcImage->GetSize().height, 0, format, type, nullptr);
gl->fTexImage2D(texImageTarget.get(), level, internalformat, srcImage->GetSize().width, srcImage->GetSize().height, 0, format, type, nullptr);
}
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(), srcImage->GetSize(), tex->GLName(), texImageTarget, mPixelStoreFlipY);
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(), srcImage->GetSize(), tex->GLName(), texImageTarget.get(), mPixelStoreFlipY);
if (ok) {
tex->SetImageInfo(texImageTarget, level, srcImage->GetSize().width, srcImage->GetSize().height, format, type, WebGLImageDataStatus::InitializedImageData);
tex->Bind(TexImageTargetToTexTarget(texImageTarget));

View File

@ -17,6 +17,7 @@
#include "WebGLActiveInfo.h"
#include "WebGLObjectModel.h"
#include "WebGLRenderbuffer.h"
#include "WebGLStrongTypes.h"
#include <stdarg.h>
#include "nsTArray.h"
@ -123,7 +124,7 @@ struct WebGLContextOptions {
};
// From WebGLContextUtils
GLenum TexImageTargetToTexTarget(GLenum texImageTarget);
TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);
class WebGLContext :
public nsIDOMWebGLRenderingContext,
@ -224,8 +225,7 @@ public:
void DummyFramebufferOperation(const char *info);
WebGLTexture* activeBoundTextureForTarget(GLenum texTarget) const {
MOZ_ASSERT(texTarget == LOCAL_GL_TEXTURE_2D || texTarget == LOCAL_GL_TEXTURE_CUBE_MAP);
WebGLTexture* activeBoundTextureForTarget(const TexTarget texTarget) const {
return texTarget == LOCAL_GL_TEXTURE_2D ? mBound2DTextures[mActiveTexture]
: mBoundCubeMapTextures[mActiveTexture];
}
@ -234,8 +234,8 @@ public:
* GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP_[POSITIVE|NEGATIVE]_[X|Y|Z], and
* not the actual texture binding target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP.
*/
WebGLTexture* activeBoundTextureForTexImageTarget(GLenum texImgTarget) const {
const GLenum texTarget = TexImageTargetToTexTarget(texImgTarget);
WebGLTexture* activeBoundTextureForTexImageTarget(const TexImageTarget texImgTarget) const {
const TexTarget texTarget = TexImageTargetToTexTarget(texImgTarget);
return activeBoundTextureForTarget(texTarget);
}
@ -465,21 +465,24 @@ public:
dom::ImageData* pixels, ErrorResult& rv);
// Allow whatever element types the bindings are willing to pass
// us in TexImage2D
bool TexImageFromVideoElement(GLenum texImageTarget, GLint level,
bool TexImageFromVideoElement(TexImageTarget texImageTarget, GLint level,
GLenum internalformat, GLenum format, GLenum type,
mozilla::dom::Element& image);
template<class ElementType>
void TexImage2D(GLenum texImageTarget, GLint level,
void TexImage2D(GLenum rawTexImgTarget, GLint level,
GLenum internalformat, GLenum format, GLenum type,
ElementType& elt, ErrorResult& rv)
{
if (IsContextLost())
return;
const GLenum target = TexImageTargetToTexTarget(texImageTarget);
if (target == LOCAL_GL_NONE)
return ErrorInvalidEnumInfo("texImage2D: target", target);
auto dims = 2;
if (!ValidateTexImageTarget(dims, rawTexImgTarget, WebGLTexImageFunc::TexImage))
return ErrorInvalidEnumInfo("texSubImage2D: target", rawTexImgTarget);
const TexImageTarget texImageTarget(rawTexImgTarget);
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
return;
@ -491,7 +494,7 @@ public:
if (level > maxLevel)
return ErrorInvalidValue("texImage2D: level %d is too large, max is %d", level, maxLevel);
WebGLTexture* tex = activeBoundTextureForTarget(target);
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("no texture is bound to this target");
@ -536,16 +539,17 @@ public:
// Allow whatever element types the bindings are willing to pass
// us in TexSubImage2D
template<class ElementType>
void TexSubImage2D(GLenum texImageTarget, GLint level,
void TexSubImage2D(GLenum rawTexImageTarget, GLint level,
GLint xoffset, GLint yoffset, GLenum format,
GLenum type, ElementType& elt, ErrorResult& rv)
{
if (IsContextLost())
return;
const GLenum target = TexImageTargetToTexTarget(texImageTarget);
if (target == LOCAL_GL_NONE)
return ErrorInvalidEnumInfo("texSubImage2D: target", texImageTarget);
if (!ValidateTexImageTarget(2, rawTexImageTarget, WebGLTexImageFunc::TexSubImage))
return ErrorInvalidEnumInfo("texSubImage2D: target", rawTexImageTarget);
const TexImageTarget texImageTarget(rawTexImageTarget);
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
return;
@ -1088,7 +1092,7 @@ protected:
bool ValidateGLSLString(const nsAString& string, const char *info);
bool ValidateCopyTexImage(GLenum format, WebGLTexImageFunc func);
bool ValidateTexImage(GLuint dims, GLenum target,
bool ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
GLint level, GLint internalFormat,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
@ -1098,7 +1102,7 @@ protected:
bool ValidateTexImageFormat(GLenum format, WebGLTexImageFunc func);
bool ValidateTexImageType(GLenum type, WebGLTexImageFunc func);
bool ValidateTexImageFormatAndType(GLenum format, GLenum type, WebGLTexImageFunc func);
bool ValidateTexImageSize(GLenum target, GLint level,
bool ValidateTexImageSize(TexImageTarget target, GLint level,
GLint width, GLint height, GLint depth,
WebGLTexImageFunc func);
bool ValidateTexSubImageSize(GLint x, GLint y, GLint z,
@ -1106,7 +1110,7 @@ protected:
GLsizei baseWidth, GLsizei baseHeight, GLsizei baseDepth,
WebGLTexImageFunc func);
bool ValidateCompTexImageSize(GLenum target, GLint level, GLenum format,
bool ValidateCompTexImageSize(GLint level, GLenum format,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLsizei levelWidth, GLsizei levelHeight,
@ -1124,13 +1128,13 @@ protected:
void MakeContextCurrent() const;
// helpers
void TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
void TexImage2D_base(TexImageTarget target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei srcStrideOrZero, GLint border,
GLenum format, GLenum type,
void *data, uint32_t byteLength,
int jsArrayType,
WebGLTexelFormat srcFormat, bool srcPremultiplied);
void TexSubImage2D_base(GLenum target, GLint level,
void TexSubImage2D_base(TexImageTarget target, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
GLenum format, GLenum type,
@ -1168,7 +1172,7 @@ protected:
RefPtr<gfx::DataSourceSurface>& imageOut,
WebGLTexelFormat *format);
void CopyTexSubImage2D_base(GLenum target,
void CopyTexSubImage2D_base(TexImageTarget texImageTarget,
GLint level,
GLenum internalformat,
GLint xoffset,
@ -1200,17 +1204,12 @@ private:
bool ValidateObjectAssumeNonNull(const char* info, ObjectType *aObject);
protected:
int32_t MaxTextureSizeForTarget(GLenum target) const {
MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D ||
(target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z),
"Invalid target enum");
int32_t MaxTextureSizeForTarget(TexTarget target) const {
return (target == LOCAL_GL_TEXTURE_2D) ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize;
}
int32_t MaxTextureLevelForTexImageTarget(GLenum texImageTarget) const {
const GLenum target = TexImageTargetToTexTarget(texImageTarget);
MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D || target == LOCAL_GL_TEXTURE_CUBE_MAP);
int32_t MaxTextureLevelForTexImageTarget(TexImageTarget texImageTarget) const {
const TexTarget target = TexImageTargetToTexTarget(texImageTarget);
return (target == LOCAL_GL_TEXTURE_2D) ? mGLMaxTextureSizeLog2 : mGLMaxCubeMapTextureSizeLog2;
}
@ -1222,7 +1221,7 @@ protected:
GLenum usage);
/** like glTexImage2D but if the call may change the texture size, checks any GL error generated
* by this glTexImage2D call and returns it */
GLenum CheckedTexImage2D(GLenum target,
GLenum CheckedTexImage2D(TexImageTarget texImageTarget,
GLint level,
GLenum internalFormat,
GLsizei width,

View File

@ -215,7 +215,7 @@ WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer *wrb)
}
void
WebGLContext::BindTexture(GLenum target, WebGLTexture *newTex)
WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture *newTex)
{
if (IsContextLost())
return;
@ -223,18 +223,10 @@ WebGLContext::BindTexture(GLenum target, WebGLTexture *newTex)
if (!ValidateObjectAllowDeletedOrNull("bindTexture", newTex))
return;
if (newTex) {
// silently ignore a deleted texture
if (newTex->IsDeleted())
return;
if (newTex->Target() != LOCAL_GL_NONE && newTex->Target() != target)
return ErrorInvalidOperation("bindTexture: this texture has already been bound to a different target");
}
// Need to check rawTarget first before comparing against newTex->Target() as
// newTex->Target() returns a TexTarget, which will assert on invalid value.
WebGLRefPtr<WebGLTexture>* currentTexPtr = nullptr;
switch (target) {
switch (rawTarget) {
case LOCAL_GL_TEXTURE_2D:
currentTexPtr = &mBound2DTextures[mActiveTexture];
break;
@ -242,9 +234,20 @@ WebGLContext::BindTexture(GLenum target, WebGLTexture *newTex)
currentTexPtr = &mBoundCubeMapTextures[mActiveTexture];
break;
default:
return ErrorInvalidEnumInfo("bindTexture: target", target);
return ErrorInvalidEnumInfo("bindTexture: target", rawTarget);
}
if (newTex) {
// silently ignore a deleted texture
if (newTex->IsDeleted())
return;
if (newTex->HasEverBeenBound() && newTex->Target() != rawTarget)
return ErrorInvalidOperation("bindTexture: this texture has already been bound to a different target");
}
const TexTarget target(rawTarget);
WebGLTextureFakeBlackStatus currentTexFakeBlackStatus = WebGLTextureFakeBlackStatus::NotNeeded;
if (*currentTexPtr) {
currentTexFakeBlackStatus = (*currentTexPtr)->ResolvedFakeBlackStatus();
@ -265,7 +268,7 @@ WebGLContext::BindTexture(GLenum target, WebGLTexture *newTex)
if (newTex)
newTex->Bind(target);
else
gl->fBindTexture(target, 0 /* == texturename */);
gl->fBindTexture(target.get(), 0 /* == texturename */);
}
void WebGLContext::BlendEquation(GLenum mode)
@ -349,7 +352,7 @@ WebGLContext::CheckFramebufferStatus(GLenum target)
}
void
WebGLContext::CopyTexSubImage2D_base(GLenum target,
WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
GLint level,
GLenum internalformat,
GLint xoffset,
@ -369,7 +372,7 @@ WebGLContext::CopyTexSubImage2D_base(GLenum target,
// TODO: This changes with color_buffer_float. Reassess when the
// patch lands.
if (!ValidateTexImage(2, target, level, internalformat,
if (!ValidateTexImage(2, texImageTarget, level, internalformat,
xoffset, yoffset, 0,
width, height, 0,
0, internalformat, LOCAL_GL_UNSIGNED_BYTE,
@ -386,16 +389,16 @@ WebGLContext::CopyTexSubImage2D_base(GLenum target,
MakeContextCurrent();
WebGLTexture *tex = activeBoundTextureForTexImageTarget(target);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("%s: no texture is bound to this target");
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
if (sub)
gl->fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
gl->fCopyTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, x, y, width, height);
else
gl->fCopyTexImage2D(target, level, internalformat, x, y, width, height, 0);
gl->fCopyTexImage2D(texImageTarget.get(), level, internalformat, x, y, width, height, 0);
} else {
// the rect doesn't fit in the framebuffer
@ -429,10 +432,10 @@ WebGLContext::CopyTexSubImage2D_base(GLenum target,
// now initialize the texture as black
if (sub)
gl->fTexSubImage2D(target, level, 0, 0, width, height,
gl->fTexSubImage2D(texImageTarget.get(), level, 0, 0, width, height,
internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
else
gl->fTexImage2D(target, level, internalformat, width, height,
gl->fTexImage2D(texImageTarget.get(), level, internalformat, width, height,
0, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
free(tempZeroData);
@ -456,12 +459,12 @@ WebGLContext::CopyTexSubImage2D_base(GLenum target,
GLsizei actual_height = actual_y_plus_height - actual_y;
GLint actual_yoffset = yoffset + actual_y - y;
gl->fCopyTexSubImage2D(target, level, actual_xoffset, actual_yoffset, actual_x, actual_y, actual_width, actual_height);
gl->fCopyTexSubImage2D(texImageTarget.get(), level, actual_xoffset, actual_yoffset, actual_x, actual_y, actual_width, actual_height);
}
}
void
WebGLContext::CopyTexImage2D(GLenum target,
WebGLContext::CopyTexImage2D(GLenum rawTexImgTarget,
GLint level,
GLenum internalformat,
GLint x,
@ -478,7 +481,10 @@ WebGLContext::CopyTexImage2D(GLenum target,
const GLenum format = internalformat; // WebGL/ES Format
const GLenum type = LOCAL_GL_UNSIGNED_BYTE; // WebGL/ES Format
if (!ValidateTexImage(2, target, level, format,
if (!ValidateTexImageTarget(2, rawTexImgTarget, WebGLTexImageFunc::CopyTexImage))
return;
if (!ValidateTexImage(2, rawTexImgTarget, level, format,
0, 0, 0,
width, height, 0,
border, format, type,
@ -493,11 +499,13 @@ WebGLContext::CopyTexImage2D(GLenum target,
if (!mBoundFramebuffer)
ClearBackbufferIfNeeded();
const TexImageTarget texImageTarget(rawTexImgTarget);
// check if the memory size of this texture may change with this call
bool sizeMayChange = true;
WebGLTexture* tex = activeBoundTextureForTexImageTarget(target);
if (tex->HasImageInfoAt(target, level)) {
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(target, level);
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
if (tex->HasImageInfoAt(texImageTarget, level)) {
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
sizeMayChange = width != imageInfo.Width() ||
height != imageInfo.Height() ||
@ -508,7 +516,7 @@ WebGLContext::CopyTexImage2D(GLenum target,
if (sizeMayChange)
GetAndFlushUnderlyingGLErrors();
CopyTexSubImage2D_base(target, level, format, 0, 0, x, y, width, height, false);
CopyTexSubImage2D_base(texImageTarget, level, format, 0, 0, x, y, width, height, false);
if (sizeMayChange) {
GLenum error = GetAndFlushUnderlyingGLErrors();
@ -518,12 +526,12 @@ WebGLContext::CopyTexImage2D(GLenum target,
}
}
tex->SetImageInfo(target, level, width, height, format, type,
tex->SetImageInfo(texImageTarget, level, width, height, format, type,
WebGLImageDataStatus::InitializedImageData);
}
void
WebGLContext::CopyTexSubImage2D(GLenum target,
WebGLContext::CopyTexSubImage2D(GLenum rawTexImgTarget,
GLint level,
GLint xoffset,
GLint yoffset,
@ -535,7 +543,7 @@ WebGLContext::CopyTexSubImage2D(GLenum target,
if (IsContextLost())
return;
switch (target) {
switch (rawTexImgTarget) {
case LOCAL_GL_TEXTURE_2D:
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
@ -545,13 +553,15 @@ WebGLContext::CopyTexSubImage2D(GLenum target,
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
break;
default:
return ErrorInvalidEnumInfo("copyTexSubImage2D: target", target);
return ErrorInvalidEnumInfo("copyTexSubImage2D: target", rawTexImgTarget);
}
const TexImageTarget texImageTarget(rawTexImgTarget);
if (level < 0)
return ErrorInvalidValue("copyTexSubImage2D: level may not be negative");
GLsizei maxTextureSize = MaxTextureSizeForTarget(target);
GLsizei maxTextureSize = MaxTextureSizeForTarget(TexImageTargetToTexTarget(texImageTarget));
if (!(maxTextureSize >> level))
return ErrorInvalidValue("copyTexSubImage2D: 2^level exceeds maximum texture size");
@ -561,14 +571,14 @@ WebGLContext::CopyTexSubImage2D(GLenum target,
if (xoffset < 0 || yoffset < 0)
return ErrorInvalidValue("copyTexSubImage2D: xoffset and yoffset may not be negative");
WebGLTexture *tex = activeBoundTextureForTexImageTarget(target);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("copyTexSubImage2D: no texture bound to this target");
if (!tex->HasImageInfoAt(target, level))
if (!tex->HasImageInfoAt(texImageTarget, level))
return ErrorInvalidOperation("copyTexSubImage2D: no texture image previously defined for this level and face");
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(target, level);
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(texImageTarget, level);
GLsizei texWidth = imageInfo.Width();
GLsizei texHeight = imageInfo.Height();
@ -582,10 +592,10 @@ WebGLContext::CopyTexSubImage2D(GLenum target,
ClearBackbufferIfNeeded();
if (imageInfo.HasUninitializedImageData()) {
tex->DoDeferredImageInitialization(target, level);
tex->DoDeferredImageInitialization(texImageTarget, level);
}
return CopyTexSubImage2D_base(target, level, imageInfo.WebGLFormat(), xoffset, yoffset, x, y, width, height, true);
return CopyTexSubImage2D_base(texImageTarget, level, imageInfo.WebGLFormat(), xoffset, yoffset, x, y, width, height, true);
}
@ -692,11 +702,11 @@ WebGLContext::DeleteTexture(WebGLTexture *tex)
GLuint activeTexture = mActiveTexture;
for (int32_t i = 0; i < mGLMaxTextureUnits; i++) {
if ((tex->Target() == LOCAL_GL_TEXTURE_2D && mBound2DTextures[i] == tex) ||
(tex->Target() == LOCAL_GL_TEXTURE_CUBE_MAP && mBoundCubeMapTextures[i] == tex))
if ((mBound2DTextures[i] == tex && tex->Target() == LOCAL_GL_TEXTURE_2D) ||
(mBoundCubeMapTextures[i] == tex && tex->Target() == LOCAL_GL_TEXTURE_CUBE_MAP))
{
ActiveTexture(LOCAL_GL_TEXTURE0 + i);
BindTexture(tex->Target(), static_cast<WebGLTexture*>(nullptr));
BindTexture(tex->Target().get(), static_cast<WebGLTexture*>(nullptr));
}
}
ActiveTexture(LOCAL_GL_TEXTURE0 + activeTexture);
@ -801,7 +811,14 @@ WebGLContext::FramebufferTexture2D(GLenum target,
if (!mBoundFramebuffer)
return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
return mBoundFramebuffer->FramebufferTexture2D(target, attachment, textarget, tobj, level);
if (textarget != LOCAL_GL_TEXTURE_2D &&
(textarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
textarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
{
return ErrorInvalidEnumInfo("framebufferTexture2D: invalid texture target", textarget);
}
return mBoundFramebuffer->FramebufferTexture2D(target, attachment, TexImageTarget(textarget), tobj, level);
}
void
@ -857,21 +874,24 @@ WebGLContext::GetActiveAttrib(WebGLProgram *prog, uint32_t index)
}
void
WebGLContext::GenerateMipmap(GLenum target)
WebGLContext::GenerateMipmap(GLenum rawTarget)
{
if (IsContextLost())
return;
if (!ValidateTextureTargetEnum(target, "generateMipmap"))
if (!ValidateTextureTargetEnum(rawTarget, "generateMipmap"))
return;
const TexTarget target(rawTarget);
WebGLTexture *tex = activeBoundTextureForTarget(target);
if (!tex)
return ErrorInvalidOperation("generateMipmap: No texture is bound to this target.");
GLenum imageTarget = (target == LOCAL_GL_TEXTURE_2D) ? LOCAL_GL_TEXTURE_2D
: LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
const TexImageTarget imageTarget = (target == LOCAL_GL_TEXTURE_2D)
? LOCAL_GL_TEXTURE_2D
: LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
if (!tex->HasImageInfoAt(imageTarget, 0))
{
return ErrorInvalidOperation("generateMipmap: Level zero of texture is not defined.");
@ -905,11 +925,11 @@ WebGLContext::GenerateMipmap(GLenum target)
// overhead so we do it unconditionally.
//
// note that the choice of GL_NEAREST_MIPMAP_NEAREST really matters. See Chromium bug 101105.
gl->fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST_MIPMAP_NEAREST);
gl->fGenerateMipmap(target);
gl->fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, tex->MinFilter());
gl->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST_MIPMAP_NEAREST);
gl->fGenerateMipmap(target.get());
gl->fTexParameteri(target.get(), LOCAL_GL_TEXTURE_MIN_FILTER, tex->MinFilter());
} else {
gl->fGenerateMipmap(target);
gl->fGenerateMipmap(target.get());
}
}
@ -1173,10 +1193,10 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
return WebGLObjectAsJSValue(cx, fba.Texture(), rv);
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
return JS::Int32Value(fba.TexImageLevel());
return JS::Int32Value(fba.MipLevel());
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: {
GLenum face = fba.TexImageTarget();
GLenum face = fba.ImageTarget().get();
if (face == LOCAL_GL_TEXTURE_2D)
face = 0;
return JS::Int32Value(face);
@ -1199,8 +1219,8 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
return JS::NumberValue(uint32_t(LOCAL_GL_NONE));
uint32_t ret = LOCAL_GL_NONE;
GLenum type = fba.Texture()->ImageInfoAt(fba.TexImageTarget(),
fba.TexImageLevel()).WebGLType();
GLenum type = fba.Texture()->ImageInfoAt(fba.ImageTarget(),
fba.MipLevel()).WebGLType();
switch (type) {
case LOCAL_GL_UNSIGNED_BYTE:
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
@ -1445,7 +1465,7 @@ WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsACString& retval)
// here we have to support all pnames with both int and float params.
// See this discussion:
// https://www.khronos.org/webgl/public-mailing-list/archives/1008/msg00014.html
void WebGLContext::TexParameter_base(GLenum target, GLenum pname,
void WebGLContext::TexParameter_base(GLenum rawTarget, GLenum pname,
GLint *intParamPtr,
GLfloat *floatParamPtr)
{
@ -1457,10 +1477,12 @@ void WebGLContext::TexParameter_base(GLenum target, GLenum pname,
GLint intParam = intParamPtr ? *intParamPtr : GLint(*floatParamPtr);
GLfloat floatParam = floatParamPtr ? *floatParamPtr : GLfloat(*intParamPtr);
if (!ValidateTextureTargetEnum(target, "texParameter: target"))
if (!ValidateTextureTargetEnum(rawTarget, "texParameter: target"))
return;
WebGLTexture *tex = activeBoundTextureForTarget(target);
const TexTarget texTarget = TexTarget(rawTarget);
WebGLTexture *tex = activeBoundTextureForTarget(texTarget);
if (!tex)
return ErrorInvalidOperation("texParameter: no texture is bound to this target");
@ -1546,22 +1568,24 @@ void WebGLContext::TexParameter_base(GLenum target, GLenum pname,
MakeContextCurrent();
if (intParamPtr)
gl->fTexParameteri(target, pname, intParam);
gl->fTexParameteri(texTarget.get(), pname, intParam);
else
gl->fTexParameterf(target, pname, floatParam);
gl->fTexParameterf(texTarget.get(), pname, floatParam);
}
JS::Value
WebGLContext::GetTexParameter(GLenum target, GLenum pname)
WebGLContext::GetTexParameter(GLenum rawTarget, GLenum pname)
{
if (IsContextLost())
return JS::NullValue();
MakeContextCurrent();
if (!ValidateTextureTargetEnum(target, "getTexParameter: target"))
if (!ValidateTextureTargetEnum(rawTarget, "getTexParameter: target"))
return JS::NullValue();
const TexTarget target(rawTarget);
if (!activeBoundTextureForTarget(target)) {
ErrorInvalidOperation("getTexParameter: no texture bound");
return JS::NullValue();
@ -1574,13 +1598,13 @@ WebGLContext::GetTexParameter(GLenum target, GLenum pname)
case LOCAL_GL_TEXTURE_WRAP_T:
{
GLint i = 0;
gl->fGetTexParameteriv(target, pname, &i);
gl->fGetTexParameteriv(target.get(), pname, &i);
return JS::NumberValue(uint32_t(i));
}
case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) {
GLfloat f = 0.f;
gl->fGetTexParameterfv(target, pname, &f);
gl->fGetTexParameterfv(target.get(), pname, &f);
return JS::DoubleValue(f);
}
@ -3275,7 +3299,7 @@ WebGLContext::CompileShader(WebGLShader *shader)
}
void
WebGLContext::CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
WebGLContext::CompressedTexImage2D(GLenum rawTexImgTarget, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLint border,
const ArrayBufferView& view)
{
@ -3284,7 +3308,10 @@ WebGLContext::CompressedTexImage2D(GLenum target, GLint level, GLenum internalfo
const WebGLTexImageFunc func = WebGLTexImageFunc::CompTexImage;
if (!ValidateTexImage(2, target, level, internalformat,
if (!ValidateTexImageTarget(2, rawTexImgTarget, WebGLTexImageFunc::CompTexImage))
return;
if (!ValidateTexImage(2, rawTexImgTarget, level, internalformat,
0, 0, 0, width, height, 0,
border, internalformat, LOCAL_GL_UNSIGNED_BYTE,
func))
@ -3295,26 +3322,27 @@ WebGLContext::CompressedTexImage2D(GLenum target, GLint level, GLenum internalfo
view.ComputeLengthAndData();
uint32_t byteLength = view.Length();
if (!ValidateCompTexImageDataSize(target, internalformat, width, height, byteLength, func)) {
if (!ValidateCompTexImageDataSize(level, internalformat, width, height, byteLength, func)) {
return;
}
if (!ValidateCompTexImageSize(target, level, internalformat, 0, 0,
width, height, width, height, func))
if (!ValidateCompTexImageSize(level, internalformat, 0, 0, width, height, width, height, func))
{
return;
}
const TexImageTarget texImageTarget(rawTexImgTarget);
MakeContextCurrent();
gl->fCompressedTexImage2D(target, level, internalformat, width, height, border, byteLength, view.Data());
WebGLTexture* tex = activeBoundTextureForTexImageTarget(target);
gl->fCompressedTexImage2D(texImageTarget.get(), level, internalformat, width, height, border, byteLength, view.Data());
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
MOZ_ASSERT(tex);
tex->SetImageInfo(target, level, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE,
tex->SetImageInfo(texImageTarget, level, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE,
WebGLImageDataStatus::InitializedImageData);
}
void
WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint xoffset,
GLint yoffset, GLsizei width, GLsizei height,
GLenum format, const ArrayBufferView& view)
{
@ -3323,7 +3351,10 @@ WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
const WebGLTexImageFunc func = WebGLTexImageFunc::CompTexSubImage;
if (!ValidateTexImage(2, target,
if (!ValidateTexImageTarget(2, rawTexImgTarget, WebGLTexImageFunc::CompTexSubImage))
return;
if (!ValidateTexImage(2, rawTexImgTarget,
level, format,
xoffset, yoffset, 0,
width, height, 0,
@ -3333,17 +3364,19 @@ WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
return;
}
WebGLTexture *tex = activeBoundTextureForTexImageTarget(target);
const TexImageTarget texImageTarget(rawTexImgTarget);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
MOZ_ASSERT(tex);
WebGLTexture::ImageInfo& levelInfo = tex->ImageInfoAt(target, level);
WebGLTexture::ImageInfo& levelInfo = tex->ImageInfoAt(texImageTarget, level);
view.ComputeLengthAndData();
uint32_t byteLength = view.Length();
if (!ValidateCompTexImageDataSize(target, format, width, height, byteLength, func))
if (!ValidateCompTexImageDataSize(level, format, width, height, byteLength, func))
return;
if (!ValidateCompTexImageSize(target, level, format,
if (!ValidateCompTexImageSize(level, format,
xoffset, yoffset,
width, height,
levelInfo.Width(), levelInfo.Height(),
@ -3353,10 +3386,10 @@ WebGLContext::CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
}
if (levelInfo.HasUninitializedImageData())
tex->DoDeferredImageInitialization(target, level);
tex->DoDeferredImageInitialization(texImageTarget, level);
MakeContextCurrent();
gl->fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, byteLength, view.Data());
gl->fCompressedTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, width, height, format, byteLength, view.Data());
}
JS::Value
@ -3543,7 +3576,7 @@ WebGLContext::GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval)
retval.Assign(shader->TranslatedSource());
}
GLenum WebGLContext::CheckedTexImage2D(GLenum target,
GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
GLint level,
GLenum internalFormat,
GLsizei width,
@ -3554,13 +3587,13 @@ GLenum WebGLContext::CheckedTexImage2D(GLenum target,
const GLvoid *data)
{
MOZ_ASSERT(internalFormat == format);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(target);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
MOZ_ASSERT(tex != nullptr, "no texture bound");
bool sizeMayChange = true;
if (tex->HasImageInfoAt(target, level)) {
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(target, level);
if (tex->HasImageInfoAt(texImageTarget, level)) {
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
sizeMayChange = width != imageInfo.Width() ||
height != imageInfo.Height() ||
format != imageInfo.WebGLFormat() ||
@ -3577,7 +3610,7 @@ GLenum WebGLContext::CheckedTexImage2D(GLenum target,
GetAndFlushUnderlyingGLErrors();
}
gl->fTexImage2D(target, level, driverInternalFormat, width, height, border, driverFormat, driverType, data);
gl->fTexImage2D(texImageTarget.get(), level, driverInternalFormat, width, height, border, driverFormat, driverType, data);
GLenum error = LOCAL_GL_NO_ERROR;
if (sizeMayChange) {
@ -3588,7 +3621,7 @@ GLenum WebGLContext::CheckedTexImage2D(GLenum target,
}
void
WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
GLint border,
GLenum format, GLenum type,
@ -3598,7 +3631,7 @@ WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
{
const WebGLTexImageFunc func = WebGLTexImageFunc::TexImage;
if (!ValidateTexImage(2, target, level, internalformat,
if (!ValidateTexImage(2, texImageTarget, level, internalformat,
0, 0, 0,
width, height, 0,
border, format, type, func))
@ -3641,7 +3674,7 @@ WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
return ErrorInvalidOperation("texImage2D: not enough data for operation (need %d, have %d)",
bytesNeeded, byteLength);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(target);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("texImage2D: no texture is bound to this target");
@ -3680,7 +3713,7 @@ WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
imageInfoStatusIfSuccess = WebGLImageDataStatus::InitializedImageData;
}
GLenum error = CheckedTexImage2D(target, level, internalformat, width,
GLenum error = CheckedTexImage2D(texImageTarget, level, internalformat, width,
height, border, format, type, pixels);
if (error) {
@ -3693,11 +3726,11 @@ WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
// have NoImageData at this point.
MOZ_ASSERT(imageInfoStatusIfSuccess != WebGLImageDataStatus::NoImageData);
tex->SetImageInfo(target, level, width, height, format, type, imageInfoStatusIfSuccess);
tex->SetImageInfo(texImageTarget, level, width, height, format, type, imageInfoStatusIfSuccess);
}
void
WebGLContext::TexImage2D(GLenum target, GLint level,
WebGLContext::TexImage2D(GLenum rawTarget, GLint level,
GLenum internalformat, GLsizei width,
GLsizei height, GLint border, GLenum format,
GLenum type, const Nullable<ArrayBufferView> &pixels, ErrorResult& rv)
@ -3721,13 +3754,16 @@ WebGLContext::TexImage2D(GLenum target, GLint level,
jsArrayType = int(JS_GetArrayBufferViewType(view.Obj()));
}
return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
if (!ValidateTexImageTarget(2, rawTarget, WebGLTexImageFunc::TexImage))
return;
return TexImage2D_base(rawTarget, level, internalformat, width, height, 0, border, format, type,
data, length, jsArrayType,
WebGLTexelFormat::Auto, false);
}
void
WebGLContext::TexImage2D(GLenum target, GLint level,
WebGLContext::TexImage2D(GLenum rawTarget, GLint level,
GLenum internalformat, GLenum format,
GLenum type, ImageData* pixels, ErrorResult& rv)
{
@ -3744,15 +3780,21 @@ WebGLContext::TexImage2D(GLenum target, GLint level,
MOZ_ASSERT(inited);
arr.ComputeLengthAndData();
return TexImage2D_base(target, level, internalformat, pixels->Width(),
void* pixelData = arr.Data();
const uint32_t pixelDataLength = arr.Length();
if (!ValidateTexImageTarget(2, rawTarget, WebGLTexImageFunc::TexImage))
return;
return TexImage2D_base(rawTarget, level, internalformat, pixels->Width(),
pixels->Height(), 4*pixels->Width(), 0,
format, type, arr.Data(), arr.Length(), -1,
format, type, pixelData, pixelDataLength, -1,
WebGLTexelFormat::RGBA8, false);
}
void
WebGLContext::TexSubImage2D_base(GLenum target, GLint level,
WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
GLenum format, GLenum type,
@ -3762,7 +3804,7 @@ WebGLContext::TexSubImage2D_base(GLenum target, GLint level,
{
const WebGLTexImageFunc func = WebGLTexImageFunc::TexSubImage;
if (!ValidateTexImage(2, target, level, format,
if (!ValidateTexImage(2, texImageTarget, level, format,
xoffset, yoffset, 0,
width, height, 0,
0, format, type, func))
@ -3797,11 +3839,11 @@ WebGLContext::TexSubImage2D_base(GLenum target, GLint level,
if (byteLength < bytesNeeded)
return ErrorInvalidOperation("texSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(target);
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(target, level);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(texImageTarget, level);
if (imageInfo.HasUninitializedImageData())
tex->DoDeferredImageInitialization(target, level);
tex->DoDeferredImageInitialization(texImageTarget, level);
MakeContextCurrent();
@ -3835,11 +3877,11 @@ WebGLContext::TexSubImage2D_base(GLenum target, GLint level,
GLenum driverFormat = LOCAL_GL_NONE;
DriverFormatsFromFormatAndType(gl, format, type, &driverInternalFormat, &driverFormat);
gl->fTexSubImage2D(target, level, xoffset, yoffset, width, height, driverFormat, driverType, pixels);
gl->fTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, width, height, driverFormat, driverType, pixels);
}
void
WebGLContext::TexSubImage2D(GLenum target, GLint level,
WebGLContext::TexSubImage2D(GLenum rawTarget, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
@ -3855,7 +3897,10 @@ WebGLContext::TexSubImage2D(GLenum target, GLint level,
const ArrayBufferView& view = pixels.Value();
view.ComputeLengthAndData();
return TexSubImage2D_base(target, level, xoffset, yoffset,
if (!ValidateTexImageTarget(2, rawTarget, WebGLTexImageFunc::TexSubImage))
return;
return TexSubImage2D_base(rawTarget, level, xoffset, yoffset,
width, height, 0, format, type,
view.Data(), view.Length(),
JS_GetArrayBufferViewType(view.Obj()),

View File

@ -56,10 +56,10 @@ FormatHasAlpha(GLenum webGLFormat)
webGLFormat == LOCAL_GL_SRGB_ALPHA;
}
GLenum
TexImageTargetToTexTarget(GLenum texImageTarget)
TexTarget
TexImageTargetToTexTarget(TexImageTarget texImageTarget)
{
switch (texImageTarget) {
switch (texImageTarget.get()) {
case LOCAL_GL_TEXTURE_2D:
return LOCAL_GL_TEXTURE_2D;
case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
@ -70,6 +70,8 @@ TexImageTargetToTexTarget(GLenum texImageTarget)
case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
return LOCAL_GL_TEXTURE_CUBE_MAP;
default:
MOZ_ASSERT(false, "Bad texture conversion");
// Should be caught by the constructor for TexTarget
return LOCAL_GL_NONE;
}
}

View File

@ -7,6 +7,7 @@
#define WEBGLCONTEXTUTILS_H_
#include "WebGLContext.h"
#include "WebGLStrongTypes.h"
#include "mozilla/Assertions.h"
#include "mozilla/dom/BindingUtils.h"
@ -31,7 +32,7 @@ GLenum DriverTypeFromType(gl::GLContext* gl, GLenum webGLType);
// the currently bound texture is appropriate for this texImageTarget.
//
// Returns GL_NONE if passed an invalid texture image target
GLenum TexImageTargetToTexTarget(GLenum texImageTarget);
TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);
struct GLComponents
{

View File

@ -149,10 +149,10 @@ IsSubFunc(WebGLTexImageFunc func)
* returns true is target is a texture cube map target.
*/
static bool
IsTexImageCubemapTarget(GLenum target)
IsTexImageCubemapTarget(GLenum texImageTarget)
{
return (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
return (texImageTarget >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
texImageTarget <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
}
/*
@ -712,7 +712,7 @@ WebGLContext::ValidateTexImageType(GLenum type, WebGLTexImageFunc func)
*/
// TODO: WebGL 2
bool
WebGLContext::ValidateCompTexImageSize(GLenum target, GLint level, GLenum format,
WebGLContext::ValidateCompTexImageSize(GLint level, GLenum format,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLsizei levelWidth, GLsizei levelHeight,
@ -884,7 +884,7 @@ WebGLContext::ValidateCompTexImageDataSize(GLint level, GLenum format,
* Target and level must have been validated before calling.
*/
bool
WebGLContext::ValidateTexImageSize(GLenum target, GLint level,
WebGLContext::ValidateTexImageSize(TexImageTarget texImageTarget, GLint level,
GLint width, GLint height, GLint depth,
WebGLTexImageFunc func)
{
@ -903,8 +903,8 @@ WebGLContext::ValidateTexImageSize(GLenum target, GLint level,
if (level > 31)
level = 31;
const GLuint maxTexImageSize = MaxTextureSizeForTarget(target) >> level;
const bool isCubemapTarget = IsTexImageCubemapTarget(target);
const GLuint maxTexImageSize = MaxTextureSizeForTarget(TexImageTargetToTexTarget(texImageTarget)) >> level;
const bool isCubemapTarget = IsTexImageCubemapTarget(texImageTarget.get());
const bool isSub = IsSubFunc(func);
if (!isSub && isCubemapTarget && (width != height)) {
@ -918,7 +918,7 @@ WebGLContext::ValidateTexImageSize(GLenum target, GLint level,
return false;
}
if (target == LOCAL_GL_TEXTURE_2D || isCubemapTarget)
if (texImageTarget == LOCAL_GL_TEXTURE_2D || isCubemapTarget)
{
/* GL ES Version 2.0.25 - 3.7.1 Texture Image Specification
* "If wt and ht are the specified image width and height,
@ -978,7 +978,7 @@ WebGLContext::ValidateTexImageSize(GLenum target, GLint level,
}
// TODO: WebGL 2
if (target == LOCAL_GL_TEXTURE_3D) {
if (texImageTarget == LOCAL_GL_TEXTURE_3D) {
if (depth < 0) {
ErrorInvalidValue("%s: depth must be >= 0", InfoFrom(func));
return false;
@ -1308,7 +1308,7 @@ WebGLContext::ValidateCopyTexImage(GLenum format, WebGLTexImageFunc func)
*/
// TODO: Texture dims is here for future expansion in WebGL 2.0
bool
WebGLContext::ValidateTexImage(GLuint dims, GLenum target,
WebGLContext::ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
GLint level, GLint internalFormat,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
@ -1317,10 +1317,6 @@ WebGLContext::ValidateTexImage(GLuint dims, GLenum target,
{
const char* info = InfoFrom(func);
/* Check target */
if (!ValidateTexImageTarget(dims, target, func))
return false;
/* Check level */
if (level < 0) {
ErrorInvalidValue("%s: level must be >= 0", info);
@ -1357,7 +1353,7 @@ WebGLContext::ValidateTexImage(GLuint dims, GLenum target,
}
/* Check texture image size */
if (!ValidateTexImageSize(target, level, width, height, 0, func))
if (!ValidateTexImageSize(texImageTarget, level, width, height, 0, func))
return false;
/* 5.14.8 Texture objects - WebGL Spec.
@ -1365,21 +1361,21 @@ WebGLContext::ValidateTexImage(GLuint dims, GLenum target,
* WebGLTexture bound (see above), an INVALID_OPERATION error
* is generated."
*/
WebGLTexture* tex = activeBoundTextureForTexImageTarget(target);
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
if (!tex) {
ErrorInvalidOperation("%s: no texture is bound to target %s",
info, WebGLContext::EnumName(target));
info, WebGLContext::EnumName(texImageTarget.get()));
return false;
}
if (IsSubFunc(func)) {
if (!tex->HasImageInfoAt(target, level)) {
if (!tex->HasImageInfoAt(texImageTarget, level)) {
ErrorInvalidOperation("%s: no texture image previously defined for target %s at level %d",
info, WebGLContext::EnumName(target), level);
info, WebGLContext::EnumName(texImageTarget.get()), level);
return false;
}
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(target, level);
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
if (!ValidateTexSubImageSize(xoffset, yoffset, zoffset,
width, height, depth,
imageInfo.Width(), imageInfo.Height(), 0,
@ -1401,7 +1397,7 @@ WebGLContext::ValidateTexImage(GLuint dims, GLenum target,
}
/* Additional checks for depth textures */
if (target != LOCAL_GL_TEXTURE_2D &&
if (texImageTarget != LOCAL_GL_TEXTURE_2D &&
(format == LOCAL_GL_DEPTH_COMPONENT ||
format == LOCAL_GL_DEPTH_STENCIL))
{

View File

@ -24,7 +24,7 @@ WebGLFramebuffer::WrapObject(JSContext* cx)
}
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context)
: WebGLBindableName()
: WebGLBindableName<GLenum>()
, WebGLContextBoundObject(context)
, mStatus(0)
, mDepthAttachment(LOCAL_GL_DEPTH_ATTACHMENT)
@ -42,6 +42,7 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context)
WebGLFramebuffer::Attachment::Attachment(GLenum aAttachmentPoint)
: mAttachmentPoint(aAttachmentPoint)
, mTexImageTarget(LOCAL_GL_NONE)
, mNeedsFinalize(false)
{}
@ -84,9 +85,9 @@ WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::Attachment& att
if (attachment.Texture()) {
const WebGLTexture& tex = *attachment.Texture();
MOZ_ASSERT(tex.HasImageInfoAt(tex.Target(), 0));
MOZ_ASSERT(tex.HasImageInfoAt(attachment.ImageTarget(), 0));
const WebGLTexture::ImageInfo& imgInfo = tex.ImageInfoAt(tex.Target(), 0);
const WebGLTexture::ImageInfo& imgInfo = tex.ImageInfoAt(attachment.ImageTarget(), 0);
return imgInfo.WebGLFormat();
}
@ -130,7 +131,7 @@ WebGLFramebuffer::Attachment::IsReadableFloat() const
}
void
WebGLFramebuffer::Attachment::SetTexImage(WebGLTexture* tex, GLenum target, GLint level)
WebGLFramebuffer::Attachment::SetTexImage(WebGLTexture* tex, TexImageTarget target, GLint level)
{
mTexturePtr = tex;
mRenderbufferPtr = nullptr;
@ -395,14 +396,18 @@ WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, GLenum attachmen
if (Texture()) {
MOZ_ASSERT(gl == Texture()->Context()->gl);
const GLenum imageTarget = ImageTarget().get();
const GLint mipLevel = MipLevel();
const GLuint glName = Texture()->GLName();
if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
TexImageTarget(), Texture()->GLName(), TexImageLevel());
imageTarget, glName, mipLevel);
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
TexImageTarget(), Texture()->GLName(), TexImageLevel());
imageTarget, glName, mipLevel);
} else {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
TexImageTarget(), Texture()->GLName(), TexImageLevel());
imageTarget, glName, mipLevel);
}
return;
}
@ -500,7 +505,7 @@ WebGLFramebuffer::FramebufferRenderbuffer(GLenum target,
void
WebGLFramebuffer::FramebufferTexture2D(GLenum target,
GLenum attachment,
GLenum textarget,
TexImageTarget texImageTarget,
WebGLTexture* wtex,
GLint level)
{
@ -512,16 +517,9 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum target,
if (target != LOCAL_GL_FRAMEBUFFER)
return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: target", target);
if (textarget != LOCAL_GL_TEXTURE_2D &&
(textarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
textarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
{
return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: invalid texture target", textarget);
}
if (wtex) {
bool isTexture2D = wtex->Target() == LOCAL_GL_TEXTURE_2D;
bool isTexTarget2D = textarget == LOCAL_GL_TEXTURE_2D;
bool isTexTarget2D = texImageTarget == LOCAL_GL_TEXTURE_2D;
if (isTexture2D != isTexTarget2D) {
return mContext->ErrorInvalidOperation("framebufferTexture2D: mismatched texture and texture target");
}
@ -555,7 +553,7 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum target,
if (wtex)
wtex->AttachTo(this, attachment);
a->SetTexImage(wtex, textarget, level);
a->SetTexImage(wtex, texImageTarget, level);
}
WebGLFramebuffer::Attachment*

View File

@ -8,6 +8,7 @@
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
#include "nsWrapperCache.h"
@ -24,7 +25,7 @@ namespace gl {
class WebGLFramebuffer MOZ_FINAL
: public nsWrapperCache
, public WebGLBindableName
, public WebGLBindableName<GLenum>
, public WebGLRefCountedObject<WebGLFramebuffer>
, public LinkedListElement<WebGLFramebuffer>
, public WebGLContextBoundObject
@ -41,7 +42,7 @@ public:
WebGLRefPtr<WebGLTexture> mTexturePtr;
WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
GLenum mAttachmentPoint;
GLenum mTexImageTarget;
TexImageTarget mTexImageTarget;
GLint mTexImageLevel;
mutable bool mNeedsFinalize;
@ -57,7 +58,7 @@ public:
bool HasAlpha() const;
bool IsReadableFloat() const;
void SetTexImage(WebGLTexture* tex, GLenum target, GLint level);
void SetTexImage(WebGLTexture* tex, TexImageTarget target, GLint level);
void SetRenderbuffer(WebGLRenderbuffer* rb);
const WebGLTexture* Texture() const {
@ -72,10 +73,10 @@ public:
WebGLRenderbuffer* Renderbuffer() {
return mRenderbufferPtr;
}
GLenum TexImageTarget() const {
TexImageTarget ImageTarget() const {
return mTexImageTarget;
}
GLint TexImageLevel() const {
GLint MipLevel() const {
return mTexImageLevel;
}
@ -101,7 +102,7 @@ public:
void FramebufferTexture2D(GLenum target,
GLenum attachment,
GLenum textarget,
TexImageTarget texImageTarget,
WebGLTexture* wtex,
GLint level);

View File

@ -43,7 +43,7 @@ WebGLRenderbuffer::WrapObject(JSContext *cx) {
}
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext *context)
: WebGLBindableName()
: WebGLBindableName<GLenum>()
, WebGLContextBoundObject(context)
, mPrimaryRB(0)
, mSecondaryRB(0)

View File

@ -18,7 +18,7 @@ namespace mozilla {
class WebGLRenderbuffer MOZ_FINAL
: public nsWrapperCache
, public WebGLBindableName
, public WebGLBindableName<GLenum>
, public WebGLRefCountedObject<WebGLRenderbuffer>
, public LinkedListElement<WebGLRenderbuffer>
, public WebGLRectangleObject

View File

@ -16,7 +16,7 @@
namespace mozilla {
class WebGLSampler MOZ_FINAL
: public WebGLBindableName
: public WebGLBindableName<GLenum>
, public nsWrapperCache
, public WebGLRefCountedObject<WebGLSampler>
, public LinkedListElement<WebGLSampler>

View File

@ -0,0 +1,152 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef WEBGLSTRONGTYPES_H_
#define WEBGLSTRONGTYPES_H_
#include "GLDefs.h"
#include "mozilla/Assertions.h"
#include "mozilla/ArrayUtils.h"
// Usage:
// ===========
//
// To create a new type from a set of GLenums do the following:
//
// STRONG_GLENUM_BEGIN(TypeName)
// Enum1,
// Enum2,
// ...
// STRONG_GLENUM_END()
//
// where TypeName is the name you want to give the type. Now simply use TypeName
// instead of GLenum.
//
// ~~~~~~~~~~~~~~~~
// Important Notes:
// ~~~~~~~~~~~~~~~~
//
// Boolean operators (==, !=) are provided in an effort to prevent some mistakes
// when using constants. For example we want to make sure that GL_ENUM_X is
// a valid value for the type in code like:
//
// if (myNewType == LOCAL_GL_SOME_ENUM)
// ...
//
// The operators will assert that LOCAL_GL_SOME_ENUM is a value that myNewType
// can have.
//
// ----
//
// A get() method is provided to allow access to the underlying GLenum. This
// method should ideally only be called when passing parameters to the gl->fXXXX
// functions, and be used very minimally everywhere else.
//
// Definitely XXX - DO NOT DO - XXX:
//
// if (myNewType.get() == LOCAL_GL_SOME_ENUM)
// ...
//
// As that undermines the debug checks that were implemented in the ==, and !=
// operators. If you see code like this it should be treated with suspicion.
//
// Background:
// ===========
//
// This macro is the first step in an effort to make the WebGL code safer.
// Many of the different functions take GLenum as their parameter which leads
// to bugs because of subtle differences in the enums purpose. For example there
// are two types of 'texture targets'. One is the texture binding locations:
//
// GL_TEXTURE_2D
// GL_TEXTURE_CUBE_MAP
//
// Yet, this is not the same as texture image targets:
//
// GL_TEXTURE_2D
// GL_TEXTURE_CUBE_MAP_POSITIVE_X
// GL_TEXTURE_CUBE_MAP_NEGATIVE_X
// GL_TEXTURE_CUBE_MAP_POSITIVE_Y
// ...
//
// This subtle distinction has already led to many bugs in the texture code
// because of invalid assumptions about what type goes where. The macro below
// is an attempt at fixing this by providing a small wrapper around GLenum that
// validates its values.
//
#ifdef DEBUG
template<size_t N>
static bool
IsValueInArr(GLenum value, const GLenum (&arr)[N])
{
for (size_t i = 0; i < N; ++i) {
if (value == arr[i])
return true;
}
return false;
}
#endif
#define STRONG_GLENUM_BEGIN(NAME) \
class NAME { \
private: \
GLenum mValue; \
public: \
MOZ_CONSTEXPR NAME(const NAME& other) \
: mValue(other.mValue) { } \
\
bool operator==(const NAME& other) const { \
return mValue == other.mValue; \
} \
\
bool operator!=(const NAME& other) const { \
return mValue != other.mValue; \
} \
\
GLenum get() const { \
MOZ_ASSERT(mValue != LOCAL_GL_NONE); \
return mValue; \
} \
\
NAME(GLenum val) \
: mValue(val) \
{ \
const GLenum validValues[] = {
#define STRONG_GLENUM_END() \
}; \
(void)validValues; \
MOZ_ASSERT(IsValueInArr(mValue, validValues)); \
} \
};
/******************************************************************************
* Add your types after this comment
*****************************************************************************/
STRONG_GLENUM_BEGIN(TexImageTarget)
LOCAL_GL_NONE,
LOCAL_GL_TEXTURE_2D,
LOCAL_GL_TEXTURE_3D,
LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X,
LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
STRONG_GLENUM_END()
STRONG_GLENUM_BEGIN(TexTarget)
LOCAL_GL_NONE,
LOCAL_GL_TEXTURE_2D,
LOCAL_GL_TEXTURE_3D,
LOCAL_GL_TEXTURE_CUBE_MAP,
STRONG_GLENUM_END()
#endif

View File

@ -23,7 +23,7 @@ WebGLTexture::WrapObject(JSContext *cx) {
}
WebGLTexture::WebGLTexture(WebGLContext *context)
: WebGLBindableName()
: WebGLBindableName<TexTarget>()
, WebGLContextBoundObject(context)
, mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR)
, mMagFilter(LOCAL_GL_LINEAR)
@ -76,7 +76,7 @@ WebGLTexture::MemoryUsage() const {
}
bool
WebGLTexture::DoesTexture2DMipmapHaveAllLevelsConsistentlyDefined(GLenum texImageTarget) const {
WebGLTexture::DoesTexture2DMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImageTarget) const {
if (mHaveGeneratedMipmap)
return true;
@ -103,15 +103,15 @@ WebGLTexture::DoesTexture2DMipmapHaveAllLevelsConsistentlyDefined(GLenum texImag
}
void
WebGLTexture::Bind(GLenum aTarget) {
WebGLTexture::Bind(TexTarget aTexTarget) {
// this function should only be called by bindTexture().
// it assumes that the GL context is already current.
bool firstTimeThisTextureIsBound = !HasEverBeenBound();
if (firstTimeThisTextureIsBound) {
BindTo(aTarget);
} else if (aTarget != Target()) {
BindTo(aTexTarget);
} else if (aTexTarget != Target()) {
mContext->ErrorInvalidOperation("bindTexture: this texture has already been bound to a different target");
// very important to return here before modifying texture state! This was the place when I lost a whole day figuring
// very strange 'invalid write' crashes.
@ -119,12 +119,11 @@ WebGLTexture::Bind(GLenum aTarget) {
}
GLuint name = GLName();
GLenum target = Target();
mContext->gl->fBindTexture(target, name);
mContext->gl->fBindTexture(aTexTarget.get(), name);
if (firstTimeThisTextureIsBound) {
mFacesCount = (mTarget == LOCAL_GL_TEXTURE_2D) ? 1 : 6;
mFacesCount = (aTexTarget == LOCAL_GL_TEXTURE_2D) ? 1 : 6;
EnsureMaxLevelWithCustomImagesAtLeast(0);
SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
@ -132,12 +131,12 @@ WebGLTexture::Bind(GLenum aTarget) {
// present in GLES 2, but is present in GL and it seems as if for cube maps
// we need to set it to GL_CLAMP_TO_EDGE to get the expected GLES behavior.
if (mTarget == LOCAL_GL_TEXTURE_CUBE_MAP && !mContext->gl->IsGLES())
mContext->gl->fTexParameteri(mTarget, LOCAL_GL_TEXTURE_WRAP_R, LOCAL_GL_CLAMP_TO_EDGE);
mContext->gl->fTexParameteri(aTexTarget.get(), LOCAL_GL_TEXTURE_WRAP_R, LOCAL_GL_CLAMP_TO_EDGE);
}
}
void
WebGLTexture::SetImageInfo(GLenum aTexImageTarget, GLint aLevel,
WebGLTexture::SetImageInfo(TexImageTarget aTexImageTarget, GLint aLevel,
GLsizei aWidth, GLsizei aHeight,
GLenum aFormat, GLenum aType, WebGLImageDataStatus aStatus)
{
@ -227,13 +226,11 @@ WebGLTexture::IsCubeComplete() const {
return AreAllLevel0ImageInfosEqual();
}
static GLenum
static TexImageTarget
GLCubeMapFaceById(int id)
{
GLenum result = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + id;
MOZ_ASSERT(result >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
result <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
return result;
// Correctness is checked by the constructor for TexImageTarget
return TexImageTarget(LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + id);
}
bool
@ -241,7 +238,7 @@ WebGLTexture::IsMipmapCubeComplete() const {
if (!IsCubeComplete()) // in particular, this checks that this is a cube map
return false;
for (int i = 0; i < 6; i++) {
GLenum face = GLCubeMapFaceById(i);
const TexImageTarget face = GLCubeMapFaceById(i);
if (!DoesTexture2DMipmapHaveAllLevelsConsistentlyDefined(face))
return false;
}
@ -279,7 +276,7 @@ WebGLTexture::ResolvedFakeBlackStatus() {
("%s is a 2D texture, with a minification filter requiring a mipmap, "
"and is not mipmap complete (as defined in section 3.7.10).", msg_rendering_as_black);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
} else if (!ImageInfoAt(mTarget, 0).IsPowerOfTwo()) {
} else if (!ImageInfoBase().IsPowerOfTwo()) {
mContext->GenerateWarning
("%s is a 2D texture, with a minification filter requiring a mipmap, "
"and either its width or height is not a power of two.", msg_rendering_as_black);
@ -288,12 +285,12 @@ WebGLTexture::ResolvedFakeBlackStatus() {
}
else // no mipmap required
{
if (!ImageInfoAt(mTarget, 0).IsPositive()) {
if (!ImageInfoBase().IsPositive()) {
mContext->GenerateWarning
("%s is a 2D texture and its width or height is equal to zero.",
msg_rendering_as_black);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
} else if (!AreBothWrapModesClampToEdge() && !ImageInfoAt(mTarget, 0).IsPowerOfTwo()) {
} else if (!AreBothWrapModesClampToEdge() && !ImageInfoBase().IsPowerOfTwo()) {
mContext->GenerateWarning
("%s is a 2D texture, with a minification filter not requiring a mipmap, "
"with its width or height not a power of two, and with a wrap mode "
@ -411,9 +408,9 @@ WebGLTexture::ResolvedFakeBlackStatus() {
// glTexImage2D is able to upload data to images.
for (size_t level = 0; level <= mMaxLevelWithCustomImages; ++level) {
for (size_t face = 0; face < mFacesCount; ++face) {
GLenum imageTarget = mTarget == LOCAL_GL_TEXTURE_2D
? LOCAL_GL_TEXTURE_2D
: LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
TexImageTarget imageTarget = mTarget == LOCAL_GL_TEXTURE_2D
? LOCAL_GL_TEXTURE_2D
: LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
const ImageInfo& imageInfo = ImageInfoAt(imageTarget, level);
if (imageInfo.mImageDataStatus == WebGLImageDataStatus::UninitializedImageData) {
DoDeferredImageInitialization(imageTarget, level);
@ -461,7 +458,7 @@ ClearByMask(WebGLContext* context, GLbitfield mask)
// `mask` from glClear.
static bool
ClearWithTempFB(WebGLContext* context, GLuint tex,
GLenum texImageTarget, GLint level,
TexImageTarget texImageTarget, GLint level,
GLenum baseInternalFormat,
GLsizei width, GLsizei height)
{
@ -485,22 +482,22 @@ ClearWithTempFB(WebGLContext* context, GLuint tex,
case LOCAL_GL_BGRA:
mask = LOCAL_GL_COLOR_BUFFER_BIT;
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
texImageTarget, tex, level);
texImageTarget.get(), tex, level);
break;
case LOCAL_GL_DEPTH_COMPONENT:
mask = LOCAL_GL_DEPTH_BUFFER_BIT;
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
texImageTarget, tex, level);
texImageTarget.get(), tex, level);
break;
case LOCAL_GL_DEPTH_STENCIL:
mask = LOCAL_GL_DEPTH_BUFFER_BIT |
LOCAL_GL_STENCIL_BUFFER_BIT;
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
texImageTarget, tex, level);
texImageTarget.get(), tex, level);
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
texImageTarget, tex, level);
texImageTarget.get(), tex, level);
break;
default:
@ -537,7 +534,7 @@ ClearWithTempFB(WebGLContext* context, GLuint tex,
void
WebGLTexture::DoDeferredImageInitialization(GLenum imageTarget, GLint level)
WebGLTexture::DoDeferredImageInitialization(TexImageTarget imageTarget, GLint level)
{
const ImageInfo& imageInfo = ImageInfoAt(imageTarget, level);
MOZ_ASSERT(imageInfo.mImageDataStatus == WebGLImageDataStatus::UninitializedImageData);
@ -558,7 +555,7 @@ WebGLTexture::DoDeferredImageInitialization(GLenum imageTarget, GLint level)
}
// That didn't work. Try uploading zeros then.
gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget);
gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget.get());
uint32_t texelsize = WebGLTexelConversions::TexelBytesForFormat(texelformat);
CheckedUint32 checked_byteLength
@ -578,7 +575,7 @@ WebGLTexture::DoDeferredImageInitialization(GLenum imageTarget, GLint level)
DriverFormatsFromFormatAndType(gl, format, type, &driverInternalFormat, &driverFormat);
mContext->GetAndFlushUnderlyingGLErrors();
gl->fTexImage2D(imageTarget, level, driverInternalFormat,
gl->fTexImage2D(imageTarget.get(), level, driverInternalFormat,
imageInfo.mWidth, imageInfo.mHeight,
0, driverFormat, driverType,
zeros);

View File

@ -9,6 +9,7 @@
#include "WebGLBindableName.h"
#include "WebGLFramebufferAttachable.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
#include "nsWrapperCache.h"
@ -28,7 +29,7 @@ inline bool is_pot_assuming_nonnegative(GLsizei x)
// WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
class WebGLTexture MOZ_FINAL
: public nsWrapperCache
, public WebGLBindableName
, public WebGLBindableName<TexTarget>
, public WebGLRefCountedObject<WebGLTexture>
, public LinkedListElement<WebGLTexture>
, public WebGLContextBoundObject
@ -129,13 +130,11 @@ public:
};
private:
static size_t FaceForTarget(GLenum target) {
// Call this out explicitly:
MOZ_ASSERT(target != LOCAL_GL_TEXTURE_CUBE_MAP);
MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D ||
(target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z));
return target == LOCAL_GL_TEXTURE_2D ? 0 : target - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
static size_t FaceForTarget(TexImageTarget texImageTarget) {
if (texImageTarget == LOCAL_GL_TEXTURE_2D)
return 0;
return texImageTarget.get() - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
}
ImageInfo& ImageInfoAtFace(size_t face, GLint level) {
@ -152,20 +151,16 @@ private:
}
public:
ImageInfo& ImageInfoAt(GLenum imageTarget, GLint level) {
MOZ_ASSERT(imageTarget);
ImageInfo& ImageInfoAt(TexImageTarget imageTarget, GLint level) {
size_t face = FaceForTarget(imageTarget);
return ImageInfoAtFace(face, level);
}
const ImageInfo& ImageInfoAt(GLenum imageTarget, GLint level) const {
const ImageInfo& ImageInfoAt(TexImageTarget imageTarget, GLint level) const {
return const_cast<WebGLTexture*>(this)->ImageInfoAt(imageTarget, level);
}
bool HasImageInfoAt(GLenum imageTarget, GLint level) const {
MOZ_ASSERT(imageTarget);
bool HasImageInfoAt(TexImageTarget imageTarget, GLint level) const {
size_t face = FaceForTarget(imageTarget);
CheckedUint32 checked_index = CheckedUint32(level) * mFacesCount + face;
return checked_index.isValid() &&
@ -183,7 +178,7 @@ public:
int64_t MemoryUsage() const;
void SetImageDataStatus(GLenum imageTarget, GLint level, WebGLImageDataStatus newStatus) {
void SetImageDataStatus(TexImageTarget imageTarget, GLint level, WebGLImageDataStatus newStatus) {
MOZ_ASSERT(HasImageInfoAt(imageTarget, level));
ImageInfo& imageInfo = ImageInfoAt(imageTarget, level);
// there is no way to go from having image data to not having any
@ -195,7 +190,7 @@ public:
imageInfo.mImageDataStatus = newStatus;
}
void DoDeferredImageInitialization(GLenum imageTarget, GLint level);
void DoDeferredImageInitialization(TexImageTarget imageTarget, GLint level);
protected:
@ -222,13 +217,13 @@ protected:
return mWrapS == LOCAL_GL_CLAMP_TO_EDGE && mWrapT == LOCAL_GL_CLAMP_TO_EDGE;
}
bool DoesTexture2DMipmapHaveAllLevelsConsistentlyDefined(GLenum texImageTarget) const;
bool DoesTexture2DMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImageTarget) const;
public:
void Bind(GLenum aTarget);
void Bind(TexTarget aTexTarget);
void SetImageInfo(GLenum aTarget, GLint aLevel,
void SetImageInfo(TexImageTarget aTarget, GLint aLevel,
GLsizei aWidth, GLsizei aHeight,
GLenum aFormat, GLenum aType, WebGLImageDataStatus aStatus);

View File

@ -16,7 +16,7 @@
namespace mozilla {
class WebGLTransformFeedback MOZ_FINAL
: public WebGLBindableName
: public WebGLBindableName<GLenum>
, public nsWrapperCache
, public WebGLRefCountedObject<WebGLTransformFeedback>
, public LinkedListElement<WebGLTransformFeedback>

View File

@ -20,7 +20,7 @@ WebGLVertexArray::WrapObject(JSContext *cx) {
}
WebGLVertexArray::WebGLVertexArray(WebGLContext* context)
: WebGLBindableName()
: WebGLBindableName<GLenum>()
, WebGLContextBoundObject(context)
{
SetIsDOMBinding();

View File

@ -21,7 +21,7 @@ class WebGLVertexArrayFake;
class WebGLVertexArray
: public nsWrapperCache
, public WebGLBindableName
, public WebGLBindableName<GLenum>
, public WebGLRefCountedObject<WebGLVertexArray>
, public LinkedListElement<WebGLVertexArray>
, public WebGLContextBoundObject

View File

@ -53,7 +53,6 @@ UNIFIED_SOURCES += [
'WebGL2ContextUniforms.cpp',
'WebGL2ContextVAOs.cpp',
'WebGLActiveInfo.cpp',
'WebGLBindableName.cpp',
'WebGLBuffer.cpp',
'WebGLContext.cpp',
'WebGLContextAsyncQueries.cpp',