зеркало из https://github.com/mozilla/gecko-dev.git
Bug 738867 - Implement WebGL OES_element_index_uint extension. r=bjacob
This commit is contained in:
Родитель
a25810ce35
Коммит
68bdfcf2af
|
@ -48,9 +48,15 @@ T RandomInteger(T a, T b)
|
|||
template<typename T>
|
||||
GLenum GLType()
|
||||
{
|
||||
return sizeof(T) == 1
|
||||
? LOCAL_GL_UNSIGNED_BYTE
|
||||
: LOCAL_GL_UNSIGNED_SHORT;
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case 4: return LOCAL_GL_UNSIGNED_INT;
|
||||
case 2: return LOCAL_GL_UNSIGNED_SHORT;
|
||||
case 1: return LOCAL_GL_UNSIGNED_BYTE;
|
||||
default:
|
||||
VERIFY(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -79,6 +85,7 @@ void CheckValidate(WebGLElementArrayCache& c, size_t firstByte, size_t countByte
|
|||
{
|
||||
CheckValidateOneType<uint8_t>(c, firstByte, countBytes);
|
||||
CheckValidateOneType<uint16_t>(c, firstByte, countBytes);
|
||||
CheckValidateOneType<uint32_t>(c, firstByte, countBytes);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -151,6 +158,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
CheckSanity<uint8_t>();
|
||||
CheckSanity<uint16_t>();
|
||||
CheckSanity<uint32_t>();
|
||||
|
||||
CheckUintOverflow<uint8_t>();
|
||||
CheckUintOverflow<uint16_t>();
|
||||
|
|
|
@ -40,6 +40,7 @@ CPPSRCS += \
|
|||
WebGLExtensionCompressedTextureS3TC.cpp \
|
||||
WebGLExtensionDebugRendererInfo.cpp \
|
||||
WebGLExtensionDepthTexture.cpp \
|
||||
WebGLExtensionElementIndexUint.cpp \
|
||||
WebGLExtensionLoseContext.cpp \
|
||||
WebGLExtensionStandardDerivatives.cpp \
|
||||
WebGLExtensionTextureFilterAnisotropic.cpp \
|
||||
|
|
|
@ -943,6 +943,8 @@ bool WebGLContext::IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) con
|
|||
}
|
||||
|
||||
switch (ext) {
|
||||
case OES_element_index_uint:
|
||||
return !gl->IsGLES2() || gl->IsExtensionSupported(GLContext::OES_element_index_uint);
|
||||
case OES_standard_derivatives:
|
||||
case WEBGL_lose_context:
|
||||
// We always support these extensions.
|
||||
|
@ -1013,7 +1015,11 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& r
|
|||
WebGLExtensionID ext = WebGLExtensionID_unknown_extension;
|
||||
|
||||
// step 1: figure what extension is wanted
|
||||
if (CompareWebGLExtensionName(name, "OES_texture_float"))
|
||||
if (CompareWebGLExtensionName(name, "OES_element_index_uint"))
|
||||
{
|
||||
ext = OES_element_index_uint;
|
||||
}
|
||||
else if (CompareWebGLExtensionName(name, "OES_texture_float"))
|
||||
{
|
||||
ext = OES_texture_float;
|
||||
}
|
||||
|
@ -1075,6 +1081,9 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& r
|
|||
if (!IsExtensionEnabled(ext)) {
|
||||
WebGLExtensionBase *obj = nullptr;
|
||||
switch (ext) {
|
||||
case OES_element_index_uint:
|
||||
obj = new WebGLExtensionElementIndexUint(this);
|
||||
break;
|
||||
case OES_standard_derivatives:
|
||||
obj = new WebGLExtensionStandardDerivatives(this);
|
||||
break;
|
||||
|
@ -1439,6 +1448,8 @@ WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray<nsString>
|
|||
|
||||
nsTArray<nsString>& arr = retval.SetValue();
|
||||
|
||||
if (IsExtensionSupported(cx, OES_element_index_uint))
|
||||
arr.AppendElement(NS_LITERAL_STRING("OES_element_index_uint"));
|
||||
if (IsExtensionSupported(cx, OES_texture_float))
|
||||
arr.AppendElement(NS_LITERAL_STRING("OES_texture_float"));
|
||||
if (IsExtensionSupported(cx, OES_standard_derivatives))
|
||||
|
|
|
@ -912,6 +912,7 @@ protected:
|
|||
// extensions
|
||||
enum WebGLExtensionID {
|
||||
EXT_texture_filter_anisotropic,
|
||||
OES_element_index_uint,
|
||||
OES_standard_derivatives,
|
||||
OES_texture_float,
|
||||
WEBGL_compressed_texture_atc,
|
||||
|
|
|
@ -1511,6 +1511,11 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
|
|||
} else if (type == LOCAL_GL_UNSIGNED_BYTE) {
|
||||
checked_byteCount = count;
|
||||
first = byteOffset;
|
||||
} else if (type == LOCAL_GL_UNSIGNED_INT && IsExtensionEnabled(OES_element_index_uint)) {
|
||||
checked_byteCount = 4 * CheckedUint32(count);
|
||||
if (byteOffset % 4 != 0)
|
||||
return ErrorInvalidOperation("drawElements: invalid byteOffset for UNSIGNED_INT (must be a multiple of 4)");
|
||||
first = byteOffset / 4;
|
||||
} else {
|
||||
return ErrorInvalidEnum("drawElements: type must be UNSIGNED_SHORT or UNSIGNED_BYTE");
|
||||
}
|
||||
|
|
|
@ -106,8 +106,8 @@ namespace mozilla {
|
|||
* by having WebGLElementArrayCache lazily create trees for each type only upon first use.
|
||||
*
|
||||
* Another consequence of this constraint is that when invalidating the trees, we have to invalidate
|
||||
* all existing trees. So if trees for types uint8_t and uint16_t have ever been constructed for this buffer,
|
||||
* every subsequent invalidation will have to invalidate both trees even if one of the two types is never
|
||||
* all existing trees. So if trees for types uint8_t, uint16_t and uint32_t have ever been constructed for this buffer,
|
||||
* every subsequent invalidation will have to invalidate all trees even if one of the types is never
|
||||
* used again. This implies that it is important to minimize the cost of invalidation i.e.
|
||||
* do lazy updates upon use as opposed to immediately updating invalidated trees. This poses a problem:
|
||||
* it is nontrivial to keep track of the part of the tree that's invalidated. The current solution
|
||||
|
@ -329,6 +329,12 @@ struct TreeForType<uint16_t>
|
|||
static WebGLElementArrayCacheTree<uint16_t>*& Run(WebGLElementArrayCache *b) { return b->mUint16Tree; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TreeForType<uint32_t>
|
||||
{
|
||||
static WebGLElementArrayCacheTree<uint32_t>*& Run(WebGLElementArrayCache *b) { return b->mUint32Tree; }
|
||||
};
|
||||
|
||||
// When the buffer gets updated from firstByte to lastByte,
|
||||
// calling this method will notify the tree accordingly
|
||||
template<typename T>
|
||||
|
@ -441,6 +447,7 @@ void WebGLElementArrayCacheTree<T>::Update()
|
|||
WebGLElementArrayCache::~WebGLElementArrayCache() {
|
||||
delete mUint8Tree;
|
||||
delete mUint16Tree;
|
||||
delete mUint32Tree;
|
||||
free(mUntypedData);
|
||||
}
|
||||
|
||||
|
@ -452,6 +459,9 @@ bool WebGLElementArrayCache::BufferData(const void* ptr, size_t byteSize) {
|
|||
if (mUint16Tree)
|
||||
if (!mUint16Tree->ResizeToParentSize())
|
||||
return false;
|
||||
if (mUint32Tree)
|
||||
if (!mUint32Tree->ResizeToParentSize())
|
||||
return false;
|
||||
mUntypedData = realloc(mUntypedData, byteSize);
|
||||
if (!mUntypedData)
|
||||
return false;
|
||||
|
@ -474,6 +484,8 @@ void WebGLElementArrayCache::InvalidateTrees(size_t firstByte, size_t lastByte)
|
|||
mUint8Tree->Invalidate(firstByte, lastByte);
|
||||
if (mUint16Tree)
|
||||
mUint16Tree->Invalidate(firstByte, lastByte);
|
||||
if (mUint32Tree)
|
||||
mUint32Tree->Invalidate(firstByte, lastByte);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -541,16 +553,20 @@ bool WebGLElementArrayCache::Validate(GLenum type, uint32_t maxAllowed, size_t f
|
|||
return Validate<uint8_t>(maxAllowed, firstElement, countElements);
|
||||
if (type == LOCAL_GL_UNSIGNED_SHORT)
|
||||
return Validate<uint16_t>(maxAllowed, firstElement, countElements);
|
||||
if (type == LOCAL_GL_UNSIGNED_INT)
|
||||
return Validate<uint32_t>(maxAllowed, firstElement, countElements);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t WebGLElementArrayCache::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
|
||||
size_t uint8TreeSize = mUint8Tree ? mUint8Tree->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
size_t uint16TreeSize = mUint16Tree ? mUint16Tree->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
size_t uint32TreeSize = mUint32Tree ? mUint32Tree->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
return aMallocSizeOf(this) +
|
||||
mByteSize +
|
||||
uint8TreeSize +
|
||||
uint16TreeSize;
|
||||
uint16TreeSize +
|
||||
uint32TreeSize;
|
||||
}
|
||||
|
||||
} // end namespace mozilla
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
, mByteSize(0)
|
||||
, mUint8Tree(nullptr)
|
||||
, mUint16Tree(nullptr)
|
||||
, mUint32Tree(nullptr)
|
||||
{}
|
||||
|
||||
~WebGLElementArrayCache();
|
||||
|
@ -73,6 +74,7 @@ private:
|
|||
size_t mByteSize;
|
||||
WebGLElementArrayCacheTree<uint8_t>* mUint8Tree;
|
||||
WebGLElementArrayCacheTree<uint16_t>* mUint16Tree;
|
||||
WebGLElementArrayCacheTree<uint32_t>* mUint32Tree;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/* -*- 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 "WebGLContext.h"
|
||||
#include "WebGLExtensions.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
WebGLExtensionElementIndexUint::WebGLExtensionElementIndexUint(WebGLContext* context)
|
||||
: WebGLExtensionBase(context)
|
||||
{
|
||||
}
|
||||
|
||||
WebGLExtensionElementIndexUint::~WebGLExtensionElementIndexUint()
|
||||
{
|
||||
}
|
||||
|
||||
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionElementIndexUint)
|
|
@ -87,6 +87,16 @@ public:
|
|||
DECL_WEBGL_EXTENSION_GOOP
|
||||
};
|
||||
|
||||
class WebGLExtensionElementIndexUint
|
||||
: public WebGLExtensionBase
|
||||
{
|
||||
public:
|
||||
WebGLExtensionElementIndexUint(WebGLContext*);
|
||||
virtual ~WebGLExtensionElementIndexUint();
|
||||
|
||||
DECL_WEBGL_EXTENSION_GOOP
|
||||
};
|
||||
|
||||
class WebGLExtensionLoseContext
|
||||
: public WebGLExtensionBase
|
||||
{
|
||||
|
|
|
@ -1102,6 +1102,11 @@ DOMInterfaces = {
|
|||
'headerFile': 'WebGLExtensions.h'
|
||||
},
|
||||
|
||||
'WebGLExtensionElementIndexUint': {
|
||||
'nativeType': 'mozilla::WebGLExtensionElementIndexUint',
|
||||
'headerFile': 'WebGLExtensions.h'
|
||||
},
|
||||
|
||||
'WebGLExtensionLoseContext': {
|
||||
'nativeType': 'mozilla::WebGLExtensionLoseContext',
|
||||
'headerFile': 'WebGLExtensions.h'
|
||||
|
|
|
@ -806,6 +806,11 @@ interface WebGLExtensionDepthTexture
|
|||
const GLenum UNSIGNED_INT_24_8_WEBGL = 0x84FA;
|
||||
};
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface WebGLExtensionElementIndexUint
|
||||
{
|
||||
};
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface WebGLExtensionLoseContext {
|
||||
void loseContext();
|
||||
|
|
|
@ -80,6 +80,7 @@ static const char *sExtensionNames[] = {
|
|||
"GL_OES_EGL_sync",
|
||||
"GL_OES_EGL_image_external",
|
||||
"GL_EXT_packed_depth_stencil",
|
||||
"GL_OES_element_index_uint",
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
|
|
@ -1016,6 +1016,7 @@ public:
|
|||
OES_EGL_sync,
|
||||
OES_EGL_image_external,
|
||||
EXT_packed_depth_stencil,
|
||||
OES_element_index_uint,
|
||||
Extensions_Max
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче