Bug 1048720 - [WebGL2] Implement WebGL2Sampler. r=jgilbert

--HG--
extra : source : 361e31698c4a6074f3195502b468502d38aa82e8
This commit is contained in:
Dan Glastonbury 2014-10-27 09:40:37 +10:00
parent 826712af6b
commit f73cc0ce95
10 changed files with 465 additions and 35 deletions

View File

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGL2Context.h"
#include "WebGLSampler.h"
#include "GLContext.h"
using namespace mozilla;
@ -12,67 +13,206 @@ using namespace mozilla::dom;
already_AddRefed<WebGLSampler>
WebGL2Context::CreateSampler()
{
MOZ_CRASH("Not Implemented.");
return nullptr;
if (IsContextLost())
return nullptr;
GLuint sampler;
MakeContextCurrent();
gl->fGenSamplers(1, &sampler);
nsRefPtr<WebGLSampler> globj = new WebGLSampler(this, sampler);
return globj.forget();
}
void
WebGL2Context::DeleteSampler(WebGLSampler* sampler)
{
MOZ_CRASH("Not Implemented.");
if (IsContextLost())
return;
if (!ValidateObjectAllowDeletedOrNull("deleteSampler", sampler))
return;
if (!sampler || sampler->IsDeleted())
return;
sampler->RequestDelete();
}
bool
WebGL2Context::IsSampler(WebGLSampler* sampler)
{
MOZ_CRASH("Not Implemented.");
return false;
if (IsContextLost())
return false;
if (!sampler)
return false;
if (!ValidateObjectAllowDeleted("isSampler", sampler))
return false;
if (sampler->IsDeleted())
return false;
return !sampler->HasEverBeenBound();
}
void
WebGL2Context::BindSampler(GLuint unit, WebGLSampler* sampler)
{
MOZ_CRASH("Not Implemented.");
if (IsContextLost())
return;
if (!ValidateObjectAllowDeletedOrNull("bindSampler", sampler))
return;
if (GLint(unit) >= mGLMaxTextureUnits)
return ErrorInvalidValue("bindSampler: unit must be < %d", mGLMaxTextureUnits);
if (sampler && sampler->IsDeleted())
return ErrorInvalidOperation("bindSampler: binding deleted sampler");
WebGLContextUnchecked::BindSampler(unit, sampler);
}
void
WebGL2Context::SamplerParameteri(WebGLSampler* sampler, GLenum pname, GLint param)
{
MOZ_CRASH("Not Implemented.");
if (IsContextLost())
return;
if (!sampler || sampler->IsDeleted())
return ErrorInvalidOperation("samplerParameteri: invalid sampler");
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param), "samplerParameteri"))
return;
WebGLContextUnchecked::SamplerParameteri(sampler, pname, param);
}
void
WebGL2Context::SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const dom::Int32Array& param)
{
MOZ_CRASH("Not Implemented.");
if (IsContextLost())
return;
if (!sampler || sampler->IsDeleted())
return ErrorInvalidOperation("samplerParameteriv: invalid sampler");
param.ComputeLengthAndData();
if (param.Length() < 1)
return /* TODO(djg): Error message */;
/* TODO(djg): All of these calls in ES3 only take 1 param */
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param.Data()[0]), "samplerParameteriv"))
return;
WebGLContextUnchecked::SamplerParameteriv(sampler, pname, param.Data());
}
void
WebGL2Context::SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const dom::Sequence<GLint>& param)
{
MOZ_CRASH("Not Implemented.");
if (IsContextLost())
return;
if (!sampler || sampler->IsDeleted())
return ErrorInvalidOperation("samplerParameteriv: invalid sampler");
if (param.Length() < 1)
return /* TODO(djg): Error message */;
/* TODO(djg): All of these calls in ES3 only take 1 param */
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param[0]), "samplerParameteriv"))
return;
WebGLContextUnchecked::SamplerParameteriv(sampler, pname, param.Elements());
}
void
WebGL2Context::SamplerParameterf(WebGLSampler* sampler, GLenum pname, GLfloat param)
{
MOZ_CRASH("Not Implemented.");
if (IsContextLost())
return;
if (!sampler || sampler->IsDeleted())
return ErrorInvalidOperation("samplerParameterf: invalid sampler");
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param), "samplerParameterf"))
return;
WebGLContextUnchecked::SamplerParameterf(sampler, pname, param);
}
void
WebGL2Context::SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const dom::Float32Array& param)
{
MOZ_CRASH("Not Implemented.");
if (IsContextLost())
return;
if (!sampler || sampler->IsDeleted())
return ErrorInvalidOperation("samplerParameterfv: invalid sampler");
param.ComputeLengthAndData();
if (param.Length() < 1)
return /* TODO(djg): Error message */;
/* TODO(djg): All of these calls in ES3 only take 1 param */
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param.Data()[0]), "samplerParameterfv"))
return;
WebGLContextUnchecked::SamplerParameterfv(sampler, pname, param.Data());
}
void
WebGL2Context::SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const dom::Sequence<GLfloat>& param)
{
MOZ_CRASH("Not Implemented.");
if (IsContextLost())
return;
if (!sampler || sampler->IsDeleted())
return ErrorInvalidOperation("samplerParameterfv: invalid sampler");
if (param.Length() < 1)
return /* TODO(djg): Error message */;
/* TODO(djg): All of these calls in ES3 only take 1 param */
if (!ValidateSamplerParameterParams(pname, WebGLIntOrFloat(param[0]), "samplerParameterfv"))
return;
WebGLContextUnchecked::SamplerParameterfv(sampler, pname, param.Elements());
}
void
WebGL2Context::GetSamplerParameter(JSContext*, WebGLSampler* sampler, GLenum pname, JS::MutableHandleValue retval)
{
MOZ_CRASH("Not Implemented.");
if (IsContextLost())
return;
if (!sampler || sampler->IsDeleted())
return ErrorInvalidOperation("getSamplerParameter: invalid sampler");
if (!ValidateSamplerParameterName(pname, "getSamplerParameter"))
return;
retval.set(JS::NullValue());
switch (pname) {
case LOCAL_GL_TEXTURE_MIN_FILTER:
case LOCAL_GL_TEXTURE_MAG_FILTER:
case LOCAL_GL_TEXTURE_WRAP_S:
case LOCAL_GL_TEXTURE_WRAP_T:
case LOCAL_GL_TEXTURE_WRAP_R:
case LOCAL_GL_TEXTURE_COMPARE_MODE:
case LOCAL_GL_TEXTURE_COMPARE_FUNC:
retval.set(JS::Int32Value(
WebGLContextUnchecked::GetSamplerParameteriv(sampler, pname)));
return;
case LOCAL_GL_TEXTURE_MIN_LOD:
case LOCAL_GL_TEXTURE_MAX_LOD:
retval.set(JS::Float32Value(
WebGLContextUnchecked::GetSamplerParameterfv(sampler, pname)));
return;
}
}

