mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 801499 - Move WebGLBuffer to a separate file. r=bjacob
This commit is contained in:
parent
b76b368af6
commit
c0ea184dc2
@ -55,6 +55,7 @@ CPPSRCS += \
|
|||||||
WebGLExtensionTextureFilterAnisotropic.cpp \
|
WebGLExtensionTextureFilterAnisotropic.cpp \
|
||||||
WebGLExtensionTextureFloat.cpp \
|
WebGLExtensionTextureFloat.cpp \
|
||||||
WebGLFramebuffer.cpp \
|
WebGLFramebuffer.cpp \
|
||||||
|
WebGLObjectModel.cpp \
|
||||||
WebGLProgram.cpp \
|
WebGLProgram.cpp \
|
||||||
WebGLRenderbuffer.cpp \
|
WebGLRenderbuffer.cpp \
|
||||||
WebGLShader.cpp \
|
WebGLShader.cpp \
|
||||||
|
@ -3,11 +3,57 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "WebGLBuffer.h"
|
||||||
#include "WebGLContext.h"
|
#include "WebGLContext.h"
|
||||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
|
WebGLBuffer::WebGLBuffer(WebGLContext *context)
|
||||||
|
: WebGLContextBoundObject(context)
|
||||||
|
, mHasEverBeenBound(false)
|
||||||
|
, mByteLength(0)
|
||||||
|
, mTarget(LOCAL_GL_NONE)
|
||||||
|
{
|
||||||
|
SetIsDOMBinding();
|
||||||
|
mContext->MakeContextCurrent();
|
||||||
|
mContext->gl->fGenBuffers(1, &mGLName);
|
||||||
|
mContext->mBuffers.insertBack(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebGLBuffer::~WebGLBuffer() {
|
||||||
|
DeleteOnce();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WebGLBuffer::Delete() {
|
||||||
|
mContext->MakeContextCurrent();
|
||||||
|
mContext->gl->fDeleteBuffers(1, &mGLName);
|
||||||
|
mByteLength = 0;
|
||||||
|
mCache = nullptr;
|
||||||
|
LinkedListElement<WebGLBuffer>::remove(); // remove from mContext->mBuffers
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WebGLBuffer::SetTarget(GLenum target) {
|
||||||
|
mTarget = target;
|
||||||
|
if (!mCache && mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||||
|
mCache = new WebGLElementArrayCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WebGLBuffer::ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes) {
|
||||||
|
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||||
|
return mCache->BufferData(ptr, buffer_size_in_bytes);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WebGLBuffer::ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes) {
|
||||||
|
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||||
|
mCache->BufferSubData(pos, ptr, update_size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
WebGLBuffer::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) {
|
WebGLBuffer::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) {
|
||||||
return dom::WebGLBufferBinding::Wrap(cx, scope, this, triedToWrap);
|
return dom::WebGLBufferBinding::Wrap(cx, scope, this, triedToWrap);
|
||||||
|
74
content/canvas/src/WebGLBuffer.h
Normal file
74
content/canvas/src/WebGLBuffer.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/* -*- 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 WEBGLBUFFER_H_
|
||||||
|
#define WEBGLBUFFER_H_
|
||||||
|
|
||||||
|
#include "WebGLElementArrayCache.h"
|
||||||
|
#include "WebGLObjectModel.h"
|
||||||
|
|
||||||
|
#include "nsWrapperCache.h"
|
||||||
|
|
||||||
|
#include "mozilla/LinkedList.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
class WebGLBuffer MOZ_FINAL
|
||||||
|
: public nsISupports
|
||||||
|
, public WebGLRefCountedObject<WebGLBuffer>
|
||||||
|
, public LinkedListElement<WebGLBuffer>
|
||||||
|
, public WebGLContextBoundObject
|
||||||
|
, public nsWrapperCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebGLBuffer(WebGLContext *context);
|
||||||
|
|
||||||
|
~WebGLBuffer();
|
||||||
|
|
||||||
|
void Delete();
|
||||||
|
|
||||||
|
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
|
||||||
|
size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||||
|
return aMallocSizeOf(this) + sizeOfCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasEverBeenBound() { return mHasEverBeenBound; }
|
||||||
|
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
|
||||||
|
GLuint GLName() const { return mGLName; }
|
||||||
|
GLuint ByteLength() const { return mByteLength; }
|
||||||
|
GLenum Target() const { return mTarget; }
|
||||||
|
|
||||||
|
void SetByteLength(GLuint byteLength) { mByteLength = byteLength; }
|
||||||
|
|
||||||
|
void SetTarget(GLenum target);
|
||||||
|
|
||||||
|
bool ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes);
|
||||||
|
|
||||||
|
void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes);
|
||||||
|
|
||||||
|
bool Validate(WebGLenum type, uint32_t max_allowed, size_t first, size_t count) {
|
||||||
|
return mCache->Validate(type, max_allowed, first, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebGLContext *GetParentObject() const {
|
||||||
|
return Context();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
|
||||||
|
|
||||||
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLBuffer)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
WebGLuint mGLName;
|
||||||
|
bool mHasEverBeenBound;
|
||||||
|
GLuint mByteLength;
|
||||||
|
GLenum mTarget;
|
||||||
|
|
||||||
|
nsAutoPtr<WebGLElementArrayCache> mCache;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif //WEBGLBUFFER_H_
|
@ -4,6 +4,7 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "WebGLContext.h"
|
#include "WebGLContext.h"
|
||||||
|
#include "WebGLObjectModel.h"
|
||||||
#include "WebGLExtensions.h"
|
#include "WebGLExtensions.h"
|
||||||
#include "WebGLContextUtils.h"
|
#include "WebGLContextUtils.h"
|
||||||
|
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
#ifndef WEBGLCONTEXT_H_
|
#ifndef WEBGLCONTEXT_H_
|
||||||
#define WEBGLCONTEXT_H_
|
#define WEBGLCONTEXT_H_
|
||||||
|
|
||||||
|
#include "WebGLElementArrayCache.h"
|
||||||
|
#include "WebGLObjectModel.h"
|
||||||
|
#include "WebGLBuffer.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -42,8 +46,6 @@
|
|||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
|
|
||||||
#include "WebGLElementArrayCache.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25
|
* Minimum value constants defined in 6.2 State Tables of OpenGL ES - 2.0.25
|
||||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=686732
|
* https://bugzilla.mozilla.org/show_bug.cgi?id=686732
|
||||||
@ -62,30 +64,16 @@
|
|||||||
#define MINVALUE_GL_MAX_RENDERBUFFER_SIZE 1024 // Different from the spec, which sets it to 1 on page 164
|
#define MINVALUE_GL_MAX_RENDERBUFFER_SIZE 1024 // Different from the spec, which sets it to 1 on page 164
|
||||||
#define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 8 // Page 164
|
#define MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 8 // Page 164
|
||||||
|
|
||||||
// Manual reflection of WebIDL typedefs
|
|
||||||
typedef uint32_t WebGLenum;
|
|
||||||
typedef uint32_t WebGLbitfield;
|
|
||||||
typedef int32_t WebGLint;
|
|
||||||
typedef int32_t WebGLsizei;
|
|
||||||
typedef int64_t WebGLsizeiptr;
|
|
||||||
typedef int64_t WebGLintptr;
|
|
||||||
typedef uint32_t WebGLuint;
|
|
||||||
typedef float WebGLfloat;
|
|
||||||
typedef float WebGLclampf;
|
|
||||||
typedef bool WebGLboolean;
|
|
||||||
|
|
||||||
class nsIPropertyBag;
|
class nsIPropertyBag;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class WebGLTexture;
|
class WebGLTexture;
|
||||||
class WebGLBuffer;
|
|
||||||
class WebGLProgram;
|
class WebGLProgram;
|
||||||
class WebGLShader;
|
class WebGLShader;
|
||||||
class WebGLFramebuffer;
|
class WebGLFramebuffer;
|
||||||
class WebGLRenderbuffer;
|
|
||||||
class WebGLUniformLocation;
|
class WebGLUniformLocation;
|
||||||
class WebGLContext;
|
class WebGLRenderbuffer;
|
||||||
struct WebGLVertexAttribData;
|
struct WebGLVertexAttribData;
|
||||||
class WebGLMemoryPressureObserver;
|
class WebGLMemoryPressureObserver;
|
||||||
class WebGLRectangleObject;
|
class WebGLRectangleObject;
|
||||||
@ -163,246 +151,6 @@ inline bool is_pot_assuming_nonnegative(WebGLsizei x)
|
|||||||
return x && (x & (x-1)) == 0;
|
return x && (x & (x-1)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Each WebGL object class WebGLFoo wants to:
|
|
||||||
* - inherit WebGLRefCountedObject<WebGLFoo>
|
|
||||||
* - implement a Delete() method
|
|
||||||
* - have its destructor call DeleteOnce()
|
|
||||||
*
|
|
||||||
* This base class provides two features to WebGL object types:
|
|
||||||
* 1. support for OpenGL object reference counting
|
|
||||||
* 2. support for OpenGL deletion statuses
|
|
||||||
*
|
|
||||||
***** 1. OpenGL object reference counting *****
|
|
||||||
*
|
|
||||||
* WebGL objects such as WebGLTexture's really have two different refcounts:
|
|
||||||
* the XPCOM refcount, that is directly exposed to JavaScript, and the OpenGL
|
|
||||||
* refcount.
|
|
||||||
*
|
|
||||||
* For example, when in JavaScript one does: var newname = existingTexture;
|
|
||||||
* that increments the XPCOM refcount, but doesn't affect the OpenGL refcount.
|
|
||||||
* When one attaches the texture to a framebuffer object, that does increment
|
|
||||||
* its OpenGL refcount (and also its XPCOM refcount, to prevent the regular
|
|
||||||
* XPCOM refcounting mechanism from destroying objects prematurely).
|
|
||||||
*
|
|
||||||
* The actual OpenGL refcount is opaque to us (it's internal to the OpenGL
|
|
||||||
* implementation) but is affects the WebGL semantics that we have to implement:
|
|
||||||
* for example, a WebGLTexture that is attached to a WebGLFramebuffer must not
|
|
||||||
* be actually deleted, even if deleteTexture has been called on it, and even
|
|
||||||
* if JavaScript doesn't have references to it anymore. We can't just rely on
|
|
||||||
* OpenGL to keep alive the underlying OpenGL texture for us, for a variety of
|
|
||||||
* reasons, most importantly: we'd need to know when OpenGL objects are actually
|
|
||||||
* deleted, and OpenGL doesn't notify us about that, so we would have to query
|
|
||||||
* status very often with glIsXxx calls which isn't practical.
|
|
||||||
*
|
|
||||||
* This means that we have to keep track of the OpenGL refcount ourselves,
|
|
||||||
* in addition to the XPCOM refcount.
|
|
||||||
*
|
|
||||||
* This class implements such a refcount, see the mWebGLRefCnt
|
|
||||||
* member. In order to avoid name clashes (with regular XPCOM refcounting)
|
|
||||||
* in the derived class, we prefix members with 'WebGL', whence the names
|
|
||||||
* WebGLAddRef, WebGLRelease, etc.
|
|
||||||
*
|
|
||||||
* In practice, WebGLAddRef and WebGLRelease are only called from the
|
|
||||||
* WebGLRefPtr class.
|
|
||||||
*
|
|
||||||
***** 2. OpenGL deletion statuses *****
|
|
||||||
*
|
|
||||||
* In OpenGL, an object can go through 3 different deletion statuses during its
|
|
||||||
* lifetime, which correspond to the 3 enum values for DeletionStatus in this class:
|
|
||||||
* - the Default status, which it has from its creation to when the
|
|
||||||
* suitable glDeleteXxx function is called on it;
|
|
||||||
* - the DeleteRequested status, which is has from when the suitable glDeleteXxx
|
|
||||||
* function is called on it to when it is no longer referenced by other OpenGL
|
|
||||||
* objects. For example, a texture that is attached to a non-current FBO
|
|
||||||
* will enter that status when glDeleteTexture is called on it. For objects
|
|
||||||
* with that status, GL_DELETE_STATUS queries return true, but glIsXxx
|
|
||||||
* functions still return true.
|
|
||||||
* - the Deleted status, which is the status of objects on which the
|
|
||||||
* suitable glDeleteXxx function has been called, and that are not referenced
|
|
||||||
* by other OpenGL objects.
|
|
||||||
*
|
|
||||||
* This state is stored in the mDeletionStatus member of this class.
|
|
||||||
*
|
|
||||||
* When the GL refcount hits zero, if the status is DeleteRequested then we call
|
|
||||||
* the Delete() method on the derived class and the status becomes Deleted. This is
|
|
||||||
* what the MaybeDelete() function does.
|
|
||||||
*
|
|
||||||
* The DeleteOnce() function implemented here is a helper to ensure that we don't
|
|
||||||
* call Delete() twice on the same object. Since the derived class' destructor
|
|
||||||
* needs to call DeleteOnce() which calls Delete(), we can't allow either to be
|
|
||||||
* virtual. Strictly speaking, we could let them be virtual if the derived class
|
|
||||||
* were final, but that would be impossible to enforce and would lead to strange
|
|
||||||
* bugs if it were subclassed.
|
|
||||||
*
|
|
||||||
* This WebGLRefCountedObject class takes the Derived type
|
|
||||||
* as template parameter, as a means to allow DeleteOnce to call Delete()
|
|
||||||
* on the Derived class, without either method being virtual. This is a common
|
|
||||||
* C++ pattern known as the "curiously recursive template pattern (CRTP)".
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
class WebGLRefCountedObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum DeletionStatus { Default, DeleteRequested, Deleted };
|
|
||||||
|
|
||||||
WebGLRefCountedObject()
|
|
||||||
: mDeletionStatus(Default)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
~WebGLRefCountedObject() {
|
|
||||||
NS_ABORT_IF_FALSE(mWebGLRefCnt == 0, "destroying WebGL object still referenced by other WebGL objects");
|
|
||||||
NS_ABORT_IF_FALSE(mDeletionStatus == Deleted, "Derived class destructor must call DeleteOnce()");
|
|
||||||
}
|
|
||||||
|
|
||||||
// called by WebGLRefPtr
|
|
||||||
void WebGLAddRef() {
|
|
||||||
++mWebGLRefCnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// called by WebGLRefPtr
|
|
||||||
void WebGLRelease() {
|
|
||||||
NS_ABORT_IF_FALSE(mWebGLRefCnt > 0, "releasing WebGL object with WebGL refcnt already zero");
|
|
||||||
--mWebGLRefCnt;
|
|
||||||
MaybeDelete();
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is the function that WebGL.deleteXxx() functions want to call
|
|
||||||
void RequestDelete() {
|
|
||||||
if (mDeletionStatus == Default)
|
|
||||||
mDeletionStatus = DeleteRequested;
|
|
||||||
MaybeDelete();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsDeleted() const {
|
|
||||||
return mDeletionStatus == Deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsDeleteRequested() const {
|
|
||||||
return mDeletionStatus != Default;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteOnce() {
|
|
||||||
if (mDeletionStatus != Deleted) {
|
|
||||||
static_cast<Derived*>(this)->Delete();
|
|
||||||
mDeletionStatus = Deleted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void MaybeDelete() {
|
|
||||||
if (mWebGLRefCnt == 0 &&
|
|
||||||
mDeletionStatus == DeleteRequested)
|
|
||||||
{
|
|
||||||
DeleteOnce();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsAutoRefCnt mWebGLRefCnt;
|
|
||||||
DeletionStatus mDeletionStatus;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This WebGLRefPtr class is meant to be used for references between WebGL objects.
|
|
||||||
* For example, a WebGLProgram holds WebGLRefPtr's to the WebGLShader's attached
|
|
||||||
* to it.
|
|
||||||
*
|
|
||||||
* Why the need for a separate refptr class? The only special thing that WebGLRefPtr
|
|
||||||
* does is that it increments and decrements the WebGL refcount of
|
|
||||||
* WebGLRefCountedObject's, in addition to incrementing and decrementing the
|
|
||||||
* usual XPCOM refcount.
|
|
||||||
*
|
|
||||||
* This means that by using a WebGLRefPtr instead of a nsRefPtr, you ensure that
|
|
||||||
* the WebGL refcount is incremented, which means that the object will be kept
|
|
||||||
* alive by this reference even if the matching webgl.deleteXxx() function is
|
|
||||||
* called on it.
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
class WebGLRefPtr
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WebGLRefPtr()
|
|
||||||
: mRawPtr(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
WebGLRefPtr(const WebGLRefPtr<T>& aSmartPtr)
|
|
||||||
: mRawPtr(aSmartPtr.mRawPtr)
|
|
||||||
{
|
|
||||||
AddRefOnPtr(mRawPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
WebGLRefPtr(T *aRawPtr)
|
|
||||||
: mRawPtr(aRawPtr)
|
|
||||||
{
|
|
||||||
AddRefOnPtr(mRawPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
~WebGLRefPtr() {
|
|
||||||
ReleasePtr(mRawPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
WebGLRefPtr<T>&
|
|
||||||
operator=(const WebGLRefPtr<T>& rhs)
|
|
||||||
{
|
|
||||||
assign_with_AddRef(rhs.mRawPtr);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebGLRefPtr<T>&
|
|
||||||
operator=(T* rhs)
|
|
||||||
{
|
|
||||||
assign_with_AddRef(rhs);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* get() const {
|
|
||||||
return static_cast<T*>(mRawPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator T*() const {
|
|
||||||
return get();
|
|
||||||
}
|
|
||||||
|
|
||||||
T* operator->() const {
|
|
||||||
NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator->()!");
|
|
||||||
return get();
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator*() const {
|
|
||||||
NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator*()!");
|
|
||||||
return *get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
static void AddRefOnPtr(T* rawPtr) {
|
|
||||||
if (rawPtr) {
|
|
||||||
rawPtr->WebGLAddRef();
|
|
||||||
rawPtr->AddRef();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ReleasePtr(T* rawPtr) {
|
|
||||||
if (rawPtr) {
|
|
||||||
rawPtr->WebGLRelease(); // must be done first before Release(), as Release() might actually destroy the object
|
|
||||||
rawPtr->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void assign_with_AddRef(T* rawPtr) {
|
|
||||||
AddRefOnPtr(rawPtr);
|
|
||||||
assign_assuming_AddRef(rawPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void assign_assuming_AddRef(T* newPtr) {
|
|
||||||
T* oldPtr = mRawPtr;
|
|
||||||
mRawPtr = newPtr;
|
|
||||||
ReleasePtr(oldPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
T *mRawPtr;
|
|
||||||
};
|
|
||||||
|
|
||||||
// this class is a mixin for GL objects that have dimensions
|
// this class is a mixin for GL objects that have dimensions
|
||||||
// that we need to track.
|
// that we need to track.
|
||||||
class WebGLRectangleObject
|
class WebGLRectangleObject
|
||||||
@ -1463,29 +1211,6 @@ ToSupports(WebGLContext* context)
|
|||||||
return static_cast<nsICanvasRenderingContextInternal*>(context);
|
return static_cast<nsICanvasRenderingContextInternal*>(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This class is a mixin for objects that are tied to a specific
|
|
||||||
// context (which is to say, all of them). They provide initialization
|
|
||||||
// as well as comparison with the current context.
|
|
||||||
class WebGLContextBoundObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WebGLContextBoundObject(WebGLContext *context) {
|
|
||||||
mContext = context;
|
|
||||||
mContextGeneration = context->Generation();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsCompatibleWithContext(WebGLContext *other) {
|
|
||||||
return mContext == other &&
|
|
||||||
mContextGeneration == other->Generation();
|
|
||||||
}
|
|
||||||
|
|
||||||
WebGLContext *Context() const { return mContext; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
WebGLContext *mContext;
|
|
||||||
uint32_t mContextGeneration;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WebGLVertexAttribData {
|
struct WebGLVertexAttribData {
|
||||||
// note that these initial values are what GL initializes vertex attribs to
|
// note that these initial values are what GL initializes vertex attribs to
|
||||||
WebGLVertexAttribData()
|
WebGLVertexAttribData()
|
||||||
@ -1531,90 +1256,6 @@ struct WebGLVertexAttribData {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class WebGLBuffer MOZ_FINAL
|
|
||||||
: public nsISupports
|
|
||||||
, public WebGLRefCountedObject<WebGLBuffer>
|
|
||||||
, public LinkedListElement<WebGLBuffer>
|
|
||||||
, public WebGLContextBoundObject
|
|
||||||
, public nsWrapperCache
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WebGLBuffer(WebGLContext *context)
|
|
||||||
: WebGLContextBoundObject(context)
|
|
||||||
, mHasEverBeenBound(false)
|
|
||||||
, mByteLength(0)
|
|
||||||
, mTarget(LOCAL_GL_NONE)
|
|
||||||
{
|
|
||||||
SetIsDOMBinding();
|
|
||||||
mContext->MakeContextCurrent();
|
|
||||||
mContext->gl->fGenBuffers(1, &mGLName);
|
|
||||||
mContext->mBuffers.insertBack(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~WebGLBuffer() {
|
|
||||||
DeleteOnce();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Delete() {
|
|
||||||
mContext->MakeContextCurrent();
|
|
||||||
mContext->gl->fDeleteBuffers(1, &mGLName);
|
|
||||||
mByteLength = 0;
|
|
||||||
mCache = nullptr;
|
|
||||||
LinkedListElement<WebGLBuffer>::removeFrom(mContext->mBuffers);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
|
|
||||||
size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
|
||||||
return aMallocSizeOf(this) + sizeOfCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasEverBeenBound() { return mHasEverBeenBound; }
|
|
||||||
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
|
|
||||||
GLuint GLName() const { return mGLName; }
|
|
||||||
GLuint ByteLength() const { return mByteLength; }
|
|
||||||
GLenum Target() const { return mTarget; }
|
|
||||||
|
|
||||||
void SetByteLength(GLuint byteLength) { mByteLength = byteLength; }
|
|
||||||
|
|
||||||
void SetTarget(GLenum target) {
|
|
||||||
mTarget = target;
|
|
||||||
if (!mCache && mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
|
||||||
mCache = new WebGLElementArrayCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes) {
|
|
||||||
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
|
||||||
return mCache->BufferData(ptr, buffer_size_in_bytes);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes) {
|
|
||||||
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
|
||||||
mCache->BufferSubData(pos, ptr, update_size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Validate(WebGLenum type, uint32_t max_allowed, size_t first, size_t count) {
|
|
||||||
return mCache->Validate(type, max_allowed, first, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
WebGLContext *GetParentObject() const {
|
|
||||||
return Context();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap);
|
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLBuffer)
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
WebGLuint mGLName;
|
|
||||||
bool mHasEverBeenBound;
|
|
||||||
GLuint mByteLength;
|
|
||||||
GLenum mTarget;
|
|
||||||
|
|
||||||
nsAutoPtr<WebGLElementArrayCache> mCache;
|
|
||||||
};
|
|
||||||
|
|
||||||
// NOTE: When this class is switched to new DOM bindings, update the (then-slow)
|
// NOTE: When this class is switched to new DOM bindings, update the (then-slow)
|
||||||
// WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
|
// WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
|
||||||
@ -3467,22 +3108,4 @@ ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
|
|||||||
aCallback.NoteXPCOMChild(aField.buf);
|
aCallback.NoteXPCOMChild(aField.buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void
|
|
||||||
ImplCycleCollectionUnlink(mozilla::WebGLRefPtr<T>& aField)
|
|
||||||
{
|
|
||||||
aField = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void
|
|
||||||
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
|
|
||||||
mozilla::WebGLRefPtr<T>& aField,
|
|
||||||
const char* aName,
|
|
||||||
uint32_t aFlags = 0)
|
|
||||||
{
|
|
||||||
CycleCollectionNoteEdgeName(aCallback, aName, aFlags);
|
|
||||||
aCallback.NoteXPCOMChild(aField);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
19
content/canvas/src/WebGLObjectModel.cpp
Normal file
19
content/canvas/src/WebGLObjectModel.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 20; 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 "WebGLObjectModel.h"
|
||||||
|
#include "WebGLContext.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
|
WebGLContextBoundObject::WebGLContextBoundObject(WebGLContext *context) {
|
||||||
|
mContext = context;
|
||||||
|
mContextGeneration = context->Generation();
|
||||||
|
}
|
||||||
|
bool
|
||||||
|
WebGLContextBoundObject::IsCompatibleWithContext(WebGLContext *other) {
|
||||||
|
return mContext == other &&
|
||||||
|
mContextGeneration == other->Generation();
|
||||||
|
}
|
306
content/canvas/src/WebGLObjectModel.h
Normal file
306
content/canvas/src/WebGLObjectModel.h
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/* -*- 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 WEBGLOBJECTMODEL_H_
|
||||||
|
#define WEBGLOBJECTMODEL_H_
|
||||||
|
|
||||||
|
#include "nsCycleCollectionNoteChild.h"
|
||||||
|
#include "nsICanvasRenderingContextInternal.h"
|
||||||
|
|
||||||
|
// Manual reflection of WebIDL typedefs
|
||||||
|
typedef uint32_t WebGLenum;
|
||||||
|
typedef uint32_t WebGLbitfield;
|
||||||
|
typedef int32_t WebGLint;
|
||||||
|
typedef int32_t WebGLsizei;
|
||||||
|
typedef int64_t WebGLsizeiptr;
|
||||||
|
typedef int64_t WebGLintptr;
|
||||||
|
typedef uint32_t WebGLuint;
|
||||||
|
typedef float WebGLfloat;
|
||||||
|
typedef float WebGLclampf;
|
||||||
|
typedef bool WebGLboolean;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
class WebGLBuffer;
|
||||||
|
class WebGLContext;
|
||||||
|
|
||||||
|
/* Each WebGL object class WebGLFoo wants to:
|
||||||
|
* - inherit WebGLRefCountedObject<WebGLFoo>
|
||||||
|
* - implement a Delete() method
|
||||||
|
* - have its destructor call DeleteOnce()
|
||||||
|
*
|
||||||
|
* This base class provides two features to WebGL object types:
|
||||||
|
* 1. support for OpenGL object reference counting
|
||||||
|
* 2. support for OpenGL deletion statuses
|
||||||
|
*
|
||||||
|
***** 1. OpenGL object reference counting *****
|
||||||
|
*
|
||||||
|
* WebGL objects such as WebGLTexture's really have two different refcounts:
|
||||||
|
* the XPCOM refcount, that is directly exposed to JavaScript, and the OpenGL
|
||||||
|
* refcount.
|
||||||
|
*
|
||||||
|
* For example, when in JavaScript one does: var newname = existingTexture;
|
||||||
|
* that increments the XPCOM refcount, but doesn't affect the OpenGL refcount.
|
||||||
|
* When one attaches the texture to a framebuffer object, that does increment
|
||||||
|
* its OpenGL refcount (and also its XPCOM refcount, to prevent the regular
|
||||||
|
* XPCOM refcounting mechanism from destroying objects prematurely).
|
||||||
|
*
|
||||||
|
* The actual OpenGL refcount is opaque to us (it's internal to the OpenGL
|
||||||
|
* implementation) but is affects the WebGL semantics that we have to implement:
|
||||||
|
* for example, a WebGLTexture that is attached to a WebGLFramebuffer must not
|
||||||
|
* be actually deleted, even if deleteTexture has been called on it, and even
|
||||||
|
* if JavaScript doesn't have references to it anymore. We can't just rely on
|
||||||
|
* OpenGL to keep alive the underlying OpenGL texture for us, for a variety of
|
||||||
|
* reasons, most importantly: we'd need to know when OpenGL objects are actually
|
||||||
|
* deleted, and OpenGL doesn't notify us about that, so we would have to query
|
||||||
|
* status very often with glIsXxx calls which isn't practical.
|
||||||
|
*
|
||||||
|
* This means that we have to keep track of the OpenGL refcount ourselves,
|
||||||
|
* in addition to the XPCOM refcount.
|
||||||
|
*
|
||||||
|
* This class implements such a refcount, see the mWebGLRefCnt
|
||||||
|
* member. In order to avoid name clashes (with regular XPCOM refcounting)
|
||||||
|
* in the derived class, we prefix members with 'WebGL', whence the names
|
||||||
|
* WebGLAddRef, WebGLRelease, etc.
|
||||||
|
*
|
||||||
|
* In practice, WebGLAddRef and WebGLRelease are only called from the
|
||||||
|
* WebGLRefPtr class.
|
||||||
|
*
|
||||||
|
***** 2. OpenGL deletion statuses *****
|
||||||
|
*
|
||||||
|
* In OpenGL, an object can go through 3 different deletion statuses during its
|
||||||
|
* lifetime, which correspond to the 3 enum values for DeletionStatus in this class:
|
||||||
|
* - the Default status, which it has from its creation to when the
|
||||||
|
* suitable glDeleteXxx function is called on it;
|
||||||
|
* - the DeleteRequested status, which is has from when the suitable glDeleteXxx
|
||||||
|
* function is called on it to when it is no longer referenced by other OpenGL
|
||||||
|
* objects. For example, a texture that is attached to a non-current FBO
|
||||||
|
* will enter that status when glDeleteTexture is called on it. For objects
|
||||||
|
* with that status, GL_DELETE_STATUS queries return true, but glIsXxx
|
||||||
|
* functions still return true.
|
||||||
|
* - the Deleted status, which is the status of objects on which the
|
||||||
|
* suitable glDeleteXxx function has been called, and that are not referenced
|
||||||
|
* by other OpenGL objects.
|
||||||
|
*
|
||||||
|
* This state is stored in the mDeletionStatus member of this class.
|
||||||
|
*
|
||||||
|
* When the GL refcount hits zero, if the status is DeleteRequested then we call
|
||||||
|
* the Delete() method on the derived class and the status becomes Deleted. This is
|
||||||
|
* what the MaybeDelete() function does.
|
||||||
|
*
|
||||||
|
* The DeleteOnce() function implemented here is a helper to ensure that we don't
|
||||||
|
* call Delete() twice on the same object. Since the derived class' destructor
|
||||||
|
* needs to call DeleteOnce() which calls Delete(), we can't allow either to be
|
||||||
|
* virtual. Strictly speaking, we could let them be virtual if the derived class
|
||||||
|
* were final, but that would be impossible to enforce and would lead to strange
|
||||||
|
* bugs if it were subclassed.
|
||||||
|
*
|
||||||
|
* This WebGLRefCountedObject class takes the Derived type
|
||||||
|
* as template parameter, as a means to allow DeleteOnce to call Delete()
|
||||||
|
* on the Derived class, without either method being virtual. This is a common
|
||||||
|
* C++ pattern known as the "curiously recursive template pattern (CRTP)".
|
||||||
|
*/
|
||||||
|
template<typename Derived>
|
||||||
|
class WebGLRefCountedObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum DeletionStatus { Default, DeleteRequested, Deleted };
|
||||||
|
|
||||||
|
WebGLRefCountedObject()
|
||||||
|
: mDeletionStatus(Default)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~WebGLRefCountedObject() {
|
||||||
|
NS_ABORT_IF_FALSE(mWebGLRefCnt == 0, "destroying WebGL object still referenced by other WebGL objects");
|
||||||
|
NS_ABORT_IF_FALSE(mDeletionStatus == Deleted, "Derived class destructor must call DeleteOnce()");
|
||||||
|
}
|
||||||
|
|
||||||
|
// called by WebGLRefPtr
|
||||||
|
void WebGLAddRef() {
|
||||||
|
++mWebGLRefCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// called by WebGLRefPtr
|
||||||
|
void WebGLRelease() {
|
||||||
|
NS_ABORT_IF_FALSE(mWebGLRefCnt > 0, "releasing WebGL object with WebGL refcnt already zero");
|
||||||
|
--mWebGLRefCnt;
|
||||||
|
MaybeDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is the function that WebGL.deleteXxx() functions want to call
|
||||||
|
void RequestDelete() {
|
||||||
|
if (mDeletionStatus == Default)
|
||||||
|
mDeletionStatus = DeleteRequested;
|
||||||
|
MaybeDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsDeleted() const {
|
||||||
|
return mDeletionStatus == Deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsDeleteRequested() const {
|
||||||
|
return mDeletionStatus != Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteOnce() {
|
||||||
|
if (mDeletionStatus != Deleted) {
|
||||||
|
static_cast<Derived*>(this)->Delete();
|
||||||
|
mDeletionStatus = Deleted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void MaybeDelete() {
|
||||||
|
if (mWebGLRefCnt == 0 &&
|
||||||
|
mDeletionStatus == DeleteRequested)
|
||||||
|
{
|
||||||
|
DeleteOnce();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsAutoRefCnt mWebGLRefCnt;
|
||||||
|
DeletionStatus mDeletionStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This WebGLRefPtr class is meant to be used for references between WebGL objects.
|
||||||
|
* For example, a WebGLProgram holds WebGLRefPtr's to the WebGLShader's attached
|
||||||
|
* to it.
|
||||||
|
*
|
||||||
|
* Why the need for a separate refptr class? The only special thing that WebGLRefPtr
|
||||||
|
* does is that it increments and decrements the WebGL refcount of
|
||||||
|
* WebGLRefCountedObject's, in addition to incrementing and decrementing the
|
||||||
|
* usual XPCOM refcount.
|
||||||
|
*
|
||||||
|
* This means that by using a WebGLRefPtr instead of a nsRefPtr, you ensure that
|
||||||
|
* the WebGL refcount is incremented, which means that the object will be kept
|
||||||
|
* alive by this reference even if the matching webgl.deleteXxx() function is
|
||||||
|
* called on it.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
class WebGLRefPtr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebGLRefPtr()
|
||||||
|
: mRawPtr(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
WebGLRefPtr(const WebGLRefPtr<T>& aSmartPtr)
|
||||||
|
: mRawPtr(aSmartPtr.mRawPtr)
|
||||||
|
{
|
||||||
|
AddRefOnPtr(mRawPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebGLRefPtr(T *aRawPtr)
|
||||||
|
: mRawPtr(aRawPtr)
|
||||||
|
{
|
||||||
|
AddRefOnPtr(mRawPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
~WebGLRefPtr() {
|
||||||
|
ReleasePtr(mRawPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebGLRefPtr<T>&
|
||||||
|
operator=(const WebGLRefPtr<T>& rhs)
|
||||||
|
{
|
||||||
|
assign_with_AddRef(rhs.mRawPtr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebGLRefPtr<T>&
|
||||||
|
operator=(T* rhs)
|
||||||
|
{
|
||||||
|
assign_with_AddRef(rhs);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* get() const {
|
||||||
|
return static_cast<T*>(mRawPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T*() const {
|
||||||
|
return get();
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator->() const {
|
||||||
|
NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator->()!");
|
||||||
|
return get();
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator*() const {
|
||||||
|
NS_ABORT_IF_FALSE(mRawPtr != 0, "You can't dereference a NULL WebGLRefPtr with operator*()!");
|
||||||
|
return *get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static void AddRefOnPtr(T* rawPtr) {
|
||||||
|
if (rawPtr) {
|
||||||
|
rawPtr->WebGLAddRef();
|
||||||
|
rawPtr->AddRef();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ReleasePtr(T* rawPtr) {
|
||||||
|
if (rawPtr) {
|
||||||
|
rawPtr->WebGLRelease(); // must be done first before Release(), as Release() might actually destroy the object
|
||||||
|
rawPtr->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assign_with_AddRef(T* rawPtr) {
|
||||||
|
AddRefOnPtr(rawPtr);
|
||||||
|
assign_assuming_AddRef(rawPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assign_assuming_AddRef(T* newPtr) {
|
||||||
|
T* oldPtr = mRawPtr;
|
||||||
|
mRawPtr = newPtr;
|
||||||
|
ReleasePtr(oldPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
T *mRawPtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This class is a mixin for objects that are tied to a specific
|
||||||
|
// context (which is to say, all of them). They provide initialization
|
||||||
|
// as well as comparison with the current context.
|
||||||
|
class WebGLContextBoundObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebGLContextBoundObject(WebGLContext *context);
|
||||||
|
|
||||||
|
bool IsCompatibleWithContext(WebGLContext *other);
|
||||||
|
|
||||||
|
WebGLContext *Context() const { return mContext; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
WebGLContext *mContext;
|
||||||
|
uint32_t mContextGeneration;
|
||||||
|
};
|
||||||
|
|
||||||
|
}// namespace mozilla
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void
|
||||||
|
ImplCycleCollectionUnlink(mozilla::WebGLRefPtr<T>& aField)
|
||||||
|
{
|
||||||
|
aField = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void
|
||||||
|
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
|
||||||
|
mozilla::WebGLRefPtr<T>& aField,
|
||||||
|
const char* aName,
|
||||||
|
uint32_t aFlags = 0)
|
||||||
|
{
|
||||||
|
CycleCollectionNoteEdgeName(aCallback, aName, aFlags);
|
||||||
|
aCallback.NoteXPCOMChild(aField);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user