Skip to content

Commit

Permalink
Bug 1063053 - Add stronger types to WebGL texture code for better deb…
Browse files Browse the repository at this point in the history
…ug/compile time checking. r=jgilbert,kamidphish
  • Loading branch information
waltermoz committed Sep 18, 2014
1 parent ea42260 commit c73cf2e
Show file tree
Hide file tree
Showing 24 changed files with 456 additions and 278 deletions.
27 changes: 0 additions & 27 deletions dom/canvas/WebGLBindableName.cpp

This file was deleted.

32 changes: 27 additions & 5 deletions dom/canvas/WebGLBindableName.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,49 @@

#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:

//! Called after mTarget has been changed by BindTo(target).
virtual void OnTargetChanged() {}

GLuint mGLName;
GLenum mTarget;
T mTarget;
};

} // namespace mozilla
Expand Down
2 changes: 1 addition & 1 deletion dom/canvas/WebGLBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
using namespace mozilla;

WebGLBuffer::WebGLBuffer(WebGLContext *context)
: WebGLBindableName()
: WebGLBindableName<GLenum>()
, WebGLContextBoundObject(context)
, mByteLength(0)
{
Expand Down
2 changes: 1 addition & 1 deletion dom/canvas/WebGLBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions dom/canvas/WebGLContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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));
Expand Down
59 changes: 29 additions & 30 deletions dom/canvas/WebGLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "WebGLActiveInfo.h"
#include "WebGLObjectModel.h"
#include "WebGLRenderbuffer.h"
#include "WebGLStrongTypes.h"
#include <stdarg.h>

#include "nsTArray.h"
Expand Down Expand Up @@ -123,7 +124,7 @@ struct WebGLContextOptions {
};

// From WebGLContextUtils
GLenum TexImageTargetToTexTarget(GLenum texImageTarget);
TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);

class WebGLContext :
public nsIDOMWebGLRenderingContext,
Expand Down Expand Up @@ -224,8 +225,7 @@ class WebGLContext :

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];
}
Expand All @@ -234,8 +234,8 @@ class WebGLContext :
* 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);
}

Expand Down Expand Up @@ -465,21 +465,24 @@ class WebGLContext :
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;
Expand All @@ -491,7 +494,7 @@ class WebGLContext :
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");
Expand Down Expand Up @@ -536,16 +539,17 @@ class WebGLContext :
// 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;
Expand Down Expand Up @@ -1088,7 +1092,7 @@ class WebGLContext :
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,
Expand All @@ -1098,15 +1102,15 @@ class WebGLContext :
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,
GLsizei width, GLsizei height, GLsizei depth,
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,
Expand All @@ -1124,13 +1128,13 @@ class WebGLContext :
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,
Expand Down Expand Up @@ -1168,7 +1172,7 @@ class WebGLContext :
RefPtr<gfx::DataSourceSurface>& imageOut,
WebGLTexelFormat *format);

void CopyTexSubImage2D_base(GLenum target,
void CopyTexSubImage2D_base(TexImageTarget texImageTarget,
GLint level,
GLenum internalformat,
GLint xoffset,
Expand Down Expand Up @@ -1200,17 +1204,12 @@ class WebGLContext :
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;
}

Expand All @@ -1222,7 +1221,7 @@ class WebGLContext :
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,
Expand Down
Loading

0 comments on commit c73cf2e

Please sign in to comment.