зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1048724 - [WebGL2] Transform Feedback. r=jgilbert,smaug
--HG-- extra : rebase_source : 40fe3ec66b091ced40f5a773fdc23d06bf6abc11
This commit is contained in:
Родитель
73ffa2d5f9
Коммит
baf3f4332f
|
@ -31,6 +31,8 @@ public:
|
|||
|
||||
private:
|
||||
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) MOZ_OVERRIDE;
|
||||
virtual bool ValidateBufferTarget(GLenum target, const char* info) MOZ_OVERRIDE;
|
||||
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- 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 "WebGL1Context.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Buffer objects
|
||||
|
||||
/** Target validation for BindBuffer, etc */
|
||||
bool
|
||||
WebGL1Context::ValidateBufferTarget(GLenum target, const char* info)
|
||||
{
|
||||
switch (target) {
|
||||
case LOCAL_GL_ARRAY_BUFFER:
|
||||
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
|
||||
return true;
|
||||
|
||||
default:
|
||||
ErrorInvalidEnumInfo(info, target);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
WebGL1Context::ValidateBufferIndexedTarget(GLenum target, const char* info)
|
||||
{
|
||||
ErrorInvalidEnumInfo(info, target);
|
||||
return false;
|
||||
}
|
|
@ -6,6 +6,8 @@
|
|||
#include "WebGL2Context.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLTransformFeedback.h"
|
||||
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
@ -117,6 +119,11 @@ WebGLContext::InitWebGL2()
|
|||
gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
|
||||
&mGLMaxTransformFeedbackSeparateAttribs);
|
||||
|
||||
mDefaultTransformFeedback = new WebGLTransformFeedback(this, 0);
|
||||
mBoundTransformFeedback = mDefaultTransformFeedback;
|
||||
auto xfBuffers = new WebGLRefPtr<WebGLBuffer>[mGLMaxTransformFeedbackSeparateAttribs];
|
||||
mBoundTransformFeedbackBuffers.reset(xfBuffers);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -215,14 +215,13 @@ public:
|
|||
already_AddRefed<WebGLTransformFeedback> CreateTransformFeedback();
|
||||
void DeleteTransformFeedback(WebGLTransformFeedback* tf);
|
||||
bool IsTransformFeedback(WebGLTransformFeedback* tf);
|
||||
void BindTransformFeedback(GLenum target, GLuint id);
|
||||
void BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf);
|
||||
void BeginTransformFeedback(GLenum primitiveMode);
|
||||
void EndTransformFeedback();
|
||||
void TransformFeedbackVaryings(WebGLProgram* program, GLsizei count,
|
||||
const dom::Sequence<nsString>& varyings, GLenum bufferMode);
|
||||
already_AddRefed<WebGLActiveInfo> GetTransformFeedbackVarying(WebGLProgram* program, GLuint index);
|
||||
void PauseTransformFeedback();
|
||||
void ResumeTransformFeedback();
|
||||
void TransformFeedbackVaryings(WebGLProgram* program, const dom::Sequence<nsString>& varyings, GLenum bufferMode);
|
||||
already_AddRefed<WebGLActiveInfo> GetTransformFeedbackVarying(WebGLProgram* program, GLuint index);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -263,6 +262,8 @@ private:
|
|||
const char* info);
|
||||
|
||||
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) MOZ_OVERRIDE;
|
||||
virtual bool ValidateBufferTarget(GLenum target, const char* info) MOZ_OVERRIDE;
|
||||
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -9,6 +9,35 @@
|
|||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
bool
|
||||
WebGL2Context::ValidateBufferTarget(GLenum target, const char* info)
|
||||
{
|
||||
switch (target) {
|
||||
case LOCAL_GL_ARRAY_BUFFER:
|
||||
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
|
||||
return true;
|
||||
|
||||
default:
|
||||
ErrorInvalidEnumInfo(info, target);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
WebGL2Context::ValidateBufferIndexedTarget(GLenum target, const char* info)
|
||||
{
|
||||
switch (target) {
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
|
||||
case LOCAL_GL_UNIFORM_BUFFER:
|
||||
return true;
|
||||
|
||||
default:
|
||||
ErrorInvalidEnumInfo(info, target);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Buffer objects
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGL2Context.h"
|
||||
#include "WebGLActiveInfo.h"
|
||||
#include "WebGLProgram.h"
|
||||
#include "WebGLTransformFeedback.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -15,64 +18,237 @@ using namespace mozilla::dom;
|
|||
already_AddRefed<WebGLTransformFeedback>
|
||||
WebGL2Context::CreateTransformFeedback()
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
return nullptr;
|
||||
if (IsContextLost())
|
||||
return nullptr;
|
||||
|
||||
GLuint tf = 0;
|
||||
MakeContextCurrent();
|
||||
gl->fGenTransformFeedbacks(1, &tf);
|
||||
|
||||
nsRefPtr<WebGLTransformFeedback> globj = new WebGLTransformFeedback(this, tf);
|
||||
return globj.forget();
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::DeleteTransformFeedback(WebGLTransformFeedback* tf)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateObjectAllowDeletedOrNull("deleteTransformFeedback", tf))
|
||||
return;
|
||||
|
||||
if (!tf || tf->IsDeleted())
|
||||
return;
|
||||
|
||||
if (mBoundTransformFeedback == tf)
|
||||
BindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, tf);
|
||||
|
||||
tf->RequestDelete();
|
||||
}
|
||||
|
||||
bool
|
||||
WebGL2Context::IsTransformFeedback(WebGLTransformFeedback* tf)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
return false;
|
||||
if (IsContextLost())
|
||||
return false;
|
||||
|
||||
if (!ValidateObjectAllowDeleted("isTransformFeedback", tf))
|
||||
return false;
|
||||
|
||||
if (tf->IsDeleted())
|
||||
return false;
|
||||
|
||||
MakeContextCurrent();
|
||||
return gl->fIsTransformFeedback(tf->GLName());
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::BindTransformFeedback(GLenum target, GLuint id)
|
||||
WebGL2Context::BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateObjectAllowDeletedOrNull("bindTransformFeedback", tf))
|
||||
return;
|
||||
|
||||
if (target != LOCAL_GL_TRANSFORM_FEEDBACK)
|
||||
return ErrorInvalidEnum("bindTransformFeedback: target must be TRANSFORM_FEEDBACK");
|
||||
|
||||
WebGLRefPtr<WebGLTransformFeedback> currentTF = mBoundTransformFeedback;
|
||||
if (currentTF && currentTF->mIsActive && !currentTF->mIsPaused) {
|
||||
return ErrorInvalidOperation("bindTransformFeedback: Currently bound transform "
|
||||
"feedback is active and not paused");
|
||||
}
|
||||
|
||||
if (tf && tf->IsDeleted())
|
||||
return ErrorInvalidOperation("bindTransformFeedback: Attempt to bind deleted id");
|
||||
|
||||
if (tf)
|
||||
tf->BindTo(LOCAL_GL_TRANSFORM_FEEDBACK);
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fBindTransformFeedback(target, tf ? tf->GLName() : 0);
|
||||
if (tf)
|
||||
mBoundTransformFeedback = tf;
|
||||
else
|
||||
mBoundTransformFeedback = mDefaultTransformFeedback;
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::BeginTransformFeedback(GLenum primitiveMode)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
WebGLTransformFeedback* tf = mBoundTransformFeedback;
|
||||
MOZ_ASSERT(tf);
|
||||
if (!tf)
|
||||
return;
|
||||
|
||||
if (tf->mIsActive)
|
||||
return ErrorInvalidOperation("beginTransformFeedback: transform feedback is active");
|
||||
|
||||
const GLenum mode = tf->mMode;
|
||||
if (mode != LOCAL_GL_POINTS && mode != LOCAL_GL_LINES && mode != LOCAL_GL_TRIANGLES)
|
||||
return ErrorInvalidEnum("beginTransformFeedback: primitive must be one of POINTS, LINES, or TRIANGLES");
|
||||
|
||||
// TODO:
|
||||
// GL_INVALID_OPERATION is generated by glBeginTransformFeedback
|
||||
// if any binding point used in transform feedback mode does not
|
||||
// have a buffer object bound. In interleaved mode, only the first
|
||||
// buffer object binding point is ever written to.
|
||||
|
||||
// GL_INVALID_OPERATION is generated by glBeginTransformFeedback
|
||||
// if no binding points would be used, either because no program
|
||||
// object is active of because the active program object has
|
||||
// specified no varying variables to record.
|
||||
if (!mCurrentProgram)
|
||||
return ErrorInvalidOperation("beginTransformFeedback: no program is active");
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fBeginTransformFeedback(primitiveMode);
|
||||
tf->mIsActive = true;
|
||||
tf->mIsPaused = false;
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::EndTransformFeedback()
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
WebGLTransformFeedback* tf = mBoundTransformFeedback;
|
||||
MOZ_ASSERT(tf);
|
||||
|
||||
if (!tf)
|
||||
return;
|
||||
|
||||
if (!tf->mIsActive)
|
||||
return ErrorInvalidOperation("%s: transform feedback in not active",
|
||||
"endTransformFeedback");
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fEndTransformFeedback();
|
||||
tf->mIsActive = false;
|
||||
tf->mIsPaused = false;
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::TransformFeedbackVaryings(WebGLProgram* program, GLsizei count,
|
||||
const dom::Sequence<nsString>& varyings, GLenum bufferMode)
|
||||
WebGL2Context::PauseTransformFeedback()
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
WebGLTransformFeedback* tf = mBoundTransformFeedback;
|
||||
MOZ_ASSERT(tf);
|
||||
if (!tf)
|
||||
return;
|
||||
|
||||
if (!tf->mIsActive || tf->mIsPaused) {
|
||||
return ErrorInvalidOperation("%s: transform feedback is not active or is paused",
|
||||
"pauseTransformFeedback");
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fPauseTransformFeedback();
|
||||
tf->mIsPaused = true;
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::ResumeTransformFeedback()
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
WebGLTransformFeedback* tf = mBoundTransformFeedback;
|
||||
MOZ_ASSERT(tf);
|
||||
if (!tf)
|
||||
return;
|
||||
|
||||
if (!tf->mIsActive || !tf->mIsPaused)
|
||||
return ErrorInvalidOperation("resumeTransformFeedback: transform feedback is not active or is not paused");
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fResumeTransformFeedback();
|
||||
tf->mIsPaused = false;
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::TransformFeedbackVaryings(WebGLProgram* program,
|
||||
const dom::Sequence<nsString>& varyings,
|
||||
GLenum bufferMode)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateObject("transformFeedbackVaryings: program", program))
|
||||
return;
|
||||
|
||||
GLsizei count = varyings.Length();
|
||||
GLchar** tmpVaryings = (GLchar**) nsMemory::Alloc(count * sizeof(GLchar*));
|
||||
|
||||
for (GLsizei n = 0; n < count; n++) {
|
||||
tmpVaryings[n] = (GLchar*) ToNewCString(varyings[n]);
|
||||
}
|
||||
|
||||
GLuint progname = program->GLName();
|
||||
MakeContextCurrent();
|
||||
gl->fTransformFeedbackVaryings(progname, count, tmpVaryings, bufferMode);
|
||||
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, tmpVaryings);
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<WebGLActiveInfo>
|
||||
WebGL2Context::GetTransformFeedbackVarying(WebGLProgram* program, GLuint index)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
return nullptr;
|
||||
}
|
||||
if (IsContextLost())
|
||||
return nullptr;
|
||||
|
||||
void
|
||||
WebGL2Context::PauseTransformFeedback()
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
if (!ValidateObject("getTransformFeedbackVarying: program", program))
|
||||
return nullptr;
|
||||
|
||||
void
|
||||
WebGL2Context::ResumeTransformFeedback()
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
MakeContextCurrent();
|
||||
|
||||
GLint len = 0;
|
||||
GLuint progname = program->GLName();
|
||||
gl->fGetProgramiv(progname, LOCAL_GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &len);
|
||||
if (!len)
|
||||
return nullptr;
|
||||
|
||||
UniquePtr<char[]> name(new char[len]);
|
||||
GLint tfsize = 0;
|
||||
GLuint tftype = 0;
|
||||
|
||||
gl->fGetTransformFeedbackVarying(progname, index, len, &len, &tfsize, &tftype, name.get());
|
||||
if (len == 0 || tfsize == 0 || tftype == 0)
|
||||
return nullptr;
|
||||
|
||||
// TODO(djg): Reverse lookup of name
|
||||
// nsCString reverseMappedName;
|
||||
// prog->ReverveMapIdentifier(nsDependentCString(name), &reverseMappedName);
|
||||
|
||||
nsRefPtr<WebGLActiveInfo> result = new WebGLActiveInfo(tfsize, tftype, nsDependentCString(name.get()));
|
||||
return result.forget();
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLQuery.h"
|
||||
#include "WebGLSampler.h"
|
||||
#include "WebGLTransformFeedback.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
|
||||
|
@ -328,6 +329,14 @@ WebGLContext::DestroyResourcesAndContext()
|
|||
mBoundRenderbuffer = nullptr;
|
||||
mBoundVertexArray = nullptr;
|
||||
mDefaultVertexArray = nullptr;
|
||||
mBoundTransformFeedback = nullptr;
|
||||
mDefaultTransformFeedback = nullptr;
|
||||
|
||||
if (mBoundTransformFeedbackBuffers) {
|
||||
for (GLuint i = 0; i < mGLMaxTransformFeedbackSeparateAttribs; i++) {
|
||||
mBoundTransformFeedbackBuffers[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
while (!mTextures.isEmpty())
|
||||
mTextures.getLast()->DeleteOnce();
|
||||
|
@ -347,6 +356,8 @@ WebGLContext::DestroyResourcesAndContext()
|
|||
mQueries.getLast()->DeleteOnce();
|
||||
while (!mSamplers.isEmpty())
|
||||
mSamplers.getLast()->DeleteOnce();
|
||||
while (!mTransformFeedbacks.isEmpty())
|
||||
mTransformFeedbacks.getLast()->DeleteOnce();
|
||||
|
||||
mBlackOpaqueTexture2D = nullptr;
|
||||
mBlackOpaqueTextureCubeMap = nullptr;
|
||||
|
|
|
@ -80,6 +80,7 @@ class WebGLSampler;
|
|||
class WebGLShader;
|
||||
class WebGLShaderPrecisionFormat;
|
||||
class WebGLTexture;
|
||||
class WebGLTransformFeedback;
|
||||
class WebGLUniformLocation;
|
||||
class WebGLVertexArray;
|
||||
struct WebGLVertexAttribData;
|
||||
|
@ -881,19 +882,16 @@ public:
|
|||
void DeleteBuffer(WebGLBuffer* buf);
|
||||
bool IsBuffer(WebGLBuffer* buf);
|
||||
|
||||
private:
|
||||
// ARRAY_BUFFER slot
|
||||
protected:
|
||||
// bound buffer state
|
||||
WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer;
|
||||
|
||||
// TRANSFORM_FEEDBACK_BUFFER slot
|
||||
WebGLRefPtr<WebGLBuffer> mBoundTransformFeedbackBuffer;
|
||||
|
||||
// these two functions emit INVALID_ENUM for invalid `target`.
|
||||
WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTarget(GLenum target,
|
||||
const char* info);
|
||||
UniquePtr<WebGLRefPtr<WebGLBuffer>[]> mBoundTransformFeedbackBuffers;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTarget(GLenum target);
|
||||
WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTargetIndexed(GLenum target,
|
||||
GLuint index,
|
||||
const char* info);
|
||||
GLuint index);
|
||||
bool ValidateBufferUsageEnum(GLenum target, const char* info);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1114,7 +1112,7 @@ protected:
|
|||
int32_t mGLMaxVertexUniformVectors;
|
||||
int32_t mGLMaxColorAttachments;
|
||||
int32_t mGLMaxDrawBuffers;
|
||||
uint32_t mGLMaxTransformFeedbackSeparateAttribs;
|
||||
GLuint mGLMaxTransformFeedbackSeparateAttribs;
|
||||
|
||||
public:
|
||||
GLuint MaxVertexAttribs() const {
|
||||
|
@ -1339,6 +1337,8 @@ private:
|
|||
// -------------------------------------------------------------------------
|
||||
// Context customization points
|
||||
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) = 0;
|
||||
virtual bool ValidateBufferTarget(GLenum target, const char* info) = 0;
|
||||
virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) = 0;
|
||||
|
||||
protected:
|
||||
int32_t MaxTextureSizeForTarget(TexTarget target) const {
|
||||
|
@ -1380,6 +1380,7 @@ protected:
|
|||
|
||||
WebGLRefPtr<WebGLFramebuffer> mBoundFramebuffer;
|
||||
WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
|
||||
WebGLRefPtr<WebGLTransformFeedback> mBoundTransformFeedback;
|
||||
WebGLRefPtr<WebGLVertexArray> mBoundVertexArray;
|
||||
|
||||
LinkedList<WebGLTexture> mTextures;
|
||||
|
@ -1393,8 +1394,10 @@ protected:
|
|||
|
||||
// TODO(djg): Does this need a rethink? Should it be WebGL2Context?
|
||||
LinkedList<WebGLSampler> mSamplers;
|
||||
LinkedList<WebGLTransformFeedback> mTransformFeedbacks;
|
||||
|
||||
WebGLRefPtr<WebGLVertexArray> mDefaultVertexArray;
|
||||
WebGLRefPtr<WebGLTransformFeedback> mDefaultTransformFeedback;
|
||||
|
||||
// PixelStore parameters
|
||||
uint32_t mPixelStorePackAlignment;
|
||||
|
@ -1518,6 +1521,7 @@ public:
|
|||
friend class WebGLBuffer;
|
||||
friend class WebGLSampler;
|
||||
friend class WebGLShader;
|
||||
friend class WebGLTransformFeedback;
|
||||
friend class WebGLUniformLocation;
|
||||
friend class WebGLVertexArray;
|
||||
friend class WebGLVertexArrayFake;
|
||||
|
|
|
@ -24,11 +24,12 @@ WebGLContext::BindBuffer(GLenum target, WebGLBuffer* buffer)
|
|||
if (buffer && buffer->IsDeleted())
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
|
||||
"bindBuffer");
|
||||
if (!bufferSlot)
|
||||
if (!ValidateBufferTarget(target, "bindBuffer"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target);
|
||||
MOZ_ASSERT(bufferSlot);
|
||||
|
||||
if (buffer) {
|
||||
if (!buffer->HasEverBeenBound()) {
|
||||
buffer->BindTo(target);
|
||||
|
@ -60,11 +61,19 @@ WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer)
|
|||
return;
|
||||
}
|
||||
|
||||
// ValidateBufferTarget
|
||||
switch (target) {
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
|
||||
if (index >= mGLMaxTransformFeedbackSeparateAttribs)
|
||||
return ErrorInvalidValue("bindBufferBase: index should be less than "
|
||||
"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS");
|
||||
default:
|
||||
return ErrorInvalidEnumInfo("bindBufferBase: target", target);
|
||||
}
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* indexedBufferSlot;
|
||||
indexedBufferSlot = GetBufferSlotByTargetIndexed(target, index,
|
||||
"bindBufferBase");
|
||||
if (!indexedBufferSlot)
|
||||
return;
|
||||
indexedBufferSlot = GetBufferSlotByTargetIndexed(target, index);
|
||||
MOZ_ASSERT(indexedBufferSlot);
|
||||
|
||||
if (buffer) {
|
||||
if (!buffer->HasEverBeenBound())
|
||||
|
@ -77,9 +86,7 @@ WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer)
|
|||
}
|
||||
}
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
|
||||
"bindBufferBase");
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target);
|
||||
MOZ_ASSERT(bufferSlot, "GetBufferSlotByTarget(Indexed) mismatch");
|
||||
|
||||
*indexedBufferSlot = buffer;
|
||||
|
@ -104,11 +111,20 @@ WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
|
|||
if (buffer && buffer->IsDeleted())
|
||||
return;
|
||||
|
||||
// ValidateBufferTarget
|
||||
switch (target) {
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
|
||||
if (index >= mGLMaxTransformFeedbackSeparateAttribs)
|
||||
return ErrorInvalidValue("bindBufferRange: index should be less than "
|
||||
"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS");
|
||||
|
||||
default:
|
||||
return ErrorInvalidEnumInfo("bindBufferRange: target", target);
|
||||
}
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* indexedBufferSlot;
|
||||
indexedBufferSlot = GetBufferSlotByTargetIndexed(target, index,
|
||||
"bindBufferRange");
|
||||
if (!indexedBufferSlot)
|
||||
return;
|
||||
indexedBufferSlot = GetBufferSlotByTargetIndexed(target, index);
|
||||
MOZ_ASSERT(indexedBufferSlot);
|
||||
|
||||
if (buffer) {
|
||||
if (!buffer->HasEverBeenBound())
|
||||
|
@ -128,9 +144,7 @@ WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
|
|||
}
|
||||
}
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
|
||||
"BindBufferRange");
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target);
|
||||
MOZ_ASSERT(bufferSlot, "GetBufferSlotByTarget(Indexed) mismatch");
|
||||
|
||||
*indexedBufferSlot = buffer;
|
||||
|
@ -148,11 +162,12 @@ WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, GLenum usage)
|
|||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
|
||||
"bufferData");
|
||||
if (!bufferSlot)
|
||||
if (!ValidateBufferTarget(target, "bufferData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target);
|
||||
MOZ_ASSERT(bufferSlot);
|
||||
|
||||
if (size < 0)
|
||||
return ErrorInvalidValue("bufferData: negative size");
|
||||
|
||||
|
@ -201,11 +216,12 @@ WebGLContext::BufferData(GLenum target,
|
|||
return ErrorInvalidValue("bufferData: null object passed");
|
||||
}
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
|
||||
"bufferData");
|
||||
if (!bufferSlot)
|
||||
if (!ValidateBufferTarget(target, "bufferData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target);
|
||||
MOZ_ASSERT(bufferSlot);
|
||||
|
||||
const dom::ArrayBuffer& data = maybeData.Value();
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
|
@ -244,11 +260,12 @@ WebGLContext::BufferData(GLenum target, const dom::ArrayBufferView& data,
|
|||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
|
||||
"bufferSubData");
|
||||
if (!bufferSlot)
|
||||
if (!ValidateBufferTarget(target, "bufferData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target);
|
||||
MOZ_ASSERT(bufferSlot);
|
||||
|
||||
if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
|
||||
return;
|
||||
|
||||
|
@ -290,11 +307,12 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
|||
return;
|
||||
}
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
|
||||
"bufferSubData");
|
||||
if (!bufferSlot)
|
||||
if (!ValidateBufferTarget(target, "bufferSubData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target);
|
||||
MOZ_ASSERT(bufferSlot);
|
||||
|
||||
if (byteOffset < 0)
|
||||
return ErrorInvalidValue("bufferSubData: negative offset");
|
||||
|
||||
|
@ -335,11 +353,12 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
|||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
|
||||
"bufferSubData");
|
||||
if (!bufferSlot)
|
||||
if (!ValidateBufferTarget(target, "bufferSubData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target);
|
||||
MOZ_ASSERT(bufferSlot);
|
||||
|
||||
if (byteOffset < 0)
|
||||
return ErrorInvalidValue("bufferSubData: negative offset");
|
||||
|
||||
|
@ -445,48 +464,35 @@ WebGLContext::ValidateBufferUsageEnum(GLenum target, const char* info)
|
|||
}
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>*
|
||||
WebGLContext::GetBufferSlotByTarget(GLenum target, const char* info)
|
||||
WebGLContext::GetBufferSlotByTarget(GLenum target)
|
||||
{
|
||||
/* This function assumes that target has been validated for either WebGL1 or WebGL. */
|
||||
switch (target) {
|
||||
case LOCAL_GL_ARRAY_BUFFER:
|
||||
return &mBoundArrayBuffer;
|
||||
case LOCAL_GL_ARRAY_BUFFER:
|
||||
return &mBoundArrayBuffer;
|
||||
|
||||
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
|
||||
return &mBoundVertexArray->mElementArrayBuffer;
|
||||
case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
|
||||
return &mBoundVertexArray->mElementArrayBuffer;
|
||||
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
|
||||
if (!IsWebGL2()) {
|
||||
break;
|
||||
}
|
||||
return &mBoundTransformFeedbackBuffer;
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
|
||||
return &mBoundTransformFeedbackBuffer;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ErrorInvalidEnum("%s: target: Invalid enum value 0x%x.", info, target);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>*
|
||||
WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index,
|
||||
const char* info)
|
||||
WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index)
|
||||
{
|
||||
/* This function assumes that target has been validated for either WebGL1 or WebGL. */
|
||||
switch (target) {
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
|
||||
if (index >= mGLMaxTransformFeedbackSeparateAttribs) {
|
||||
ErrorInvalidValue("%s: `index` should be less than"
|
||||
" MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.", info,
|
||||
index);
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr; // See bug 903594
|
||||
|
||||
default:
|
||||
break;
|
||||
MOZ_ASSERT(index < mGLMaxTransformFeedbackSeparateAttribs);
|
||||
return &mBoundTransformFeedbackBuffers[index];
|
||||
}
|
||||
|
||||
ErrorInvalidEnum("%s: target: invalid enum value 0x%x", info, target);
|
||||
MOZ_CRASH("Should not get here.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1105,12 +1105,12 @@ WebGLContext::GetBufferParameter(GLenum target, GLenum pname)
|
|||
if (IsContextLost())
|
||||
return JS::NullValue();
|
||||
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* slot = GetBufferSlotByTarget(target,
|
||||
"getBufferParameter");
|
||||
if (!slot)
|
||||
if (!ValidateBufferTarget(target, "getBufferParameter"))
|
||||
return JS::NullValue();
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* slot = GetBufferSlotByTarget(target);
|
||||
MOZ_ASSERT(slot);
|
||||
|
||||
if (!*slot) {
|
||||
ErrorInvalidOperation("No buffer bound to `target` (0x%4x).", target);
|
||||
return JS::NullValue();
|
||||
|
|
|
@ -11,27 +11,37 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* webgl)
|
||||
: WebGLBindableName<GLenum>(0)
|
||||
, WebGLContextBoundObject(webgl)
|
||||
WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* context,
|
||||
GLuint tf)
|
||||
: WebGLBindableName<GLenum>(tf)
|
||||
, WebGLContextBoundObject(context)
|
||||
, mMode(LOCAL_GL_NONE)
|
||||
, mIsActive(false)
|
||||
, mIsPaused(false)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
context->mTransformFeedbacks.insertBack(this);
|
||||
}
|
||||
|
||||
WebGLTransformFeedback::~WebGLTransformFeedback()
|
||||
{}
|
||||
{
|
||||
mMode = LOCAL_GL_NONE;
|
||||
mIsActive = false;
|
||||
mIsPaused = false;
|
||||
DeleteOnce();
|
||||
}
|
||||
|
||||
void
|
||||
WebGLTransformFeedback::Delete()
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
mContext->MakeContextCurrent();
|
||||
mContext->gl->fDeleteTransformFeedbacks(1, &mGLName);
|
||||
removeFrom(mContext->mTransformFeedbacks);
|
||||
}
|
||||
|
||||
WebGLContext*
|
||||
WebGLTransformFeedback::GetParentObject() const
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
return nullptr;
|
||||
return Context();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
|
|
@ -21,9 +21,10 @@ class WebGLTransformFeedback MOZ_FINAL
|
|||
, public WebGLContextBoundObject
|
||||
{
|
||||
friend class WebGLContext;
|
||||
friend class WebGL2Context;
|
||||
|
||||
public:
|
||||
explicit WebGLTransformFeedback(WebGLContext* webgl);
|
||||
explicit WebGLTransformFeedback(WebGLContext* webgl, GLuint tf);
|
||||
|
||||
void Delete();
|
||||
WebGLContext* GetParentObject() const;
|
||||
|
@ -34,6 +35,9 @@ public:
|
|||
|
||||
private:
|
||||
~WebGLTransformFeedback();
|
||||
GLenum mMode;
|
||||
bool mIsActive;
|
||||
bool mIsPaused;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -42,6 +42,7 @@ UNIFIED_SOURCES += [
|
|||
UNIFIED_SOURCES += [
|
||||
'MurmurHash3.cpp',
|
||||
'WebGL1Context.cpp',
|
||||
'WebGL1ContextBuffers.cpp',
|
||||
'WebGL1ContextUniforms.cpp',
|
||||
'WebGL2Context.cpp',
|
||||
'WebGL2ContextBuffers.cpp',
|
||||
|
|
|
@ -443,10 +443,10 @@ interface WebGL2RenderingContext : WebGLRenderingContext
|
|||
WebGLTransformFeedback? createTransformFeedback();
|
||||
void deleteTransformFeedback(WebGLTransformFeedback? tf);
|
||||
[WebGLHandlesContextLoss] GLboolean isTransformFeedback(WebGLTransformFeedback? tf);
|
||||
void bindTransformFeedback(GLenum target, GLuint id);
|
||||
void bindTransformFeedback(GLenum target, WebGLTransformFeedback? tf);
|
||||
void beginTransformFeedback(GLenum primitiveMode);
|
||||
void endTransformFeedback();
|
||||
void transformFeedbackVaryings(WebGLProgram? program, GLsizei count, sequence<DOMString> varyings, GLenum bufferMode);
|
||||
void transformFeedbackVaryings(WebGLProgram? program, sequence<DOMString> varyings, GLenum bufferMode);
|
||||
[NewObject] WebGLActiveInfo? getTransformFeedbackVarying(WebGLProgram? program, GLuint index);
|
||||
void pauseTransformFeedback();
|
||||
void resumeTransformFeedback();
|
||||
|
|
|
@ -2730,7 +2730,7 @@ public:
|
|||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fDeleteTransformFeedbacks(GLsizei n, GLuint* ids)
|
||||
void fDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
|
||||
{
|
||||
BEFORE_GL_CALL;
|
||||
ASSERT_SYMBOL_PRESENT(fDeleteTransformFeedbacks);
|
||||
|
|
|
@ -487,7 +487,7 @@ struct GLContextSymbols
|
|||
|
||||
typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids);
|
||||
PFNGLGENTRANSFORMFEEDBACKSPROC fGenTransformFeedbacks;
|
||||
typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids);
|
||||
typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint* ids);
|
||||
PFNGLDELETETRANSFORMFEEDBACKSPROC fDeleteTransformFeedbacks;
|
||||
typedef realGLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
|
||||
PFNGLISTRANSFORMFEEDBACKPROC fIsTransformFeedback;
|
||||
|
|
Загрузка…
Ссылка в новой задаче