View File

@ -7,15 +7,16 @@
#include "WebGLContextLossHandler.h"
#include "WebGL1Context.h"
#include "WebGLObjectModel.h"
#include "WebGLExtensions.h"
#include "WebGLContextUtils.h"
#include "WebGLBuffer.h"
#include "WebGLVertexAttribData.h"
#include "WebGLMemoryTracker.h"
#include "WebGLContextUtils.h"
#include "WebGLExtensions.h"
#include "WebGLFramebuffer.h"
#include "WebGLVertexArray.h"
#include "WebGLMemoryTracker.h"
#include "WebGLObjectModel.h"
#include "WebGLQuery.h"
#include "WebGLSampler.h"
#include "WebGLVertexArray.h"
#include "WebGLVertexAttribData.h"
#include "GLBlitHelper.h"
#include "AccessCheck.h"
@ -226,7 +227,7 @@ WebGLContextOptions::WebGLContextOptions()
}
WebGLContext::WebGLContext()
: gl(nullptr)
: WebGLContextUnchecked(nullptr)
, mNeedsFakeNoAlpha(false)
{
mGeneration = 0;
@ -371,6 +372,8 @@ WebGLContext::DestroyResourcesAndContext()
mPrograms.getLast()->DeleteOnce();
while (!mQueries.isEmpty())
mQueries.getLast()->DeleteOnce();
while (!mSamplers.isEmpty())
mSamplers.getLast()->DeleteOnce();
mBlackOpaqueTexture2D = nullptr;
mBlackOpaqueTextureCubeMap = nullptr;

View File

@ -15,6 +15,7 @@
#include "GLDefs.h"
#include "WebGLActiveInfo.h"
#include "WebGLContextUnchecked.h"
#include "WebGLObjectModel.h"
#include "WebGLRenderbuffer.h"
#include "WebGLTexture.h"
@ -78,10 +79,12 @@ class WebGLQuery;
class WebGLUniformLocation;
class WebGLFramebuffer;
class WebGLRenderbuffer;
class WebGLSampler;
class WebGLShaderPrecisionFormat;
class WebGLTexture;
class WebGLVertexArray;
namespace dom {
class ImageData;
class Element;
@ -127,10 +130,29 @@ struct WebGLContextOptions {
// From WebGLContextUtils
TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);
class WebGLIntOrFloat {
enum {
Int,
Float
} mType;
union {
GLint i;
GLfloat f;
} mValue;
public:
explicit WebGLIntOrFloat(GLint i) : mType(Int) { mValue.i = i; }
explicit WebGLIntOrFloat(GLfloat f) : mType(Float) { mValue.f = f; }
GLint AsInt() const { return (mType == Int) ? mValue.i : NS_lroundf(mValue.f); }
GLfloat AsFloat() const { return (mType == Float) ? mValue.f : GLfloat(mValue.i); }
};
class WebGLContext :
public nsIDOMWebGLRenderingContext,
public nsICanvasRenderingContextInternal,
public nsSupportsWeakReference,
public WebGLContextUnchecked,
public WebGLRectangleObject,
public nsWrapperCache,
public SupportsWeakPtr<WebGLContext>
@ -1005,8 +1027,6 @@ protected:
return ((x + y - 1) / y) * y;
}
nsRefPtr<gl::GLContext> gl;
CheckedUint32 mGeneration;
WebGLContextOptions mOptions;
@ -1138,6 +1158,10 @@ protected:
bool ValidateCopyTexImage(GLenum internalformat,
WebGLTexImageFunc func,
WebGLTexDimensions dims);
bool ValidateSamplerParameterName(GLenum pname, const char* info);
bool ValidateSamplerParameterParams(GLenum pname, const WebGLIntOrFloat& param, const char* info);
bool ValidateTexImage(TexImageTarget texImageTarget,
GLint level, GLenum internalFormat,
GLint xoffset, GLint yoffset, GLint zoffset,
@ -1325,6 +1349,9 @@ protected:
LinkedList<WebGLFramebuffer> mFramebuffers;
LinkedList<WebGLVertexArray> mVertexArrays;
// TODO(djg): Does this need a rethink? Should it be WebGL2Context?
LinkedList<WebGLSampler> mSamplers;
WebGLRefPtr<WebGLVertexArray> mDefaultVertexArray;
// PixelStore parameters
@ -1440,6 +1467,7 @@ public:
friend class WebGLProgram;
friend class WebGLQuery;
friend class WebGLBuffer;
friend class WebGLSampler;
friend class WebGLShader;
friend class WebGLUniformLocation;
friend class WebGLVertexArray;

View File

@ -0,0 +1,96 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
/* 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 "WebGLContextUnchecked.h"
#include "GLContext.h"
#include "WebGLSampler.h"
namespace mozilla {
WebGLContextUnchecked::WebGLContextUnchecked(gl::GLContext* gl)
: gl(gl)
{ }
// -----------------------------------------------------------------------------
// Sampler Objects
void
WebGLContextUnchecked::BindSampler(GLuint unit, WebGLSampler* sampler)
{
gl->MakeCurrent();
gl->fBindSampler(unit, sampler ? sampler->GLName() : 0);
if (sampler)
sampler->BindTo(LOCAL_GL_SAMPLER_BINDING);
}
GLint
WebGLContextUnchecked::GetSamplerParameteriv(WebGLSampler* sampler,
GLenum pname)
{
MOZ_ASSERT(sampler, "Did you validate?");
GLint param = 0;
gl->MakeCurrent();
gl->fGetSamplerParameteriv(sampler->GLName(), pname, &param);
return param;
}
GLfloat
WebGLContextUnchecked::GetSamplerParameterfv(WebGLSampler* sampler,
GLenum pname)
{
MOZ_ASSERT(sampler, "Did you validate?");
GLfloat param = 0.0f;
gl->MakeCurrent();
gl->fGetSamplerParameterfv(sampler->GLName(), pname, &param);
return param;
}
void
WebGLContextUnchecked::SamplerParameteri(WebGLSampler* sampler,
GLenum pname,
GLint param)
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameteri(sampler->GLName(), pname, param);
}
void
WebGLContextUnchecked::SamplerParameteriv(WebGLSampler* sampler,
GLenum pname,
const GLint* param)
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameteriv(sampler->GLName(), pname, param);
}
void
WebGLContextUnchecked::SamplerParameterf(WebGLSampler* sampler,
GLenum pname,
GLfloat param)
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameterf(sampler->GLName(), pname, param);
}
void
WebGLContextUnchecked::SamplerParameterfv(WebGLSampler* sampler,
GLenum pname,
const GLfloat* param)
{
MOZ_ASSERT(sampler, "Did you validate?");
gl->MakeCurrent();
gl->fSamplerParameterfv(sampler->GLName(), pname, param);
}
} // namespace mozilla

View File

@ -0,0 +1,45 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
/* 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 WEBGLCONTEXTUNCHECKED_H
#define WEBGLCONTEXTUNCHECKED_H
#include "GLDefs.h"
#include "WebGLTypes.h"
#include "nsAutoPtr.h"
#include "nsTArray.h"
namespace mozilla {
class WebGLSampler;
namespace gl {
class GLContext;
}
class WebGLContextUnchecked
{
public:
explicit WebGLContextUnchecked(gl::GLContext* gl);
// -------------------------------------------------------------------------
// Sampler Objects
void BindSampler(GLuint unit, WebGLSampler* sampler);
GLint GetSamplerParameteriv(WebGLSampler* sampler, GLenum pname);
GLfloat GetSamplerParameterfv(WebGLSampler* sampler, GLenum pname);
void SamplerParameteri(WebGLSampler* sampler, GLenum pname, GLint param);
void SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const GLint* param);
void SamplerParameterf(WebGLSampler* sampler, GLenum pname, GLfloat param);
void SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const GLfloat* param);
protected: // data
nsRefPtr<gl::GLContext> gl;
};
} // namespace mozilla
#endif // !WEBGLCONTEXTUNCHECKED_H

View File

@ -378,6 +378,118 @@ WebGLContext::ValidateFramebufferAttachment(GLenum attachment, const char* funcN
return false;
}
/**
* Return true if pname is valid for GetSamplerParameter calls.
*/
bool
WebGLContext::ValidateSamplerParameterName(GLenum pname, const char* info)
{
switch (pname) {
case LOCAL_GL_TEXTURE_MIN_FILTER:
case LOCAL_GL_TEXTURE_MAG_FILTER:
case LOCAL_GL_TEXTURE_WRAP_S:
case LOCAL_GL_TEXTURE_WRAP_T:
case LOCAL_GL_TEXTURE_WRAP_R:
case LOCAL_GL_TEXTURE_MIN_LOD:
case LOCAL_GL_TEXTURE_MAX_LOD:
case LOCAL_GL_TEXTURE_COMPARE_MODE:
case LOCAL_GL_TEXTURE_COMPARE_FUNC:
return true;
default:
ErrorInvalidEnum("%s: invalid pname: %s", info, EnumName(pname));
return false;
}
}
/**
* Return true if pname and param are valid combination for SamplerParameter calls.
*/
bool
WebGLContext::ValidateSamplerParameterParams(GLenum pname, const WebGLIntOrFloat& param, const char* info)
{
const GLenum p = param.AsInt();
switch (pname) {
case LOCAL_GL_TEXTURE_MIN_FILTER:
switch (p) {
case LOCAL_GL_NEAREST:
case LOCAL_GL_LINEAR:
case LOCAL_GL_NEAREST_MIPMAP_NEAREST:
case LOCAL_GL_NEAREST_MIPMAP_LINEAR:
case LOCAL_GL_LINEAR_MIPMAP_NEAREST:
case LOCAL_GL_LINEAR_MIPMAP_LINEAR:
return true;
default:
ErrorInvalidEnum("%s: invalid param: %s", info, EnumName(p));
return false;
}
case LOCAL_GL_TEXTURE_MAG_FILTER:
switch (p) {
case LOCAL_GL_NEAREST:
case LOCAL_GL_LINEAR:
return true;
default:
ErrorInvalidEnum("%s: invalid param: %s", info, EnumName(p));
return false;
}
case LOCAL_GL_TEXTURE_WRAP_S:
case LOCAL_GL_TEXTURE_WRAP_T:
case LOCAL_GL_TEXTURE_WRAP_R:
switch (p) {
case LOCAL_GL_CLAMP_TO_EDGE:
case LOCAL_GL_REPEAT:
case LOCAL_GL_MIRRORED_REPEAT:
return true;
default:
ErrorInvalidEnum("%s: invalid param: %s", info, EnumName(p));
return false;
}
case LOCAL_GL_TEXTURE_MIN_LOD:
case LOCAL_GL_TEXTURE_MAX_LOD:
return true;
case LOCAL_GL_TEXTURE_COMPARE_MODE:
switch (param.AsInt()) {
case LOCAL_GL_NONE:
case LOCAL_GL_COMPARE_REF_TO_TEXTURE:
return true;
default:
ErrorInvalidEnum("%s: invalid param: %s", info, EnumName(p));
return false;
}
case LOCAL_GL_TEXTURE_COMPARE_FUNC:
switch (p) {
case LOCAL_GL_LEQUAL:
case LOCAL_GL_GEQUAL:
case LOCAL_GL_LESS:
case LOCAL_GL_GREATER:
case LOCAL_GL_EQUAL:
case LOCAL_GL_NOTEQUAL:
case LOCAL_GL_ALWAYS:
case LOCAL_GL_NEVER:
return true;
default:
ErrorInvalidEnum("%s: invalid param: %s", info, EnumName(p));
return false;
}
default:
ErrorInvalidEnum("%s: invalid pname: %s", info, EnumName(pname));
return false;
}
}
/**
* Return true if format is a valid texture image format for source,
* taking into account enabled WebGL extensions.

View File

@ -373,7 +373,7 @@ WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, FBAttachment att
MOZ_ASSERT(HasImage());
if (Texture()) {
MOZ_ASSERT(gl == Texture()->Context()->gl);
MOZ_ASSERT(gl == Texture()->Context()->GL());
const GLenum imageTarget = ImageTarget().get();
const GLint mipLevel = MipLevel();

View File

@ -12,33 +12,36 @@
using namespace mozilla;
WebGLSampler::WebGLSampler(WebGLContext* context)
: WebGLBindableName<GLenum>(0),
WebGLSampler::WebGLSampler(WebGLContext* context, GLuint sampler)
: WebGLBindableName<GLenum>(sampler),
WebGLContextBoundObject(context)
{
MOZ_CRASH("Not Implemented.");
mContext->mSamplers.insertBack(this);
}
WebGLSampler::~WebGLSampler()
{}
{
DeleteOnce();
}
void
WebGLSampler::Delete()
{
MOZ_CRASH("Not Implemented.");
mContext->MakeContextCurrent();
mContext->gl->fDeleteSamplers(1, &mGLName);
removeFrom(mContext->mSamplers);
}
WebGLContext*
WebGLSampler::GetParentObject() const
{
MOZ_CRASH("Not Implemented.");
return nullptr;
return Context();
}
JSObject*
WebGLSampler::WrapObject(JSContext* cx)
{
MOZ_CRASH("Not Implemented.");
return dom::WebGLSamplerBinding::Wrap(cx, this);
}

View File

@ -3,8 +3,8 @@
* 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 WEBGL2SAMPLER_H_
#define WEBGL2SAMPLER_H_
#ifndef WEBGLSAMPLER_H_
#define WEBGLSAMPLER_H_
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
@ -26,13 +26,15 @@ class WebGLSampler MOZ_FINAL
public:
explicit WebGLSampler(WebGLContext* aContext);
explicit WebGLSampler(WebGLContext* aContext, GLuint sampler);
void Delete();
WebGLContext* GetParentObject() const;
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
private:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSampler)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler)
@ -43,4 +45,4 @@ private:
} // namespace mozilla
#endif // !WEBGL2SAMPLER_H_
#endif // !WEBGLSAMPLER_H_

View File

@ -64,6 +64,7 @@ UNIFIED_SOURCES += [
'WebGLContextLossHandler.cpp',
'WebGLContextReporter.cpp',
'WebGLContextState.cpp',
'WebGLContextUnchecked.cpp',
'WebGLContextUtils.cpp',
'WebGLContextValidate.cpp',
'WebGLContextVertexArray.cpp',