Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2014-11-27 13:09:23 +01:00
Родитель 4f5336ec51 1d5f5053d1
Коммит c8aea269d3
287 изменённых файлов: 9199 добавлений и 5958 удалений

Просмотреть файл

@ -330,9 +330,22 @@ pref("media.video-queue.default-size", 3);
pref("image.mem.decodeondraw", true);
pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */
pref("image.mem.min_discard_timeout_ms", 86400000); /* 24h, we rely on the out of memory hook */
pref("image.mem.max_decoded_image_kb", 30000); /* 30MB seems reasonable */
// 65MB seems reasonable and layout/reftests/bugs/370629-1.html requires more than 62MB
// At this point 'max_decoded_image_kb' only applies to animated images. They're
// unfortunately fairly large, so this pref still needs to be somewhat generous,
// but it makes sense to reduce it since most types of images are now in the
// surface cache. Once animated images are stored in the surface cache too, this
// pref will go away; see bug 977459. The same goes for
// 'hard_limit_decoded_image_kb'; the surface cache limits are all hard.
pref("image.mem.max_decoded_image_kb", 30000);
pref("image.mem.hard_limit_decoded_image_kb", 66560);
// Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller.
// Almost everything that was factored into 'max_decoded_image_kb' is now stored
// in the surface cache. 1/8 of main memory is 32MB on a 256MB device, which is
// about the same as the old 'max_decoded_image_kb'.
pref("image.mem.surfacecache.max_size_kb", 131072); // 128MB
pref("image.mem.surfacecache.size_factor", 8); // 1/8 of main memory
pref("image.mem.surfacecache.discard_factor", 2); // Discard 1/2 of the surface cache at a time.
pref("image.mem.surfacecache.min_expiration_ms", 86400000); // 24h, we rely on the out of memory hook
pref("image.onload.decode.limit", 24); /* don't decode more than 24 images eagerly */
// XXX this isn't a good check for "are touch events supported", but

Просмотреть файл

@ -1742,7 +1742,11 @@ pref("ui.key.menuAccessKeyFocuses", true);
#endif
// Encrypted media extensions.
#ifdef RELEASE_BUILD
pref("media.eme.enabled", false);
#else
pref("media.eme.enabled", true);
#endif
// GMPInstallManager prefs

Просмотреть файл

@ -81,13 +81,14 @@ var gAllProgressListener = {
var gFrontNotifications, gAllNotifications, gFrontNotificationsPos, gAllNotificationsPos;
var gBackgroundTab, gForegroundTab, gBackgroundBrowser, gForegroundBrowser, gTestBrowser;
var gTestPage = "/browser/browser/base/content/test/general/alltabslistener.html";
const kBasePage = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
var gNextTest;
function test() {
waitForExplicitFinish();
gBackgroundTab = gBrowser.addTab("about:blank");
gForegroundTab = gBrowser.addTab("about:blank");
gBackgroundTab = gBrowser.addTab(kBasePage);
gForegroundTab = gBrowser.addTab(kBasePage);
gBackgroundBrowser = gBrowser.getBrowserForTab(gBackgroundTab);
gForegroundBrowser = gBrowser.getBrowserForTab(gForegroundTab);
gBrowser.selectedTab = gForegroundTab;

Просмотреть файл

@ -64,7 +64,7 @@
#ifdef HAVE_64BIT_BUILD
!define HAVE_64BIT_BUILD
!define ARCH "x64"
!define MinSupportedVer "Microsoft Windows Vista x64"
!define MinSupportedVer "Microsoft Windows 7 x64"
#else
!define ARCH "x86"
!define MinSupportedVer "Microsoft Windows XP SP2"

Просмотреть файл

@ -311,9 +311,9 @@ Function .onInit
${SetBrandNameVars} "$PLUGINSDIR\ignored.ini"
!ifdef HAVE_64BIT_BUILD
; Restrict x64 builds from being installed on x86 and pre Vista
; Restrict x64 builds from being installed on x86 and pre Win7
${Unless} ${RunningX64}
${OrUnless} ${AtLeastWinVista}
${OrUnless} ${AtLeastWin7}
MessageBox MB_OK|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_OS_MSG)"
Quit
${EndUnless}

Просмотреть файл

@ -43,7 +43,7 @@ public class SDKProcessor {
private static ApiLookup sApiLookup;
private static int sMaxSdkVersion;
public static void main(String[] args) {
public static void main(String[] args) throws Exception {
// We expect a list of jars on the commandline. If missing, whinge about it.
if (args.length < 5) {
System.err.println("Usage: java SDKProcessor sdkjar classlistfile outdir fileprefix max-sdk-version");
@ -106,16 +106,10 @@ public class SDKProcessor {
String className = i.next();
System.out.println("Looking up: " + className);
try {
Class<?> c = Class.forName(className, true, loader);
generateClass(Class.forName(className, true, loader),
stubInitializer,
implementationFile,
headerFile);
} catch (Exception e) {
System.out.println("Failed to generate class " + className + ": " + e);
}
}
implementationFile.append('\n');

Просмотреть файл

@ -2279,17 +2279,8 @@ ia64*-hpux*)
dnl For profile-guided optimization
PROFILE_GEN_CFLAGS="-GL"
PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT"
dnl XXX: PGO builds can fail with warnings treated as errors,
dnl specifically "no profile data available" appears to be
dnl treated as an error sometimes. This might be a consequence
dnl of using WARNINGS_AS_ERRORS in some modules, combined
dnl with the linker doing most of the work in the whole-program
dnl optimization/PGO case. I think it's probably a compiler bug,
dnl but we work around it here.
PROFILE_USE_CFLAGS="-GL -wd4624 -wd4952"
dnl XXX: should be -LTCG:PGOPTIMIZE, but that fails on libxul.
dnl Probably also a compiler bug, but what can you do?
PROFILE_USE_LDFLAGS="-LTCG:PGUPDATE"
PROFILE_USE_CFLAGS="-GL"
PROFILE_USE_LDFLAGS="-LTCG:PGOPTIMIZE"
LDFLAGS="$LDFLAGS -DYNAMICBASE"
dnl Minimum reqiurement of Gecko is VS2010 or later which supports
dnl both SSSE3 and SSE4.1.

Просмотреть файл

@ -16,7 +16,7 @@ class nsIWebNavigationInfo;
class nsIHttpChannel;
class nsAString;
class nsDSURIContentListener :
class nsDSURIContentListener MOZ_FINAL :
public nsIURIContentListener,
public nsSupportsWeakReference

Просмотреть файл

@ -36,7 +36,7 @@ namespace dom {
class AsyncVerifyRedirectCallbackFwr;
struct EventSourceInit;
class EventSource : public DOMEventTargetHelper
class EventSource MOZ_FINAL : public DOMEventTargetHelper
, public nsIObserver
, public nsIStreamListener
, public nsIChannelEventSink

Просмотреть файл

@ -173,8 +173,8 @@ load 830098.html
load 831287.html
load 832644.html
load 836890.html
skip-if(browserIsRemote) load 838489-1.html # <keygen> broken in e10s (bug 582297)
skip-if(browserIsRemote) load 838489-2.html # <keygen> broken in e10s (bug 582297)
load 838489-1.html
load 838489-2.html
load 841205.html
load 844404.html
load 845093-1.html

Просмотреть файл

@ -28,7 +28,7 @@
class nsDOMMutationObserver;
using mozilla::dom::MutationObservingInfo;
class nsDOMMutationRecord : public nsISupports,
class nsDOMMutationRecord MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
virtual ~nsDOMMutationRecord() {}
@ -337,7 +337,7 @@ public:
{ 0x0c3b91f8, 0xcc3b, 0x4b08, \
{ 0x9e, 0xab, 0x07, 0x47, 0xa9, 0xe4, 0x65, 0xb4 } }
class nsDOMMutationObserver : public nsISupports,
class nsDOMMutationObserver MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
public:

Просмотреть файл

@ -674,7 +674,7 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 904183 # b2g(bug 904183
[test_fileapi.html]
skip-if = e10s
[test_fileapi_slice.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #bug 775227
disabled = Busted on B2G, Android, E10S and now Mulet. Bug 775227.
[test_getElementById.html]
[test_html_colors_quirks.html]
[test_html_colors_standards.html]

Просмотреть файл

@ -25,9 +25,6 @@ WebGL1Context::~WebGL1Context()
{
}
////////////////////////////////////////
// nsWrapperCache
JSObject*
WebGL1Context::WrapObject(JSContext* cx)
{
@ -36,9 +33,6 @@ WebGL1Context::WrapObject(JSContext* cx)
} // namespace mozilla
////////////////////////////////////////
// nsIDOMWebGLRenderingContext
nsresult
NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** out_result)
{

Просмотреть файл

@ -4,16 +4,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGL2Context.h"
#include "GLContext.h"
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
using namespace mozilla;
using namespace mozilla::gl;
// -----------------------------------------------------------------------------
// CONSTRUCTOR & DESTRUCTOR
namespace mozilla {
WebGL2Context::WebGL2Context()
: WebGLContext()
@ -27,34 +24,25 @@ WebGL2Context::~WebGL2Context()
}
// -----------------------------------------------------------------------------
// STATIC FUNCTIONS
bool
/*static*/ bool
WebGL2Context::IsSupported()
{
return Preferences::GetBool("webgl.enable-prototype-webgl2", false);
}
WebGL2Context*
/*static*/ WebGL2Context*
WebGL2Context::Create()
{
return new WebGL2Context();
}
// -----------------------------------------------------------------------------
// IMPLEMENT nsWrapperCache
JSObject*
WebGL2Context::WrapObject(JSContext *cx)
WebGL2Context::WrapObject(JSContext* cx)
{
return dom::WebGL2RenderingContextBinding::Wrap(cx, this);
}
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
// WebGL 2 initialisation
bool
@ -76,15 +64,15 @@ WebGLContext::InitWebGL2()
WebGLExtensionID::WEBGL_depth_texture,
WebGLExtensionID::WEBGL_draw_buffers
};
const GLFeature sFeatureRequiredArr[] = {
GLFeature::instanced_non_arrays,
GLFeature::transform_feedback2,
GLFeature::invalidate_framebuffer
const gl::GLFeature sFeatureRequiredArr[] = {
gl::GLFeature::instanced_non_arrays,
gl::GLFeature::transform_feedback2,
gl::GLFeature::invalidate_framebuffer
};
// check WebGL extensions that are supposed to be natively supported
for (size_t i = 0; i < size_t(MOZ_ARRAY_LENGTH(sExtensionNativelySupportedArr)); i++)
{
size_t len = MOZ_ARRAY_LENGTH(sExtensionNativelySupportedArr);
for (size_t i = 0; i < len; i++) {
WebGLExtensionID extension = sExtensionNativelySupportedArr[i];
if (!IsExtensionSupported(extension)) {
@ -94,40 +82,42 @@ WebGLContext::InitWebGL2()
}
// check required OpenGL extensions
if (!gl->IsExtensionSupported(GLContext::EXT_gpu_shader4)) {
if (!gl->IsExtensionSupported(gl::GLContext::EXT_gpu_shader4)) {
GenerateWarning("WebGL 2 requires GL_EXT_gpu_shader4!");
return false;
}
// check OpenGL features
if (!gl->IsSupported(GLFeature::occlusion_query) &&
!gl->IsSupported(GLFeature::occlusion_query_boolean))
if (!gl->IsSupported(gl::GLFeature::occlusion_query) &&
!gl->IsSupported(gl::GLFeature::occlusion_query_boolean))
{
/*
* on desktop, we fake occlusion_query_boolean with occlusion_query if
* necessary. See WebGLContextAsyncQueries.cpp.
*/
// On desktop, we fake occlusion_query_boolean with occlusion_query if
//necessary. (See WebGLContextAsyncQueries.cpp)
GenerateWarning("WebGL 2 requires occlusion queries!");
return false;
}
for (size_t i = 0; i < size_t(MOZ_ARRAY_LENGTH(sFeatureRequiredArr)); i++)
{
for (size_t i = 0; i < size_t(MOZ_ARRAY_LENGTH(sFeatureRequiredArr)); i++) {
if (!gl->IsSupported(sFeatureRequiredArr[i])) {
GenerateWarning("WebGL 2 requires GLFeature::%s!", GLContext::GetFeatureName(sFeatureRequiredArr[i]));
GenerateWarning("WebGL 2 requires GLFeature::%s!",
gl::GLContext::GetFeatureName(sFeatureRequiredArr[i]));
return false;
}
}
// ok WebGL 2 is compatible, we can enable natively supported extensions.
for (size_t i = 0; i < size_t(MOZ_ARRAY_LENGTH(sExtensionNativelySupportedArr)); i++) {
len = MOZ_ARRAY_LENGTH(sExtensionNativelySupportedArr);
for (size_t i = 0; i < len; i++) {
EnableExtension(sExtensionNativelySupportedArr[i]);
MOZ_ASSERT(IsExtensionEnabled(sExtensionNativelySupportedArr[i]));
}
// we initialise WebGL 2 related stuff.
gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &mGLMaxTransformFeedbackSeparateAttribs);
gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
&mGLMaxTransformFeedbackSeparateAttribs);
return true;
}
} // namespace mozilla

Просмотреть файл

@ -33,7 +33,7 @@ public:
// -------------------------------------------------------------------------
// IMPLEMENT nsWrapperCache
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
// -------------------------------------------------------------------------

Просмотреть файл

@ -14,7 +14,7 @@ using namespace mozilla::dom;
* We fake ANY_SAMPLES_PASSED and ANY_SAMPLES_PASSED_CONSERVATIVE with
* SAMPLES_PASSED on desktop.
*
* OpenGL ES 3.0 spec 4.1.6
* OpenGL ES 3.0 spec 4.1.6:
* If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE, an
* implementation may choose to use a less precise version of the test which
* can additionally set the samples-boolean state to TRUE in some other
@ -88,9 +88,9 @@ WebGL2Context::CreateQuery()
* any target is active causes an INVALID_OPERATION error to be
* generated.
*/
GenerateWarning("createQuery: the WebGL 2 prototype might generate "
"INVALID_OPERATION when creating a query object while "
"one other is active.");
GenerateWarning("createQuery: The WebGL 2 prototype might generate"
" INVALID_OPERATION when creating a query object while"
" one other is active.");
/*
* We *need* to lock webgl2 to GL>=3.0 on desktop, but we don't have a
* good mechanism to do this yet. See bug 898404.
@ -124,9 +124,9 @@ WebGL2Context::DeleteQuery(WebGLQuery* query)
* any target is active causes an INVALID_OPERATION error to be
* generated.
*/
GenerateWarning("deleteQuery: the WebGL 2 prototype might generate "
"INVALID_OPERATION when deleting a query object while "
"one other is active.");
GenerateWarning("deleteQuery: The WebGL 2 prototype might generate"
" INVALID_OPERATION when deleting a query object while"
" one other is active.");
}
query->RequestDelete();
@ -159,59 +159,56 @@ WebGL2Context::BeginQuery(GLenum target, WebGLQuery* query)
}
if (!query) {
/* SPECS BeginQuery.1
* http://www.khronos.org/registry/gles/extensions/EXT/EXT_occlusion_query_boolean.txt
* BeginQueryEXT sets the active query object name for the query type given
* by <target> to <id>. If BeginQueryEXT is called with an <id> of zero, if
* the active query object name for <target> is non-zero (for the targets
* ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if the
* active query for either target is non-zero), if <id> is the name of an
* existing query object whose type does not match <target>, or if <id> is the
* active query object name for any query type, the error INVALID_OPERATION is
* generated.
/* From GLES's EXT_occlusion_query_boolean:
* BeginQueryEXT sets the active query object name for the query
* type given by <target> to <id>. If BeginQueryEXT is called with
* an <id> of zero, if the active query object name for <target> is
* non-zero (for the targets ANY_SAMPLES_PASSED_EXT and
* ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if the active query for
* either target is non-zero), if <id> is the name of an existing
* query object whose type does not match <target>, or if <id> is
* the active query object name for any query type, the error
* INVALID_OPERATION is generated.
*/
ErrorInvalidOperation("beginQuery: query should not be null");
ErrorInvalidOperation("beginQuery: Query should not be null.");
return;
}
if (query->IsDeleted()) {
/* http://www.khronos.org/registry/gles/extensions/EXT/EXT_occlusion_query_boolean.txt
* BeginQueryEXT fails and an INVALID_OPERATION error is generated if <id>
* is not a name returned from a previous call to GenQueriesEXT, or if such
* a name has since been deleted with DeleteQueriesEXT.
/* From GLES's EXT_occlusion_query_boolean:
* BeginQueryEXT fails and an INVALID_OPERATION error is generated
* if <id> is not a name returned from a previous call to
* GenQueriesEXT, or if such a name has since been deleted with
* DeleteQueriesEXT.
*/
ErrorInvalidOperation("beginQuery: query has been deleted");
ErrorInvalidOperation("beginQuery: Query has been deleted.");
return;
}
if (query->HasEverBeenActive() &&
query->mType != target)
{
/*
* See SPECS BeginQuery.1
*/
ErrorInvalidOperation("beginQuery: target doesn't match with the query type");
ErrorInvalidOperation("beginQuery: Target doesn't match with the query"
" type.");
return;
}
if (*targetSlot) {
/*
* See SPECS BeginQuery.1
*/
ErrorInvalidOperation("beginQuery: an other query already active");
ErrorInvalidOperation("beginQuery: An other query already active.");
return;
}
if (!query->HasEverBeenActive()) {
if (!query->HasEverBeenActive())
query->mType = target;
}
MakeContextCurrent();
if (target == LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) {
gl->fBeginQuery(LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query->mGLName);
gl->fBeginQuery(LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
query->mGLName);
} else {
gl->fBeginQuery(SimulateOcclusionQueryTarget(gl, target), query->mGLName);
gl->fBeginQuery(SimulateOcclusionQueryTarget(gl, target),
query->mGLName);
}
*targetSlot = query;
@ -229,18 +226,21 @@ WebGL2Context::EndQuery(GLenum target)
return;
}
if (!*targetSlot || target != (*targetSlot)->mType) {
/* http://www.khronos.org/registry/gles/extensions/EXT/EXT_occlusion_query_boolean.txt
* marks the end of the sequence of commands to be tracked for the query type
* given by <target>. The active query object for <target> is updated to
* indicate that query results are not available, and the active query object
* name for <target> is reset to zero. When the commands issued prior to
* EndQueryEXT have completed and a final query result is available, the
* query object active when EndQueryEXT is called is updated by the GL. The
* query object is updated to indicate that the query results are available
* and to contain the query result. If the active query object name for
* <target> is zero when EndQueryEXT is called, the error INVALID_OPERATION
* is generated.
if (!*targetSlot ||
target != (*targetSlot)->mType)
{
/* From GLES's EXT_occlusion_query_boolean:
* marks the end of the sequence of commands to be tracked for the
* query type given by <target>. The active query object for
* <target> is updated to indicate that query results are not
* available, and the active query object name for <target> is reset
* to zero. When the commands issued prior to EndQueryEXT have
* completed and a final query result is available, the query object
* active when EndQueryEXT is called is updated by the GL. The query
* object is updated to indicate that the query results are
* available and to contain the query result. If the active query
* object name for <target> is zero when EndQueryEXT is called, the
* error INVALID_OPERATION is generated.
*/
ErrorInvalidOperation("endQuery: There is no active query of type %s.",
GetQueryTargetEnumString(target));
@ -271,10 +271,10 @@ WebGL2Context::GetQuery(GLenum target, GLenum pname)
}
if (pname != LOCAL_GL_CURRENT_QUERY) {
/* OpenGL ES 3.0 spec 6.1.7
/* OpenGL ES 3.0 spec 6.1.7:
* pname must be CURRENT_QUERY.
*/
ErrorInvalidEnum("getQuery: pname must be CURRENT_QUERY");
ErrorInvalidEnum("getQuery: `pname` must be CURRENT_QUERY.");
return nullptr;
}
@ -283,7 +283,8 @@ WebGL2Context::GetQuery(GLenum target, GLenum pname)
}
void
WebGL2Context::GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname, JS::MutableHandleValue retval)
WebGL2Context::GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname,
JS::MutableHandleValue retval)
{
retval.set(JS::NullValue());
@ -291,33 +292,34 @@ WebGL2Context::GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname, JS
return;
if (!query) {
/* OpenGL ES 3.0 spec 6.1.7 (spec getQueryObject 1)
* If id is not the name of a query object, or if the query object named by id is
* currently active, then an INVALID_OPERATION error is generated. pname must be
* QUERY_RESULT or QUERY_RESULT_AVAILABLE.
/* OpenGL ES 3.0 spec 6.1.7 (spec getQueryObject 1):
* If id is not the name of a query object, or if the query object
* named by id is currently active, then an INVALID_OPERATION error
* is generated. pname must be QUERY_RESULT or
* QUERY_RESULT_AVAILABLE.
*/
ErrorInvalidOperation("getQueryObject: query should not be null");
ErrorInvalidOperation("getQueryObject: `query` should not be null.");
return;
}
if (query->IsDeleted()) {
// See (spec getQueryObject 1)
ErrorInvalidOperation("getQueryObject: query has been deleted");
ErrorInvalidOperation("getQueryObject: `query` has been deleted.");
return;
}
if (query->IsActive()) {
// See (spec getQueryObject 1)
ErrorInvalidOperation("getQueryObject: query is active");
ErrorInvalidOperation("getQueryObject: `query` is active.");
return;
}
if (!query->HasEverBeenActive()) {
/* See (spec getQueryObject 1)
* If this instance of WebGLQuery has never been active before, that mean that
* query->mGLName is not a query object yet.
* If this instance of WebGLQuery has never been active before, that
* mean that query->mGLName is not a query object yet.
*/
ErrorInvalidOperation("getQueryObject: query has never been active");
ErrorInvalidOperation("getQueryObject: `query` has never been active.");
return;
}
@ -349,5 +351,5 @@ WebGL2Context::GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname, JS
break;
}
ErrorInvalidEnum("getQueryObject: pname must be QUERY_RESULT{_AVAILABLE}");
ErrorInvalidEnum("getQueryObject: `pname` must be QUERY_RESULT{_AVAILABLE}.");
}

Просмотреть файл

@ -90,7 +90,7 @@ WebGL2Context::ValidateTexStorage(GLenum target, GLsizei levels, GLenum internal
const char* info)
{
// GL_INVALID_OPERATION is generated if the default texture object is curently bound to target.
WebGLTexture* tex = activeBoundTextureForTarget(target);
WebGLTexture* tex = ActiveBoundTextureForTarget(target);
if (!tex) {
ErrorInvalidOperation("%s: no texture is bound to target %s", info, EnumName(target));
return false;
@ -145,7 +145,7 @@ WebGL2Context::TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat
return GenerateWarning("texStorage2D generated error %s", ErrorName(error));
}
WebGLTexture* tex = activeBoundTextureForTarget(target);
WebGLTexture* tex = ActiveBoundTextureForTarget(target);
tex->SetImmutable();
const size_t facesCount = (target == LOCAL_GL_TEXTURE_2D) ? 1 : 6;
@ -184,7 +184,7 @@ WebGL2Context::TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat
return GenerateWarning("texStorage3D generated error %s", ErrorName(error));
}
WebGLTexture* tex = activeBoundTextureForTarget(target);
WebGLTexture* tex = ActiveBoundTextureForTarget(target);
tex->SetImmutable();
GLsizei w = width;
@ -275,7 +275,7 @@ WebGL2Context::TexImage3D(GLenum target, GLint level, GLenum internalformat,
return ErrorInvalidOperation("texImage3D: not enough data for operation (need %d, have %d)",
bytesNeeded, dataLength);
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("texImage3D: no texture is bound to this target");
@ -338,7 +338,7 @@ WebGL2Context::TexSubImage3D(GLenum rawTarget, GLint level,
TexImageTarget texImageTarget(rawTarget);
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
if (!tex) {
return ErrorInvalidOperation("texSubImage3D: no texture bound on active texture unit");
}

Просмотреть файл

@ -3,13 +3,18 @@
* 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 "WebGLActiveInfo.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
#include "WebGLTexture.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
using namespace mozilla;
namespace mozilla {
JSObject*
WebGLActiveInfo::WrapObject(JSContext *cx) {
WebGLActiveInfo::WrapObject(JSContext* cx)
{
return dom::WebGLActiveInfoBinding::Wrap(cx, this);
}
} // namespace mozilla

Просмотреть файл

@ -3,22 +3,22 @@
* 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 WEBGLACTIVEINFO_H_
#define WEBGLACTIVEINFO_H_
#ifndef WEBGL_ACTIVE_INFO_H_
#define WEBGL_ACTIVE_INFO_H_
#include "WebGLObjectModel.h"
#include "nsString.h"
#include "js/TypeDecls.h"
#include "nsString.h"
#include "WebGLObjectModel.h"
namespace mozilla {
class WebGLActiveInfo MOZ_FINAL
{
public:
WebGLActiveInfo(GLint size, GLenum type, const nsACString& name) :
mSize(size),
mType(type),
mName(NS_ConvertASCIItoUTF16(name))
WebGLActiveInfo(GLint size, GLenum type, const nsACString& name)
: mSize(size)
, mType(type)
, mName(NS_ConvertASCIItoUTF16(name))
{}
// WebIDL attributes
@ -35,7 +35,7 @@ public:
retval = mName;
}
JSObject* WrapObject(JSContext *cx);
JSObject* WrapObject(JSContext* cx);
NS_INLINE_DECL_REFCOUNTING(WebGLActiveInfo)
@ -52,4 +52,4 @@ private:
} // namespace mozilla
#endif
#endif // WEBGL_ACTIVE_INFO_H_

Просмотреть файл

@ -10,22 +10,24 @@
#include "WebGLContext.h"
#include "WebGLElementArrayCache.h"
using namespace mozilla;
namespace mozilla {
WebGLBuffer::WebGLBuffer(WebGLContext* context, GLuint buf)
WebGLBuffer::WebGLBuffer(WebGLContext* webgl, GLuint buf)
: WebGLBindableName<BufferBinding>(buf)
, WebGLContextBoundObject(context)
, WebGLContextBoundObject(webgl)
, mByteLength(0)
{
mContext->mBuffers.insertBack(this);
}
WebGLBuffer::~WebGLBuffer() {
WebGLBuffer::~WebGLBuffer()
{
DeleteOnce();
}
void
WebGLBuffer::Delete() {
WebGLBuffer::Delete()
{
mContext->MakeContextCurrent();
mContext->gl->fDeleteBuffers(1, &mGLName);
mByteLength = 0;
@ -34,37 +36,43 @@ WebGLBuffer::Delete() {
}
void
WebGLBuffer::OnTargetChanged() {
WebGLBuffer::OnTargetChanged()
{
if (!mCache && mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
mCache = new WebGLElementArrayCache;
}
bool
WebGLBuffer::ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes) {
WebGLBuffer::ElementArrayCacheBufferData(const void* ptr,
size_t bufferSizeInBytes)
{
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
return mCache->BufferData(ptr, buffer_size_in_bytes);
return mCache->BufferData(ptr, bufferSizeInBytes);
return true;
}
void
WebGLBuffer::ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes) {
WebGLBuffer::ElementArrayCacheBufferSubData(size_t pos, const void* ptr,
size_t updateSizeInBytes)
{
if (mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
mCache->BufferSubData(pos, ptr, update_size_in_bytes);
mCache->BufferSubData(pos, ptr, updateSizeInBytes);
}
size_t
WebGLBuffer::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
WebGLBuffer::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
{
size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
return aMallocSizeOf(this) + sizeOfCache;
size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(mallocSizeOf)
: 0;
return mallocSizeOf(this) + sizeOfCache;
}
bool
WebGLBuffer::Validate(GLenum type, uint32_t max_allowed,
size_t first, size_t count,
uint32_t* out_upperBound)
WebGLBuffer::Validate(GLenum type, uint32_t maxAllowed, size_t first,
size_t count, uint32_t* const out_upperBound)
{
return mCache->Validate(type, max_allowed, first, count, out_upperBound);
return mCache->Validate(type, maxAllowed, first, count, out_upperBound);
}
bool
@ -74,7 +82,8 @@ WebGLBuffer::IsElementArrayUsedWithMultipleTypes() const
}
JSObject*
WebGLBuffer::WrapObject(JSContext *cx) {
WebGLBuffer::WrapObject(JSContext* cx)
{
return dom::WebGLBufferBinding::Wrap(cx, this);
}
@ -82,3 +91,5 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLBuffer)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLBuffer, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLBuffer, Release)
} // namespace mozilla

Просмотреть файл

@ -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 WEBGLBUFFER_H_
#define WEBGLBUFFER_H_
#ifndef WEBGL_BUFFER_H_
#define WEBGL_BUFFER_H_
#include "GLDefs.h"
#include "mozilla/LinkedList.h"
@ -12,8 +12,8 @@
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "WebGLTypes.h"
#include "WebGLStrongTypes.h"
#include "WebGLTypes.h"
namespace mozilla {
@ -27,30 +27,30 @@ class WebGLBuffer MOZ_FINAL
, public WebGLContextBoundObject
{
public:
explicit WebGLBuffer(WebGLContext* context, GLuint buf);
explicit WebGLBuffer(WebGLContext* webgl, GLuint buf);
void Delete();
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
WebGLsizeiptr ByteLength() const { return mByteLength; }
void SetByteLength(WebGLsizeiptr byteLength) { mByteLength = byteLength; }
bool ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes);
bool ElementArrayCacheBufferData(const void* ptr, size_t bufferSizeInBytes);
void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes);
void ElementArrayCacheBufferSubData(size_t pos, const void* ptr,
size_t updateSizeInBytes);
bool Validate(GLenum type, uint32_t max_allowed, size_t first, size_t count,
uint32_t* out_upperBound);
uint32_t* const out_upperBound);
bool IsElementArrayUsedWithMultipleTypes() const;
WebGLContext *GetParentObject() const {
WebGLContext* GetParentObject() const {
return Context();
}
};
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLBuffer)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLBuffer)
@ -61,8 +61,9 @@ protected:
virtual void OnTargetChanged() MOZ_OVERRIDE;
WebGLsizeiptr mByteLength;
nsAutoPtr<WebGLElementArrayCache> mCache;
};
}
#endif //WEBGLBUFFER_H_
} // namespace mozilla
#endif // WEBGL_BUFFER_H_

Просмотреть файл

@ -5,9 +5,48 @@
#include "WebGLContext.h"
#include "WebGLContextLossHandler.h"
#include "AccessCheck.h"
#include "CanvasUtils.h"
#include "gfxContext.h"
#include "gfxCrashReporterUtils.h"
#include "gfxPattern.h"
#include "gfxPrefs.h"
#include "gfxUtils.h"
#include "GLBlitHelper.h"
#include "GLContext.h"
#include "GLContextProvider.h"
#include "GLReadTexImageHelper.h"
#include "ImageContainer.h"
#include "ImageEncoder.h"
#include "Layers.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "mozilla/EnumeratedArrayCycleCollection.h"
#include "mozilla/Preferences.h"
#include "mozilla/ProcessPriorityManager.h"
#include "mozilla/Services.h"
#include "mozilla/Telemetry.h"
#include "nsContentUtils.h"
#include "nsDisplayList.h"
#include "nsError.h"
#include "nsIClassInfoImpl.h"
#include "nsIConsoleService.h"
#include "nsIGfxInfo.h"
#include "nsIObserverService.h"
#include "nsIDOMEvent.h"
#include "nsIVariant.h"
#include "nsIWidget.h"
#include "nsIXPConnect.h"
#include "nsServiceManagerUtils.h"
#include "nsSVGEffects.h"
#include "prenv.h"
#include <queue>
#include "ScopedGLHelpers.h"
#include "WebGL1Context.h"
#include "WebGLBuffer.h"
#include "WebGLContextLossHandler.h"
#include "WebGLContextUtils.h"
#include "WebGLExtensions.h"
#include "WebGLFramebuffer.h"
@ -18,71 +57,18 @@
#include "WebGLVertexArray.h"
#include "WebGLVertexAttribData.h"
#include "GLBlitHelper.h"
#include "AccessCheck.h"
#include "nsIConsoleService.h"
#include "nsServiceManagerUtils.h"
#include "nsIClassInfoImpl.h"
#include "nsContentUtils.h"
#include "nsIXPConnect.h"
#include "nsError.h"
#include "nsIGfxInfo.h"
#include "nsIWidget.h"
#include "nsIVariant.h"
#include "ImageEncoder.h"
#include "ImageContainer.h"
#include "gfxContext.h"
#include "gfxPattern.h"
#include "gfxPrefs.h"
#include "gfxUtils.h"
#include "CanvasUtils.h"
#include "nsDisplayList.h"
#include "GLContextProvider.h"
#include "GLContext.h"
#include "ScopedGLHelpers.h"
#include "GLReadTexImageHelper.h"
#include "gfxCrashReporterUtils.h"
#include "nsSVGEffects.h"
#include "prenv.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/Telemetry.h"
#include "nsIObserverService.h"
#include "nsIDOMEvent.h"
#include "mozilla/Services.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/ImageData.h"
#include "mozilla/ProcessPriorityManager.h"
#include "mozilla/EnumeratedArrayCycleCollection.h"
#include "Layers.h"
#ifdef MOZ_WIDGET_GONK
#include "mozilla/layers/ShadowLayers.h"
#endif
#include <queue>
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::gfx;
using namespace mozilla::gl;
using namespace mozilla::layers;
WebGLObserver::WebGLObserver(WebGLContext* aContext)
: mContext(aContext)
WebGLObserver::WebGLObserver(WebGLContext* webgl)
: mWebGL(webgl)
{
}
@ -95,71 +81,62 @@ WebGLObserver::Destroy()
{
UnregisterMemoryPressureEvent();
UnregisterVisibilityChangeEvent();
mContext = nullptr;
mWebGL = nullptr;
}
void
WebGLObserver::RegisterVisibilityChangeEvent()
{
if (!mContext) {
if (!mWebGL)
return;
}
HTMLCanvasElement* canvasElement = mContext->GetCanvas();
HTMLCanvasElement* canvas = mWebGL->GetCanvas();
MOZ_ASSERT(canvas);
MOZ_ASSERT(canvasElement);
if (canvasElement) {
nsIDocument* document = canvasElement->OwnerDoc();
if (canvas) {
nsIDocument* document = canvas->OwnerDoc();
document->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
this,
true,
false);
this, true, false);
}
}
void
WebGLObserver::UnregisterVisibilityChangeEvent()
{
if (!mContext) {
if (!mWebGL)
return;
}
HTMLCanvasElement* canvasElement = mContext->GetCanvas();
HTMLCanvasElement* canvas = mWebGL->GetCanvas();
if (canvasElement) {
nsIDocument* document = canvasElement->OwnerDoc();
if (canvas) {
nsIDocument* document = canvas->OwnerDoc();
document->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
this,
true);
this, true);
}
}
void
WebGLObserver::RegisterMemoryPressureEvent()
{
if (!mContext) {
if (!mWebGL)
return;
}
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
MOZ_ASSERT(observerService);
if (observerService) {
if (observerService)
observerService->AddObserver(this, "memory-pressure", false);
}
}
void
WebGLObserver::UnregisterMemoryPressureEvent()
{
if (!mContext) {
if (!mWebGL)
return;
}
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
@ -167,59 +144,55 @@ WebGLObserver::UnregisterMemoryPressureEvent()
// Do not assert on observerService here. This might be triggered by
// the cycle collector at a late enough time, that XPCOM services are
// no longer available. See bug 1029504.
if (observerService) {
if (observerService)
observerService->RemoveObserver(this, "memory-pressure");
}
}
NS_IMETHODIMP
WebGLObserver::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aSomeData)
WebGLObserver::Observe(nsISupports*, const char* topic, const char16_t*)
{
if (!mContext || strcmp(aTopic, "memory-pressure")) {
if (!mWebGL || strcmp(topic, "memory-pressure")) {
return NS_OK;
}
bool wantToLoseContext = mContext->mLoseContextOnMemoryPressure;
bool wantToLoseContext = mWebGL->mLoseContextOnMemoryPressure;
if (!mContext->mCanLoseContextInForeground &&
if (!mWebGL->mCanLoseContextInForeground &&
ProcessPriorityManager::CurrentProcessIsForeground())
{
wantToLoseContext = false;
}
if (wantToLoseContext) {
mContext->ForceLoseContext();
}
if (wantToLoseContext)
mWebGL->ForceLoseContext();
return NS_OK;
}
NS_IMETHODIMP
WebGLObserver::HandleEvent(nsIDOMEvent* aEvent)
WebGLObserver::HandleEvent(nsIDOMEvent* event)
{
nsAutoString type;
aEvent->GetType(type);
if (!mContext || !type.EqualsLiteral("visibilitychange")) {
event->GetType(type);
if (!mWebGL || !type.EqualsLiteral("visibilitychange"))
return NS_OK;
}
HTMLCanvasElement* canvasElement = mContext->GetCanvas();
HTMLCanvasElement* canvas = mWebGL->GetCanvas();
MOZ_ASSERT(canvas);
MOZ_ASSERT(canvasElement);
if (canvasElement && !canvasElement->OwnerDoc()->Hidden()) {
mContext->ForceRestoreContext();
}
if (canvas && !canvas->OwnerDoc()->Hidden())
mWebGL->ForceRestoreContext();
return NS_OK;
}
WebGLContextOptions::WebGLContextOptions()
: alpha(true), depth(true), stencil(false),
premultipliedAlpha(true), antialias(true),
preserveDrawingBuffer(false)
: alpha(true)
, depth(true)
, stencil(false)
, premultipliedAlpha(true)
, antialias(true)
, preserveDrawingBuffer(false)
{
// Set default alpha state based on preference.
if (Preferences::GetBool("webgl.default-no-alpha", false))
@ -301,9 +274,9 @@ WebGLContext::WebGLContext()
mAlreadyGeneratedWarnings = 0;
mAlreadyWarnedAboutFakeVertexAttrib0 = false;
mAlreadyWarnedAboutViewportLargerThanDest = false;
mMaxWarnings = Preferences::GetInt("webgl.max-warnings-per-context", 32);
if (mMaxWarnings < -1)
{
if (mMaxWarnings < -1) {
GenerateWarning("webgl.max-warnings-per-context size is too large (seems like a negative value wrapped)");
mMaxWarnings = 0;
}
@ -380,9 +353,8 @@ WebGLContext::DestroyResourcesAndContext()
mBlackTransparentTexture2D = nullptr;
mBlackTransparentTextureCubeMap = nullptr;
if (mFakeVertexAttrib0BufferObject) {
if (mFakeVertexAttrib0BufferObject)
gl->fDeleteBuffers(1, &mFakeVertexAttrib0BufferObject);
}
// disable all extensions except "WEBGL_lose_context". see bug #927969
// spec: http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
@ -399,9 +371,8 @@ WebGLContext::DestroyResourcesAndContext()
// We just got rid of everything, so the context had better
// have been going away.
#ifdef DEBUG
if (gl->DebugMode()) {
if (gl->DebugMode())
printf_stderr("--- WebGL context destroyed: %p\n", gl.get());
}
#endif
gl = nullptr;
@ -427,14 +398,13 @@ WebGLContext::Invalidate()
//
NS_IMETHODIMP
WebGLContext::SetContextOptions(JSContext* aCx, JS::Handle<JS::Value> aOptions)
WebGLContext::SetContextOptions(JSContext* cx, JS::Handle<JS::Value> options)
{
if (aOptions.isNullOrUndefined() && mOptionsFrozen) {
if (options.isNullOrUndefined() && mOptionsFrozen)
return NS_OK;
}
WebGLContextAttributes attributes;
NS_ENSURE_TRUE(attributes.Init(aCx, aOptions), NS_ERROR_UNEXPECTED);
NS_ENSURE_TRUE(attributes.Init(cx, options), NS_ERROR_UNEXPECTED);
WebGLContextOptions newOpts;
@ -444,14 +414,12 @@ WebGLContext::SetContextOptions(JSContext* aCx, JS::Handle<JS::Value> aOptions)
newOpts.antialias = attributes.mAntialias;
newOpts.preserveDrawingBuffer = attributes.mPreserveDrawingBuffer;
if (attributes.mAlpha.WasPassed()) {
if (attributes.mAlpha.WasPassed())
newOpts.alpha = attributes.mAlpha.Value();
}
// Don't do antialiasing if we've disabled MSAA.
if (!gfxPrefs::MSAALevel()) {
if (!gfxPrefs::MSAALevel())
newOpts.antialias = false;
}
#if 0
GenerateWarning("aaHint: %d stencil: %d depth: %d alpha: %d premult: %d preserve: %d\n",
@ -515,8 +483,7 @@ IsFeatureInBlacklist(const nsCOMPtr<nsIGfxInfo>& gfxInfo, int32_t feature)
}
static already_AddRefed<GLContext>
CreateHeadlessNativeGL(bool forceEnabled,
const nsCOMPtr<nsIGfxInfo>& gfxInfo,
CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
WebGLContext* webgl)
{
if (!forceEnabled &&
@ -541,8 +508,7 @@ CreateHeadlessNativeGL(bool forceEnabled,
// right now, we get ANGLE implicitly by using EGL on Windows.
// Eventually, we want to be able to pick ANGLE-EGL or native EGL.
static already_AddRefed<GLContext>
CreateHeadlessANGLE(bool forceEnabled,
const nsCOMPtr<nsIGfxInfo>& gfxInfo,
CreateHeadlessANGLE(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
WebGLContext* webgl)
{
nsRefPtr<GLContext> gl;
@ -568,8 +534,7 @@ CreateHeadlessANGLE(bool forceEnabled,
}
static already_AddRefed<GLContext>
CreateHeadlessEGL(bool forceEnabled,
const nsCOMPtr<nsIGfxInfo>& gfxInfo,
CreateHeadlessEGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
WebGLContext* webgl)
{
nsRefPtr<GLContext> gl;
@ -588,16 +553,14 @@ CreateHeadlessEGL(bool forceEnabled,
static already_AddRefed<GLContext>
CreateHeadlessGL(bool forceEnabled,
const nsCOMPtr<nsIGfxInfo>& gfxInfo,
CreateHeadlessGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
WebGLContext* webgl)
{
bool preferEGL = PR_GetEnv("MOZ_WEBGL_PREFER_EGL");
bool disableANGLE = Preferences::GetBool("webgl.disable-angle", false);
if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL")) {
if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL"))
disableANGLE = true;
}
nsRefPtr<GLContext> gl;
@ -623,9 +586,9 @@ CreateOffscreenWithCaps(GLContext* gl, const SurfaceCaps& caps)
static void
PopulateCapFallbackQueue(const SurfaceCaps& baseCaps,
std::queue<SurfaceCaps>* fallbackCaps)
std::queue<SurfaceCaps>* out_fallbackCaps)
{
fallbackCaps->push(baseCaps);
out_fallbackCaps->push(baseCaps);
// Dropping antialias drops our quality, but not our correctness.
// The user basically doesn't have to handle if this fails, they
@ -633,7 +596,7 @@ PopulateCapFallbackQueue(const SurfaceCaps& baseCaps,
if (baseCaps.antialias) {
SurfaceCaps nextCaps(baseCaps);
nextCaps.antialias = false;
PopulateCapFallbackQueue(nextCaps, fallbackCaps);
PopulateCapFallbackQueue(nextCaps, out_fallbackCaps);
}
// If we have to drop one of depth or stencil, we'd prefer to keep
@ -642,21 +605,19 @@ PopulateCapFallbackQueue(const SurfaceCaps& baseCaps,
if (baseCaps.stencil) {
SurfaceCaps nextCaps(baseCaps);
nextCaps.stencil = false;
PopulateCapFallbackQueue(nextCaps, fallbackCaps);
PopulateCapFallbackQueue(nextCaps, out_fallbackCaps);
}
if (baseCaps.depth) {
SurfaceCaps nextCaps(baseCaps);
nextCaps.depth = false;
PopulateCapFallbackQueue(nextCaps, fallbackCaps);
PopulateCapFallbackQueue(nextCaps, out_fallbackCaps);
}
}
static bool
CreateOffscreen(GLContext* gl,
const WebGLContextOptions& options,
const nsCOMPtr<nsIGfxInfo>& gfxInfo,
WebGLContext* webgl,
CreateOffscreen(GLContext* gl, const WebGLContextOptions& options,
const nsCOMPtr<nsIGfxInfo>& gfxInfo, WebGLContext* webgl,
layers::ISurfaceAllocator* surfAllocator)
{
SurfaceCaps baseCaps;
@ -728,11 +689,10 @@ WebGLContext::CreateOffscreenGL(bool forceEnabled)
if (layerManager) {
// XXX we really want "AsSurfaceAllocator" here for generality
layers::ShadowLayerForwarder* forwarder = layerManager->AsShadowForwarder();
if (forwarder) {
if (forwarder)
surfAllocator = static_cast<layers::ISurfaceAllocator*>(forwarder);
}
}
}
#endif
gl = CreateHeadlessGL(forceEnabled, gfxInfo, this);
@ -756,7 +716,8 @@ WebGLContext::CreateOffscreenGL(bool forceEnabled)
// Fallback for resizes:
bool
WebGLContext::ResizeBackbuffer(uint32_t requestedWidth, uint32_t requestedHeight)
WebGLContext::ResizeBackbuffer(uint32_t requestedWidth,
uint32_t requestedHeight)
{
uint32_t width = requestedWidth;
uint32_t height = requestedHeight;
@ -795,32 +756,30 @@ WebGLContext::ResizeBackbuffer(uint32_t requestedWidth, uint32_t requestedHeight
return true;
}
NS_IMETHODIMP
WebGLContext::SetDimensions(int32_t sWidth, int32_t sHeight)
WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
{
// Early error return cases
if (!GetCanvas())
return NS_ERROR_FAILURE;
if (sWidth < 0 || sHeight < 0) {
if (signedWidth < 0 || signedHeight < 0) {
GenerateWarning("Canvas size is too large (seems like a negative value wrapped)");
return NS_ERROR_OUT_OF_MEMORY;
}
uint32_t width = sWidth;
uint32_t height = sHeight;
uint32_t width = signedWidth;
uint32_t height = signedHeight;
// Early success return cases
GetCanvas()->InvalidateCanvas();
// Zero-sized surfaces can cause problems.
if (width == 0) {
if (width == 0)
width = 1;
}
if (height == 0) {
if (height == 0)
height = 1;
}
// If we already have a gl context, then we just need to resize it
if (gl) {
@ -901,9 +860,8 @@ WebGLContext::SetDimensions(int32_t sWidth, int32_t sHeight)
}
#ifdef DEBUG
if (gl->DebugMode()) {
if (gl->DebugMode())
printf_stderr("--- WebGL context created: %p\n", gl.get());
}
#endif
mResetLayer = true;
@ -914,10 +872,9 @@ WebGLContext::SetDimensions(int32_t sWidth, int32_t sHeight)
// Update our internal stuff:
if (gl->WorkAroundDriverBugs()) {
if (!mOptions.alpha && gl->Caps().alpha) {
if (!mOptions.alpha && gl->Caps().alpha)
mNeedsFakeNoAlpha = true;
}
}
// Update mOptions.
mOptions.depth = gl->Caps().depth;
@ -978,7 +935,8 @@ WebGLContext::ClearBackbufferIfNeeded()
mBackbufferNeedsClear = false;
}
void WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
void
WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
{
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
// some mobile devices can't have more than 8 GL contexts overall
@ -995,13 +953,11 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
// when choosing which one to lose first.
UpdateLastUseIndex();
WebGLMemoryTracker::ContextsArrayType &contexts
= WebGLMemoryTracker::Contexts();
WebGLMemoryTracker::ContextsArrayType& contexts = WebGLMemoryTracker::Contexts();
// quick exit path, should cover a majority of cases
if (contexts.Length() <= kMaxWebGLContextsPerPrincipal) {
if (contexts.Length() <= kMaxWebGLContextsPerPrincipal)
return;
}
// note that here by "context" we mean "non-lost context". See the check for
// IsContextLost() below. Indeed, the point of this function is to maybe lose
@ -1009,13 +965,12 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
uint64_t oldestIndex = UINT64_MAX;
uint64_t oldestIndexThisPrincipal = UINT64_MAX;
const WebGLContext *oldestContext = nullptr;
const WebGLContext *oldestContextThisPrincipal = nullptr;
const WebGLContext* oldestContext = nullptr;
const WebGLContext* oldestContextThisPrincipal = nullptr;
size_t numContexts = 0;
size_t numContextsThisPrincipal = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
// don't want to lose ourselves.
if (contexts[i] == this)
continue;
@ -1037,8 +992,8 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
oldestContext = contexts[i];
}
nsIPrincipal *ourPrincipal = GetCanvas()->NodePrincipal();
nsIPrincipal *theirPrincipal = contexts[i]->GetCanvas()->NodePrincipal();
nsIPrincipal* ourPrincipal = GetCanvas()->NodePrincipal();
nsIPrincipal* theirPrincipal = contexts[i]->GetCanvas()->NodePrincipal();
bool samePrincipal;
nsresult rv = ourPrincipal->Equals(theirPrincipal, &samePrincipal);
if (NS_SUCCEEDED(rv) && samePrincipal) {
@ -1064,26 +1019,25 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
}
void
WebGLContext::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat)
WebGLContext::GetImageBuffer(uint8_t** out_imageBuffer, int32_t* out_format)
{
*aImageBuffer = nullptr;
*aFormat = 0;
*out_imageBuffer = nullptr;
*out_format = 0;
// Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied
bool premult;
RefPtr<SourceSurface> snapshot =
GetSurfaceSnapshot(mOptions.premultipliedAlpha ? nullptr : &premult);
if (!snapshot) {
if (!snapshot)
return;
}
MOZ_ASSERT(mOptions.premultipliedAlpha || !premult, "We must get unpremult when we ask for it!");
RefPtr<DataSourceSurface> dataSurface = snapshot->GetDataSurface();
DataSourceSurface::MappedSurface map;
if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) {
if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map))
return;
}
static const fallible_t fallible = fallible_t();
uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4];
@ -1106,38 +1060,37 @@ WebGLContext::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat)
format = imgIEncoder::INPUT_FORMAT_RGBA;
}
*aImageBuffer = imageBuffer;
*aFormat = format;
*out_imageBuffer = imageBuffer;
*out_format = format;
}
NS_IMETHODIMP
WebGLContext::GetInputStream(const char* aMimeType,
const char16_t* aEncoderOptions,
nsIInputStream **aStream)
WebGLContext::GetInputStream(const char* mimeType,
const char16_t* encoderOptions,
nsIInputStream** out_stream)
{
NS_ASSERTION(gl, "GetInputStream on invalid context?");
if (!gl)
return NS_ERROR_FAILURE;
nsCString enccid("@mozilla.org/image/encoder;2?type=");
enccid += aMimeType;
enccid += mimeType;
nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get());
if (!encoder) {
if (!encoder)
return NS_ERROR_FAILURE;
}
nsAutoArrayPtr<uint8_t> imageBuffer;
int32_t format = 0;
GetImageBuffer(getter_Transfers(imageBuffer), &format);
if (!imageBuffer) {
if (!imageBuffer)
return NS_ERROR_FAILURE;
}
return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer, format,
encoder, aEncoderOptions, aStream);
encoder, encoderOptions, out_stream);
}
void WebGLContext::UpdateLastUseIndex()
void
WebGLContext::UpdateLastUseIndex()
{
static CheckedInt<uint64_t> sIndex = 0;
@ -1145,9 +1098,8 @@ void WebGLContext::UpdateLastUseIndex()
// should never happen with 64-bit; trying to handle this would be riskier than
// not handling it as the handler code would never get exercised.
if (!sIndex.isValid()) {
if (!sIndex.isValid())
NS_RUNTIMEABORT("Can't believe it's been 2^64 transactions already!");
}
mLastUseIndex = sIndex.value();
}
@ -1156,68 +1108,68 @@ static uint8_t gWebGLLayerUserData;
namespace mozilla {
class WebGLContextUserData : public LayerUserData {
class WebGLContextUserData : public LayerUserData
{
public:
explicit WebGLContextUserData(HTMLCanvasElement* aContent)
: mContent(aContent)
explicit WebGLContextUserData(HTMLCanvasElement* canvas)
: mCanvas(canvas)
{}
/* PreTransactionCallback gets called by the Layers code every time the
* WebGL canvas is going to be composited.
*/
static void PreTransactionCallback(void* data)
{
static void PreTransactionCallback(void* data) {
WebGLContextUserData* userdata = static_cast<WebGLContextUserData*>(data);
HTMLCanvasElement* canvas = userdata->mContent;
WebGLContext* context = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
HTMLCanvasElement* canvas = userdata->mCanvas;
WebGLContext* webgl = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
// Present our screenbuffer, if needed.
context->PresentScreenBuffer();
context->mDrawCallsSinceLastFlush = 0;
webgl->PresentScreenBuffer();
webgl->mDrawCallsSinceLastFlush = 0;
}
/** DidTransactionCallback gets called by the Layers code everytime the WebGL canvas gets composite,
* so it really is the right place to put actions that have to be performed upon compositing
*/
static void DidTransactionCallback(void* aData)
{
WebGLContextUserData *userdata = static_cast<WebGLContextUserData*>(aData);
HTMLCanvasElement *canvas = userdata->mContent;
WebGLContext *context = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
static void DidTransactionCallback(void* data) {
WebGLContextUserData* userdata = static_cast<WebGLContextUserData*>(data);
HTMLCanvasElement* canvas = userdata->mCanvas;
WebGLContext* webgl = static_cast<WebGLContext*>(canvas->GetContextAtIndex(0));
// Mark ourselves as no longer invalidated.
context->MarkContextClean();
webgl->MarkContextClean();
context->UpdateLastUseIndex();
webgl->UpdateLastUseIndex();
}
private:
nsRefPtr<HTMLCanvasElement> mContent;
nsRefPtr<HTMLCanvasElement> mCanvas;
};
} // end namespace mozilla
already_AddRefed<layers::CanvasLayer>
WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
CanvasLayer *aOldLayer,
LayerManager *aManager)
WebGLContext::GetCanvasLayer(nsDisplayListBuilder* builder,
CanvasLayer* oldLayer,
LayerManager* manager)
{
if (IsContextLost())
return nullptr;
if (!mResetLayer && aOldLayer &&
aOldLayer->HasUserData(&gWebGLLayerUserData)) {
nsRefPtr<layers::CanvasLayer> ret = aOldLayer;
if (!mResetLayer && oldLayer &&
oldLayer->HasUserData(&gWebGLLayerUserData)) {
nsRefPtr<layers::CanvasLayer> ret = oldLayer;
return ret.forget();
}
nsRefPtr<CanvasLayer> canvasLayer = aManager->CreateCanvasLayer();
nsRefPtr<CanvasLayer> canvasLayer = manager->CreateCanvasLayer();
if (!canvasLayer) {
NS_WARNING("CreateCanvasLayer returned null!");
return nullptr;
}
WebGLContextUserData *userData = nullptr;
if (aBuilder->IsPaintingToWindow()) {
WebGLContextUserData* userData = nullptr;
if (builder->IsPaintingToWindow()) {
// Make the layer tell us whenever a transaction finishes (including
// the current transaction), so we can clear our invalidation state and
// start invalidating again. We need to do this for the layer that is
@ -1255,7 +1207,7 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
}
void
WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributes> &retval)
WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributes>& retval)
{
retval.SetNull();
if (IsContextLost())
@ -1287,11 +1239,12 @@ WebGLContext::MozGetUnderlyingParamString(uint32_t pname, nsAString& retval)
case LOCAL_GL_RENDERER:
case LOCAL_GL_VERSION:
case LOCAL_GL_SHADING_LANGUAGE_VERSION:
case LOCAL_GL_EXTENSIONS: {
const char *s = (const char *) gl->fGetString(pname);
case LOCAL_GL_EXTENSIONS:
{
const char* s = (const char*)gl->fGetString(pname);
retval.Assign(NS_ConvertASCIItoUTF16(nsDependentCString(s)));
}
break;
}
default:
return NS_ERROR_INVALID_ARG;
@ -1320,7 +1273,8 @@ WebGLContext::ClearScreen()
}
void
WebGLContext::ForceClearFramebufferWithDefaultValues(GLbitfield mask, const bool colorAttachmentsMask[kMaxColorAttachments])
WebGLContext::ForceClearFramebufferWithDefaultValues(GLbitfield mask,
const bool colorAttachmentsMask[kMaxColorAttachments])
{
MakeContextCurrent();
@ -1462,15 +1416,17 @@ WebGLContext::PresentScreenBuffer()
}
void
WebGLContext::DummyFramebufferOperation(const char *info)
WebGLContext::DummyFramebufferOperation(const char* funcName)
{
FBStatus status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
ErrorInvalidFramebufferOperation("%s: incomplete framebuffer",
funcName);
}
}
static bool
CheckContextLost(GLContext* gl, bool* out_isGuilty)
CheckContextLost(GLContext* gl, bool* const out_isGuilty)
{
MOZ_ASSERT(gl);
MOZ_ASSERT(out_isGuilty);
@ -1543,16 +1499,16 @@ WebGLContext::RunContextLossTimer()
class UpdateContextLossStatusTask : public nsRunnable
{
nsRefPtr<WebGLContext> mContext;
nsRefPtr<WebGLContext> mWebGL;
public:
explicit UpdateContextLossStatusTask(WebGLContext* aContext)
: mContext(aContext)
explicit UpdateContextLossStatusTask(WebGLContext* webgl)
: mWebGL(webgl)
{
}
NS_IMETHOD Run() {
mContext->UpdateContextLossStatus();
mWebGL->UpdateContextLossStatus();
return NS_OK;
}
@ -1713,10 +1669,13 @@ WebGLContext::ForceRestoreContext()
}
void
WebGLContext::MakeContextCurrent() const { gl->MakeCurrent(); }
WebGLContext::MakeContextCurrent() const
{
gl->MakeCurrent();
}
mozilla::TemporaryRef<mozilla::gfx::SourceSurface>
WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
WebGLContext::GetSurfaceSnapshot(bool* out_premultAlpha)
{
if (!gl)
return nullptr;
@ -1739,13 +1698,13 @@ WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
ReadPixelsIntoDataSurface(gl, surf);
}
if (aPremultAlpha) {
*aPremultAlpha = true;
if (out_premultAlpha) {
*out_premultAlpha = true;
}
bool srcPremultAlpha = mOptions.premultipliedAlpha;
if (!srcPremultAlpha) {
if (aPremultAlpha) {
*aPremultAlpha = false;
if (out_premultAlpha) {
*out_premultAlpha = false;
} else {
gfxUtils::PremultiplyDataSurface(surf, surf);
}
@ -1779,24 +1738,25 @@ WebGLContext::DidRefresh()
}
}
bool WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget, GLint level,
GLenum internalformat, GLenum format, GLenum type,
bool
WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
GLint level, GLenum internalFormat,
GLenum format, GLenum type,
mozilla::dom::Element& elt)
{
if (type == LOCAL_GL_HALF_FLOAT_OES) {
if (type == LOCAL_GL_HALF_FLOAT_OES)
type = LOCAL_GL_HALF_FLOAT;
}
if (!ValidateTexImageFormatAndType(format, type,
WebGLTexImageFunc::TexImage, WebGLTexDimensions::Tex2D))
WebGLTexImageFunc::TexImage,
WebGLTexDimensions::Tex2D))
{
return false;
}
HTMLVideoElement* video = HTMLVideoElement::FromContentOrNull(&elt);
if (!video) {
if (!video)
return false;
}
uint16_t readyState;
if (NS_SUCCEEDED(video->GetReadyState(&readyState)) &&
@ -1808,14 +1768,12 @@ bool WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
// If it doesn't have a principal, just bail
nsCOMPtr<nsIPrincipal> principal = video->GetCurrentPrincipal();
if (!principal) {
if (!principal)
return false;
}
mozilla::layers::ImageContainer* container = video->GetImageContainer();
if (!container) {
if (!container)
return false;
}
if (video->GetCORSMode() == CORS_NONE) {
bool subsumes;
@ -1829,24 +1787,35 @@ bool WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
gl->MakeCurrent();
nsRefPtr<mozilla::layers::Image> srcImage = container->LockCurrentImage();
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
const WebGLTexture::ImageInfo& info = tex->ImageInfoAt(texImageTarget, 0);
bool dimensionsMatch = info.Width() == srcImage->GetSize().width &&
info.Height() == srcImage->GetSize().height;
if (!dimensionsMatch) {
// we need to allocation
gl->fTexImage2D(texImageTarget.get(), level, internalformat, srcImage->GetSize().width, srcImage->GetSize().height, 0, format, type, nullptr);
gl->fTexImage2D(texImageTarget.get(), level, internalFormat,
srcImage->GetSize().width, srcImage->GetSize().height,
0, format, type, nullptr);
}
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(), srcImage->GetSize(), tex->GLName(), texImageTarget.get(), mPixelStoreFlipY);
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(),
srcImage->GetSize(),
tex->GLName(),
texImageTarget.get(),
mPixelStoreFlipY);
if (ok) {
TexInternalFormat effectiveinternalformat =
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
MOZ_ASSERT(effectiveinternalformat != LOCAL_GL_NONE);
tex->SetImageInfo(texImageTarget, level, srcImage->GetSize().width, srcImage->GetSize().height, 1,
effectiveinternalformat, WebGLImageDataStatus::InitializedImageData);
TexInternalFormat effectiveInternalFormat =
EffectiveInternalFormatFromInternalFormatAndType(internalFormat,
type);
MOZ_ASSERT(effectiveInternalFormat != LOCAL_GL_NONE);
tex->SetImageInfo(texImageTarget, level, srcImage->GetSize().width,
srcImage->GetSize().height, 1,
effectiveInternalFormat,
WebGLImageDataStatus::InitializedImageData);
tex->Bind(TexImageTargetToTexTarget(texImageTarget));
}
srcImage = nullptr;
container->UnlockCurrentImage();
return ok;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -4,15 +4,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLContext.h"
#include "GLContext.h"
#include "WebGLBuffer.h"
#include "WebGLVertexArray.h"
using namespace mozilla;
using namespace mozilla::dom;
namespace mozilla {
void
WebGLContext::BindBuffer(GLenum target, WebGLBuffer *buffer)
WebGLContext::BindBuffer(GLenum target, WebGLBuffer* buffer)
{
if (IsContextLost())
return;
@ -24,17 +24,18 @@ WebGLContext::BindBuffer(GLenum target, WebGLBuffer *buffer)
if (buffer && buffer->IsDeleted())
return;
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bindBuffer");
if (!bufferSlot) {
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
"bindBuffer");
if (!bufferSlot)
return;
}
if (buffer) {
if (!buffer->HasEverBeenBound()) {
buffer->BindTo(target);
} else if (target != buffer->Target()) {
return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
ErrorInvalidOperation("bindBuffer: Buffer already bound to a"
" different target.");
return;
}
}
@ -59,21 +60,25 @@ WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer)
return;
}
WebGLRefPtr<WebGLBuffer>* indexedBufferSlot = GetBufferSlotByTargetIndexed(target, index, "bindBufferBase");
if (!indexedBufferSlot) {
WebGLRefPtr<WebGLBuffer>* indexedBufferSlot;
indexedBufferSlot = GetBufferSlotByTargetIndexed(target, index,
"bindBufferBase");
if (!indexedBufferSlot)
return;
}
if (buffer) {
if (!buffer->HasEverBeenBound())
buffer->BindTo(target);
if (target != buffer->Target())
return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
if (target != buffer->Target()) {
ErrorInvalidOperation("bindBuffer: Buffer already bound to a"
" different target.");
return;
}
}
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bindBuffer");
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
"bindBufferBase");
MOZ_ASSERT(bufferSlot, "GetBufferSlotByTarget(Indexed) mismatch");
@ -99,18 +104,21 @@ WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
if (buffer && buffer->IsDeleted())
return;
WebGLRefPtr<WebGLBuffer>* indexedBufferSlot = GetBufferSlotByTargetIndexed(target, index, "bindBufferBase");
if (!indexedBufferSlot) {
WebGLRefPtr<WebGLBuffer>* indexedBufferSlot;
indexedBufferSlot = GetBufferSlotByTargetIndexed(target, index,
"bindBufferRange");
if (!indexedBufferSlot)
return;
}
if (buffer) {
if (!buffer->HasEverBeenBound())
buffer->BindTo(target);
if (target != buffer->Target())
return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
if (target != buffer->Target()) {
ErrorInvalidOperation("bindBuffer: Buffer already bound to a"
" different target.");
return;
}
CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(offset) + size;
if (!checked_neededByteLength.isValid() ||
@ -120,7 +128,8 @@ WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
}
}
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bindBuffer");
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
"BindBufferRange");
MOZ_ASSERT(bufferSlot, "GetBufferSlotByTarget(Indexed) mismatch");
@ -129,21 +138,20 @@ WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
MakeContextCurrent();
gl->fBindBufferRange(target, index, buffer ? buffer->GLName() : 0, offset, size);
gl->fBindBufferRange(target, index, buffer ? buffer->GLName() : 0, offset,
size);
}
void
WebGLContext::BufferData(GLenum target, WebGLsizeiptr size,
GLenum usage)
WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, GLenum usage)
{
if (IsContextLost())
return;
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferData");
if (!bufferSlot) {
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
"bufferData");
if (!bufferSlot)
return;
}
if (size < 0)
return ErrorInvalidValue("bufferData: negative size");
@ -182,7 +190,7 @@ WebGLContext::BufferData(GLenum target, WebGLsizeiptr size,
void
WebGLContext::BufferData(GLenum target,
const Nullable<ArrayBuffer> &maybeData,
const dom::Nullable<dom::ArrayBuffer>& maybeData,
GLenum usage)
{
if (IsContextLost())
@ -193,13 +201,12 @@ WebGLContext::BufferData(GLenum target,
return ErrorInvalidValue("bufferData: null object passed");
}
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferData");
if (!bufferSlot) {
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
"bufferData");
if (!bufferSlot)
return;
}
const ArrayBuffer& data = maybeData.Value();
const dom::ArrayBuffer& data = maybeData.Value();
data.ComputeLengthAndData();
// Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
@ -226,23 +233,21 @@ WebGLContext::BufferData(GLenum target,
}
boundBuffer->SetByteLength(data.Length());
if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) {
if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length()))
return ErrorOutOfMemory("bufferData: out of memory");
}
}
void
WebGLContext::BufferData(GLenum target, const ArrayBufferView& data,
WebGLContext::BufferData(GLenum target, const dom::ArrayBufferView& data,
GLenum usage)
{
if (IsContextLost())
return;
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
if (!bufferSlot) {
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
"bufferSubData");
if (!bufferSlot)
return;
}
if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
return;
@ -269,14 +274,13 @@ WebGLContext::BufferData(GLenum target, const ArrayBufferView& data,
}
boundBuffer->SetByteLength(data.Length());
if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) {
if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length()))
return ErrorOutOfMemory("bufferData: out of memory");
}
}
void
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
const Nullable<ArrayBuffer> &maybeData)
const dom::Nullable<dom::ArrayBuffer>& maybeData)
{
if (IsContextLost())
return;
@ -286,11 +290,10 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
return;
}
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
if (!bufferSlot) {
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
"bufferSubData");
if (!bufferSlot)
return;
}
if (byteOffset < 0)
return ErrorInvalidValue("bufferSubData: negative offset");
@ -300,36 +303,42 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
if (!boundBuffer)
return ErrorInvalidOperation("bufferData: no buffer bound!");
const ArrayBuffer& data = maybeData.Value();
const dom::ArrayBuffer& data = maybeData.Value();
data.ComputeLengthAndData();
CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
if (!checked_neededByteLength.isValid())
return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
if (!checked_neededByteLength.isValid()) {
ErrorInvalidValue("bufferSubData: Integer overflow computing the needed"
" byte length.");
return;
}
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
return ErrorInvalidValue("bufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes",
checked_neededByteLength.value(), boundBuffer->ByteLength());
if (checked_neededByteLength.value() > boundBuffer->ByteLength()) {
ErrorInvalidValue("bufferSubData: Not enough data. Operation requires"
" %d bytes, but buffer only has %d bytes.",
checked_neededByteLength.value(),
boundBuffer->ByteLength());
return;
}
boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(),
data.Length());
MakeContextCurrent();
boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length());
gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
}
void
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
const ArrayBufferView& data)
const dom::ArrayBufferView& data)
{
if (IsContextLost())
return;
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
if (!bufferSlot) {
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target,
"bufferSubData");
if (!bufferSlot)
return;
}
if (byteOffset < 0)
return ErrorInvalidValue("bufferSubData: negative offset");
@ -342,14 +351,22 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
data.ComputeLengthAndData();
CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
if (!checked_neededByteLength.isValid())
return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
if (!checked_neededByteLength.isValid()) {
ErrorInvalidValue("bufferSubData: Integer overflow computing the needed"
" byte length.");
return;
}
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
return ErrorInvalidValue("bufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes",
checked_neededByteLength.value(), boundBuffer->ByteLength());
if (checked_neededByteLength.value() > boundBuffer->ByteLength()) {
ErrorInvalidValue("bufferSubData: Not enough data. Operation requires"
" %d bytes, but buffer only has %d bytes.",
checked_neededByteLength.value(),
boundBuffer->ByteLength());
return;
}
boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length());
boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(),
data.Length());
MakeContextCurrent();
gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
@ -370,7 +387,7 @@ WebGLContext::CreateBuffer()
}
void
WebGLContext::DeleteBuffer(WebGLBuffer *buffer)
WebGLContext::DeleteBuffer(WebGLBuffer* buffer)
{
if (IsContextLost())
return;
@ -381,10 +398,8 @@ WebGLContext::DeleteBuffer(WebGLBuffer *buffer)
if (!buffer || buffer->IsDeleted())
return;
if (mBoundArrayBuffer == buffer) {
BindBuffer(LOCAL_GL_ARRAY_BUFFER,
static_cast<WebGLBuffer*>(nullptr));
}
if (mBoundArrayBuffer == buffer)
BindBuffer(LOCAL_GL_ARRAY_BUFFER, static_cast<WebGLBuffer*>(nullptr));
if (mBoundVertexArray->mElementArrayBuffer == buffer) {
BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER,
@ -392,15 +407,18 @@ WebGLContext::DeleteBuffer(WebGLBuffer *buffer)
}
for (int32_t i = 0; i < mGLMaxVertexAttribs; i++) {
if (mBoundVertexArray->HasAttrib(i) && mBoundVertexArray->mAttribs[i].buf == buffer)
if (mBoundVertexArray->HasAttrib(i) &&
mBoundVertexArray->mAttribs[i].buf == buffer)
{
mBoundVertexArray->mAttribs[i].buf = nullptr;
}
}
buffer->RequestDelete();
}
bool
WebGLContext::IsBuffer(WebGLBuffer *buffer)
WebGLContext::IsBuffer(WebGLBuffer* buffer)
{
if (IsContextLost())
return false;
@ -411,7 +429,7 @@ WebGLContext::IsBuffer(WebGLBuffer *buffer)
}
bool
WebGLContext::ValidateBufferUsageEnum(GLenum target, const char *infos)
WebGLContext::ValidateBufferUsageEnum(GLenum target, const char* info)
{
switch (target) {
case LOCAL_GL_STREAM_DRAW:
@ -422,12 +440,12 @@ WebGLContext::ValidateBufferUsageEnum(GLenum target, const char *infos)
break;
}
ErrorInvalidEnumInfo(infos, target);
ErrorInvalidEnumInfo(info, target);
return false;
}
WebGLRefPtr<WebGLBuffer>*
WebGLContext::GetBufferSlotByTarget(GLenum target, const char* infos)
WebGLContext::GetBufferSlotByTarget(GLenum target, const char* info)
{
switch (target) {
case LOCAL_GL_ARRAY_BUFFER:
@ -446,17 +464,20 @@ WebGLContext::GetBufferSlotByTarget(GLenum target, const char* infos)
break;
}
ErrorInvalidEnum("%s: target: invalid enum value 0x%x", infos, target);
ErrorInvalidEnum("%s: target: Invalid enum value 0x%x.", info, target);
return nullptr;
}
WebGLRefPtr<WebGLBuffer>*
WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const char* infos)
WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index,
const char* info)
{
switch (target) {
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
if (index >= mGLMaxTransformFeedbackSeparateAttribs) {
ErrorInvalidValue("%s: index should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", infos, index);
ErrorInvalidValue("%s: `index` should be less than"
" MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.", info,
index);
return nullptr;
}
return nullptr; // See bug 903594
@ -465,32 +486,32 @@ WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const ch
break;
}
ErrorInvalidEnum("%s: target: invalid enum value 0x%x", infos, target);
ErrorInvalidEnum("%s: target: invalid enum value 0x%x", info, target);
return nullptr;
}
GLenum
WebGLContext::CheckedBufferData(GLenum target,
GLsizeiptr size,
const GLvoid *data,
GLenum usage)
WebGLContext::CheckedBufferData(GLenum target, GLsizeiptr size,
const GLvoid* data, GLenum usage)
{
#ifdef XP_MACOSX
// bug 790879
if (gl->WorkAroundDriverBugs() &&
int64_t(size) > INT32_MAX) // the cast avoids a potential always-true warning on 32bit
{
GenerateWarning("Rejecting valid bufferData call with size %lu to avoid a Mac bug", size);
GenerateWarning("Rejecting valid bufferData call with size %lu to avoid"
" a Mac bug", size);
return LOCAL_GL_INVALID_VALUE;
}
#endif
WebGLBuffer *boundBuffer = nullptr;
WebGLBuffer* boundBuffer = nullptr;
if (target == LOCAL_GL_ARRAY_BUFFER) {
boundBuffer = mBoundArrayBuffer;
} else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
boundBuffer = mBoundVertexArray->mElementArrayBuffer;
}
MOZ_ASSERT(boundBuffer != nullptr, "no buffer bound for this target");
MOZ_ASSERT(boundBuffer, "No buffer bound for this target.");
bool sizeChanges = uint32_t(size) != boundBuffer->ByteLength();
if (sizeChanges) {
@ -503,3 +524,5 @@ WebGLContext::CheckedBufferData(GLenum target,
return LOCAL_GL_NO_ERROR;
}
}
} // namespace mozilla

Просмотреть файл

@ -408,7 +408,7 @@ void WebGLContext::Draw_cleanup()
*/
bool
WebGLContext::ValidateBufferFetching(const char *info)
WebGLContext::ValidateBufferFetching(const char* info)
{
#ifdef DEBUG
GLint currentProgram = 0;
@ -418,9 +418,8 @@ WebGLContext::ValidateBufferFetching(const char *info)
"WebGL: current program doesn't agree with GL state");
#endif
if (mBufferFetchingIsVerified) {
if (mBufferFetchingIsVerified)
return true;
}
bool hasPerVertex = false;
uint32_t maxVertices = UINT32_MAX;
@ -735,7 +734,7 @@ WebGLContext::UnbindFakeBlackTextures()
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mActiveTexture);
}
WebGLContext::FakeBlackTexture::FakeBlackTexture(GLContext *gl, TexTarget target, GLenum format)
WebGLContext::FakeBlackTexture::FakeBlackTexture(GLContext* gl, TexTarget target, GLenum format)
: mGL(gl)
, mGLName(0)
{

Просмотреть файл

@ -12,16 +12,15 @@
#include "mozilla/Preferences.h"
#include "AccessCheck.h"
using namespace mozilla;
using namespace mozilla::gl;
namespace mozilla {
/* static */ const char*
/*static*/ const char*
WebGLContext::GetExtensionString(WebGLExtensionID ext)
{
typedef EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max, const char*>
names_array_t;
static names_array_t sExtensionNamesEnumeratedArray;
typedef EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max,
const char*> names_array_t;
static names_array_t sExtensionNamesEnumeratedArray;
static bool initialized = false;
if (!initialized) {
@ -62,11 +61,13 @@ WebGLContext::GetExtensionString(WebGLExtensionID ext)
}
bool
WebGLContext::IsExtensionEnabled(WebGLExtensionID ext) const {
WebGLContext::IsExtensionEnabled(WebGLExtensionID ext) const
{
return mExtensions[ext];
}
bool WebGLContext::IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) const
bool WebGLContext::IsExtensionSupported(JSContext* cx,
WebGLExtensionID ext) const
{
bool allowPrivilegedExts = false;
@ -96,60 +97,59 @@ bool WebGLContext::IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) con
bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
{
if (mDisableExtensions) {
if (mDisableExtensions)
return false;
}
switch (ext) {
case WebGLExtensionID::OES_vertex_array_object:
case WebGLExtensionID::WEBGL_lose_context:
// Always supported.
return true;
case WebGLExtensionID::EXT_blend_minmax:
return WebGLExtensionBlendMinMax::IsSupported(this);
case WebGLExtensionID::OES_element_index_uint:
return gl->IsSupported(GLFeature::element_index_uint);
return gl->IsSupported(gl::GLFeature::element_index_uint);
case WebGLExtensionID::OES_standard_derivatives:
return gl->IsSupported(GLFeature::standard_derivatives);
case WebGLExtensionID::WEBGL_lose_context:
// We always support this extension.
return true;
return gl->IsSupported(gl::GLFeature::standard_derivatives);
case WebGLExtensionID::OES_texture_float:
return gl->IsSupported(GLFeature::texture_float);
return gl->IsSupported(gl::GLFeature::texture_float);
case WebGLExtensionID::OES_texture_float_linear:
return gl->IsSupported(GLFeature::texture_float_linear);
return gl->IsSupported(gl::GLFeature::texture_float_linear);
case WebGLExtensionID::OES_texture_half_float:
// If we have Feature::texture_half_float, we must not be on ES2
// and need to translate HALF_FLOAT_OES -> HALF_FLOAT. We do that
// right before making the relevant calls.
return gl->IsExtensionSupported(GLContext::OES_texture_half_float) ||
gl->IsSupported(GLFeature::texture_half_float);
return gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float) ||
gl->IsSupported(gl::GLFeature::texture_half_float);
case WebGLExtensionID::OES_texture_half_float_linear:
return gl->IsSupported(GLFeature::texture_half_float_linear);
case WebGLExtensionID::OES_vertex_array_object:
return WebGLExtensionVertexArray::IsSupported(this);
return gl->IsSupported(gl::GLFeature::texture_half_float_linear);
case WebGLExtensionID::EXT_texture_filter_anisotropic:
return gl->IsExtensionSupported(GLContext::EXT_texture_filter_anisotropic);
return gl->IsExtensionSupported(gl::GLContext::EXT_texture_filter_anisotropic);
case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
if (gl->IsExtensionSupported(GLContext::EXT_texture_compression_s3tc)) {
if (gl->IsExtensionSupported(gl::GLContext::EXT_texture_compression_s3tc))
return true;
}
else if (gl->IsExtensionSupported(GLContext::EXT_texture_compression_dxt1) &&
gl->IsExtensionSupported(GLContext::ANGLE_texture_compression_dxt3) &&
gl->IsExtensionSupported(GLContext::ANGLE_texture_compression_dxt5))
{
return true;
}
return false;
return gl->IsExtensionSupported(gl::GLContext::EXT_texture_compression_dxt1) &&
gl->IsExtensionSupported(gl::GLContext::ANGLE_texture_compression_dxt3) &&
gl->IsExtensionSupported(gl::GLContext::ANGLE_texture_compression_dxt5);
case WebGLExtensionID::WEBGL_compressed_texture_atc:
return gl->IsExtensionSupported(GLContext::AMD_compressed_ATC_texture);
return gl->IsExtensionSupported(gl::GLContext::AMD_compressed_ATC_texture);
case WebGLExtensionID::WEBGL_compressed_texture_etc1:
return gl->IsExtensionSupported(GLContext::OES_compressed_ETC1_RGB8_texture);
return gl->IsExtensionSupported(gl::GLContext::OES_compressed_ETC1_RGB8_texture);
case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
return gl->IsExtensionSupported(GLContext::IMG_texture_compression_pvrtc);
return gl->IsExtensionSupported(gl::GLContext::IMG_texture_compression_pvrtc);
case WebGLExtensionID::WEBGL_depth_texture:
// WEBGL_depth_texture supports DEPTH_STENCIL textures
if (!gl->IsSupported(GLFeature::packed_depth_stencil)) {
if (!gl->IsSupported(gl::GLFeature::packed_depth_stencil))
return false;
}
return gl->IsSupported(GLFeature::depth_texture) ||
gl->IsExtensionSupported(GLContext::ANGLE_depth_texture);
return gl->IsSupported(gl::GLFeature::depth_texture) ||
gl->IsExtensionSupported(gl::GLContext::ANGLE_depth_texture);
case WebGLExtensionID::ANGLE_instanced_arrays:
return WebGLExtensionInstancedArrays::IsSupported(this);
case WebGLExtensionID::EXT_sRGB:
@ -159,13 +159,16 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
case WebGLExtensionID::EXT_frag_depth:
return WebGLExtensionFragDepth::IsSupported(this);
case WebGLExtensionID::EXT_shader_texture_lod:
return gl->IsExtensionSupported(GLContext::EXT_shader_texture_lod);
return gl->IsExtensionSupported(gl::GLContext::EXT_shader_texture_lod);
default:
// For warnings-as-errors.
break;
}
if (Preferences::GetBool("webgl.enable-draft-extensions", false) || IsWebGL2()) {
if (Preferences::GetBool("webgl.enable-draft-extensions", false) ||
IsWebGL2())
{
switch (ext) {
case WebGLExtensionID::EXT_color_buffer_half_float:
return WebGLExtensionColorBufferHalfFloat::IsSupported(this);
@ -181,7 +184,7 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
}
static bool
CompareWebGLExtensionName(const nsACString& name, const char *other)
CompareWebGLExtensionName(const nsACString& name, const char* other)
{
return name.Equals(other, nsCaseInsensitiveCStringComparator());
}
@ -200,16 +203,15 @@ WebGLContext::EnableSupportedExtension(JSContext* js, WebGLExtensionID ext)
}
void
WebGLContext::GetExtension(JSContext *cx, const nsAString& aName,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv)
WebGLContext::GetExtension(JSContext* cx, const nsAString& wideName,
JS::MutableHandle<JSObject*> retval, ErrorResult& rv)
{
if (IsContextLost()) {
aRetval.set(nullptr);
return;
}
retval.set(nullptr);
NS_LossyConvertUTF16toASCII name(aName);
if (IsContextLost())
return;
NS_LossyConvertUTF16toASCII name(wideName);
WebGLExtensionID ext = WebGLExtensionID::Unknown;
@ -224,52 +226,47 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName,
}
if (ext == WebGLExtensionID::Unknown) {
/**
* We keep backward compatibility for these deprecated vendor-prefixed
* alias. Do not add new ones anymore. Hide it behind the
* webgl.enable-draft-extensions flag instead.
*/
// We keep backward compatibility for these deprecated vendor-prefixed
// alias. Do not add new ones anymore. Hide it behind the
// webgl.enable-draft-extensions flag instead.
if (CompareWebGLExtensionName(name, "MOZ_WEBGL_lose_context")) {
ext = WebGLExtensionID::WEBGL_lose_context;
}
else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_s3tc")) {
} else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_s3tc")) {
ext = WebGLExtensionID::WEBGL_compressed_texture_s3tc;
}
else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_atc")) {
} else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_atc")) {
ext = WebGLExtensionID::WEBGL_compressed_texture_atc;
}
else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_pvrtc")) {
} else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_pvrtc")) {
ext = WebGLExtensionID::WEBGL_compressed_texture_pvrtc;
}
else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_depth_texture")) {
} else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_depth_texture")) {
ext = WebGLExtensionID::WEBGL_depth_texture;
}
if (ext != WebGLExtensionID::Unknown) {
GenerateWarning("getExtension('%s'): MOZ_ prefixed WebGL extension strings are deprecated. "
"Support for them will be removed in the future. Use unprefixed extension strings. "
"To get draft extensions, set the webgl.enable-draft-extensions preference.",
GenerateWarning("getExtension('%s'): MOZ_ prefixed WebGL extension"
" strings are deprecated. Support for them will be"
" removed in the future. Use unprefixed extension"
" strings. To get draft extensions, set the"
" webgl.enable-draft-extensions preference.",
name.get());
}
}
if (ext == WebGLExtensionID::Unknown) {
aRetval.set(nullptr);
if (ext == WebGLExtensionID::Unknown)
return;
}
// step 2: check if the extension is supported
if (!IsExtensionSupported(cx, ext)) {
aRetval.set(nullptr);
if (!IsExtensionSupported(cx, ext))
return;
}
// step 3: if the extension hadn't been previously been created, create it now, thus enabling it
WebGLExtensionBase* extObj = EnableSupportedExtension(cx, ext);
if (!extObj) {
aRetval.set(nullptr);
if (!extObj)
return;
}
// Step 4: Enable any implied extensions.
switch (ext) {
@ -285,7 +282,7 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName,
break;
}
aRetval.set(WebGLObjectAsJSObject(cx, extObj, rv));
retval.set(WebGLObjectAsJSObject(cx, extObj, rv));
}
void
@ -369,13 +366,15 @@ WebGLContext::EnableExtension(WebGLExtensionID ext)
break;
default:
MOZ_ASSERT(false, "should not get there.");
break;
}
mExtensions[ext] = obj;
}
void
WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray<nsString> > &retval)
WebGLContext::GetSupportedExtensions(JSContext* cx,
Nullable< nsTArray<nsString> >& retval)
{
retval.SetNull();
if (IsContextLost())
@ -383,12 +382,12 @@ WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray<nsString>
nsTArray<nsString>& arr = retval.SetValue();
for (size_t i = 0; i < size_t(WebGLExtensionID::Max); i++)
{
for (size_t i = 0; i < size_t(WebGLExtensionID::Max); i++) {
WebGLExtensionID extension = WebGLExtensionID(i);
if (IsExtensionSupported(cx, extension)) {
arr.AppendElement(NS_ConvertUTF8toUTF16(GetExtensionString(extension)));
const char* extStr = GetExtensionString(extension);
arr.AppendElement(NS_ConvertUTF8toUTF16(extStr));
}
}
@ -409,3 +408,4 @@ WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray<nsString>
arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_depth_texture"));
}
} // namespace mozilla

Просмотреть файл

@ -55,7 +55,8 @@ using namespace mozilla::dom;
using namespace mozilla::gl;
using namespace mozilla::gfx;
static bool BaseTypeAndSizeFromUniformType(GLenum uType, GLenum *baseType, GLint *unitSize);
static bool BaseTypeAndSizeFromUniformType(GLenum uType, GLenum* baseType,
GLint* unitSize);
const WebGLRectangleObject*
WebGLContext::CurValidFBRectObject() const
@ -101,7 +102,7 @@ WebGLContext::ActiveTexture(GLenum texture)
}
void
WebGLContext::AttachShader(WebGLProgram *program, WebGLShader *shader)
WebGLContext::AttachShader(WebGLProgram* program, WebGLShader* shader)
{
if (IsContextLost())
return;
@ -158,7 +159,7 @@ WebGLContext::BindAttribLocation(WebGLProgram* prog, GLuint location,
}
void
WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer *wfb)
WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer* wfb)
{
if (IsContextLost())
return;
@ -187,7 +188,7 @@ WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer *wfb)
}
void
WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer *wrb)
WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb)
{
if (IsContextLost())
return;
@ -219,7 +220,7 @@ WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer *wrb)
}
void
WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture *newTex)
WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture* newTex)
{
if (IsContextLost())
return;
@ -403,7 +404,7 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
MakeContextCurrent();
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("%s: no texture is bound to this target");
@ -587,7 +588,7 @@ WebGLContext::CopyTexSubImage2D(GLenum rawTexImgTarget,
if (xoffset < 0 || yoffset < 0)
return ErrorInvalidValue("copyTexSubImage2D: xoffset and yoffset may not be negative");
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("copyTexSubImage2D: no texture bound to this target");
@ -686,7 +687,7 @@ WebGLContext::DeleteFramebuffer(WebGLFramebuffer* fbuf)
}
void
WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer *rbuf)
WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer* rbuf)
{
if (IsContextLost())
return;
@ -711,7 +712,7 @@ WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer *rbuf)
}
void
WebGLContext::DeleteTexture(WebGLTexture *tex)
WebGLContext::DeleteTexture(WebGLTexture* tex)
{
if (IsContextLost())
return;
@ -744,7 +745,7 @@ WebGLContext::DeleteTexture(WebGLTexture *tex)
}
void
WebGLContext::DeleteProgram(WebGLProgram *prog)
WebGLContext::DeleteProgram(WebGLProgram* prog)
{
if (IsContextLost())
return;
@ -759,7 +760,7 @@ WebGLContext::DeleteProgram(WebGLProgram *prog)
}
void
WebGLContext::DeleteShader(WebGLShader *shader)
WebGLContext::DeleteShader(WebGLShader* shader)
{
if (IsContextLost())
return;
@ -774,7 +775,7 @@ WebGLContext::DeleteShader(WebGLShader *shader)
}
void
WebGLContext::DetachShader(WebGLProgram *program, WebGLShader *shader)
WebGLContext::DetachShader(WebGLProgram* program, WebGLShader* shader)
{
if (IsContextLost())
return;
@ -816,7 +817,8 @@ WebGLContext::DepthRange(GLfloat zNear, GLfloat zFar)
}
void
WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum rbtarget, WebGLRenderbuffer *wrb)
WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment,
GLenum rbtarget, WebGLRenderbuffer* wrb)
{
if (IsContextLost())
return;
@ -840,7 +842,7 @@ void
WebGLContext::FramebufferTexture2D(GLenum target,
GLenum attachment,
GLenum textarget,
WebGLTexture *tobj,
WebGLTexture* tobj,
GLint level)
{
if (IsContextLost())
@ -884,7 +886,7 @@ WebGLContext::FrontFace(GLenum mode)
}
already_AddRefed<WebGLActiveInfo>
WebGLContext::GetActiveAttrib(WebGLProgram *prog, uint32_t index)
WebGLContext::GetActiveAttrib(WebGLProgram* prog, uint32_t index)
{
if (IsContextLost())
return nullptr;
@ -938,7 +940,7 @@ WebGLContext::GenerateMipmap(GLenum rawTarget)
const TexTarget target(rawTarget);
WebGLTexture *tex = activeBoundTextureForTarget(target);
WebGLTexture* tex = ActiveBoundTextureForTarget(target);
if (!tex)
return ErrorInvalidOperation("generateMipmap: No texture is bound to this target.");
@ -992,7 +994,7 @@ WebGLContext::GenerateMipmap(GLenum rawTarget)
}
already_AddRefed<WebGLActiveInfo>
WebGLContext::GetActiveUniform(WebGLProgram *prog, uint32_t index)
WebGLContext::GetActiveUniform(WebGLProgram* prog, uint32_t index)
{
if (IsContextLost())
return nullptr;
@ -1053,7 +1055,7 @@ WebGLContext::GetActiveUniform(WebGLProgram *prog, uint32_t index)
}
void
WebGLContext::GetAttachedShaders(WebGLProgram *prog,
WebGLContext::GetAttachedShaders(WebGLProgram* prog,
Nullable<nsTArray<nsRefPtr<WebGLShader>>>& retval)
{
retval.SetNull();
@ -1076,7 +1078,7 @@ WebGLContext::GetAttachedShaders(WebGLProgram *prog,
}
GLint
WebGLContext::GetAttribLocation(WebGLProgram *prog, const nsAString& name)
WebGLContext::GetAttribLocation(WebGLProgram* prog, const nsAString& name)
{
if (IsContextLost())
return -1;
@ -1432,7 +1434,7 @@ WebGLContext::GetError()
}
JS::Value
WebGLContext::GetProgramParameter(WebGLProgram *prog, GLenum pname)
WebGLContext::GetProgramParameter(WebGLProgram* prog, GLenum pname)
{
if (IsContextLost())
return JS::NullValue();
@ -1488,7 +1490,7 @@ WebGLContext::GetProgramParameter(WebGLProgram *prog, GLenum pname)
}
void
WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsAString& retval)
WebGLContext::GetProgramInfoLog(WebGLProgram* prog, nsAString& retval)
{
nsAutoCString s;
GetProgramInfoLog(prog, s);
@ -1499,7 +1501,7 @@ WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsAString& retval)
}
void
WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsACString& retval)
WebGLContext::GetProgramInfoLog(WebGLProgram* prog, nsACString& retval)
{
if (IsContextLost())
{
@ -1540,8 +1542,8 @@ WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsACString& retval)
// See this discussion:
// https://www.khronos.org/webgl/public-mailing-list/archives/1008/msg00014.html
void WebGLContext::TexParameter_base(GLenum rawTarget, GLenum pname,
GLint *intParamPtr,
GLfloat *floatParamPtr)
GLint* intParamPtr,
GLfloat* floatParamPtr)
{
MOZ_ASSERT(intParamPtr || floatParamPtr);
@ -1556,7 +1558,7 @@ void WebGLContext::TexParameter_base(GLenum rawTarget, GLenum pname,
const TexTarget texTarget = TexTarget(rawTarget);
WebGLTexture *tex = activeBoundTextureForTarget(texTarget);
WebGLTexture* tex = ActiveBoundTextureForTarget(texTarget);
if (!tex)
return ErrorInvalidOperation("texParameter: no texture is bound to this target");
@ -1673,7 +1675,7 @@ WebGLContext::GetTexParameter(GLenum rawTarget, GLenum pname)
const TexTarget target(rawTarget);
if (!activeBoundTextureForTarget(target)) {
if (!ActiveBoundTextureForTarget(target)) {
ErrorInvalidOperation("getTexParameter: no texture bound");
return JS::NullValue();
}
@ -1712,8 +1714,8 @@ WebGLContext::GetTexParameterInternal(const TexTarget& target, GLenum pname)
}
JS::Value
WebGLContext::GetUniform(JSContext* cx, WebGLProgram *prog,
WebGLUniformLocation *location)
WebGLContext::GetUniform(JSContext* cx, WebGLProgram* prog,
WebGLUniformLocation* location)
{
if (IsContextLost())
return JS::NullValue();
@ -1849,7 +1851,7 @@ WebGLContext::GetUniform(JSContext* cx, WebGLProgram *prog,
}
already_AddRefed<WebGLUniformLocation>
WebGLContext::GetUniformLocation(WebGLProgram *prog, const nsAString& name)
WebGLContext::GetUniformLocation(WebGLProgram* prog, const nsAString& name)
{
if (IsContextLost())
return nullptr;
@ -1905,7 +1907,7 @@ WebGLContext::Hint(GLenum target, GLenum mode)
}
bool
WebGLContext::IsFramebuffer(WebGLFramebuffer *fb)
WebGLContext::IsFramebuffer(WebGLFramebuffer* fb)
{
if (IsContextLost())
return false;
@ -1916,7 +1918,7 @@ WebGLContext::IsFramebuffer(WebGLFramebuffer *fb)
}
bool
WebGLContext::IsProgram(WebGLProgram *prog)
WebGLContext::IsProgram(WebGLProgram* prog)
{
if (IsContextLost())
return false;
@ -1925,7 +1927,7 @@ WebGLContext::IsProgram(WebGLProgram *prog)
}
bool
WebGLContext::IsRenderbuffer(WebGLRenderbuffer *rb)
WebGLContext::IsRenderbuffer(WebGLRenderbuffer* rb)
{
if (IsContextLost())
return false;
@ -1936,7 +1938,7 @@ WebGLContext::IsRenderbuffer(WebGLRenderbuffer *rb)
}
bool
WebGLContext::IsShader(WebGLShader *shader)
WebGLContext::IsShader(WebGLShader* shader)
{
if (IsContextLost())
return false;
@ -1946,7 +1948,7 @@ WebGLContext::IsShader(WebGLShader *shader)
}
bool
WebGLContext::IsTexture(WebGLTexture *tex)
WebGLContext::IsTexture(WebGLTexture* tex)
{
if (IsContextLost())
return false;
@ -1957,7 +1959,8 @@ WebGLContext::IsTexture(WebGLTexture *tex)
}
// Try to bind an attribute that is an array to location 0:
bool WebGLContext::BindArrayAttribToLocation0(WebGLProgram *program)
bool
WebGLContext::BindArrayAttribToLocation0(WebGLProgram* program)
{
if (mBoundVertexArray->IsAttribArrayEnabled(0)) {
return false;
@ -2006,7 +2009,7 @@ LinkAndUpdateProgram(GLContext* gl, WebGLProgram* prog)
}
void
WebGLContext::LinkProgram(WebGLProgram *program)
WebGLContext::LinkProgram(WebGLProgram* program)
{
if (IsContextLost())
return;
@ -2077,7 +2080,7 @@ WebGLContext::LinkProgram(WebGLProgram *program)
if (shader->CompileStatus())
continue;
const char *shaderTypeName = nullptr;
const char* shaderTypeName = nullptr;
if (shader->ShaderType() == LOCAL_GL_VERTEX_SHADER) {
shaderTypeName = "vertex";
} else if (shader->ShaderType() == LOCAL_GL_FRAGMENT_SHADER) {
@ -2656,7 +2659,8 @@ WebGLContext::StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum
nsresult
WebGLContext::SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromElementResult& res,
RefPtr<DataSourceSurface>& imageOut, WebGLTexelFormat *format)
RefPtr<DataSourceSurface>& imageOut,
WebGLTexelFormat* format)
{
*format = WebGLTexelFormat::None;
@ -3058,7 +3062,7 @@ WebGLContext::UniformMatrix4fv_base(WebGLUniformLocation* loc, bool transpose,
////////////////////////////////////////////////////////////////////////////////
void
WebGLContext::UseProgram(WebGLProgram *prog)
WebGLContext::UseProgram(WebGLProgram* prog)
{
if (IsContextLost())
return;
@ -3081,7 +3085,7 @@ WebGLContext::UseProgram(WebGLProgram *prog)
}
void
WebGLContext::ValidateProgram(WebGLProgram *prog)
WebGLContext::ValidateProgram(WebGLProgram* prog)
{
if (IsContextLost())
return;
@ -3145,7 +3149,7 @@ WebGLContext::Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
}
void
WebGLContext::CompileShader(WebGLShader *shader)
WebGLContext::CompileShader(WebGLShader* shader)
{
if (IsContextLost())
return;
@ -3231,7 +3235,7 @@ WebGLContext::CompileShader(WebGLShader *shader)
maxSourceLength);
}
const char *s = sourceCString.get();
const char* s = sourceCString.get();
#define WEBGL2_BYPASS_ANGLE
#ifdef WEBGL2_BYPASS_ANGLE
@ -3251,8 +3255,8 @@ WebGLContext::CompileShader(WebGLShader *shader)
* - one for the angle compilor, to get informations about vertex attributes
* and uniforms
*/
static const char *bypassPrefixSearch = "#version proto-200";
static const char *bypassANGLEPrefix[2] = {"precision mediump float;\n"
static const char* bypassPrefixSearch = "#version proto-200";
static const char* bypassANGLEPrefix[2] = {"precision mediump float;\n"
"#define gl_VertexID 0\n"
"#define gl_InstanceID 0\n",
@ -3262,13 +3266,13 @@ WebGLContext::CompileShader(WebGLShader *shader)
const bool bypassANGLE = IsWebGL2() && (strstr(s, bypassPrefixSearch) != 0);
const char *angleShaderCode = s;
const char* angleShaderCode = s;
nsTArray<char> bypassANGLEShaderCode;
nsTArray<char> bypassDriverShaderCode;
if (bypassANGLE) {
const int bypassStage = (shader->ShaderType() == LOCAL_GL_FRAGMENT_SHADER) ? 1 : 0;
const char *originalShader = strstr(s, bypassPrefixSearch) + strlen(bypassPrefixSearch);
const char* originalShader = strstr(s, bypassPrefixSearch) + strlen(bypassPrefixSearch);
int originalShaderSize = strlen(s) - (originalShader - s);
int bypassShaderCodeSize = originalShaderSize + 4096 + 1;
@ -3428,7 +3432,7 @@ WebGLContext::CompileShader(WebGLShader *shader)
CopyASCIItoUTF16(translatedSrc, shader->mTranslatedSource);
const char *ts = translatedSrc.get();
const char* ts = translatedSrc.get();
#ifdef WEBGL2_BYPASS_ANGLE
if (bypassANGLE) {
@ -3490,7 +3494,7 @@ WebGLContext::CompressedTexImage2D(GLenum rawTexImgTarget,
const TexImageTarget texImageTarget(rawTexImgTarget);
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
MOZ_ASSERT(tex);
if (tex->IsImmutable()) {
return ErrorInvalidOperation(
@ -3532,7 +3536,7 @@ WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint
const TexImageTarget texImageTarget(rawTexImgTarget);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
MOZ_ASSERT(tex);
WebGLTexture::ImageInfo& levelInfo = tex->ImageInfoAt(texImageTarget, level);
@ -3572,7 +3576,7 @@ WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint
}
JS::Value
WebGLContext::GetShaderParameter(WebGLShader *shader, GLenum pname)
WebGLContext::GetShaderParameter(WebGLShader* shader, GLenum pname)
{
if (IsContextLost())
return JS::NullValue();
@ -3610,7 +3614,7 @@ WebGLContext::GetShaderParameter(WebGLShader *shader, GLenum pname)
}
void
WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsAString& retval)
WebGLContext::GetShaderInfoLog(WebGLShader* shader, nsAString& retval)
{
nsAutoCString s;
GetShaderInfoLog(shader, s);
@ -3621,7 +3625,7 @@ WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsAString& retval)
}
void
WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsACString& retval)
WebGLContext::GetShaderInfoLog(WebGLShader* shader, nsACString& retval)
{
if (IsContextLost())
{
@ -3706,7 +3710,7 @@ WebGLContext::GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype)
}
void
WebGLContext::GetShaderSource(WebGLShader *shader, nsAString& retval)
WebGLContext::GetShaderSource(WebGLShader* shader, nsAString& retval)
{
if (IsContextLost()) {
retval.SetIsVoid(true);
@ -3720,7 +3724,7 @@ WebGLContext::GetShaderSource(WebGLShader *shader, nsAString& retval)
}
void
WebGLContext::ShaderSource(WebGLShader *shader, const nsAString& source)
WebGLContext::ShaderSource(WebGLShader* shader, const nsAString& source)
{
if (IsContextLost())
return;
@ -3742,7 +3746,7 @@ WebGLContext::ShaderSource(WebGLShader *shader, const nsAString& source)
}
void
WebGLContext::GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval)
WebGLContext::GetShaderTranslatedSource(WebGLShader* shader, nsAString& retval)
{
if (IsContextLost()) {
retval.SetIsVoid(true);
@ -3763,10 +3767,10 @@ GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
GLint border,
TexFormat format,
TexType type,
const GLvoid *data)
const GLvoid* data)
{
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
MOZ_ASSERT(tex != nullptr, "no texture bound");
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
MOZ_ASSERT(tex, "no texture bound");
TexInternalFormat effectiveInternalFormat =
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
@ -3881,7 +3885,7 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
return ErrorInvalidOperation("texImage2D: not enough data for operation (need %d, have %d)",
bytesNeeded, byteLength);
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("texImage2D: no texture is bound to this target");
@ -4031,18 +4035,15 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
const WebGLTexImageFunc func = WebGLTexImageFunc::TexSubImage;
const WebGLTexDimensions dims = WebGLTexDimensions::Tex2D;
if (type == LOCAL_GL_HALF_FLOAT_OES) {
if (type == LOCAL_GL_HALF_FLOAT_OES)
type = LOCAL_GL_HALF_FLOAT;
}
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
if (!tex) {
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
if (!tex)
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
}
if (!tex->HasImageInfoAt(texImageTarget, level)) {
if (!tex->HasImageInfoAt(texImageTarget, level))
return ErrorInvalidOperation("texSubImage2D: no previously defined texture image");
}
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
const TexInternalFormat existingEffectiveInternalFormat = imageInfo.EffectiveInternalFormat();
@ -4234,7 +4235,7 @@ WebGLContext::RestoreContext()
}
bool
BaseTypeAndSizeFromUniformType(GLenum uType, GLenum *baseType, GLint *unitSize)
BaseTypeAndSizeFromUniformType(GLenum uType, GLenum* baseType, GLint* unitSize)
{
switch (uType) {
case LOCAL_GL_INT:

Просмотреть файл

@ -41,9 +41,8 @@ WebGLContextLossHandler::StartTimer(unsigned long delayMS)
nsITimer::TYPE_ONE_SHOT);
}
/* static */ void
WebGLContextLossHandler::StaticTimerCallback(nsITimer*,
void* voidHandler)
/*static*/ void
WebGLContextLossHandler::StaticTimerCallback(nsITimer*, void* voidHandler)
{
typedef WebGLContextLossHandler T;
T* handler = static_cast<T*>(voidHandler);

Просмотреть файл

@ -29,7 +29,7 @@ class WebGLContextLossHandler
public:
NS_INLINE_DECL_REFCOUNTING(WebGLContextLossHandler)
explicit WebGLContextLossHandler(WebGLContext* aWebgl);
explicit WebGLContextLossHandler(WebGLContext* webgl);
void RunTimer();
void DisableTimer();

Просмотреть файл

@ -5,6 +5,6 @@
#include "nsIDOMWebGLRenderingContext.h"
#define DUMMY(func,rtype) nsresult func (rtype ** aResult) { return NS_ERROR_FAILURE; }
#define DUMMY(func,rtype) nsresult func (rtype **) { return NS_ERROR_FAILURE; }
DUMMY(NS_NewCanvasRenderingContextWebGL, nsIDOMWebGLRenderingContext)

Просмотреть файл

@ -11,15 +11,15 @@ using namespace mozilla;
NS_IMPL_ISUPPORTS(WebGLObserver, nsIObserver)
NS_IMETHODIMP
WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize)
WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* handleReport,
nsISupports* data, bool)
{
#define REPORT(_path, _kind, _units, _amount, _desc) \
do { \
nsresult rv; \
rv = aHandleReport->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \
rv = handleReport->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \
_kind, _units, _amount, \
NS_LITERAL_CSTRING(_desc), aData); \
NS_LITERAL_CSTRING(_desc), data); \
NS_ENSURE_SUCCESS(rv, rv); \
} while (0)
@ -89,7 +89,8 @@ NS_IMPL_ISUPPORTS(WebGLMemoryTracker, nsIMemoryReporter)
StaticRefPtr<WebGLMemoryTracker> WebGLMemoryTracker::sUniqueInstance;
WebGLMemoryTracker* WebGLMemoryTracker::UniqueInstance()
WebGLMemoryTracker*
WebGLMemoryTracker::UniqueInstance()
{
if (!sUniqueInstance) {
sUniqueInstance = new WebGLMemoryTracker;
@ -116,11 +117,12 @@ WebGLMemoryTracker::~WebGLMemoryTracker()
MOZ_DEFINE_MALLOC_SIZE_OF(WebGLBufferMallocSizeOf)
int64_t
WebGLMemoryTracker::GetBufferCacheMemoryUsed() {
const ContextsArrayType & contexts = Contexts();
WebGLMemoryTracker::GetBufferCacheMemoryUsed()
{
const ContextsArrayType& contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLBuffer *buffer = contexts[i]->mBuffers.getFirst();
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
buffer;
buffer = buffer->getNext())
{
@ -134,11 +136,12 @@ WebGLMemoryTracker::GetBufferCacheMemoryUsed() {
MOZ_DEFINE_MALLOC_SIZE_OF(WebGLShaderMallocSizeOf)
int64_t
WebGLMemoryTracker::GetShaderSize() {
const ContextsArrayType & contexts = Contexts();
WebGLMemoryTracker::GetShaderSize()
{
const ContextsArrayType& contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLShader *shader = contexts[i]->mShaders.getFirst();
for (const WebGLShader* shader = contexts[i]->mShaders.getFirst();
shader;
shader = shader->getNext())
{

Просмотреть файл

@ -5,10 +5,9 @@
#include "WebGLContext.h"
#include <stdarg.h>
#include "GLContext.h"
#include "jsapi.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/Preferences.h"
#include "nsIDOMDataContainerEvent.h"
#include "nsIDOMEvent.h"
@ -17,6 +16,7 @@
#include "nsPrintfCString.h"
#include "nsServiceManagerUtils.h"
#include "prprf.h"
#include <stdarg.h>
#include "WebGLBuffer.h"
#include "WebGLExtensions.h"
#include "WebGLFramebuffer.h"
@ -25,8 +25,6 @@
#include "WebGLVertexArray.h"
#include "WebGLContextUtils.h"
#include "mozilla/dom/ScriptSettings.h"
namespace mozilla {
using namespace gl;
@ -173,8 +171,8 @@ EffectiveInternalFormatFromUnsizedInternalFormatAndType(TexInternalFormat intern
void
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(TexInternalFormat effectiveinternalformat,
TexInternalFormat* out_internalformat,
TexType* out_type)
TexInternalFormat* const out_internalformat,
TexType* const out_type)
{
MOZ_ASSERT(TypeFromInternalFormat(effectiveinternalformat) != LOCAL_GL_NONE);
@ -207,13 +205,13 @@ EffectiveInternalFormatFromInternalFormatAndType(TexInternalFormat internalforma
TexType type)
{
TexType typeOfInternalFormat = TypeFromInternalFormat(internalformat);
if (typeOfInternalFormat == LOCAL_GL_NONE) {
if (typeOfInternalFormat == LOCAL_GL_NONE)
return EffectiveInternalFormatFromUnsizedInternalFormatAndType(internalformat, type);
} else if (typeOfInternalFormat == type) {
if (typeOfInternalFormat == type)
return internalformat;
} else {
return LOCAL_GL_NONE;
}
}
/**
@ -223,9 +221,9 @@ EffectiveInternalFormatFromInternalFormatAndType(TexInternalFormat internalforma
void
DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
TexInternalFormat effectiveinternalformat,
GLenum* out_driverInternalFormat,
GLenum* out_driverFormat,
GLenum* out_driverType)
GLenum* const out_driverInternalFormat,
GLenum* const out_driverFormat,
GLenum* const out_driverType)
{
MOZ_ASSERT(out_driverInternalFormat);
MOZ_ASSERT(out_driverFormat);
@ -235,14 +233,14 @@ DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
TexType type = LOCAL_GL_NONE;
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(effectiveinternalformat,
&unsizedinternalformat, &type);
&unsizedinternalformat,
&type);
// driverType: almost always the generic type that we just got, except on ES
// we must replace HALF_FLOAT by HALF_FLOAT_OES
GLenum driverType = type.get();
if (gl->IsGLES() && type == LOCAL_GL_HALF_FLOAT) {
if (gl->IsGLES() && type == LOCAL_GL_HALF_FLOAT)
driverType = LOCAL_GL_HALF_FLOAT_OES;
}
// driverFormat: always just the unsized internalformat that we just got
GLenum driverFormat = unsizedinternalformat.get();
@ -253,11 +251,10 @@ DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
GLenum driverInternalFormat = driverFormat;
if (!gl->IsGLES()) {
// Cases where desktop OpenGL requires a tweak to 'format'
if (driverFormat == LOCAL_GL_SRGB) {
if (driverFormat == LOCAL_GL_SRGB)
driverFormat = LOCAL_GL_RGB;
} else if (driverFormat == LOCAL_GL_SRGB_ALPHA) {
else if (driverFormat == LOCAL_GL_SRGB_ALPHA)
driverFormat = LOCAL_GL_RGBA;
}
// WebGL2's new formats are not legal values for internalformat,
// as using unsized internalformat is deprecated.
@ -405,7 +402,7 @@ GetBitsPerTexel(TexInternalFormat effectiveinternalformat)
}
void
WebGLContext::GenerateWarning(const char *fmt, ...)
WebGLContext::GenerateWarning(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@ -416,7 +413,7 @@ WebGLContext::GenerateWarning(const char *fmt, ...)
}
void
WebGLContext::GenerateWarning(const char *fmt, va_list ap)
WebGLContext::GenerateWarning(const char* fmt, va_list ap)
{
if (!ShouldGenerateWarnings())
return;
@ -432,27 +429,24 @@ WebGLContext::GenerateWarning(const char *fmt, va_list ap)
JS_ReportWarning(cx, "WebGL: %s", buf);
if (!ShouldGenerateWarnings()) {
JS_ReportWarning(cx,
"WebGL: No further warnings will be reported for this WebGL context "
"(already reported %d warnings)", mAlreadyGeneratedWarnings);
"WebGL: No further warnings will be reported for this"
" WebGL context. (already reported %d warnings)",
mAlreadyGeneratedWarnings);
}
}
bool
WebGLContext::ShouldGenerateWarnings() const
{
if (mMaxWarnings == -1) {
if (mMaxWarnings == -1)
return true;
}
return mAlreadyGeneratedWarnings < mMaxWarnings;
}
CheckedUint32
WebGLContext::GetImageSize(GLsizei height,
GLsizei width,
GLsizei depth,
uint32_t pixelSize,
uint32_t packOrUnpackAlignment)
WebGLContext::GetImageSize(GLsizei height, GLsizei width, GLsizei depth,
uint32_t pixelSize, uint32_t packOrUnpackAlignment)
{
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * pixelSize;
@ -460,8 +454,11 @@ WebGLContext::GetImageSize(GLsizei height,
CheckedUint32 checked_alignedRowSize = RoundedToNextMultipleOf(checked_plainRowSize, packOrUnpackAlignment);
// if height is 0, we don't need any memory to store this; without this check, we'll get an overflow
CheckedUint32 checked_2dImageSize
= height <= 0 ? 0 : (height-1) * checked_alignedRowSize + checked_plainRowSize;
CheckedUint32 checked_2dImageSize = 0;
if (height >= 1) {
checked_2dImageSize = (height-1) * checked_alignedRowSize +
checked_plainRowSize;
}
// FIXME - we should honor UNPACK_IMAGE_HEIGHT
CheckedUint32 checked_imageSize = checked_2dImageSize * depth;
@ -482,7 +479,7 @@ WebGLContext::SynthesizeGLError(GLenum err)
}
void
WebGLContext::SynthesizeGLError(GLenum err, const char *fmt, ...)
WebGLContext::SynthesizeGLError(GLenum err, const char* fmt, ...)
{
va_list va;
va_start(va, fmt);
@ -493,7 +490,7 @@ WebGLContext::SynthesizeGLError(GLenum err, const char *fmt, ...)
}
void
WebGLContext::ErrorInvalidEnum(const char *fmt, ...)
WebGLContext::ErrorInvalidEnum(const char* fmt, ...)
{
va_list va;
va_start(va, fmt);
@ -504,7 +501,7 @@ WebGLContext::ErrorInvalidEnum(const char *fmt, ...)
}
void
WebGLContext::ErrorInvalidEnumInfo(const char *info, GLenum enumvalue)
WebGLContext::ErrorInvalidEnumInfo(const char* info, GLenum enumvalue)
{
nsCString name;
EnumName(enumvalue, &name);
@ -513,7 +510,7 @@ WebGLContext::ErrorInvalidEnumInfo(const char *info, GLenum enumvalue)
}
void
WebGLContext::ErrorInvalidOperation(const char *fmt, ...)
WebGLContext::ErrorInvalidOperation(const char* fmt, ...)
{
va_list va;
va_start(va, fmt);
@ -524,7 +521,7 @@ WebGLContext::ErrorInvalidOperation(const char *fmt, ...)
}
void
WebGLContext::ErrorInvalidValue(const char *fmt, ...)
WebGLContext::ErrorInvalidValue(const char* fmt, ...)
{
va_list va;
va_start(va, fmt);
@ -535,7 +532,7 @@ WebGLContext::ErrorInvalidValue(const char *fmt, ...)
}
void
WebGLContext::ErrorInvalidFramebufferOperation(const char *fmt, ...)
WebGLContext::ErrorInvalidFramebufferOperation(const char* fmt, ...)
{
va_list va;
va_start(va, fmt);
@ -546,7 +543,7 @@ WebGLContext::ErrorInvalidFramebufferOperation(const char *fmt, ...)
}
void
WebGLContext::ErrorOutOfMemory(const char *fmt, ...)
WebGLContext::ErrorOutOfMemory(const char* fmt, ...)
{
va_list va;
va_start(va, fmt);
@ -556,7 +553,7 @@ WebGLContext::ErrorOutOfMemory(const char *fmt, ...)
return SynthesizeGLError(LOCAL_GL_OUT_OF_MEMORY);
}
const char *
const char*
WebGLContext::ErrorName(GLenum error)
{
switch(error) {
@ -574,7 +571,7 @@ WebGLContext::ErrorName(GLenum error)
return "NO_ERROR";
default:
MOZ_ASSERT(false);
return "[unknown WebGL error!]";
return "[unknown WebGL error]";
}
}
@ -995,7 +992,8 @@ AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow)
}
void
AssertMaskedUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint mask, GLuint shadow)
AssertMaskedUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint mask,
GLuint shadow)
{
GLuint val = 0;
gl->GetUIntegerv(pname, &val);
@ -1040,11 +1038,11 @@ WebGLContext::AssertCachedBindings()
GLenum activeTexture = mActiveTexture + LOCAL_GL_TEXTURE0;
AssertUintParamCorrect(gl, LOCAL_GL_ACTIVE_TEXTURE, activeTexture);
WebGLTexture* curTex = activeBoundTextureForTarget(LOCAL_GL_TEXTURE_2D);
WebGLTexture* curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_2D);
bound = curTex ? curTex->GLName() : 0;
AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_2D, bound);
curTex = activeBoundTextureForTarget(LOCAL_GL_TEXTURE_CUBE_MAP);
curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_CUBE_MAP);
bound = curTex ? curTex->GLName() : 0;
AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_CUBE_MAP, bound);

Просмотреть файл

@ -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 WEBGLCONTEXTUTILS_H_
#define WEBGLCONTEXTUTILS_H_
#ifndef WEBGL_CONTEXT_UTILS_H_
#define WEBGL_CONTEXT_UTILS_H_
#include "WebGLContext.h"
#include "WebGLStrongTypes.h"
@ -16,12 +16,13 @@ namespace mozilla {
bool IsGLDepthFormat(TexInternalFormat webGLFormat);
bool IsGLDepthStencilFormat(TexInternalFormat webGLFormat);
bool FormatHasAlpha(TexInternalFormat webGLFormat);
void
DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
TexInternalFormat internalformat,
GLenum* out_driverInternalFormat,
GLenum* out_driverFormat,
GLenum* out_driverType);
GLenum* const out_driverInternalFormat,
GLenum* const out_driverFormat,
GLenum* const out_driverType);
TexInternalFormat
EffectiveInternalFormatFromInternalFormatAndType(TexInternalFormat internalformat,
TexType type);
@ -30,14 +31,14 @@ EffectiveInternalFormatFromUnsizedInternalFormatAndType(TexInternalFormat intern
TexType type);
void
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(TexInternalFormat effectiveinternalformat,
TexInternalFormat* out_internalformat,
TexType* out_type);
TexType
TypeFromInternalFormat(TexInternalFormat internalformat);
TexInternalFormat* const out_internalformat,
TexType* const out_type);
TexType TypeFromInternalFormat(TexInternalFormat internalformat);
TexInternalFormat
UnsizedInternalFormatFromInternalFormat(TexInternalFormat internalformat);
size_t
GetBitsPerTexel(TexInternalFormat effectiveinternalformat);
size_t GetBitsPerTexel(TexInternalFormat effectiveinternalformat);
// For use with the different texture calls, i.e.
// TexImage2D, CopyTex[Sub]Image2D, ...
@ -68,9 +69,9 @@ struct GLComponents
GLComponents()
: mComponents(0)
{ }
{}
explicit GLComponents(TexInternalFormat aFormat);
explicit GLComponents(TexInternalFormat format);
// Returns true iff other has all (or more) of
// the components present in this GLComponents
@ -79,17 +80,17 @@ struct GLComponents
template <typename WebGLObjectType>
JS::Value
WebGLContext::WebGLObjectAsJSValue(JSContext *cx, const WebGLObjectType *object, ErrorResult& rv) const
WebGLContext::WebGLObjectAsJSValue(JSContext* cx, const WebGLObjectType* object,
ErrorResult& rv) const
{
if (!object) {
if (!object)
return JS::NullValue();
}
MOZ_ASSERT(this == object->Context());
JS::Rooted<JS::Value> v(cx);
JS::Rooted<JSObject*> wrapper(cx, GetWrapper());
JSAutoCompartment ac(cx, wrapper);
if (!dom::GetOrCreateDOMReflector(cx, const_cast<WebGLObjectType*>(object),
&v)) {
if (!dom::GetOrCreateDOMReflector(cx, const_cast<WebGLObjectType*>(object), &v)) {
rv.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
}
@ -98,12 +99,14 @@ WebGLContext::WebGLObjectAsJSValue(JSContext *cx, const WebGLObjectType *object,
template <typename WebGLObjectType>
JSObject*
WebGLContext::WebGLObjectAsJSObject(JSContext *cx, const WebGLObjectType *object, ErrorResult& rv) const
WebGLContext::WebGLObjectAsJSObject(JSContext* cx,
const WebGLObjectType* object,
ErrorResult& rv) const
{
JS::Value v = WebGLObjectAsJSValue(cx, object, rv);
if (v.isNull()) {
if (v.isNull())
return nullptr;
}
return &v.toObject();
}
@ -111,9 +114,8 @@ WebGLContext::WebGLObjectAsJSObject(JSContext *cx, const WebGLObjectType *object
* Return the displayable name for the texture function that is the
* source for validation.
*/
const char*
InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims);
const char* InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims);
} // namespace mozilla
#endif // WEBGLCONTEXTUTILS_H_
#endif // WEBGL_CONTEXT_UTILS_H_

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -4,15 +4,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLContext.h"
#include "WebGLBuffer.h"
#include "WebGLVertexAttribData.h"
#include "WebGLVertexArray.h"
#include "GLContext.h"
using namespace mozilla;
#include "GLContext.h"
#include "WebGLBuffer.h"
#include "WebGLVertexArray.h"
#include "WebGLVertexAttribData.h"
namespace mozilla {
void
WebGLContext::BindVertexArray(WebGLVertexArray *array)
WebGLContext::BindVertexArray(WebGLVertexArray* array)
{
if (IsContextLost())
return;
@ -59,7 +60,7 @@ WebGLContext::CreateVertexArray()
}
void
WebGLContext::DeleteVertexArray(WebGLVertexArray *array)
WebGLContext::DeleteVertexArray(WebGLVertexArray* array)
{
if (IsContextLost())
return;
@ -77,7 +78,7 @@ WebGLContext::DeleteVertexArray(WebGLVertexArray *array)
}
bool
WebGLContext::IsVertexArray(WebGLVertexArray *array)
WebGLContext::IsVertexArray(WebGLVertexArray* array)
{
if (IsContextLost())
return false;
@ -89,3 +90,5 @@ WebGLContext::IsVertexArray(WebGLVertexArray *array)
!array->IsDeleted() &&
array->HasEverBeenBound();
}
} // namespace mozilla

Просмотреть файл

@ -437,7 +437,7 @@ WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type,
return ErrorInvalidOperation("vertexAttribPointer: type must match bound VBO type: %d != %d", type, mBoundArrayBuffer->GLType());
*/
WebGLVertexAttribData &vd = mBoundVertexArray->mAttribs[index];
WebGLVertexAttribData& vd = mBoundVertexArray->mAttribs[index];
vd.buf = mBoundArrayBuffer;
vd.stride = stride;

Просмотреть файл

@ -5,54 +5,57 @@
#include "WebGLElementArrayCache.h"
#include "mozilla/Assertions.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/MathAlgorithms.h"
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <algorithm>
#include "mozilla/Assertions.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/MemoryReporting.h"
namespace mozilla {
static void
UpdateUpperBound(uint32_t* out_upperBound, uint32_t newBound)
UpdateUpperBound(uint32_t* const out_upperBound, uint32_t newBound)
{
MOZ_ASSERT(out_upperBound);
*out_upperBound = std::max(*out_upperBound, newBound);
}
/*
* WebGLElementArrayCacheTree contains most of the implementation of WebGLElementArrayCache,
* which performs WebGL element array buffer validation for drawElements.
/* WebGLElementArrayCacheTree contains most of the implementation of
* WebGLElementArrayCache, which performs WebGL element array buffer validation
* for drawElements.
*
* Attention: Here lie nontrivial data structures, bug-prone algorithms, and non-canonical tweaks!
* Whence the explanatory comments, and compiled unit test.
* Attention: Here lie nontrivial data structures, bug-prone algorithms, and
* non-canonical tweaks! Whence the explanatory comments, and compiled unit
* test.
*
* *** What problem are we solving here? ***
*
* WebGL::DrawElements has to validate that the elements are in range wrt the current vertex attribs.
* This boils down to the problem, given an array of integers, of computing the maximum in an arbitrary
* sub-array. The naive algorithm has linear complexity; this has been a major performance problem,
* see bug 569431. In that bug, we took the approach of caching the max for the whole array, which
* does cover most cases (DrawElements typically consumes the whole element array buffer) but doesn't
* help in other use cases:
* - when doing "partial DrawElements" i.e. consuming only part of the element array buffer
* - when doing frequent "partial buffer updates" i.e. bufferSubData calls updating parts of the
* element array buffer
* WebGL::DrawElements has to validate that the elements are in range wrt the
* current vertex attribs. This boils down to the problem, given an array of
* integers, of computing the maximum in an arbitrary sub-array. The naive
* algorithm has linear complexity; this has been a major performance problem,
* see bug 569431. In that bug, we took the approach of caching the max for the
* whole array, which does cover most cases (DrawElements typically consumes the
* whole element array buffer) but doesn't help in other use cases:
* - when doing "partial DrawElements" i.e. consuming only part of the element
* array buffer
* - when doing frequent "partial buffer updates" i.e. bufferSubData calls
* updating parts of the element array buffer
*
* *** The solution: a binary tree ***
* *** The solution: A binary tree ***
*
* The solution implemented here is to use a binary tree as the cache data structure. Each tree node
* contains the max of its two children nodes. In this way, finding the maximum in any contiguous sub-array
* has log complexity instead of linear complexity.
* The solution implemented here is to use a binary tree as the cache data
* structure. Each tree node contains the max of its two children nodes. In this
* way, finding the maximum in any contiguous sub-array has log complexity
* instead of linear complexity.
*
* Simplistically, if the element array is
* Simplistically, if the element array is:
*
* 1 4 3 2
* [1 4 3 2]
*
* then the corresponding tree is
* then the corresponding tree is:
*
* 4
* _/ \_
@ -60,33 +63,35 @@ UpdateUpperBound(uint32_t* out_upperBound, uint32_t newBound)
* / \ / \
* 1 4 3 2
*
* In practice, the bottom-most levels of the tree are both the largest to store (because they
* have more nodes), and the least useful performance-wise (because each node in the bottom
* levels concerns only few entries in the elements array buffer, it is cheap to compute).
* In practice, the bottom-most levels of the tree are both the largest to store
* (because they have more nodes), and the least useful performance-wise
* (because each node in the bottom levels concerns only few entries in the
* elements array buffer, it is cheap to compute).
*
* For this reason, we stop the tree a few levels above, so that each tree leaf actually corresponds
* to more than one element array entry.
* For this reason, we stop the tree a few levels above, so that each tree leaf
* actually corresponds to more than one element array entry.
*
* The number of levels that we "drop" is |sSkippedBottomTreeLevels| and the number of element array entries
* that each leaf corresponds to, is |sElementsPerLeaf|. This being a binary tree, we have
* The number of levels that we "drop" is |kSkippedBottomTreeLevels| and the
* number of element array entries that each leaf corresponds to, is
* |kElementsPerLeaf|. This being a binary tree, we have:
*
* sElementsPerLeaf = 2 ^ sSkippedBottomTreeLevels.
* kElementsPerLeaf = 2 ^ kSkippedBottomTreeLevels.
*
* *** Storage layout of the binary tree ***
*
* We take advantage of the specifics of the situation to avoid generalist tree storage and instead
* store the tree entries in a vector, mTreeData.
* We take advantage of the specifics of the situation to avoid generalist tree
* storage and instead store the tree entries in a vector, mTreeData.
*
* TreeData is always a vector of length
* TreeData is always a vector of length:
*
* 2 * (number of leaves).
*
* Its data layout is as follows: mTreeData[0] is unused, mTreeData[1] is the root node,
* then at offsets 2..3 is the tree level immediately below the root node, then at offsets 4..7
* is the tree level below that, etc.
* Its data layout is as follows: mTreeData[0] is unused, mTreeData[1] is the
* root node, then at offsets 2..3 is the tree level immediately below the root
* node, then at offsets 4..7 is the tree level below that, etc.
*
* The figure below illustrates this by writing at each tree node the offset into mTreeData at
* which it is stored:
* The figure below illustrates this by writing at each tree node the offset
* into mTreeData at which it is stored:
*
* 1
* _/ \_
@ -95,45 +100,52 @@ UpdateUpperBound(uint32_t* out_upperBound, uint32_t newBound)
* 4 5 6 7
* ...
*
* Thus, under the convention that the root level is level 0, we see that level N is stored at offsets
* Thus, under the convention that the root level is level 0, we see that level
* N is stored at offsets:
*
* [ 2^n .. 2^(n+1) - 1 ]
*
* in mTreeData. Likewise, all the usual tree operations have simple mathematical expressions in
* terms of mTreeData offsets, see all the methods such as ParentNode, LeftChildNode, etc.
* in mTreeData. Likewise, all the usual tree operations have simple
* mathematical expressions in terms of mTreeData offsets, see all the methods
* such as ParentNode, LeftChildNode, etc.
*
* *** Design constraint: element types aren't known at buffer-update time ***
* *** Design constraint: Element types aren't known at buffer-update time ***
*
* Note that a key constraint that we're operating under, is that we don't know the types of the elements
* by the time WebGL bufferData/bufferSubData methods are called. The type of elements is only
* specified in the drawElements call. This means that we may potentially have to store caches for
* multiple element types, for the same element array buffer. Since we don't know yet how many
* element types we'll eventually support (extensions add more), the concern about memory usage is serious.
* This is addressed by sSkippedBottomTreeLevels as explained above. Of course, in the typical
* case where each element array buffer is only ever used with one type, this is also addressed
* by having WebGLElementArrayCache lazily create trees for each type only upon first use.
* Note that a key constraint that we're operating under, is that we don't know
* the types of the elements by the time WebGL bufferData/bufferSubData methods
* are called. The type of elements is only specified in the drawElements call.
* This means that we may potentially have to store caches for multiple element
* types, for the same element array buffer. Since we don't know yet how many
* element types we'll eventually support (extensions add more), the concern
* about memory usage is serious. This is addressed by kSkippedBottomTreeLevels
* as explained above. Of course, in the typical case where each element array
* buffer is only ever used with one type, this is also addressed by having
* WebGLElementArrayCache lazily create trees for each type only upon first use.
*
* Another consequence of this constraint is that when updating the trees, we have to update
* all existing trees. So if trees for types uint8_t, uint16_t and uint32_t have ever been constructed for this buffer,
* every subsequent update will have to update all trees even if one of the types is never
* used again. That's inefficient, but content should not put indices of different types in the
* same element array buffer anyways. Different index types can only be consumed in separate
* drawElements calls, so nothing particular is to be achieved by lumping them in the same
* buffer object.
* Another consequence of this constraint is that when updating the trees, we
* have to update all existing trees. So if trees for types uint8_t, uint16_t
* and uint32_t have ever been constructed for this buffer, every subsequent
* update will have to update all trees even if one of the types is never used
* again. That's inefficient, but content should not put indices of different
* types in the same element array buffer anyways. Different index types can
* only be consumed in separate drawElements calls, so nothing particular is
* to be achieved by lumping them in the same buffer object.
*/
template<typename T>
struct WebGLElementArrayCacheTree
{
// A too-high sSkippedBottomTreeLevels would harm the performance of small drawElements calls
// A too-low sSkippedBottomTreeLevels would cause undue memory usage.
// The current value has been validated by some benchmarking. See bug 732660.
static const size_t sSkippedBottomTreeLevels = 3;
static const size_t sElementsPerLeaf = 1 << sSkippedBottomTreeLevels;
static const size_t sElementsPerLeafMask = sElementsPerLeaf - 1; // sElementsPerLeaf is POT
/* A too-high kSkippedBottomTreeLevels would harm the performance of small
* drawElements calls. A too-low kSkippedBottomTreeLevels would cause undue
* memory usage. The current value has been validated by some benchmarking.
* See bug 732660.
*/
static const size_t kSkippedBottomTreeLevels = 3;
static const size_t kElementsPerLeaf = 1 << kSkippedBottomTreeLevels;
// Since kElementsPerLeaf is POT:
static const size_t kElementsPerLeafMask = kElementsPerLeaf - 1;
private:
// The WebGLElementArrayCache that owns this tree
// The WebGLElementArrayCache that owns this tree:
WebGLElementArrayCache& mParent;
// The tree's internal data storage. Its length is 2 * (number of leaves)
@ -144,8 +156,8 @@ public:
// Constructor. Takes a reference to the WebGLElementArrayCache that is to be
// the parent. Does not initialize the tree. Should be followed by a call
// to Update() to attempt initializing the tree.
explicit WebGLElementArrayCacheTree(WebGLElementArrayCache& aValue)
: mParent(aValue)
explicit WebGLElementArrayCacheTree(WebGLElementArrayCache& value)
: mParent(value)
{
}
@ -196,12 +208,12 @@ public:
}
size_t NumLeaves() const {
// see class comment for why we the tree storage size is 2 * numLeaves
// See class comment for why we the tree storage size is 2 * numLeaves.
return mTreeData.Length() >> 1;
}
size_t LeafForElement(size_t element) const {
size_t leaf = element / sElementsPerLeaf;
size_t leaf = element / kElementsPerLeaf;
MOZ_ASSERT(leaf < NumLeaves());
return leaf;
}
@ -210,74 +222,81 @@ public:
return LeafForElement(byte / sizeof(T));
}
// Returns the index, into the tree storage, where a given leaf is stored
// Returns the index, into the tree storage, where a given leaf is stored.
size_t TreeIndexForLeaf(size_t leaf) const {
// See above class comment. The tree storage is an array of length 2 * numLeaves.
// The leaves are stored in its second half.
// See above class comment. The tree storage is an array of length
// 2 * numLeaves. The leaves are stored in its second half.
return leaf + NumLeaves();
}
static size_t LastElementUnderSameLeaf(size_t element) {
return element | sElementsPerLeafMask;
return element | kElementsPerLeafMask;
}
static size_t FirstElementUnderSameLeaf(size_t element) {
return element & ~sElementsPerLeafMask;
return element & ~kElementsPerLeafMask;
}
static size_t NextMultipleOfElementsPerLeaf(size_t numElements) {
MOZ_ASSERT(numElements >= 1);
return ((numElements - 1) | sElementsPerLeafMask) + 1;
return ((numElements - 1) | kElementsPerLeafMask) + 1;
}
bool Validate(T maxAllowed, size_t firstLeaf, size_t lastLeaf,
uint32_t* out_upperBound)
uint32_t* const out_upperBound)
{
size_t firstTreeIndex = TreeIndexForLeaf(firstLeaf);
size_t lastTreeIndex = TreeIndexForLeaf(lastLeaf);
while (true) {
// given that we tweak these values in nontrivial ways, it doesn't hurt to do
// this sanity check
// Given that we tweak these values in nontrivial ways, it doesn't
// hurt to do this sanity check.
MOZ_ASSERT(firstTreeIndex <= lastTreeIndex);
// final case where there is only 1 node to validate at the current tree level
// Final case where there is only one node to validate at the
// current tree level:
if (lastTreeIndex == firstTreeIndex) {
const T& curData = mTreeData[firstTreeIndex];
UpdateUpperBound(out_upperBound, curData);
return curData <= maxAllowed;
}
// if the first node at current tree level is a right node, handle it individually
// and replace it with its right neighbor, which is a left node
// If the first node at current tree level is a right node, handle
// it individually and replace it with its right neighbor, which is
// a left node.
if (IsRightNode(firstTreeIndex)) {
const T& curData = mTreeData[firstTreeIndex];
UpdateUpperBound(out_upperBound, curData);
if (curData > maxAllowed)
return false;
firstTreeIndex = RightNeighborNode(firstTreeIndex);
}
// if the last node at current tree level is a left node, handle it individually
// and replace it with its left neighbor, which is a right node
// If the last node at current tree level is a left node, handle it
// individually and replace it with its left neighbor, which is a
// right node.
if (IsLeftNode(lastTreeIndex)) {
const T& curData = mTreeData[lastTreeIndex];
UpdateUpperBound(out_upperBound, curData);
if (curData > maxAllowed)
return false;
lastTreeIndex = LeftNeighborNode(lastTreeIndex);
}
// at this point it can happen that firstTreeIndex and lastTreeIndex "crossed" each
// other. That happens if firstTreeIndex was a right node and lastTreeIndex was its
// right neighor: in that case, both above tweaks happened and as a result, they ended
// up being swapped: lastTreeIndex is now the _left_ neighbor of firstTreeIndex.
// When that happens, there is nothing left to validate.
if (lastTreeIndex == LeftNeighborNode(firstTreeIndex)) {
/* At this point it can happen that firstTreeIndex and lastTreeIndex
* "crossed" eachother. That happens if firstTreeIndex was a right
* node and lastTreeIndex was its right neighor: In that case, both
* above tweaks happened and as a result, they ended up being
* swapped: LastTreeIndex is now the _left_ neighbor of
* firstTreeIndex. When that happens, there is nothing left to
* validate.
*/
if (lastTreeIndex == LeftNeighborNode(firstTreeIndex))
return true;
}
// walk up 1 level
// Walk up one level.
firstTreeIndex = ParentNode(firstTreeIndex);
lastTreeIndex = ParentNode(lastTreeIndex);
}
@ -287,9 +306,9 @@ public:
// may have to resize the tree storage.
bool Update(size_t firstByte, size_t lastByte);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
{
return aMallocSizeOf(this) + mTreeData.SizeOfExcludingThis(aMallocSizeOf);
return mallocSizeOf(this) + mTreeData.SizeOfExcludingThis(mallocSizeOf);
}
};
@ -302,7 +321,7 @@ template<>
struct TreeForType<uint8_t>
{
static ScopedDeletePtr<WebGLElementArrayCacheTree<uint8_t>>&
Value(WebGLElementArrayCache *b) {
Value(WebGLElementArrayCache* b) {
return b->mUint8Tree;
}
};
@ -311,7 +330,7 @@ template<>
struct TreeForType<uint16_t>
{
static ScopedDeletePtr<WebGLElementArrayCacheTree<uint16_t>>&
Value(WebGLElementArrayCache *b) {
Value(WebGLElementArrayCache* b) {
return b->mUint16Tree;
}
};
@ -320,15 +339,16 @@ template<>
struct TreeForType<uint32_t>
{
static ScopedDeletePtr<WebGLElementArrayCacheTree<uint32_t>>&
Value(WebGLElementArrayCache *b) {
Value(WebGLElementArrayCache* b) {
return b->mUint32Tree;
}
};
// Calling this method will 1) update the leaves in this interval
// from the raw buffer data, and 2) propagate this update up the tree
// from the raw buffer data, and 2) propagate this update up the tree.
template<typename T>
bool WebGLElementArrayCacheTree<T>::Update(size_t firstByte, size_t lastByte)
bool
WebGLElementArrayCacheTree<T>::Update(size_t firstByte, size_t lastByte)
{
MOZ_ASSERT(firstByte <= lastByte);
MOZ_ASSERT(lastByte < mParent.mBytes.Length());
@ -336,21 +356,23 @@ bool WebGLElementArrayCacheTree<T>::Update(size_t firstByte, size_t lastByte)
size_t numberOfElements = mParent.mBytes.Length() / sizeof(T);
size_t requiredNumLeaves = 0;
if (numberOfElements > 0) {
// If we didn't require the number of leaves to be a power of two, then
// it would just be equal to
//
// ceil(numberOfElements / sElementsPerLeaf)
//
// The way we implement this (division+ceil) operation in integer arithmetic
// is as follows:
size_t numLeavesNonPOT = (numberOfElements + sElementsPerLeaf - 1) / sElementsPerLeaf;
/* If we didn't require the number of leaves to be a power of two, then
* it would just be equal to
*
* ceil(numberOfElements / kElementsPerLeaf)
*
* The way we implement this (division+ceil) operation in integer
* arithmetic
* is as follows:
*/
size_t numLeavesNonPOT = (numberOfElements + kElementsPerLeaf - 1) / kElementsPerLeaf;
// It only remains to round that up to the next power of two:
requiredNumLeaves = RoundUpPow2(numLeavesNonPOT);
}
// Step #0: if needed, resize our tree data storage.
// Step #0: If needed, resize our tree data storage.
if (requiredNumLeaves != NumLeaves()) {
// see class comment for why we the tree storage size is 2 * numLeaves
// See class comment for why we the tree storage size is 2 * numLeaves.
if (!mTreeData.SetLength(2 * requiredNumLeaves)) {
mTreeData.SetLength(0);
return false;
@ -358,22 +380,20 @@ bool WebGLElementArrayCacheTree<T>::Update(size_t firstByte, size_t lastByte)
MOZ_ASSERT(NumLeaves() == requiredNumLeaves);
if (NumLeaves()) {
// when resizing, update the whole tree, not just the subset corresponding
// to the part of the buffer being updated.
// When resizing, update the whole tree, not just the subset
// corresponding to the part of the buffer being updated.
memset(mTreeData.Elements(), 0, mTreeData.Length() * sizeof(T));
firstByte = 0;
lastByte = mParent.mBytes.Length() - 1;
}
}
if (NumLeaves() == 0) {
if (NumLeaves() == 0)
return true;
}
lastByte = std::min(lastByte, NumLeaves() * sElementsPerLeaf * sizeof(T) - 1);
if (firstByte > lastByte) {
lastByte = std::min(lastByte, NumLeaves() * kElementsPerLeaf * sizeof(T) - 1);
if (firstByte > lastByte)
return true;
}
size_t firstLeaf = LeafForByte(firstByte);
size_t lastLeaf = LeafForByte(lastByte);
@ -383,19 +403,22 @@ bool WebGLElementArrayCacheTree<T>::Update(size_t firstByte, size_t lastByte)
size_t firstTreeIndex = TreeIndexForLeaf(firstLeaf);
size_t lastTreeIndex = TreeIndexForLeaf(lastLeaf);
// Step #1: initialize the tree leaves from plain buffer data.
// That is, each tree leaf must be set to the max of the |sElementsPerLeaf| corresponding
// buffer entries.
// condition-less scope to prevent leaking this scope's variables into the code below
// Step #1: Initialize the tree leaves from plain buffer data.
// That is, each tree leaf must be set to the max of the |kElementsPerLeaf|
// corresponding buffer entries.
// Condition-less scope to prevent leaking this scope's variables into the
// code below:
{
// treeIndex is the index of the tree leaf we're writing, i.e. the destination index
// TreeIndex is the index of the tree leaf we're writing, i.e. the
// destination index.
size_t treeIndex = firstTreeIndex;
// srcIndex is the index in the source buffer
size_t srcIndex = firstLeaf * sElementsPerLeaf;
// srcIndex is the index in the source buffer.
size_t srcIndex = firstLeaf * kElementsPerLeaf;
while (treeIndex <= lastTreeIndex) {
T m = 0;
size_t a = srcIndex;
size_t srcIndexNextLeaf = std::min(a + sElementsPerLeaf, numberOfElements);
size_t srcIndexNextLeaf = std::min(a + kElementsPerLeaf, numberOfElements);
for (; srcIndex < srcIndexNextLeaf; srcIndex++) {
m = std::max(m, mParent.Element<T>(srcIndex));
}
@ -404,14 +427,14 @@ bool WebGLElementArrayCacheTree<T>::Update(size_t firstByte, size_t lastByte)
}
}
// Step #2: propagate the values up the tree. This is simply a matter of walking up
// the tree and setting each node to the max of its two children.
// Step #2: Propagate the values up the tree. This is simply a matter of
// walking up the tree and setting each node to the max of its two children.
while (firstTreeIndex > 1) {
// move up 1 level
// Move up one level.
firstTreeIndex = ParentNode(firstTreeIndex);
lastTreeIndex = ParentNode(lastTreeIndex);
// fast-exit case where only one node is updated at the current level
// Fast-exit case where only one node is updated at the current level.
if (firstTreeIndex == lastTreeIndex) {
mTreeData[firstTreeIndex] = std::max(mTreeData[LeftChildNode(firstTreeIndex)], mTreeData[RightChildNode(firstTreeIndex)]);
continue;
@ -419,8 +442,7 @@ bool WebGLElementArrayCacheTree<T>::Update(size_t firstByte, size_t lastByte)
size_t child = LeftChildNode(firstTreeIndex);
size_t parent = firstTreeIndex;
while (parent <= lastTreeIndex)
{
while (parent <= lastTreeIndex) {
T a = mTreeData[child];
child = RightNeighborNode(child);
T b = mTreeData[child];
@ -433,13 +455,17 @@ bool WebGLElementArrayCacheTree<T>::Update(size_t firstByte, size_t lastByte)
return true;
}
WebGLElementArrayCache::WebGLElementArrayCache() {
WebGLElementArrayCache::WebGLElementArrayCache()
{
}
WebGLElementArrayCache::~WebGLElementArrayCache() {
WebGLElementArrayCache::~WebGLElementArrayCache()
{
}
bool WebGLElementArrayCache::BufferData(const void* ptr, size_t byteLength) {
bool
WebGLElementArrayCache::BufferData(const void* ptr, size_t byteLength)
{
if (mBytes.Length() != byteLength) {
if (!mBytes.SetLength(byteLength)) {
mBytes.SetLength(0);
@ -450,10 +476,14 @@ bool WebGLElementArrayCache::BufferData(const void* ptr, size_t byteLength) {
return BufferSubData(0, ptr, byteLength);
}
bool WebGLElementArrayCache::BufferSubData(size_t pos, const void* ptr, size_t updateByteLength) {
bool
WebGLElementArrayCache::BufferSubData(size_t pos, const void* ptr,
size_t updateByteLength)
{
MOZ_ASSERT(pos + updateByteLength <= mBytes.Length());
if (!updateByteLength)
return true;
if (ptr)
memcpy(mBytes.Elements() + pos, ptr, updateByteLength);
else
@ -461,7 +491,8 @@ bool WebGLElementArrayCache::BufferSubData(size_t pos, const void* ptr, size_t u
return UpdateTrees(pos, pos + updateByteLength - 1);
}
bool WebGLElementArrayCache::UpdateTrees(size_t firstByte, size_t lastByte)
bool
WebGLElementArrayCache::UpdateTrees(size_t firstByte, size_t lastByte)
{
bool result = true;
if (mUint8Tree)
@ -476,11 +507,13 @@ bool WebGLElementArrayCache::UpdateTrees(size_t firstByte, size_t lastByte)
template<typename T>
bool
WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
size_t countElements, uint32_t* out_upperBound)
size_t countElements,
uint32_t* const out_upperBound)
{
*out_upperBound = 0;
// if maxAllowed is >= the max T value, then there is no way that a T index could be invalid
// If maxAllowed is >= the max T value, then there is no way that a T index
// could be invalid.
uint32_t maxTSize = std::numeric_limits<T>::max();
if (maxAllowed >= maxTSize) {
UpdateUpperBound(out_upperBound, maxTSize);
@ -489,8 +522,8 @@ WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
T maxAllowedT(maxAllowed);
// integer overflow must have been handled earlier, so we assert that maxAllowedT
// is exactly the max allowed value.
// Integer overflow must have been handled earlier, so we assert that
// maxAllowedT is exactly the max allowed value.
MOZ_ASSERT(uint32_t(maxAllowedT) == maxAllowed);
if (!mBytes.Length() || !countElements)
@ -502,8 +535,9 @@ WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
if (mBytes.Length()) {
bool valid = tree->Update(0, mBytes.Length() - 1);
if (!valid) {
// Do not assert here. This case would happen if an allocation failed.
// We've already settled on fallible allocations around here.
// Do not assert here. This case would happen if an allocation
// failed. We've already settled on fallible allocations around
// here.
tree = nullptr;
return false;
}
@ -512,19 +546,19 @@ WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
size_t lastElement = firstElement + countElements - 1;
// fast exit path when the global maximum for the whole element array buffer
// falls in the allowed range
// Fast-exit path when the global maximum for the whole element array buffer
// falls in the allowed range:
T globalMax = tree->GlobalMaximum();
if (globalMax <= maxAllowedT)
{
if (globalMax <= maxAllowedT) {
UpdateUpperBound(out_upperBound, globalMax);
return true;
}
const T* elements = Elements<T>();
// before calling tree->Validate, we have to validate ourselves the boundaries of the elements span,
// to round them to the nearest multiple of sElementsPerLeaf.
// Before calling tree->Validate, we have to validate ourselves the
// boundaries of the elements span, to round them to the nearest multiple of
// kElementsPerLeaf.
size_t firstElementAdjustmentEnd = std::min(lastElement,
tree->LastElementUnderSameLeaf(firstElement));
while (firstElement <= firstElementAdjustmentEnd) {
@ -532,6 +566,7 @@ WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
UpdateUpperBound(out_upperBound, curData);
if (curData > maxAllowedT)
return false;
firstElement++;
}
size_t lastElementAdjustmentEnd = std::max(firstElement,
@ -541,6 +576,7 @@ WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
UpdateUpperBound(out_upperBound, curData);
if (curData > maxAllowedT)
return false;
lastElement--;
}
@ -549,39 +585,46 @@ WebGLElementArrayCache::Validate(uint32_t maxAllowed, size_t firstElement,
return true;
// general case
return tree->Validate(maxAllowedT,
tree->LeafForElement(firstElement),
tree->LeafForElement(lastElement),
out_upperBound);
return tree->Validate(maxAllowedT, tree->LeafForElement(firstElement),
tree->LeafForElement(lastElement), out_upperBound);
}
bool
WebGLElementArrayCache::Validate(GLenum type, uint32_t maxAllowed,
size_t firstElement, size_t countElements,
uint32_t* out_upperBound)
uint32_t* const out_upperBound)
{
if (type == LOCAL_GL_UNSIGNED_BYTE)
return Validate<uint8_t>(maxAllowed, firstElement, countElements, out_upperBound);
return Validate<uint8_t>(maxAllowed, firstElement, countElements,
out_upperBound);
if (type == LOCAL_GL_UNSIGNED_SHORT)
return Validate<uint16_t>(maxAllowed, firstElement, countElements, out_upperBound);
return Validate<uint16_t>(maxAllowed, firstElement, countElements,
out_upperBound);
if (type == LOCAL_GL_UNSIGNED_INT)
return Validate<uint32_t>(maxAllowed, firstElement, countElements, out_upperBound);
return Validate<uint32_t>(maxAllowed, firstElement, countElements,
out_upperBound);
MOZ_ASSERT(false, "Invalid type.");
return false;
}
size_t
WebGLElementArrayCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
template<typename T>
static size_t
SizeOfNullable(mozilla::MallocSizeOf mallocSizeOf, const T& obj)
{
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) +
mBytes.SizeOfExcludingThis(aMallocSizeOf) +
uint8TreeSize +
uint16TreeSize +
uint32TreeSize;
if (!obj)
return 0;
return obj->SizeOfIncludingThis(mallocSizeOf);
}
size_t
WebGLElementArrayCache::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
{
return mallocSizeOf(this) +
mBytes.SizeOfExcludingThis(mallocSizeOf) +
SizeOfNullable(mallocSizeOf, mUint8Tree) +
SizeOfNullable(mallocSizeOf, mUint16Tree) +
SizeOfNullable(mallocSizeOf, mUint32Tree);
}
bool

Просмотреть файл

@ -3,81 +3,85 @@
* 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 WEBGLELEMENTARRAYCACHE_H
#define WEBGLELEMENTARRAYCACHE_H
#ifndef WEBGL_ELEMENT_ARRAY_CACHE_H
#define WEBGL_ELEMENT_ARRAY_CACHE_H
#include "GLDefs.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Scoped.h"
#include "nscore.h"
#include "nsTArray.h"
#include <stdint.h>
#include "nscore.h"
#include "GLDefs.h"
namespace mozilla {
template<typename T>
struct WebGLElementArrayCacheTree;
/*
* WebGLElementArrayCache implements WebGL element array buffer validation for drawElements.
/* WebGLElementArrayCache implements WebGL element array buffer validation for
* drawElements.
*
* Its exposes methods meant to be called by WebGL method implementations:
* - Validate, to be called by WebGLContext::DrawElements, is where we use the cache
* - BufferData and BufferSubData, to be called by eponymous WebGL methods, are how
* data is fed into the cache
*
* Most of the implementation is hidden in the auxilary class template, WebGLElementArrayCacheTree.
* Refer to its code for design comments.
* - Validate, to be called by WebGLContext::DrawElements, is where we use the
* cache.
*
* - BufferData and BufferSubData, to be called by eponymous WebGL methods, are
* how data is fed into the cache.
*
* Most of the implementation is hidden in the auxilary class template,
* WebGLElementArrayCacheTree. Refer to its code for design comments.
*/
class WebGLElementArrayCache {
public:
bool BufferData(const void* ptr, size_t byteLength);
bool BufferSubData(size_t pos, const void* ptr, size_t updateByteSize);
bool Validate(GLenum type, uint32_t maxAllowed, size_t first, size_t count,
uint32_t* out_upperBound);
uint32_t* const out_upperBound);
template<typename T>
T Element(size_t i) const { return Elements<T>()[i]; }
WebGLElementArrayCache();
~WebGLElementArrayCache();
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
bool BeenUsedWithMultipleTypes() const;
private:
/*
* Returns true if a drawElements call with the given parameters should succeed,
* false otherwise.
/* Returns true if a drawElements call with the given parameters should
* succeed, false otherwise.
*
* In other words, this returns true if all entries in the element array at positions
* In other words, this returns true if all entries in the element array at
* positions:
*
* first .. first+count-1
*
* are less than or equal to maxAllowed.
*
* Input parameters:
* maxAllowed: maximum value to be allowed in the specificied portion of the element array.
* first: start of the portion of the element array to consume.
* count: number of entries from the element array to consume.
* maxAllowed: Maximum value to be allowed in the specificied portion of
* the element array.
* first: Start of the portion of the element array to consume.
* count: Number of entries from the element array to consume.
*
* Output parameter:
* out_upperBound: upon success, is set to the actual maximum value in the specified range,
* which is then guaranteed to be less than or equal to maxAllowed.
* upon failure, is set to the first value in the specified range, that
* is greater than maxAllowed.
* out_upperBound: Upon success, is set to the actual maximum value in the
* specified range, which is then guaranteed to be less
* than or equal to maxAllowed. upon failure, is set to
* the first value in the specified range, that is greater
* than maxAllowed.
*/
template<typename T>
bool Validate(uint32_t maxAllowed, size_t first, size_t count,
uint32_t* out_upperBound);
uint32_t* const out_upperBound);
template<typename T>
const T* Elements() const { return reinterpret_cast<const T*>(mBytes.Elements()); }
const T* Elements() const {
return reinterpret_cast<const T*>(mBytes.Elements());
}
template<typename T>
T* Elements() { return reinterpret_cast<T*>(mBytes.Elements()); }
@ -94,7 +98,6 @@ private:
ScopedDeletePtr<WebGLElementArrayCacheTree<uint32_t>> mUint32Tree;
};
} // end namespace mozilla
#endif // WEBGLELEMENTARRAYCACHE_H
#endif // WEBGL_ELEMENT_ARRAY_CACHE_H

Просмотреть файл

@ -2,27 +2,30 @@
* 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 "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionBlendMinMax::WebGLExtensionBlendMinMax(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionBlendMinMax::WebGLExtensionBlendMinMax(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
}
WebGLExtensionBlendMinMax::~WebGLExtensionBlendMinMax()
{
}
bool WebGLExtensionBlendMinMax::IsSupported(const WebGLContext* context)
bool
WebGLExtensionBlendMinMax::IsSupported(const WebGLContext* webgl)
{
return context->GL()->IsSupported(gl::GLFeature::blend_minmax);
return webgl->GL()->IsSupported(gl::GLFeature::blend_minmax);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionBlendMinMax)
} // namespace mozilla

Просмотреть файл

@ -8,12 +8,12 @@
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionColorBufferFloat::WebGLExtensionColorBufferFloat(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionColorBufferFloat::WebGLExtensionColorBufferFloat(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
MOZ_ASSERT(IsSupported(context));
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
}
WebGLExtensionColorBufferFloat::~WebGLExtensionColorBufferFloat()
@ -21,9 +21,9 @@ WebGLExtensionColorBufferFloat::~WebGLExtensionColorBufferFloat()
}
bool
WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext* context)
WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext* webgl)
{
gl::GLContext* gl = context->GL();
gl::GLContext* gl = webgl->GL();
// ANGLE supports this, but doesn't have a way to advertize its support,
// since it's compliant with WEBGL_color_buffer_float's clamping, but not
@ -33,3 +33,5 @@ WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext* context)
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionColorBufferFloat)
} // namespace mozilla

Просмотреть файл

@ -8,12 +8,12 @@
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionColorBufferHalfFloat::WebGLExtensionColorBufferHalfFloat(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionColorBufferHalfFloat::WebGLExtensionColorBufferHalfFloat(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
MOZ_ASSERT(IsSupported(context));
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
}
WebGLExtensionColorBufferHalfFloat::~WebGLExtensionColorBufferHalfFloat()
@ -21,12 +21,14 @@ WebGLExtensionColorBufferHalfFloat::~WebGLExtensionColorBufferHalfFloat()
}
bool
WebGLExtensionColorBufferHalfFloat::IsSupported(const WebGLContext* context)
WebGLExtensionColorBufferHalfFloat::IsSupported(const WebGLContext* webgl)
{
gl::GLContext* gl = context->GL();
gl::GLContext* gl = webgl->GL();
// ANGLE doesn't support ReadPixels from a RGBA16F with RGBA/FLOAT.
return gl->IsSupported(gl::GLFeature::renderbuffer_color_half_float);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionColorBufferHalfFloat)
} // namespace mozilla

Просмотреть файл

@ -2,18 +2,19 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionCompressedTextureATC::WebGLExtensionCompressedTextureATC(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionCompressedTextureATC::WebGLExtensionCompressedTextureATC(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_ATC_RGB);
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA);
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_ATC_RGB);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA);
}
WebGLExtensionCompressedTextureATC::~WebGLExtensionCompressedTextureATC()
@ -21,3 +22,5 @@ WebGLExtensionCompressedTextureATC::~WebGLExtensionCompressedTextureATC()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureATC)
} // namespace mozilla

Просмотреть файл

@ -7,12 +7,12 @@
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionCompressedTextureETC1::WebGLExtensionCompressedTextureETC1(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionCompressedTextureETC1::WebGLExtensionCompressedTextureETC1(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_ETC1_RGB8_OES);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_ETC1_RGB8_OES);
}
WebGLExtensionCompressedTextureETC1::~WebGLExtensionCompressedTextureETC1()
@ -20,3 +20,5 @@ WebGLExtensionCompressedTextureETC1::~WebGLExtensionCompressedTextureETC1()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureETC1)
} // namespace mozilla

Просмотреть файл

@ -2,19 +2,20 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionCompressedTexturePVRTC::WebGLExtensionCompressedTexturePVRTC(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionCompressedTexturePVRTC::WebGLExtensionCompressedTexturePVRTC(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1);
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1);
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1);
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1);
}
WebGLExtensionCompressedTexturePVRTC::~WebGLExtensionCompressedTexturePVRTC()
@ -22,3 +23,5 @@ WebGLExtensionCompressedTexturePVRTC::~WebGLExtensionCompressedTexturePVRTC()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTexturePVRTC)
} // namespace mozilla

Просмотреть файл

@ -2,19 +2,20 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionCompressedTextureS3TC::WebGLExtensionCompressedTextureS3TC(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionCompressedTextureS3TC::WebGLExtensionCompressedTextureS3TC(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
context->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
webgl->mCompressedTextureFormats.AppendElement(LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
}
WebGLExtensionCompressedTextureS3TC::~WebGLExtensionCompressedTextureS3TC()
@ -22,3 +23,5 @@ WebGLExtensionCompressedTextureS3TC::~WebGLExtensionCompressedTextureS3TC()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureS3TC)
} // namespace mozilla

Просмотреть файл

@ -3,14 +3,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionDebugRendererInfo::WebGLExtensionDebugRendererInfo(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionDebugRendererInfo::WebGLExtensionDebugRendererInfo(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -19,3 +20,5 @@ WebGLExtensionDebugRendererInfo::~WebGLExtensionDebugRendererInfo()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDebugRendererInfo)
} // namespace mozilla

Просмотреть файл

@ -3,14 +3,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionDebugShaders::WebGLExtensionDebugShaders(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionDebugShaders::WebGLExtensionDebugShaders(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -18,24 +19,25 @@ WebGLExtensionDebugShaders::~WebGLExtensionDebugShaders()
{
}
/* If no source has been defined, compileShader() has not been called,
* or the translation has failed for shader, an empty string is
* returned; otherwise, return the translated source.
*/
// If no source has been defined, compileShader() has not been called, or the
// translation has failed for shader, an empty string is returned; otherwise,
// return the translated source.
void
WebGLExtensionDebugShaders::GetTranslatedShaderSource(WebGLShader* shader,
nsAString& retval)
{
retval.SetIsVoid(true);
if (mIsLost) {
return mContext->ErrorInvalidOperation("getTranslatedShaderSource: "
"Extension is lost.");
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"getTranslatedShaderSource");
return;
}
retval.SetIsVoid(false);
mContext->GetShaderTranslatedSource(shader, retval);
if (retval.IsVoid()) {
CopyASCIItoUTF16("", retval);
}
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDebugShaders)
} // namespace mozilla

Просмотреть файл

@ -3,14 +3,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionDepthTexture::WebGLExtensionDepthTexture(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionDepthTexture::WebGLExtensionDepthTexture(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -19,3 +20,5 @@ WebGLExtensionDepthTexture::~WebGLExtensionDepthTexture()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDepthTexture)
} // namespace mozilla

Просмотреть файл

@ -3,28 +3,28 @@
* 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"
#include "WebGLTexture.h"
#include "WebGLRenderbuffer.h"
#include "WebGLFramebuffer.h"
#include "GLContext.h"
#include <algorithm>
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
#include "WebGLFramebuffer.h"
#include "WebGLRenderbuffer.h"
#include "WebGLTexture.h"
using namespace mozilla;
using namespace gl;
namespace mozilla {
WebGLExtensionDrawBuffers::WebGLExtensionDrawBuffers(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionDrawBuffers::WebGLExtensionDrawBuffers(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
GLint maxColorAttachments = 0;
GLint maxDrawBuffers = 0;
gl::GLContext* gl = context->GL();
context->MakeContextCurrent();
webgl->MakeContextCurrent();
gl::GLContext* gl = webgl->GL();
gl->fGetIntegerv(LOCAL_GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
gl->fGetIntegerv(LOCAL_GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
@ -32,56 +32,57 @@ WebGLExtensionDrawBuffers::WebGLExtensionDrawBuffers(WebGLContext* context)
// WEBGL_draw_buffers specifications don't give a maximal value reachable by MAX_COLOR_ATTACHMENTS.
maxColorAttachments = std::min(maxColorAttachments, GLint(WebGLContext::kMaxColorAttachments));
if (context->MinCapabilityMode())
{
maxColorAttachments = std::min(maxColorAttachments, GLint(sMinColorAttachments));
}
if (webgl->MinCapabilityMode())
maxColorAttachments = std::min(maxColorAttachments, GLint(kMinColorAttachments));
// WEBGL_draw_buffers specifications request MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
maxDrawBuffers = std::min(maxDrawBuffers, GLint(maxColorAttachments));
context->mGLMaxColorAttachments = maxColorAttachments;
context->mGLMaxDrawBuffers = maxDrawBuffers;
webgl->mGLMaxColorAttachments = maxColorAttachments;
webgl->mGLMaxDrawBuffers = maxDrawBuffers;
}
WebGLExtensionDrawBuffers::~WebGLExtensionDrawBuffers()
{
}
void WebGLExtensionDrawBuffers::DrawBuffersWEBGL(const dom::Sequence<GLenum>& buffers)
void
WebGLExtensionDrawBuffers::DrawBuffersWEBGL(const dom::Sequence<GLenum>& buffers)
{
if (mIsLost)
return mContext->ErrorInvalidOperation("drawBuffersWEBGL: Extension is lost.");
if (mIsLost) {
mContext->ErrorInvalidOperation("drawBuffersWEBGL: Extension is lost.");
return;
}
mContext->DrawBuffers(buffers);
}
bool WebGLExtensionDrawBuffers::IsSupported(const WebGLContext* context)
bool
WebGLExtensionDrawBuffers::IsSupported(const WebGLContext* webgl)
{
gl::GLContext * gl = context->GL();
gl::GLContext* gl = webgl->GL();
if (!gl->IsSupported(GLFeature::draw_buffers)) {
if (!gl->IsSupported(gl::GLFeature::draw_buffers))
return false;
}
GLint supportedColorAttachments = 0;
GLint supportedDrawBuffers = 0;
context->MakeContextCurrent();
webgl->MakeContextCurrent();
gl->fGetIntegerv(LOCAL_GL_MAX_COLOR_ATTACHMENTS, &supportedColorAttachments);
gl->fGetIntegerv(LOCAL_GL_MAX_COLOR_ATTACHMENTS, &supportedDrawBuffers);
if (size_t(supportedColorAttachments) < sMinColorAttachments){
// WEBGL_draw_buffers specifications request for 4 color attachments at least.
// WEBGL_draw_buffers requires at least 4 color attachments.
if (size_t(supportedColorAttachments) < kMinColorAttachments)
return false;
}
if (size_t(supportedDrawBuffers) < sMinDrawBuffers){
if (size_t(supportedDrawBuffers) < kMinDrawBuffers)
return false;
}
return true;
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDrawBuffers)
} // namespace mozilla

Просмотреть файл

@ -3,14 +3,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionElementIndexUint::WebGLExtensionElementIndexUint(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionElementIndexUint::WebGLExtensionElementIndexUint(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -19,3 +20,5 @@ WebGLExtensionElementIndexUint::~WebGLExtensionElementIndexUint()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionElementIndexUint)
} // namespace mozilla

Просмотреть файл

@ -3,18 +3,18 @@
* 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"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionFragDepth::WebGLExtensionFragDepth(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionFragDepth::WebGLExtensionFragDepth(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
MOZ_ASSERT(IsSupported(context),
"Should not construct extension object if unsupported.");
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
}
WebGLExtensionFragDepth::~WebGLExtensionFragDepth()
@ -22,12 +22,13 @@ WebGLExtensionFragDepth::~WebGLExtensionFragDepth()
}
bool
WebGLExtensionFragDepth::IsSupported(const WebGLContext* context)
WebGLExtensionFragDepth::IsSupported(const WebGLContext* webgl)
{
gl::GLContext* gl = context->GL();
gl::GLContext* gl = webgl->GL();
return gl->IsSupported(gl::GLFeature::frag_depth);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionFragDepth)
} // namespace mozilla

Просмотреть файл

@ -3,18 +3,18 @@
* 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"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionInstancedArrays::WebGLExtensionInstancedArrays(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionInstancedArrays::WebGLExtensionInstancedArrays(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
MOZ_ASSERT(IsSupported(context), "should not construct WebGLExtensionInstancedArrays: "
"ANGLE_instanced_arrays unsupported.");
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
}
WebGLExtensionInstancedArrays::~WebGLExtensionInstancedArrays()
@ -22,42 +22,57 @@ WebGLExtensionInstancedArrays::~WebGLExtensionInstancedArrays()
}
void
WebGLExtensionInstancedArrays::DrawArraysInstancedANGLE(GLenum mode, GLint first,
GLsizei count, GLsizei primcount)
WebGLExtensionInstancedArrays::DrawArraysInstancedANGLE(GLenum mode,
GLint first,
GLsizei count,
GLsizei primcount)
{
if (mIsLost)
return mContext->GenerateWarning("drawArraysInstancedANGLE: Extension is lost.");
if (mIsLost) {
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"drawArraysInstancedANGLE");
return;
}
mContext->DrawArraysInstanced(mode, first, count, primcount);
}
void
WebGLExtensionInstancedArrays::DrawElementsInstancedANGLE(GLenum mode, GLsizei count,
GLenum type, WebGLintptr offset,
WebGLExtensionInstancedArrays::DrawElementsInstancedANGLE(GLenum mode,
GLsizei count,
GLenum type,
WebGLintptr offset,
GLsizei primcount)
{
if (mIsLost)
return mContext->GenerateWarning("drawElementsInstancedANGLE: Extension is lost.");
if (mIsLost) {
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"drawElementsInstancedANGLE");
return;
}
mContext->DrawElementsInstanced(mode, count, type, offset, primcount);
}
void
WebGLExtensionInstancedArrays::VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
WebGLExtensionInstancedArrays::VertexAttribDivisorANGLE(GLuint index,
GLuint divisor)
{
if (mIsLost)
return mContext->GenerateWarning("vertexAttribDivisorANGLE: Extension is lost.");
if (mIsLost) {
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"vertexAttribDivisorANGLE");
return;
}
mContext->VertexAttribDivisor(index, divisor);
}
bool
WebGLExtensionInstancedArrays::IsSupported(const WebGLContext* context)
WebGLExtensionInstancedArrays::IsSupported(const WebGLContext* webgl)
{
gl::GLContext* gl = context->GL();
gl::GLContext* gl = webgl->GL();
return gl->IsSupported(gl::GLFeature::draw_instanced) &&
gl->IsSupported(gl::GLFeature::instanced_arrays);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionInstancedArrays)
} // namespace mozilla

Просмотреть файл

@ -3,14 +3,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionLoseContext::WebGLExtensionLoseContext(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionLoseContext::WebGLExtensionLoseContext(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -31,3 +32,5 @@ WebGLExtensionLoseContext::RestoreContext()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionLoseContext)
} // namespace mozilla

Просмотреть файл

@ -3,22 +3,23 @@
* 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"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionSRGB::WebGLExtensionSRGB(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionSRGB::WebGLExtensionSRGB(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
MOZ_ASSERT(IsSupported(context), "should not construct WebGLExtensionSRGB: "
"sRGB is unsupported.");
gl::GLContext* gl = context->GL();
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
gl::GLContext* gl = webgl->GL();
if (!gl->IsGLES()) {
// Desktop OpenGL requires the following to be enabled to support
// sRGB operations on framebuffers
// Desktop OpenGL requires the following to be enabled in order to
// support sRGB operations on framebuffers.
gl->MakeCurrent();
gl->fEnable(LOCAL_GL_FRAMEBUFFER_SRGB_EXT);
}
@ -29,12 +30,14 @@ WebGLExtensionSRGB::~WebGLExtensionSRGB()
}
bool
WebGLExtensionSRGB::IsSupported(const WebGLContext* context)
WebGLExtensionSRGB::IsSupported(const WebGLContext* webgl)
{
gl::GLContext* gl = context->GL();
gl::GLContext* gl = webgl->GL();
return gl->IsSupported(gl::GLFeature::sRGB);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionSRGB)
} // namespace mozilla

Просмотреть файл

@ -3,14 +3,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionShaderTextureLod::WebGLExtensionShaderTextureLod(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionShaderTextureLod::WebGLExtensionShaderTextureLod(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -19,3 +20,5 @@ WebGLExtensionShaderTextureLod::~WebGLExtensionShaderTextureLod()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionShaderTextureLod)
} // namespace mozilla

Просмотреть файл

@ -3,14 +3,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionStandardDerivatives::WebGLExtensionStandardDerivatives(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionStandardDerivatives::WebGLExtensionStandardDerivatives(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -19,3 +20,5 @@ WebGLExtensionStandardDerivatives::~WebGLExtensionStandardDerivatives()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionStandardDerivatives)
} // namespace mozilla

Просмотреть файл

@ -3,14 +3,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionTextureFilterAnisotropic::WebGLExtensionTextureFilterAnisotropic(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionTextureFilterAnisotropic::WebGLExtensionTextureFilterAnisotropic(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -19,3 +20,5 @@ WebGLExtensionTextureFilterAnisotropic::~WebGLExtensionTextureFilterAnisotropic(
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureFilterAnisotropic)
} // namespace mozilla

Просмотреть файл

@ -2,14 +2,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -18,3 +19,5 @@ WebGLExtensionTextureFloat::~WebGLExtensionTextureFloat()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureFloat)
} // namespace mozilla

Просмотреть файл

@ -2,14 +2,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionTextureFloatLinear::WebGLExtensionTextureFloatLinear(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionTextureFloatLinear::WebGLExtensionTextureFloatLinear(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -18,3 +19,5 @@ WebGLExtensionTextureFloatLinear::~WebGLExtensionTextureFloatLinear()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureFloatLinear)
} // namespace mozilla

Просмотреть файл

@ -2,14 +2,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionTextureHalfFloat::WebGLExtensionTextureHalfFloat(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionTextureHalfFloat::WebGLExtensionTextureHalfFloat(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -18,3 +19,5 @@ WebGLExtensionTextureHalfFloat::~WebGLExtensionTextureHalfFloat()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureHalfFloat)
} // namespace mozilla

Просмотреть файл

@ -2,14 +2,15 @@
* 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"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionTextureHalfFloatLinear::WebGLExtensionTextureHalfFloatLinear(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionTextureHalfFloatLinear::WebGLExtensionTextureHalfFloatLinear(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
}
@ -18,3 +19,5 @@ WebGLExtensionTextureHalfFloatLinear::~WebGLExtensionTextureHalfFloatLinear()
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureHalfFloatLinear)
} // namespace mozilla

Просмотреть файл

@ -3,67 +3,73 @@
* 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 "WebGLBuffer.h"
#include "WebGLVertexArray.h"
#include "WebGLExtensions.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLBuffer.h"
#include "WebGLContext.h"
#include "WebGLVertexArray.h"
using namespace mozilla;
namespace mozilla {
WebGLExtensionVertexArray::WebGLExtensionVertexArray(WebGLContext* context)
: WebGLExtensionBase(context)
WebGLExtensionVertexArray::WebGLExtensionVertexArray(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
{
MOZ_ASSERT(IsSupported(context), "should not construct WebGLExtensionVertexArray :"
"OES_vertex_array_object unsuported.");
}
WebGLExtensionVertexArray::~WebGLExtensionVertexArray()
{
}
already_AddRefed<WebGLVertexArray> WebGLExtensionVertexArray::CreateVertexArrayOES()
already_AddRefed<WebGLVertexArray>
WebGLExtensionVertexArray::CreateVertexArrayOES()
{
if (mIsLost) {
mContext->GenerateWarning("createVertexArrayOES: Extension is lost. Returning null.");
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"createVertexArrayOES");
return nullptr;
}
return mContext->CreateVertexArray();
}
void WebGLExtensionVertexArray::DeleteVertexArrayOES(WebGLVertexArray* array)
void
WebGLExtensionVertexArray::DeleteVertexArrayOES(WebGLVertexArray* array)
{
if (mIsLost)
return mContext->GenerateWarning("deleteVertexArrayOES: Extension is lost.");
if (mIsLost) {
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"deleteVertexArrayOES");
return;
}
mContext->DeleteVertexArray(array);
}
bool WebGLExtensionVertexArray::IsVertexArrayOES(WebGLVertexArray* array)
bool
WebGLExtensionVertexArray::IsVertexArrayOES(WebGLVertexArray* array)
{
if (mIsLost) {
mContext->GenerateWarning("isVertexArrayOES: Extension is lost. Returning false.");
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"isVertexArrayOES");
return false;
}
return mContext->IsVertexArray(array);
}
void WebGLExtensionVertexArray::BindVertexArrayOES(WebGLVertexArray* array)
void
WebGLExtensionVertexArray::BindVertexArrayOES(WebGLVertexArray* array)
{
if (mIsLost)
return mContext->GenerateWarning("bindVertexArrayOES: Extension is lost.");
if (mIsLost) {
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"bindVertexArrayOES");
return;
}
mContext->BindVertexArray(array);
}
bool WebGLExtensionVertexArray::IsSupported(const WebGLContext* context)
{
// If it is not supported then it's emulated, therefore it's always 'supported'
// See - WebGLVertexArrayFake.h/cpp for the emulation
return true;
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionVertexArray)
} // namespace mozilla

Просмотреть файл

@ -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 WEBGLEXTENSIONS_H_
#define WEBGLEXTENSIONS_H_
#ifndef WEBGL_EXTENSIONS_H_
#define WEBGL_EXTENSIONS_H_
#include "jsapi.h"
#include "mozilla/Attributes.h"
@ -23,9 +23,9 @@ class WebGLExtensionBase
, public WebGLContextBoundObject
{
public:
explicit WebGLExtensionBase(WebGLContext* aValue);
explicit WebGLExtensionBase(WebGLContext* webgl);
WebGLContext *GetParentObject() const {
WebGLContext* GetParentObject() const {
return Context();
}
@ -41,11 +41,11 @@ protected:
};
#define DECL_WEBGL_EXTENSION_GOOP \
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
#define IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionType) \
JSObject* \
WebGLExtensionType::WrapObject(JSContext *cx) { \
WebGLExtensionType::WrapObject(JSContext* cx) { \
return dom::WebGLExtensionType##Binding::Wrap(cx, this); \
}
@ -273,8 +273,8 @@ public:
static bool IsSupported(const WebGLContext*);
static const size_t sMinColorAttachments = 4;
static const size_t sMinDrawBuffers = 4;
static const size_t kMinColorAttachments = 4;
static const size_t kMinDrawBuffers = 4;
/*
WEBGL_draw_buffers does not give a minal value for GL_MAX_DRAW_BUFFERS. But, we request
for GL_MAX_DRAW_BUFFERS = 4 at least to be able to use all requested color attachments.
@ -288,7 +288,7 @@ class WebGLExtensionVertexArray
: public WebGLExtensionBase
{
public:
explicit WebGLExtensionVertexArray(WebGLContext* aValue);
explicit WebGLExtensionVertexArray(WebGLContext* webgl);
virtual ~WebGLExtensionVertexArray();
already_AddRefed<WebGLVertexArray> CreateVertexArrayOES();
@ -296,8 +296,6 @@ public:
bool IsVertexArrayOES(WebGLVertexArray* array);
void BindVertexArrayOES(WebGLVertexArray* array);
static bool IsSupported(const WebGLContext* context);
DECL_WEBGL_EXTENSION_GOOP
};
@ -305,17 +303,16 @@ class WebGLExtensionInstancedArrays
: public WebGLExtensionBase
{
public:
explicit WebGLExtensionInstancedArrays(WebGLContext* aContext);
explicit WebGLExtensionInstancedArrays(WebGLContext* webgl);
virtual ~WebGLExtensionInstancedArrays();
void DrawArraysInstancedANGLE(GLenum mode, GLint first,
GLsizei count, GLsizei primcount);
void DrawElementsInstancedANGLE(GLenum mode, GLsizei count,
GLenum type, WebGLintptr offset,
void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count,
GLsizei primcount);
void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type,
WebGLintptr offset, GLsizei primcount);
void VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
static bool IsSupported(const WebGLContext* context);
static bool IsSupported(const WebGLContext* webgl);
DECL_WEBGL_EXTENSION_GOOP
};
@ -324,7 +321,7 @@ class WebGLExtensionBlendMinMax
: public WebGLExtensionBase
{
public:
explicit WebGLExtensionBlendMinMax(WebGLContext* aValue);
explicit WebGLExtensionBlendMinMax(WebGLContext* webgl);
virtual ~WebGLExtensionBlendMinMax();
static bool IsSupported(const WebGLContext*);
@ -334,4 +331,4 @@ public:
} // namespace mozilla
#endif // WEBGLEXTENSIONS_H_
#endif // WEBGL_EXTENSIONS_H_

Просмотреть файл

@ -5,20 +5,15 @@
#include "WebGLFramebuffer.h"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
#include "WebGLContextUtils.h"
#include "WebGLExtensions.h"
#include "WebGLRenderbuffer.h"
#include "WebGLRenderbuffer.h"
#include "WebGLTexture.h"
#include "WebGLTexture.h"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
using namespace mozilla;
using namespace mozilla::gl;
namespace mozilla {
JSObject*
WebGLFramebuffer::WrapObject(JSContext* cx)
@ -26,9 +21,9 @@ WebGLFramebuffer::WrapObject(JSContext* cx)
return dom::WebGLFramebufferBinding::Wrap(cx, this);
}
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context, GLuint fbo)
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl, GLuint fbo)
: WebGLBindableName<FBTarget>(fbo)
, WebGLContextBoundObject(context)
, WebGLContextBoundObject(webgl)
, mStatus(0)
, mDepthAttachment(LOCAL_GL_DEPTH_ATTACHMENT)
, mStencilAttachment(LOCAL_GL_STENCIL_ATTACHMENT)
@ -40,8 +35,8 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context, GLuint fbo)
mColorAttachments[0].mAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0;
}
WebGLFramebuffer::Attachment::Attachment(FBAttachment aAttachmentPoint)
: mAttachmentPoint(aAttachmentPoint)
WebGLFramebuffer::Attachment::Attachment(FBAttachment attachmentPoint)
: mAttachmentPoint(attachmentPoint)
, mTexImageTarget(LOCAL_GL_NONE)
, mNeedsFinalize(false)
{}
@ -76,11 +71,17 @@ WebGLFramebuffer::Attachment::HasAlpha() const
{
MOZ_ASSERT(HasImage());
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
return FormatHasAlpha(Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).EffectiveInternalFormat());
else if (Renderbuffer())
if (Texture() &&
Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
{
return FormatHasAlpha(Texture()->ImageInfoAt(mTexImageTarget,
mTexImageLevel).EffectiveInternalFormat());
}
if (Renderbuffer())
return FormatHasAlpha(Renderbuffer()->InternalFormat());
else return false;
return false;
}
GLenum
@ -93,7 +94,8 @@ WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::Attachment& att
const WebGLTexture& tex = *attachment.Texture();
MOZ_ASSERT(tex.HasImageInfoAt(attachment.ImageTarget(), 0));
const WebGLTexture::ImageInfo& imgInfo = tex.ImageInfoAt(attachment.ImageTarget(), 0);
const WebGLTexture::ImageInfo& imgInfo = tex.ImageInfoAt(attachment.ImageTarget(),
0);
return imgInfo.EffectiveInternalFormat().get();
}
@ -108,13 +110,13 @@ WebGLFramebuffer::Attachment::EffectiveInternalFormat() const
{
const WebGLTexture* tex = Texture();
if (tex && tex->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
return tex->ImageInfoAt(mTexImageTarget, mTexImageLevel).EffectiveInternalFormat();
return tex->ImageInfoAt(mTexImageTarget,
mTexImageLevel).EffectiveInternalFormat();
}
const WebGLRenderbuffer* rb = Renderbuffer();
if (rb) {
if (rb)
return rb->InternalFormat();
}
return LOCAL_GL_NONE;
}
@ -130,7 +132,8 @@ WebGLFramebuffer::Attachment::IsReadableFloat() const
}
void
WebGLFramebuffer::Attachment::SetTexImage(WebGLTexture* tex, TexImageTarget target, GLint level)
WebGLFramebuffer::Attachment::SetTexImage(WebGLTexture* tex,
TexImageTarget target, GLint level)
{
mTexturePtr = tex;
mRenderbufferPtr = nullptr;
@ -155,13 +158,13 @@ WebGLFramebuffer::Attachment::HasUninitializedImageData() const
if (!HasImage())
return false;
if (Renderbuffer()) {
if (Renderbuffer())
return Renderbuffer()->HasUninitializedImageData();
}
if (Texture()) {
MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
return Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).HasUninitializedImageData();
return Texture()->ImageInfoAt(mTexImageTarget,
mTexImageLevel).HasUninitializedImageData();
}
MOZ_ASSERT(false, "Should not get here.");
@ -180,7 +183,8 @@ WebGLFramebuffer::Attachment::SetImageDataStatus(WebGLImageDataStatus newStatus)
}
if (Texture()) {
Texture()->SetImageDataStatus(mTexImageTarget, mTexImageLevel, newStatus);
Texture()->SetImageDataStatus(mTexImageTarget, mTexImageLevel,
newStatus);
return;
}
@ -202,30 +206,29 @@ WebGLFramebuffer::Attachment::HasImage() const
const WebGLRectangleObject&
WebGLFramebuffer::Attachment::RectangleObject() const
{
MOZ_ASSERT(HasImage(), "Make sure it has an image before requesting the rectangle.");
MOZ_ASSERT(HasImage(),
"Make sure it has an image before requesting the rectangle.");
if (Texture()) {
MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
return Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);
}
if (Renderbuffer()) {
if (Renderbuffer())
return *Renderbuffer();
}
MOZ_CRASH("Should not get here.");
}
/* The following IsValidFBOTextureXXX functions check the internal
format that is used by GL or GL ES texture formats. This
corresponds to the state that is stored in
WebGLTexture::ImageInfo::InternalFormat()*/
// The following IsValidFBOTextureXXX functions check the internal format that
// is used by GL or GL ES texture formats. This corresponds to the state that
// is stored in WebGLTexture::ImageInfo::InternalFormat()
static inline bool
IsValidFBOTextureColorFormat(TexInternalFormat internalformat)
{
/* These formats are internal formats for each texture -- the actual
* low level format, which we might have to do conversions for when
* running against desktop GL (e.g. GL_RGBA + GL_FLOAT -> GL_RGBA32F).
/* These formats are internal formats for each texture -- the actual low
* level format, which we might have to do conversions for when running
* against desktop GL (e.g. GL_RGBA + GL_FLOAT -> GL_RGBA32F).
*
* This function just handles all of them whether desktop GL or ES.
*/
@ -252,17 +255,16 @@ IsValidFBOTextureDepthStencilFormat(GLenum internalformat)
return IsGLDepthStencilFormat(internalformat);
}
/* The following IsValidFBORenderbufferXXX functions check the internal
format that is stored by WebGLRenderbuffer::InternalFormat(). Valid
values can be found in WebGLContext::RenderbufferStorage. */
// The following IsValidFBORenderbufferXXX functions check the internal format
// that is stored by WebGLRenderbuffer::InternalFormat(). Valid values can be
// found in WebGLContext::RenderbufferStorage.
static inline bool
IsValidFBORenderbufferColorFormat(GLenum internalFormat)
{
return (
internalFormat == LOCAL_GL_RGB565 ||
return internalFormat == LOCAL_GL_RGB565 ||
internalFormat == LOCAL_GL_RGB5_A1 ||
internalFormat == LOCAL_GL_RGBA4 ||
internalFormat == LOCAL_GL_SRGB8_ALPHA8_EXT);
internalFormat == LOCAL_GL_SRGB8_ALPHA8_EXT;
}
static inline bool
@ -336,13 +338,14 @@ WebGLFramebuffer::Attachment::IsComplete() const
if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT)
return IsValidFBOTextureDepthFormat(sizedFormat);
if (mAttachmentPoint == LOCAL_GL_STENCIL_ATTACHMENT)
return false; // Textures can't have the correct format for stencil buffers
if (mAttachmentPoint == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
return IsValidFBOTextureDepthStencilFormat(sizedFormat);
if (mAttachmentPoint == LOCAL_GL_STENCIL_ATTACHMENT) {
// Textures can't have the correct format for stencil buffers.
return false;
}
if (mAttachmentPoint == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
return IsValidFBOTextureDepthStencilFormat(sizedFormat);
if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
mAttachmentPoint <= FBAttachment(LOCAL_GL_COLOR_ATTACHMENT0 - 1 +
WebGLContext::kMaxColorAttachments))
@ -376,13 +379,13 @@ WebGLFramebuffer::Attachment::IsComplete() const
MOZ_ASSERT(false, "Invalid WebGL attachment point?");
return false;
}
MOZ_ASSERT(false, "Should not get here.");
return false;
}
void
WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, FBAttachment attachmentLoc) const
WebGLFramebuffer::Attachment::FinalizeAttachment(gl::GLContext* gl,
FBAttachment attachmentLoc) const
{
if (!mNeedsFinalize)
return;
@ -391,12 +394,15 @@ WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, FBAttachment att
if (!HasImage()) {
if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_DEPTH_ATTACHMENT,
LOCAL_GL_RENDERBUFFER, 0);
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_STENCIL_ATTACHMENT,
LOCAL_GL_RENDERBUFFER, 0);
} else {
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachmentLoc.get(),
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
attachmentLoc.get(),
LOCAL_GL_RENDERBUFFER, 0);
}
@ -412,10 +418,12 @@ WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, FBAttachment att
const GLuint glName = Texture()->GLName();
if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
imageTarget, glName, mipLevel);
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
imageTarget, glName, mipLevel);
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_DEPTH_ATTACHMENT, imageTarget,
glName, mipLevel);
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_STENCIL_ATTACHMENT, imageTarget,
glName, mipLevel);
} else {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc.get(),
imageTarget, glName, mipLevel);
@ -451,15 +459,16 @@ WebGLFramebuffer::DetachAttachment(WebGLFramebuffer::Attachment& attachment)
if (attachment.Texture())
attachment.Texture()->DetachFrom(this, attachment.mAttachmentPoint);
if (attachment.Renderbuffer())
attachment.Renderbuffer()->DetachFrom(this, attachment.mAttachmentPoint);
if (attachment.Renderbuffer()) {
attachment.Renderbuffer()->DetachFrom(this,
attachment.mAttachmentPoint);
}
}
void
WebGLFramebuffer::DetachAllAttachments()
{
size_t count = mColorAttachments.Length();
for (size_t i = 0; i < count; i++) {
for (size_t i = 0; i < mColorAttachments.Length(); i++) {
DetachAttachment(mColorAttachments[i]);
}
@ -469,130 +478,156 @@ WebGLFramebuffer::DetachAllAttachments()
}
void
WebGLFramebuffer::FramebufferRenderbuffer(FBAttachment attachment,
WebGLFramebuffer::FramebufferRenderbuffer(FBAttachment attachPoint,
RBTarget rbtarget,
WebGLRenderbuffer* wrb)
WebGLRenderbuffer* rb)
{
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
if (!mContext->ValidateObjectAllowNull("framebufferRenderbuffer: renderbuffer", wrb))
if (!mContext->ValidateObjectAllowNull("framebufferRenderbuffer: renderbuffer",
rb))
{
return;
}
/* Get the requested attachment. If result is NULL, attachment is
* invalid and an error is generated.
/* Get the requested attachment. If result is NULL, attachment is invalid
* and an error is generated.
*
* Don't use GetAttachment(...) here because it opt builds it
* returns mColorAttachment[0] for invalid attachment, which we
* really don't want to mess with.
* Don't use GetAttachment(...) here because it opt builds it returns
* mColorAttachment[0] for invalid attachment, which we really don't want to
* mess with.
*/
Attachment* a = GetAttachmentOrNull(attachment);
if (!a)
Attachment* attachment = GetAttachmentOrNull(attachPoint);
if (!attachment)
return; // Error generated internally to GetAttachmentOrNull.
/* Invalidate cached framebuffer status and inform texture of it's
* new attachment
*/
// Invalidate cached framebuffer status and inform texture of its new
// attachment.
mStatus = 0;
// Detach current
if (a->Texture())
a->Texture()->DetachFrom(this, attachment);
else if (a->Renderbuffer())
a->Renderbuffer()->DetachFrom(this, attachment);
// Attach new
if (wrb)
wrb->AttachTo(this, attachment);
// Detach current:
if (attachment->Texture())
attachment->Texture()->DetachFrom(this, attachPoint);
else if (attachment->Renderbuffer())
attachment->Renderbuffer()->DetachFrom(this, attachPoint);
a->SetRenderbuffer(wrb);
// Attach new:
if (rb)
rb->AttachTo(this, attachPoint);
attachment->SetRenderbuffer(rb);
}
void
WebGLFramebuffer::FramebufferTexture2D(FBAttachment attachment,
WebGLFramebuffer::FramebufferTexture2D(FBAttachment attachPoint,
TexImageTarget texImageTarget,
WebGLTexture* wtex,
GLint level)
WebGLTexture* tex, GLint level)
{
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
if (!mContext->ValidateObjectAllowNull("framebufferTexture2D: texture", wtex))
if (!mContext->ValidateObjectAllowNull("framebufferTexture2D: texture",
tex))
{
return;
}
if (wtex) {
bool isTexture2D = wtex->Target() == LOCAL_GL_TEXTURE_2D;
if (tex) {
bool isTexture2D = tex->Target() == LOCAL_GL_TEXTURE_2D;
bool isTexTarget2D = texImageTarget == LOCAL_GL_TEXTURE_2D;
if (isTexture2D != isTexTarget2D) {
return mContext->ErrorInvalidOperation("framebufferTexture2D: mismatched texture and texture target");
mContext->ErrorInvalidOperation("framebufferTexture2D: Mismatched"
" texture and texture target.");
return;
}
}
if (level != 0)
return mContext->ErrorInvalidValue("framebufferTexture2D: level must be 0");
if (level != 0) {
mContext->ErrorInvalidValue("framebufferTexture2D: Level must be 0.");
return;
}
/* Get the requested attachment. If result is NULL, attachment is
* invalid and an error is generated.
/* Get the requested attachment. If result is NULL, attachment is invalid
* and an error is generated.
*
* Don't use GetAttachment(...) here because it opt builds it
* returns mColorAttachment[0] for invalid attachment, which we
* really don't want to mess with.
* Don't use GetAttachment(...) here because it opt builds it returns
* mColorAttachment[0] for invalid attachment, which we really don't want to
* mess with.
*/
Attachment* a = GetAttachmentOrNull(attachment);
if (!a)
Attachment* attachment = GetAttachmentOrNull(attachPoint);
if (!attachment)
return; // Error generated internally to GetAttachmentOrNull.
/* Invalidate cached framebuffer status and inform texture of it's
* new attachment
*/
// Invalidate cached framebuffer status and inform texture of its new
// attachment.
mStatus = 0;
// Detach current
if (a->Texture())
a->Texture()->DetachFrom(this, attachment);
else if (a->Renderbuffer())
a->Renderbuffer()->DetachFrom(this, attachment);
// Attach new
if (wtex)
wtex->AttachTo(this, attachment);
// Detach current:
if (attachment->Texture())
attachment->Texture()->DetachFrom(this, attachPoint);
else if (attachment->Renderbuffer())
attachment->Renderbuffer()->DetachFrom(this, attachPoint);
a->SetTexImage(wtex, texImageTarget, level);
// Attach new:
if (tex)
tex->AttachTo(this, attachPoint);
attachment->SetTexImage(tex, texImageTarget, level);
}
WebGLFramebuffer::Attachment*
WebGLFramebuffer::GetAttachmentOrNull(FBAttachment attachment)
WebGLFramebuffer::GetAttachmentOrNull(FBAttachment attachPoint)
{
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
switch (attachPoint.get()) {
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
return &mDepthStencilAttachment;
if (attachment == LOCAL_GL_DEPTH_ATTACHMENT)
case LOCAL_GL_DEPTH_ATTACHMENT:
return &mDepthAttachment;
if (attachment == LOCAL_GL_STENCIL_ATTACHMENT)
case LOCAL_GL_STENCIL_ATTACHMENT:
return &mStencilAttachment;
if (!mContext->ValidateFramebufferAttachment(attachment.get(), "getAttachmentOrNull"))
return nullptr;
default:
break;
}
size_t colorAttachmentId = attachment.get() - LOCAL_GL_COLOR_ATTACHMENT0;
if (!mContext->ValidateFramebufferAttachment(attachPoint.get(),
"getAttachmentOrNull"))
{
return nullptr;
}
size_t colorAttachmentId = attachPoint.get() - LOCAL_GL_COLOR_ATTACHMENT0;
EnsureColorAttachments(colorAttachmentId);
return &mColorAttachments[colorAttachmentId];
}
const WebGLFramebuffer::Attachment&
WebGLFramebuffer::GetAttachment(FBAttachment attachment) const
WebGLFramebuffer::GetAttachment(FBAttachment attachPoint) const
{
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
switch (attachPoint.get()) {
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
return mDepthStencilAttachment;
if (attachment == LOCAL_GL_DEPTH_ATTACHMENT)
case LOCAL_GL_DEPTH_ATTACHMENT:
return mDepthAttachment;
if (attachment == LOCAL_GL_STENCIL_ATTACHMENT)
case LOCAL_GL_STENCIL_ATTACHMENT:
return mStencilAttachment;
if (!mContext->ValidateFramebufferAttachment(attachment.get(), "getAttachment")) {
default:
break;
}
if (!mContext->ValidateFramebufferAttachment(attachPoint.get(),
"getAttachment"))
{
MOZ_ASSERT(false);
return mColorAttachments[0];
}
size_t colorAttachmentId = attachment.get() - LOCAL_GL_COLOR_ATTACHMENT0;
size_t colorAttachmentId = attachPoint.get() - LOCAL_GL_COLOR_ATTACHMENT0;
if (colorAttachmentId >= mColorAttachments.Length()) {
MOZ_ASSERT(false);
return mColorAttachments[0];
@ -604,39 +639,51 @@ WebGLFramebuffer::GetAttachment(FBAttachment attachment) const
void
WebGLFramebuffer::DetachTexture(const WebGLTexture* tex)
{
size_t count = mColorAttachments.Length();
for (size_t i = 0; i < count; i++) {
for (size_t i = 0; i < (size_t)mColorAttachments.Length(); i++) {
if (mColorAttachments[i].Texture() == tex) {
FramebufferTexture2D(LOCAL_GL_COLOR_ATTACHMENT0+i, LOCAL_GL_TEXTURE_2D, nullptr, 0);
// a texture might be attached more that once while editing the framebuffer
FramebufferTexture2D(LOCAL_GL_COLOR_ATTACHMENT0+i,
LOCAL_GL_TEXTURE_2D, nullptr, 0);
// It might be attached in multiple places, so don't break.
}
}
if (mDepthAttachment.Texture() == tex)
FramebufferTexture2D(LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
if (mStencilAttachment.Texture() == tex)
FramebufferTexture2D(LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
if (mDepthStencilAttachment.Texture() == tex)
FramebufferTexture2D(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
if (mDepthAttachment.Texture() == tex) {
FramebufferTexture2D(LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_TEXTURE_2D,
nullptr, 0);
}
if (mStencilAttachment.Texture() == tex) {
FramebufferTexture2D(LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D,
nullptr, 0);
}
if (mDepthStencilAttachment.Texture() == tex) {
FramebufferTexture2D(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT,
LOCAL_GL_TEXTURE_2D, nullptr, 0);
}
}
void
WebGLFramebuffer::DetachRenderbuffer(const WebGLRenderbuffer* rb)
{
size_t count = mColorAttachments.Length();
for (size_t i = 0; i < count; i++) {
for (size_t i = 0; i < (size_t)mColorAttachments.Length(); i++) {
if (mColorAttachments[i].Renderbuffer() == rb) {
FramebufferRenderbuffer(LOCAL_GL_COLOR_ATTACHMENT0+i, LOCAL_GL_RENDERBUFFER, nullptr);
// a renderbuffer might be attached more that once while editing the framebuffer
FramebufferRenderbuffer(LOCAL_GL_COLOR_ATTACHMENT0+i,
LOCAL_GL_RENDERBUFFER, nullptr);
// It might be attached in multiple places, so don't break.
}
}
if (mDepthAttachment.Renderbuffer() == rb)
FramebufferRenderbuffer(LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
if (mStencilAttachment.Renderbuffer() == rb)
FramebufferRenderbuffer(LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
if (mDepthStencilAttachment.Renderbuffer() == rb)
FramebufferRenderbuffer(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
if (mDepthAttachment.Renderbuffer() == rb) {
FramebufferRenderbuffer(LOCAL_GL_DEPTH_ATTACHMENT,
LOCAL_GL_RENDERBUFFER, nullptr);
}
if (mStencilAttachment.Renderbuffer() == rb) {
FramebufferRenderbuffer(LOCAL_GL_STENCIL_ATTACHMENT,
LOCAL_GL_RENDERBUFFER, nullptr);
}
if (mDepthStencilAttachment.Renderbuffer() == rb) {
FramebufferRenderbuffer(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT,
LOCAL_GL_RENDERBUFFER, nullptr);
}
}
bool
@ -644,8 +691,7 @@ WebGLFramebuffer::HasDefinedAttachments() const
{
bool hasAttachments = false;
size_t count = mColorAttachments.Length();
for (size_t i = 0; i < count; i++) {
for (size_t i = 0; i < (size_t)mColorAttachments.Length(); i++) {
hasAttachments |= mColorAttachments[i].IsDefined();
}
@ -668,8 +714,7 @@ WebGLFramebuffer::HasIncompleteAttachments() const
{
bool hasIncomplete = false;
size_t count = mColorAttachments.Length();
for (size_t i = 0; i < count; i++) {
for (size_t i = 0; i < (size_t)mColorAttachments.Length(); i++) {
hasIncomplete |= IsIncomplete(mColorAttachments[i]);
}
@ -680,14 +725,12 @@ WebGLFramebuffer::HasIncompleteAttachments() const
return hasIncomplete;
}
const WebGLRectangleObject&
WebGLFramebuffer::GetAnyRectObject() const
{
MOZ_ASSERT(HasDefinedAttachments());
size_t count = mColorAttachments.Length();
for (size_t i = 0; i < count; i++) {
for (size_t i = 0; i < (size_t)mColorAttachments.Length(); i++) {
if (mColorAttachments[i].HasImage())
return mColorAttachments[i].RectangleObject();
}
@ -704,7 +747,6 @@ WebGLFramebuffer::GetAnyRectObject() const
MOZ_CRASH("Should not get here.");
}
static bool
RectsMatch(const WebGLFramebuffer::Attachment& attachment,
const WebGLRectangleObject& rect)
@ -723,8 +765,7 @@ WebGLFramebuffer::AllImageRectsMatch() const
// Alright, we have *a* rect, let's check all the others.
bool imageRectsMatch = true;
size_t count = mColorAttachments.Length();
for (size_t i = 0; i < count; i++) {
for (size_t i = 0; i < (size_t)mColorAttachments.Length(); i++) {
if (mColorAttachments[i].HasImage())
imageRectsMatch &= RectsMatch(mColorAttachments[i], rect);
}
@ -826,7 +867,7 @@ WebGLFramebuffer::CheckAndInitializeAttachments()
return false;
// Cool! We've checked out ok. Just need to initialize.
size_t colorAttachmentCount = mColorAttachments.Length();
const size_t colorAttachmentCount = mColorAttachments.Length();
// Check if we need to initialize anything
{
@ -914,9 +955,9 @@ WebGLFramebuffer::NotifyAttachableChanged() const
}
static void
FinalizeDrawAndReadBuffers(GLContext* aGL, bool aColorBufferDefined)
FinalizeDrawAndReadBuffers(gl::GLContext* gl, bool isColorBufferDefined)
{
MOZ_ASSERT(aGL, "Expected a valid GLContext ptr.");
MOZ_ASSERT(gl, "Expected a valid GLContext ptr.");
// GLES don't support DrawBuffer()/ReadBuffer.
// According to http://www.opengl.org/wiki/Framebuffer_Object
//
@ -928,54 +969,53 @@ FinalizeDrawAndReadBuffers(GLContext* aGL, bool aColorBufferDefined)
//
// Note that this test is not performed if OpenGL 4.2 or ARB_ES2_compatibility is
// available.
if (aGL->IsGLES() ||
aGL->IsSupported(GLFeature::ES2_compatibility) ||
aGL->IsAtLeast(ContextProfile::OpenGL, 420))
if (gl->IsGLES() ||
gl->IsSupported(gl::GLFeature::ES2_compatibility) ||
gl->IsAtLeast(gl::ContextProfile::OpenGL, 420))
{
return;
}
// TODO(djg): Assert that fDrawBuffer/fReadBuffer is not NULL.
GLenum colorBufferSource = aColorBufferDefined ? LOCAL_GL_COLOR_ATTACHMENT0 : LOCAL_GL_NONE;
aGL->fDrawBuffer(colorBufferSource);
aGL->fReadBuffer(colorBufferSource);
GLenum colorBufferSource = isColorBufferDefined ? LOCAL_GL_COLOR_ATTACHMENT0
: LOCAL_GL_NONE;
gl->fDrawBuffer(colorBufferSource);
gl->fReadBuffer(colorBufferSource);
}
void
WebGLFramebuffer::FinalizeAttachments() const
{
GLContext* gl = mContext->gl;
gl::GLContext* gl = mContext->gl;
size_t count = ColorAttachmentCount();
for (size_t i = 0; i < count; i++) {
ColorAttachment(i).FinalizeAttachment(gl, LOCAL_GL_COLOR_ATTACHMENT0 + i);
for (size_t i = 0; i < ColorAttachmentCount(); i++) {
ColorAttachment(i).FinalizeAttachment(gl, LOCAL_GL_COLOR_ATTACHMENT0+i);
}
DepthAttachment().FinalizeAttachment(gl, LOCAL_GL_DEPTH_ATTACHMENT);
StencilAttachment().FinalizeAttachment(gl, LOCAL_GL_STENCIL_ATTACHMENT);
DepthStencilAttachment().FinalizeAttachment(gl, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
DepthStencilAttachment().FinalizeAttachment(gl,
LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
FinalizeDrawAndReadBuffers(gl, ColorAttachment(0).IsDefined());
}
inline void
ImplCycleCollectionUnlink(mozilla::WebGLFramebuffer::Attachment& aField)
ImplCycleCollectionUnlink(mozilla::WebGLFramebuffer::Attachment& field)
{
aField.mTexturePtr = nullptr;
aField.mRenderbufferPtr = nullptr;
field.mTexturePtr = nullptr;
field.mRenderbufferPtr = nullptr;
}
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
mozilla::WebGLFramebuffer::Attachment& aField,
const char* aName,
uint32_t aFlags = 0)
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback,
mozilla::WebGLFramebuffer::Attachment& field,
const char* name,
uint32_t flags = 0)
{
CycleCollectionNoteChild(aCallback, aField.mTexturePtr.get(),
aName, aFlags);
CycleCollectionNoteChild(aCallback, aField.mRenderbufferPtr.get(),
aName, aFlags);
CycleCollectionNoteChild(callback, field.mTexturePtr.get(), name, flags);
CycleCollectionNoteChild(callback, field.mRenderbufferPtr.get(), name,
flags);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLFramebuffer,
@ -986,3 +1026,5 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLFramebuffer,
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLFramebuffer, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLFramebuffer, Release)
} // namespace mozilla

Просмотреть файл

@ -3,22 +3,21 @@
* 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 WEBGLFRAMEBUFFER_H_
#define WEBGLFRAMEBUFFER_H_
#ifndef WEBGL_FRAMEBUFFER_H_
#define WEBGL_FRAMEBUFFER_H_
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
#include "nsWrapperCache.h"
#include "mozilla/LinkedList.h"
namespace mozilla {
class WebGLFramebufferAttachable;
class WebGLTexture;
class WebGLRenderbuffer;
class WebGLTexture;
namespace gl {
class GLContext;
}
@ -34,7 +33,7 @@ class WebGLFramebuffer MOZ_FINAL
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(WebGLFramebuffer)
explicit WebGLFramebuffer(WebGLContext* context, GLuint fbo);
explicit WebGLFramebuffer(WebGLContext* webgl, GLuint fbo);
struct Attachment
{
@ -46,7 +45,7 @@ public:
GLint mTexImageLevel;
mutable bool mNeedsFinalize;
explicit Attachment(FBAttachment aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0);
explicit Attachment(FBAttachment attachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0);
~Attachment();
bool IsDefined() const;
@ -90,18 +89,17 @@ public:
bool HasImage() const;
bool IsComplete() const;
void FinalizeAttachment(gl::GLContext* gl, FBAttachment attachmentLoc) const;
void FinalizeAttachment(gl::GLContext* gl,
FBAttachment attachmentLoc) const;
};
void Delete();
void FramebufferRenderbuffer(FBAttachment attachment,
RBTarget rbtarget,
WebGLRenderbuffer* wrb);
void FramebufferRenderbuffer(FBAttachment attachment, RBTarget rbtarget,
WebGLRenderbuffer* rb);
void FramebufferTexture2D(FBAttachment attachment,
TexImageTarget texImageTarget,
WebGLTexture* wtex,
TexImageTarget texImageTarget, WebGLTexture* tex,
GLint level);
private:
@ -116,7 +114,9 @@ public:
bool AllImageRectsMatch() const;
FBStatus PrecheckFramebufferStatus() const;
FBStatus CheckFramebufferStatus() const;
GLenum GetFormatForAttachment(const WebGLFramebuffer::Attachment& attachment) const;
GLenum
GetFormatForAttachment(const WebGLFramebuffer::Attachment& attachment) const;
bool HasDepthStencilConflict() const {
return int(mDepthAttachment.IsDefined()) +
@ -167,7 +167,8 @@ public:
bool CheckAndInitializeAttachments();
bool CheckColorAttachmentNumber(FBAttachment attachment, const char* functionName) const;
bool CheckColorAttachmentNumber(FBAttachment attachment,
const char* funcName) const;
void EnsureColorAttachments(size_t colorAttachmentId);
@ -183,11 +184,11 @@ private:
// we only store pointers to attached renderbuffers, not to attached textures, because
// we will only need to initialize renderbuffers. Textures are already initialized.
nsTArray<Attachment> mColorAttachments;
Attachment mDepthAttachment,
mStencilAttachment,
mDepthStencilAttachment;
Attachment mDepthAttachment;
Attachment mStencilAttachment;
Attachment mDepthStencilAttachment;
};
} // namespace mozilla
#endif
#endif // WEBGL_FRAMEBUFFER_H_

Просмотреть файл

@ -3,19 +3,19 @@
* 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 WEBGLMEMORYTRACKER_H_
#define WEBGLMEMORYTRACKER_H_
#ifndef WEBGL_MEMORY_TRACKER_H_
#define WEBGL_MEMORY_TRACKER_H_
#include "WebGLContext.h"
#include "WebGLBuffer.h"
#include "WebGLVertexAttribData.h"
#include "WebGLShader.h"
#include "WebGLProgram.h"
#include "WebGLUniformLocation.h"
#include "WebGLTexture.h"
#include "WebGLRenderbuffer.h"
#include "mozilla/StaticPtr.h"
#include "nsIMemoryReporter.h"
#include "WebGLBuffer.h"
#include "WebGLContext.h"
#include "WebGLVertexAttribData.h"
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
#include "WebGLShader.h"
#include "WebGLTexture.h"
#include "WebGLUniformLocation.h"
namespace mozilla {
@ -37,7 +37,7 @@ class WebGLMemoryTracker : public nsIMemoryReporter
static WebGLMemoryTracker* UniqueInstance();
static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; }
static ContextsArrayType& Contexts() { return UniqueInstance()->mContexts; }
friend class WebGLContext;
@ -62,7 +62,7 @@ class WebGLMemoryTracker : public nsIMemoryReporter
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLTexture *texture = contexts[i]->mTextures.getFirst();
for (const WebGLTexture* texture = contexts[i]->mTextures.getFirst();
texture;
texture = texture->getNext())
{
@ -76,7 +76,7 @@ class WebGLMemoryTracker : public nsIMemoryReporter
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLTexture *texture = contexts[i]->mTextures.getFirst();
for (const WebGLTexture* texture = contexts[i]->mTextures.getFirst();
texture;
texture = texture->getNext())
{
@ -90,7 +90,7 @@ class WebGLMemoryTracker : public nsIMemoryReporter
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLBuffer *buffer = contexts[i]->mBuffers.getFirst();
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
buffer;
buffer = buffer->getNext())
{
@ -106,7 +106,7 @@ class WebGLMemoryTracker : public nsIMemoryReporter
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLBuffer *buffer = contexts[i]->mBuffers.getFirst();
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
buffer;
buffer = buffer->getNext())
{
@ -120,7 +120,7 @@ class WebGLMemoryTracker : public nsIMemoryReporter
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLRenderbuffer *rb = contexts[i]->mRenderbuffers.getFirst();
for (const WebGLRenderbuffer* rb = contexts[i]->mRenderbuffers.getFirst();
rb;
rb = rb->getNext())
{
@ -134,7 +134,7 @@ class WebGLMemoryTracker : public nsIMemoryReporter
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLRenderbuffer *rb = contexts[i]->mRenderbuffers.getFirst();
for (const WebGLRenderbuffer* rb = contexts[i]->mRenderbuffers.getFirst();
rb;
rb = rb->getNext())
{
@ -150,7 +150,7 @@ class WebGLMemoryTracker : public nsIMemoryReporter
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLShader *shader = contexts[i]->mShaders.getFirst();
for (const WebGLShader* shader = contexts[i]->mShaders.getFirst();
shader;
shader = shader->getNext())
{
@ -165,7 +165,6 @@ class WebGLMemoryTracker : public nsIMemoryReporter
}
};
} // namespace mozilla
#endif
#endif // WEBGL_MEMORY_TRACKER_H_

Просмотреть файл

@ -4,16 +4,22 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLObjectModel.h"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLContextBoundObject::WebGLContextBoundObject(WebGLContext *context) {
mContext = context;
mContextGeneration = context->Generation();
WebGLContextBoundObject::WebGLContextBoundObject(WebGLContext* webgl)
: mContext(webgl)
, mContextGeneration(webgl->Generation())
{
}
bool
WebGLContextBoundObject::IsCompatibleWithContext(WebGLContext *other) {
return mContext == other &&
mContextGeneration == other->Generation();
WebGLContextBoundObject::IsCompatibleWithContext(WebGLContext* other)
{
return (mContext == other &&
mContextGeneration == other->Generation());
}
} // namespace mozilla

Просмотреть файл

@ -60,36 +60,37 @@ class WebGLContext;
***** 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.
* 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 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.
* 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's
* 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)".
* 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
@ -99,11 +100,14 @@ public:
WebGLRefCountedObject()
: mDeletionStatus(Default)
{ }
{}
~WebGLRefCountedObject() {
MOZ_ASSERT(mWebGLRefCnt == 0, "destroying WebGL object still referenced by other WebGL objects");
MOZ_ASSERT(mDeletionStatus == Deleted, "Derived class destructor must call DeleteOnce()");
MOZ_ASSERT(mWebGLRefCnt == 0,
"Destroying WebGL object still referenced by other WebGL"
" objects.");
MOZ_ASSERT(mDeletionStatus == Deleted,
"Derived class destructor must call DeleteOnce().");
}
// called by WebGLRefPtr
@ -113,7 +117,8 @@ public:
// called by WebGLRefPtr
void WebGLRelease() {
MOZ_ASSERT(mWebGLRefCnt > 0, "releasing WebGL object with WebGL refcnt already zero");
MOZ_ASSERT(mWebGLRefCnt > 0,
"Releasing WebGL object with WebGL refcnt already zero");
--mWebGLRefCnt;
MaybeDelete();
}
@ -154,12 +159,12 @@ protected:
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.
/* 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
* 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.
*
@ -174,16 +179,16 @@ class WebGLRefPtr
public:
WebGLRefPtr()
: mRawPtr(0)
{ }
{}
WebGLRefPtr(const WebGLRefPtr<T>& aSmartPtr)
: mRawPtr(aSmartPtr.mRawPtr)
WebGLRefPtr(const WebGLRefPtr<T>& smartPtr)
: mRawPtr(smartPtr.mRawPtr)
{
AddRefOnPtr(mRawPtr);
}
explicit WebGLRefPtr(T* aRawPtr)
: mRawPtr(aRawPtr)
explicit WebGLRefPtr(T* rawPtr)
: mRawPtr(rawPtr)
{
AddRefOnPtr(mRawPtr);
}
@ -252,7 +257,7 @@ private:
}
protected:
T *mRawPtr;
T* mRawPtr;
};
// This class is a mixin for objects that are tied to a specific
@ -261,15 +266,15 @@ protected:
class WebGLContextBoundObject
{
public:
explicit WebGLContextBoundObject(WebGLContext* context);
explicit WebGLContextBoundObject(WebGLContext* webgl);
bool IsCompatibleWithContext(WebGLContext *other);
bool IsCompatibleWithContext(WebGLContext* other);
WebGLContext *Context() const { return mContext; }
WebGLContext* Context() const { return mContext; }
protected:
WebGLContext *mContext;
uint32_t mContextGeneration;
WebGLContext* const mContext;
const uint32_t mContextGeneration;
};
// this class is a mixin for GL objects that have dimensions
@ -278,10 +283,14 @@ class WebGLRectangleObject
{
public:
WebGLRectangleObject()
: mWidth(0), mHeight(0) { }
: mWidth(0)
, mHeight(0)
{}
WebGLRectangleObject(GLsizei width, GLsizei height)
: mWidth(width), mHeight(height) { }
: mWidth(width)
, mHeight(height)
{}
GLsizei Width() const { return mWidth; }
void width(GLsizei value) { mWidth = value; }
@ -294,7 +303,7 @@ public:
mHeight = height;
}
void setDimensions(WebGLRectangleObject *rect) {
void setDimensions(WebGLRectangleObject* rect) {
if (rect) {
mWidth = rect->Width();
mHeight = rect->Height();
@ -317,19 +326,19 @@ protected:
template <typename T>
inline void
ImplCycleCollectionUnlink(mozilla::WebGLRefPtr<T>& aField)
ImplCycleCollectionUnlink(mozilla::WebGLRefPtr<T>& field)
{
aField = nullptr;
field = nullptr;
}
template <typename T>
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
mozilla::WebGLRefPtr<T>& aField,
const char* aName,
uint32_t aFlags = 0)
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback,
mozilla::WebGLRefPtr<T>& field,
const char* name,
uint32_t flags = 0)
{
CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags);
CycleCollectionNoteChild(callback, field.get(), name, flags);
}
#endif

Просмотреть файл

@ -3,32 +3,38 @@
* 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 "WebGLProgram.h"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "MurmurHash3.h"
#include "WebGLContext.h"
#include "WebGLShader.h"
#include "WebGLProgram.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "GLContext.h"
#include "MurmurHash3.h"
namespace mozilla {
using namespace mozilla;
/** Takes an ASCII string like "foo[i]", turns it into "foo" and returns "[i]" in bracketPart
/** Takes an ASCII string like "foo[i]", turns it into "foo" and returns "[i]"
* in bracketPart.
*
* \param string input/output: the string to split, becomes the string without the bracket part
* \param bracketPart output: gets the bracket part.
* \param string input/output: The string to split, becomes the string without
* the bracket part.
* \param bracketPart output: Gets the bracket part.
*
* Notice that if there are multiple brackets like "foo[i].bar[j]", only the last bracket is split.
* Notice that if there are multiple brackets like "foo[i].bar[j]", only the
* last bracket is split.
*/
static bool SplitLastSquareBracket(nsACString& string, nsCString& bracketPart)
static bool
SplitLastSquareBracket(nsACString& string, nsCString& bracketPart)
{
MOZ_ASSERT(bracketPart.IsEmpty(), "SplitLastSquareBracket must be called with empty bracketPart string");
MOZ_ASSERT(bracketPart.IsEmpty(),
"SplitLastSquareBracket must be called with empty bracketPart"
" string.");
if (string.IsEmpty())
return false;
char *string_start = string.BeginWriting();
char *s = string_start + string.Length() - 1;
char* string_start = string.BeginWriting();
char* s = string_start + string.Length() - 1;
if (*s != ']')
return false;
@ -47,12 +53,12 @@ static bool SplitLastSquareBracket(nsACString& string, nsCString& bracketPart)
}
JSObject*
WebGLProgram::WrapObject(JSContext *cx) {
WebGLProgram::WrapObject(JSContext* cx) {
return dom::WebGLProgramBinding::Wrap(cx, this);
}
WebGLProgram::WebGLProgram(WebGLContext *context)
: WebGLContextBoundObject(context)
WebGLProgram::WebGLProgram(WebGLContext* webgl)
: WebGLContextBoundObject(webgl)
, mLinkStatus(false)
, mGeneration(0)
, mIdentifierMap(new CStringMap)
@ -66,7 +72,8 @@ WebGLProgram::WebGLProgram(WebGLContext *context)
}
void
WebGLProgram::Delete() {
WebGLProgram::Delete()
{
DetachShaders();
mContext->MakeContextCurrent();
mContext->gl->fDeleteProgram(mGLName);
@ -74,9 +81,11 @@ WebGLProgram::Delete() {
}
bool
WebGLProgram::AttachShader(WebGLShader *shader) {
WebGLProgram::AttachShader(WebGLShader* shader)
{
if (ContainsShader(shader))
return false;
mAttachedShaders.AppendElement(shader);
mContext->MakeContextCurrent();
@ -86,7 +95,8 @@ WebGLProgram::AttachShader(WebGLShader *shader) {
}
bool
WebGLProgram::DetachShader(WebGLShader *shader) {
WebGLProgram::DetachShader(WebGLShader* shader)
{
if (!mAttachedShaders.RemoveElement(shader))
return false;
@ -97,32 +107,37 @@ WebGLProgram::DetachShader(WebGLShader *shader) {
}
bool
WebGLProgram::HasAttachedShaderOfType(GLenum shaderType) {
WebGLProgram::HasAttachedShaderOfType(GLenum shaderType)
{
for (uint32_t i = 0; i < mAttachedShaders.Length(); ++i) {
if (mAttachedShaders[i] && mAttachedShaders[i]->ShaderType() == shaderType) {
if (mAttachedShaders[i] && mAttachedShaders[i]->ShaderType() == shaderType)
return true;
}
}
return false;
}
bool
WebGLProgram::HasBadShaderAttached() {
WebGLProgram::HasBadShaderAttached()
{
for (uint32_t i = 0; i < mAttachedShaders.Length(); ++i) {
if (mAttachedShaders[i] && !mAttachedShaders[i]->CompileStatus()) {
if (mAttachedShaders[i] && !mAttachedShaders[i]->CompileStatus())
return true;
}
}
return false;
}
size_t
WebGLProgram::UpperBoundNumSamplerUniforms() {
WebGLProgram::UpperBoundNumSamplerUniforms()
{
size_t numSamplerUniforms = 0;
for (size_t i = 0; i < mAttachedShaders.Length(); ++i) {
const WebGLShader *shader = mAttachedShaders[i];
const WebGLShader* shader = mAttachedShaders[i];
if (!shader)
continue;
for (size_t j = 0; j < shader->mUniformInfos.Length(); ++j) {
WebGLUniformInfo u = shader->mUniformInfos[j];
if (u.type == LOCAL_GL_SAMPLER_2D ||
@ -132,11 +147,14 @@ WebGLProgram::UpperBoundNumSamplerUniforms() {
}
}
}
return numSamplerUniforms;
}
void
WebGLProgram::MapIdentifier(const nsACString& name, nsCString *mappedName) {
WebGLProgram::MapIdentifier(const nsACString& name,
nsCString* const out_mappedName)
{
MOZ_ASSERT(mIdentifierMap);
nsCString mutableName(name);
@ -145,30 +163,36 @@ WebGLProgram::MapIdentifier(const nsACString& name, nsCString *mappedName) {
if (hadBracketPart)
mutableName.AppendLiteral("[0]");
if (mIdentifierMap->Get(mutableName, mappedName)) {
if (mIdentifierMap->Get(mutableName, out_mappedName)) {
if (hadBracketPart) {
nsCString mappedBracketPart;
bool mappedHadBracketPart = SplitLastSquareBracket(*mappedName, mappedBracketPart);
bool mappedHadBracketPart = SplitLastSquareBracket(*out_mappedName,
mappedBracketPart);
if (mappedHadBracketPart)
mappedName->Append(bracketPart);
out_mappedName->Append(bracketPart);
}
return;
}
// not found? We might be in the situation we have a uniform array name and the GL's glGetActiveUniform
// returned its name without [0], as is allowed by desktop GL but not in ES. Let's then try with [0].
// Not found? We might be in the situation we have a uniform array name and
// the GL's glGetActiveUniform returned its name without [0], as is allowed
// by desktop GL but not in ES. Let's then try with [0].
mutableName.AppendLiteral("[0]");
if (mIdentifierMap->Get(mutableName, mappedName))
if (mIdentifierMap->Get(mutableName, out_mappedName))
return;
// not found? return name unchanged. This case happens e.g. on bad user input, or when
// we're not using identifier mapping, or if we didn't store an identifier in the map because
// e.g. its mapping is trivial (as happens for short identifiers)
mappedName->Assign(name);
/* Not found? Return name unchanged. This case happens e.g. on bad user
* input, or when we're not using identifier mapping, or if we didn't store
* an identifier in the map because e.g. its mapping is trivial. (as happens
* for short identifiers)
*/
out_mappedName->Assign(name);
}
void
WebGLProgram::ReverseMapIdentifier(const nsACString& name, nsCString *reverseMappedName) {
WebGLProgram::ReverseMapIdentifier(const nsACString& name,
nsCString* const out_reverseMappedName)
{
MOZ_ASSERT(mIdentifierReverseMap);
nsCString mutableName(name);
@ -177,42 +201,48 @@ WebGLProgram::ReverseMapIdentifier(const nsACString& name, nsCString *reverseMap
if (hadBracketPart)
mutableName.AppendLiteral("[0]");
if (mIdentifierReverseMap->Get(mutableName, reverseMappedName)) {
if (mIdentifierReverseMap->Get(mutableName, out_reverseMappedName)) {
if (hadBracketPart) {
nsCString reverseMappedBracketPart;
bool reverseMappedHadBracketPart = SplitLastSquareBracket(*reverseMappedName, reverseMappedBracketPart);
bool reverseMappedHadBracketPart = SplitLastSquareBracket(*out_reverseMappedName,
reverseMappedBracketPart);
if (reverseMappedHadBracketPart)
reverseMappedName->Append(bracketPart);
out_reverseMappedName->Append(bracketPart);
}
return;
}
// not found? We might be in the situation we have a uniform array name and the GL's glGetActiveUniform
// returned its name without [0], as is allowed by desktop GL but not in ES. Let's then try with [0].
// Not found? We might be in the situation we have a uniform array name and
// the GL's glGetActiveUniform returned its name without [0], as is allowed
// by desktop GL but not in ES. Let's then try with [0].
mutableName.AppendLiteral("[0]");
if (mIdentifierReverseMap->Get(mutableName, reverseMappedName))
if (mIdentifierReverseMap->Get(mutableName, out_reverseMappedName))
return;
// not found? return name unchanged. This case happens e.g. on bad user input, or when
// we're not using identifier mapping, or if we didn't store an identifier in the map because
// e.g. its mapping is trivial (as happens for short identifiers)
reverseMappedName->Assign(name);
/* Not found? Return name unchanged. This case happens e.g. on bad user
* input, or when we're not using identifier mapping, or if we didn't store
* an identifier in the map because e.g. its mapping is trivial. (as happens
* for short identifiers)
*/
out_reverseMappedName->Assign(name);
}
WebGLUniformInfo
WebGLProgram::GetUniformInfoForMappedIdentifier(const nsACString& name) {
WebGLProgram::GetUniformInfoForMappedIdentifier(const nsACString& name)
{
MOZ_ASSERT(mUniformInfoMap);
nsCString mutableName(name);
nsCString bracketPart;
bool hadBracketPart = SplitLastSquareBracket(mutableName, bracketPart);
// if there is a bracket, we're either an array or an entry in an array.
// If there is a bracket, we're either an array or an entry in an array.
if (hadBracketPart)
mutableName.AppendLiteral("[0]");
WebGLUniformInfo info;
mUniformInfoMap->Get(mutableName, &info);
// we don't check if that Get failed, as if it did, it left info with default values
// We don't check if that Get failed, as if it did, it left info with
// default values.
return info;
}
@ -221,14 +251,17 @@ bool
WebGLProgram::UpdateInfo()
{
mAttribMaxNameLength = 0;
for (size_t i = 0; i < mAttachedShaders.Length(); i++)
mAttribMaxNameLength = std::max(mAttribMaxNameLength, mAttachedShaders[i]->mAttribMaxNameLength);
for (size_t i = 0; i < mAttachedShaders.Length(); i++) {
mAttribMaxNameLength = std::max(mAttribMaxNameLength,
mAttachedShaders[i]->mAttribMaxNameLength);
}
GLint attribCount;
mContext->gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, &attribCount);
if (!mAttribsInUse.SetLength(mContext->mGLMaxVertexAttribs)) {
mContext->ErrorOutOfMemory("updateInfo: out of memory to allocate %d attribs", mContext->mGLMaxVertexAttribs);
mContext->ErrorOutOfMemory("updateInfo: Out of memory to allocate %d"
" attribs.", mContext->mGLMaxVertexAttribs);
return false;
}
@ -241,14 +274,17 @@ WebGLProgram::UpdateInfo()
GLint attrnamelen;
GLint attrsize;
GLenum attrtype;
mContext->gl->fGetActiveAttrib(mGLName, i, mAttribMaxNameLength, &attrnamelen, &attrsize, &attrtype, nameBuf);
mContext->gl->fGetActiveAttrib(mGLName, i, mAttribMaxNameLength,
&attrnamelen, &attrsize, &attrtype,
nameBuf);
if (attrnamelen > 0) {
GLint loc = mContext->gl->fGetAttribLocation(mGLName, nameBuf);
MOZ_ASSERT(loc >= 0, "major oops in managing the attributes of a WebGL program");
MOZ_ASSERT(loc >= 0, "Major oops in managing the attributes of a"
" WebGL program.");
if (loc < mContext->mGLMaxVertexAttribs) {
mAttribsInUse[loc] = true;
} else {
mContext->GenerateWarning("program exceeds MAX_VERTEX_ATTRIBS");
mContext->GenerateWarning("Program exceeds MAX_VERTEX_ATTRIBS.");
return false;
}
}
@ -262,16 +298,22 @@ WebGLProgram::UpdateInfo()
// Loop through ATTRIBUTES
for (size_t j = 0; j < mAttachedShaders[i]->mAttributes.Length(); j++) {
const WebGLMappedIdentifier& attrib = mAttachedShaders[i]->mAttributes[j];
mIdentifierMap->Put(attrib.original, attrib.mapped); // FORWARD MAPPING
mIdentifierReverseMap->Put(attrib.mapped, attrib.original); // REVERSE MAPPING
// FORWARD MAPPING
mIdentifierMap->Put(attrib.original, attrib.mapped);
// REVERSE MAPPING
mIdentifierReverseMap->Put(attrib.mapped, attrib.original);
}
// Loop through UNIFORMS
for (size_t j = 0; j < mAttachedShaders[i]->mUniforms.Length(); j++) {
// Add the uniforms name mapping to mIdentifier[Reverse]Map
const WebGLMappedIdentifier& uniform = mAttachedShaders[i]->mUniforms[j];
mIdentifierMap->Put(uniform.original, uniform.mapped); // FOWARD MAPPING
mIdentifierReverseMap->Put(uniform.mapped, uniform.original); // REVERSE MAPPING
// FOWARD MAPPING
mIdentifierMap->Put(uniform.original, uniform.mapped);
// REVERSE MAPPING
mIdentifierReverseMap->Put(uniform.mapped, uniform.original);
// Add uniform info to mUniformInfoMap
const WebGLUniformInfo& info = mAttachedShaders[i]->mUniformInfos[j];
@ -301,8 +343,8 @@ WebGLProgram::UpdateInfo()
return true;
}
/* static */ uint64_t
WebGLProgram::IdentifierHashFunction(const char *ident, size_t size)
/*static*/ uint64_t
WebGLProgram::IdentifierHashFunction(const char* ident, size_t size)
{
uint64_t outhash[2];
// NB: we use the x86 function everywhere, even though it's suboptimal perf
@ -311,16 +353,20 @@ WebGLProgram::IdentifierHashFunction(const char *ident, size_t size)
return outhash[0];
}
/* static */ void
WebGLProgram::HashMapIdentifier(const nsACString& name, nsCString *hashedName)
/*static*/ void
WebGLProgram::HashMapIdentifier(const nsACString& name,
nsCString* const out_hashedName)
{
uint64_t hash = IdentifierHashFunction(name.BeginReading(), name.Length());
hashedName->Truncate();
// This MUST MATCH angle/src/compiler/translator/HashNames.h HASHED_NAME_PREFIX
hashedName->AppendPrintf("webgl_%llx", hash);
out_hashedName->Truncate();
// This MUST MATCH HASHED_NAME_PREFIX from
// angle/src/compiler/translator/HashNames.h .
out_hashedName->AppendPrintf("webgl_%llx", hash);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLProgram, mAttachedShaders)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLProgram, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLProgram, Release)
} // namespace mozilla

Просмотреть файл

@ -3,16 +3,14 @@
* 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 WEBGLPROGRAM_H_
#define WEBGLPROGRAM_H_
#include "WebGLObjectModel.h"
#ifndef WEBGL_PROGRAM_H_
#define WEBGL_PROGRAM_H_
#include <map>
#include "mozilla/CheckedInt.h"
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLObjectModel.h"
#include "WebGLShader.h"
#include "WebGLUniformInfo.h"
@ -22,7 +20,8 @@ class WebGLShader;
struct WebGLUniformInfo;
typedef nsDataHashtable<nsCStringHashKey, nsCString> CStringMap;
typedef nsDataHashtable<nsCStringHashKey, WebGLUniformInfo> CStringToUniformInfoMap;
typedef nsDataHashtable<nsCStringHashKey,
WebGLUniformInfo> CStringToUniformInfoMap;
class WebGLProgram MOZ_FINAL
: public nsWrapperCache
@ -31,7 +30,7 @@ class WebGLProgram MOZ_FINAL
, public WebGLContextBoundObject
{
public:
explicit WebGLProgram(WebGLContext* aContext);
explicit WebGLProgram(WebGLContext* webgl);
void Delete();
@ -40,26 +39,27 @@ public:
}
GLuint GLName() { return mGLName; }
const nsTArray<WebGLRefPtr<WebGLShader> >& AttachedShaders() const { return mAttachedShaders; }
const nsTArray<WebGLRefPtr<WebGLShader> >& AttachedShaders() const {
return mAttachedShaders;
}
bool LinkStatus() { return mLinkStatus; }
uint32_t Generation() const { return mGeneration.value(); }
void SetLinkStatus(bool val) { mLinkStatus = val; }
bool ContainsShader(WebGLShader *shader) {
bool ContainsShader(WebGLShader* shader) {
return mAttachedShaders.Contains(shader);
}
// return true if the shader wasn't already attached
bool AttachShader(WebGLShader *shader);
bool AttachShader(WebGLShader* shader);
// return true if the shader was found and removed
bool DetachShader(WebGLShader *shader);
bool DetachShader(WebGLShader* shader);
bool HasAttachedShaderOfType(GLenum shaderType);
bool HasBothShaderTypesAttached() {
return
HasAttachedShaderOfType(LOCAL_GL_VERTEX_SHADER) &&
return HasAttachedShaderOfType(LOCAL_GL_VERTEX_SHADER) &&
HasAttachedShaderOfType(LOCAL_GL_FRAGMENT_SHADER);
}
@ -67,42 +67,43 @@ public:
size_t UpperBoundNumSamplerUniforms();
bool NextGeneration()
{
bool NextGeneration() {
if (!(mGeneration + 1).isValid())
return false; // must exit without changing mGeneration
++mGeneration;
return true;
}
/* Called only after LinkProgram */
// Called only after LinkProgram
bool UpdateInfo();
/* Getters for cached program info */
bool IsAttribInUse(unsigned i) const { return mAttribsInUse[i]; }
// Getters for cached program info
bool IsAttribInUse(uint32_t i) const { return mAttribsInUse[i]; }
/* Maps identifier |name| to the mapped identifier |*mappedName|
* Both are ASCII strings.
*/
void MapIdentifier(const nsACString& name, nsCString *mappedName);
// Maps identifier |name| to the mapped identifier |*mappedName|
// Both are ASCII strings.
void MapIdentifier(const nsACString& name, nsCString* out_mappedName);
/* Un-maps mapped identifier |name| to the original identifier |*reverseMappedName|
* Both are ASCII strings.
*/
void ReverseMapIdentifier(const nsACString& name, nsCString *reverseMappedName);
// Un-maps mapped identifier |name| to the original identifier
// |*reverseMappedName|.
// Both are ASCII strings.
void ReverseMapIdentifier(const nsACString& name,
nsCString* out_reverseMappedName);
/* Returns the uniform array size (or 1 if the uniform is not an array) of
* the uniform with given mapped identifier.
*
* Note: the input string |name| is the mapped identifier, not the original identifier.
* Note: The input string |name| is the mapped identifier, not the original
* identifier.
*/
WebGLUniformInfo GetUniformInfoForMappedIdentifier(const nsACString& name);
WebGLContext *GetParentObject() const {
WebGLContext* GetParentObject() const {
return Context();
}
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLProgram)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLProgram)
@ -110,8 +111,9 @@ public:
// public post-link data
std::map<GLint, nsCString> mActiveAttribMap;
static uint64_t IdentifierHashFunction(const char *ident, size_t size);
static void HashMapIdentifier(const nsACString& name, nsCString *hashedName);
static uint64_t IdentifierHashFunction(const char* ident, size_t size);
static void HashMapIdentifier(const nsACString& name,
nsCString* const out_hashedName);
protected:
~WebGLProgram() {
@ -133,4 +135,4 @@ protected:
} // namespace mozilla
#endif
#endif // WEBGL_PROGRAM_H_

Просмотреть файл

@ -6,11 +6,11 @@
#include "WebGLQuery.h"
#include "GLContext.h"
#include "WebGLContext.h"
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
#include "nsContentUtils.h"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
JSObject*
WebGLQuery::WrapObject(JSContext* cx)
@ -18,8 +18,8 @@ WebGLQuery::WrapObject(JSContext* cx)
return dom::WebGLQueryBinding::Wrap(cx, this);
}
WebGLQuery::WebGLQuery(WebGLContext* context)
: WebGLContextBoundObject(context)
WebGLQuery::WebGLQuery(WebGLContext* webgl)
: WebGLContextBoundObject(webgl)
, mGLName(0)
, mType(0)
{
@ -43,12 +43,12 @@ WebGLQuery::IsActive() const
WebGLRefPtr<WebGLQuery>* targetSlot = mContext->GetQueryTargetSlot(mType);
MOZ_ASSERT(targetSlot, "unknown query object's type");
return targetSlot && *targetSlot == this;
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLQuery)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLQuery, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLQuery, Release)
} // namespace mozilla

Просмотреть файл

@ -3,14 +3,12 @@
* 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 WEBGLQUERY_H_
#define WEBGLQUERY_H_
#include "WebGLObjectModel.h"
#include "nsWrapperCache.h"
#ifndef WEBGL_QUERY_H_
#define WEBGL_QUERY_H_
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLObjectModel.h"
namespace mozilla {
@ -20,62 +18,41 @@ class WebGLQuery MOZ_FINAL
, public LinkedListElement<WebGLQuery>
, public WebGLContextBoundObject
{
// -----------------------------------------------------------------------------
// PUBLIC
public:
// -------------------------------------------------------------------------
// CONSTRUCTOR
explicit WebGLQuery(WebGLContext* aContext);
// -------------------------------------------------------------------------
// MEMBER FUNCTIONS
explicit WebGLQuery(WebGLContext* webgl);
bool IsActive() const;
bool HasEverBeenActive()
{
bool HasEverBeenActive() {
return mType != 0;
}
// -------------------------------------------------------------------------
// IMPLEMENT WebGLRefCountedObject and WebGLContextBoundObject
// WebGLRefCountedObject
void Delete();
WebGLContext* GetParentObject() const
{
// nsWrapperCache
WebGLContext* GetParentObject() const {
return Context();
}
// -------------------------------------------------------------------------
// IMPLEMENT NS
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
// NS
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery)
// -----------------------------------------------------------------------------
// PRIVATE
private:
~WebGLQuery() {
DeleteOnce();
};
// -------------------------------------------------------------------------
// MEMBERS
GLuint mGLName;
GLenum mType;
// -------------------------------------------------------------------------
// FRIENDSHIPS
friend class WebGL2Context;
};
} // namespace mozilla
#endif
#endif // WEBGL_QUERY_H_

Просмотреть файл

@ -3,18 +3,19 @@
* 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 "WebGLRenderbuffer.h"
#include "WebGLTexture.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "GLContext.h"
#include "ScopedGLHelpers.h"
using namespace mozilla;
using namespace mozilla::gl;
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "ScopedGLHelpers.h"
#include "WebGLContext.h"
#include "WebGLTexture.h"
namespace mozilla {
static GLenum
DepthStencilDepthFormat(GLContext* gl) {
DepthStencilDepthFormat(gl::GLContext* gl)
{
// We might not be able to get 24-bit, so let's pretend!
if (gl->IsGLES() && !gl->IsExtensionSupported(gl::GLContext::OES_depth24))
return LOCAL_GL_DEPTH_COMPONENT16;
@ -23,13 +24,15 @@ DepthStencilDepthFormat(GLContext* gl) {
}
static bool
SupportsDepthStencil(GLContext* gl) {
return gl->IsExtensionSupported(GLContext::EXT_packed_depth_stencil) ||
gl->IsExtensionSupported(GLContext::OES_packed_depth_stencil);
SupportsDepthStencil(gl::GLContext* gl)
{
return gl->IsExtensionSupported(gl::GLContext::EXT_packed_depth_stencil) ||
gl->IsExtensionSupported(gl::GLContext::OES_packed_depth_stencil);
}
static bool
NeedsDepthStencilEmu(GLContext* gl, GLenum internalFormat) {
NeedsDepthStencilEmu(gl::GLContext* gl, GLenum internalFormat)
{
MOZ_ASSERT(internalFormat != LOCAL_GL_DEPTH_STENCIL);
if (internalFormat != LOCAL_GL_DEPTH24_STENCIL8)
return false;
@ -38,13 +41,14 @@ NeedsDepthStencilEmu(GLContext* gl, GLenum internalFormat) {
}
JSObject*
WebGLRenderbuffer::WrapObject(JSContext *cx) {
WebGLRenderbuffer::WrapObject(JSContext* cx)
{
return dom::WebGLRenderbufferBinding::Wrap(cx, this);
}
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* context)
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* webgl)
: WebGLBindable<RBTarget>()
, WebGLContextBoundObject(context)
, WebGLContextBoundObject(webgl)
, mPrimaryRB(0)
, mSecondaryRB(0)
, mInternalFormat(0)
@ -61,7 +65,8 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* context)
}
void
WebGLRenderbuffer::Delete() {
WebGLRenderbuffer::Delete()
{
mContext->MakeContextCurrent();
mContext->gl->fDeleteRenderbuffers(1, &mPrimaryRB);
@ -72,14 +77,14 @@ WebGLRenderbuffer::Delete() {
}
int64_t
WebGLRenderbuffer::MemoryUsage() const {
WebGLRenderbuffer::MemoryUsage() const
{
int64_t pixels = int64_t(Width()) * int64_t(Height());
GLenum primaryFormat = InternalFormatForGL();
// If there is no defined format, we're not taking up any memory
if (!primaryFormat) {
if (!primaryFormat)
return 0;
}
int64_t secondarySize = 0;
if (mSecondaryRB) {
@ -133,7 +138,8 @@ WebGLRenderbuffer::MemoryUsage() const {
}
void
WebGLRenderbuffer::BindRenderbuffer() const {
WebGLRenderbuffer::BindRenderbuffer() const
{
/* Do this explicitly here, since the meaning changes for depth-stencil emu.
* Under normal circumstances, there's only one RB: `mPrimaryRB`.
* `mSecondaryRB` is used when we have to pretend that the renderbuffer is
@ -151,8 +157,10 @@ WebGLRenderbuffer::BindRenderbuffer() const {
}
void
WebGLRenderbuffer::RenderbufferStorage(GLenum internalFormat, GLsizei width, GLsizei height) const {
GLContext* gl = mContext->gl;
WebGLRenderbuffer::RenderbufferStorage(GLenum internalFormat, GLsizei width,
GLsizei height) const
{
gl::GLContext* gl = mContext->gl;
GLenum primaryFormat = internalFormat;
GLenum secondaryFormat = 0;
@ -172,7 +180,7 @@ WebGLRenderbuffer::RenderbufferStorage(GLenum internalFormat, GLsizei width, GLs
// handle the case where we attach a non-depth-stencil RB to a
// depth-stencil attachment point, or attach this depth-stencil RB to a
// non-depth-stencil attachment point.
ScopedBindRenderbuffer autoRB(gl, mSecondaryRB);
gl::ScopedBindRenderbuffer autoRB(gl, mSecondaryRB);
if (secondaryFormat) {
gl->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER, secondaryFormat, width, height);
} else {
@ -181,63 +189,73 @@ WebGLRenderbuffer::RenderbufferStorage(GLenum internalFormat, GLsizei width, GLs
}
void
WebGLRenderbuffer::FramebufferRenderbuffer(FBAttachment attachment) const {
GLContext* gl = mContext->gl;
WebGLRenderbuffer::FramebufferRenderbuffer(FBAttachment attachment) const
{
gl::GLContext* gl = mContext->gl;
if (attachment != LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachment.get(), LOCAL_GL_RENDERBUFFER, mPrimaryRB);
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachment.get(),
LOCAL_GL_RENDERBUFFER, mPrimaryRB);
return;
}
GLuint stencilRB = mPrimaryRB;
if (NeedsDepthStencilEmu(mContext->gl, InternalFormatForGL())) {
printf_stderr("DEV-ONLY: Using secondary buffer to emulate DepthStencil.\n");
MOZ_ASSERT(mSecondaryRB);
stencilRB = mSecondaryRB;
}
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_RENDERBUFFER, mPrimaryRB);
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, stencilRB);
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_DEPTH_ATTACHMENT,
LOCAL_GL_RENDERBUFFER, mPrimaryRB);
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_STENCIL_ATTACHMENT,
LOCAL_GL_RENDERBUFFER, stencilRB);
}
GLint
WebGLRenderbuffer::GetRenderbufferParameter(RBTarget target, RBParam pname) const {
GLContext* gl = mContext->gl;
WebGLRenderbuffer::GetRenderbufferParameter(RBTarget target,
RBParam pname) const
{
gl::GLContext* gl = mContext->gl;
switch (pname.get()) {
case LOCAL_GL_RENDERBUFFER_STENCIL_SIZE: {
case LOCAL_GL_RENDERBUFFER_STENCIL_SIZE:
if (NeedsDepthStencilEmu(mContext->gl, InternalFormatForGL())) {
if (gl->WorkAroundDriverBugs() &&
gl->Renderer() == GLRenderer::Tegra)
gl->Renderer() == gl::GLRenderer::Tegra)
{
return 8;
}
ScopedBindRenderbuffer autoRB(gl, mSecondaryRB);
gl::ScopedBindRenderbuffer autoRB(gl, mSecondaryRB);
GLint i = 0;
gl->fGetRenderbufferParameteriv(target.get(), pname.get(), &i);
return i;
}
// Fall through otherwise.
}
case LOCAL_GL_RENDERBUFFER_WIDTH:
case LOCAL_GL_RENDERBUFFER_HEIGHT:
case LOCAL_GL_RENDERBUFFER_RED_SIZE:
case LOCAL_GL_RENDERBUFFER_GREEN_SIZE:
case LOCAL_GL_RENDERBUFFER_BLUE_SIZE:
case LOCAL_GL_RENDERBUFFER_ALPHA_SIZE:
case LOCAL_GL_RENDERBUFFER_DEPTH_SIZE: {
case LOCAL_GL_RENDERBUFFER_DEPTH_SIZE:
{
GLint i = 0;
gl->fGetRenderbufferParameteriv(target.get(), pname.get(), &i);
return i;
}
}
MOZ_ASSERT(false, "This function should only be called with valid `pname`.");
MOZ_ASSERT(false,
"This function should only be called with valid `pname`.");
return 0;
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLRenderbuffer)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLRenderbuffer, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLRenderbuffer, Release)
} // namespace mozilla

Просмотреть файл

@ -3,16 +3,14 @@
* 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 WEBGLRENDERBUFFER_H_
#define WEBGLRENDERBUFFER_H_
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "WebGLFramebufferAttachable.h"
#include "nsWrapperCache.h"
#ifndef WEBGL_RENDERBUFFER_H_
#define WEBGL_RENDERBUFFER_H_
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLFramebufferAttachable.h"
#include "WebGLObjectModel.h"
namespace mozilla {
@ -26,11 +24,13 @@ class WebGLRenderbuffer MOZ_FINAL
, public WebGLFramebufferAttachable
{
public:
explicit WebGLRenderbuffer(WebGLContext* context);
explicit WebGLRenderbuffer(WebGLContext* webgl);
void Delete();
bool HasUninitializedImageData() const { return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData; }
bool HasUninitializedImageData() const {
return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData;
}
void SetImageDataStatus(WebGLImageDataStatus x) {
// there is no way to go from having image data to not having any
MOZ_ASSERT(x != WebGLImageDataStatus::NoImageData ||
@ -39,24 +39,29 @@ public:
}
GLenum InternalFormat() const { return mInternalFormat; }
void SetInternalFormat(GLenum aInternalFormat) { mInternalFormat = aInternalFormat; }
void SetInternalFormat(GLenum internalFormat) {
mInternalFormat = internalFormat;
}
GLenum InternalFormatForGL() const { return mInternalFormatForGL; }
void SetInternalFormatForGL(GLenum aInternalFormatForGL) { mInternalFormatForGL = aInternalFormatForGL; }
void SetInternalFormatForGL(GLenum internalFormatForGL) {
mInternalFormatForGL = internalFormatForGL;
}
int64_t MemoryUsage() const;
WebGLContext *GetParentObject() const {
WebGLContext* GetParentObject() const {
return Context();
}
void BindRenderbuffer() const;
void RenderbufferStorage(GLenum internalFormat, GLsizei width, GLsizei height) const;
void RenderbufferStorage(GLenum internalFormat, GLsizei width,
GLsizei height) const;
void FramebufferRenderbuffer(FBAttachment attachment) const;
// Only handles a subset of `pname`s.
GLint GetRenderbufferParameter(RBTarget target, RBParam pname) const;
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLRenderbuffer)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLRenderbuffer)
@ -74,6 +79,7 @@ protected:
friend class WebGLFramebuffer;
};
} // namespace mozilla
#endif
#endif // WEBGL_RENDERBUFFER_H_

Просмотреть файл

@ -3,18 +3,17 @@
* 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 "WebGLSampler.h"
#include "GLContext.h"
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
#include "WebGLContext.h"
using namespace mozilla;
namespace mozilla {
WebGLSampler::WebGLSampler(WebGLContext* context, GLuint sampler)
WebGLSampler::WebGLSampler(WebGLContext* webgl, GLuint sampler)
: WebGLBindableName<GLenum>(sampler),
WebGLContextBoundObject(context)
WebGLContextBoundObject(webgl)
{
mContext->mSamplers.insertBack(this);
}
@ -49,3 +48,5 @@ WebGLSampler::WrapObject(JSContext* cx)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSampler)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLSampler, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLSampler, Release)
} // namespace mozilla

Просмотреть файл

@ -3,15 +3,13 @@
* 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 WEBGLSAMPLER_H_
#define WEBGLSAMPLER_H_
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "nsWrapperCache.h"
#ifndef WEBGL_SAMPLER_H_
#define WEBGL_SAMPLER_H_
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
namespace mozilla {
@ -25,8 +23,7 @@ class WebGLSampler MOZ_FINAL
friend class WebGLContext2;
public:
explicit WebGLSampler(WebGLContext* aContext, GLuint sampler);
explicit WebGLSampler(WebGLContext* webgl, GLuint sampler);
void Delete();
WebGLContext* GetParentObject() const;
@ -39,10 +36,9 @@ private:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler)
private:
~WebGLSampler();
};
} // namespace mozilla
#endif // !WEBGLSAMPLER_H_
#endif // WEBGL_SAMPLER_H_

Просмотреть файл

@ -3,23 +3,25 @@
* 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 "WebGLShader.h"
#include "WebGLContext.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "GLContext.h"
using namespace mozilla;
#include "angle/ShaderLang.h"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "mozilla/MemoryReporting.h"
#include "WebGLContext.h"
#include "WebGLObjectModel.h"
namespace mozilla {
JSObject*
WebGLShader::WrapObject(JSContext *cx) {
WebGLShader::WrapObject(JSContext* cx) {
return dom::WebGLShaderBinding::Wrap(cx, this);
}
WebGLShader::WebGLShader(WebGLContext *context, GLenum stype)
: WebGLContextBoundObject(context)
, mType(stype)
WebGLShader::WebGLShader(WebGLContext* webgl, GLenum type)
: WebGLContextBoundObject(webgl)
, mType(type)
, mNeedsTranslation(true)
, mAttribMaxNameLength(0)
, mCompileStatus(false)
@ -30,7 +32,8 @@ WebGLShader::WebGLShader(WebGLContext *context, GLenum stype)
}
void
WebGLShader::Delete() {
WebGLShader::Delete()
{
mSource.Truncate();
mTranslationLog.Truncate();
mContext->MakeContextCurrent();
@ -39,14 +42,16 @@ WebGLShader::Delete() {
}
size_t
WebGLShader::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) +
mSource.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
mTranslationLog.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
WebGLShader::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
{
return mallocSizeOf(this) +
mSource.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
mTranslationLog.SizeOfExcludingThisIfUnshared(mallocSizeOf);
}
void
WebGLShader::SetTranslationSuccess() {
WebGLShader::SetTranslationSuccess()
{
mTranslationLog.SetIsVoid(true);
mNeedsTranslation = false;
}
@ -55,3 +60,5 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLShader)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLShader, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLShader, Release)
} // namespace mozilla

Просмотреть файл

@ -3,24 +3,27 @@
* 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 WEBGLSHADER_H_
#define WEBGLSHADER_H_
#include "WebGLObjectModel.h"
#include "WebGLUniformInfo.h"
#include "nsWrapperCache.h"
#include "angle/ShaderLang.h"
#ifndef WEBGL_SHADER_H_
#define WEBGL_SHADER_H_
#include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h"
#include "nsWrapperCache.h"
#include "WebGLObjectModel.h"
#include "WebGLUniformInfo.h"
namespace mozilla {
struct WebGLMappedIdentifier {
nsCString original, mapped; // ASCII strings
WebGLMappedIdentifier(const nsACString& o, const nsACString& m) : original(o), mapped(m) {}
struct WebGLMappedIdentifier
{
// ASCII strings
nsCString original;
nsCString mapped;
WebGLMappedIdentifier(const nsACString& o, const nsACString& m)
: original(o)
, mapped(m)
{}
};
class WebGLShader MOZ_FINAL
@ -33,15 +36,16 @@ class WebGLShader MOZ_FINAL
friend class WebGLProgram;
public:
WebGLShader(WebGLContext *context, GLenum stype);
WebGLShader(WebGLContext* webgl, GLenum type);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
GLuint GLName() { return mGLName; }
sh::GLenum ShaderType() { return mType; }
void SetSource(const nsAString& src) {
// XXX do some quick gzip here maybe -- getting this will be very rare
// TODO: Do some quick gzip here maybe? Getting this will be very rare,
// and we have to keep it forever.
mSource.Assign(src);
}
@ -70,11 +74,11 @@ public:
const nsString& TranslatedSource() const { return mTranslatedSource; }
WebGLContext *GetParentObject() const {
WebGLContext* GetParentObject() const {
return Context();
}
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLShader)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLShader)
@ -85,7 +89,7 @@ protected:
}
GLuint mGLName;
sh::GLenum mType;
GLenum mType;
nsString mSource;
nsString mTranslatedSource;
nsCString mTranslationLog; // The translation log should contain only ASCII characters
@ -96,6 +100,7 @@ protected:
int mAttribMaxNameLength;
bool mCompileStatus;
};
} // namespace mozilla
#endif
#endif // WEBGL_SHADER_H_

Просмотреть файл

@ -3,14 +3,17 @@
* 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 "WebGLShaderPrecisionFormat.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
using namespace mozilla;
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
namespace mozilla {
JSObject*
WebGLShaderPrecisionFormat::WrapObject(JSContext *cx)
WebGLShaderPrecisionFormat::WrapObject(JSContext* cx)
{
return dom::WebGLShaderPrecisionFormatBinding::Wrap(cx, this);
}
} // namespace mozilla

Просмотреть файл

@ -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 WEBGLSHADERPRECISIONFORMAT_H_
#define WEBGLSHADERPRECISIONFORMAT_H_
#ifndef WEBGL_SHADER_PRECISION_FORMAT_H_
#define WEBGL_SHADER_PRECISION_FORMAT_H_
#include "WebGLObjectModel.h"
@ -16,23 +16,25 @@ class WebGLShaderPrecisionFormat MOZ_FINAL
: public WebGLContextBoundObject
{
public:
WebGLShaderPrecisionFormat(WebGLContext *context, GLint rangeMin, GLint rangeMax, GLint precision) :
WebGLContextBoundObject(context),
mRangeMin(rangeMin),
mRangeMax(rangeMax),
mPrecision(precision)
{
}
WebGLShaderPrecisionFormat(WebGLContext* context, GLint rangeMin,
GLint rangeMax, GLint precision)
: WebGLContextBoundObject(context)
, mRangeMin(rangeMin)
, mRangeMax(rangeMax)
, mPrecision(precision)
{ }
JSObject* WrapObject(JSContext *cx);
JSObject* WrapObject(JSContext* cx);
// WebIDL WebGLShaderPrecisionFormat API
GLint RangeMin() const {
return mRangeMin;
}
GLint RangeMax() const {
return mRangeMax;
}
GLint Precision() const {
return mPrecision;
}
@ -41,9 +43,7 @@ public:
private:
// Private destructor, to discourage deletion outside of Release():
~WebGLShaderPrecisionFormat()
{
}
~WebGLShaderPrecisionFormat() { }
GLint mRangeMin;
GLint mRangeMax;
@ -52,4 +52,4 @@ private:
} // namespace mozilla
#endif
#endif // WEBGL_SHADER_PRECISION_FORMAT_H_

Просмотреть файл

@ -1,99 +1,100 @@
/* -*- 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 WEBGLSTRONGTYPES_H_
#define WEBGLSTRONGTYPES_H_
#ifndef WEBGL_STRONG_TYPES_H_
#define WEBGL_STRONG_TYPES_H_
#include "GLDefs.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
// Usage:
// ===========
//
// To create a new type from a set of GLenums do the following:
//
// STRONG_GLENUM_BEGIN(TypeName)
// STRONG_GLENUM_VALUE(ENUM1),
// STRONG_GLENUM_VALUE(ENUM2),
// ...
// STRONG_GLENUM_END()
//
// where TypeName is the name you want to give the type. Now simply use TypeName
// instead of GLenum. The enum values must be given without GL_ prefix.
//
// ~~~~~~~~~~~~~~~~
// Important Notes:
// ~~~~~~~~~~~~~~~~
//
// Boolean operators (==, !=) are provided in an effort to prevent some mistakes
// when using constants. For example we want to make sure that GL_ENUM_X is
// a valid value for the type in code like:
//
// if (myNewType == STRONG_GLENUM_VALUE(SOME_ENUM))
// ...
//
// The operators will assert that STRONG_GLENUM_VALUE(SOME_ENUM) is a value that myNewType
// can have.
//
// ----
//
// A get() method is provided to allow access to the underlying GLenum. This
// method should ideally only be called when passing parameters to the gl->fXXXX
// functions, and be used very minimally everywhere else.
//
// Definitely XXX - DO NOT DO - XXX:
//
// if (myNewType.get() == STRONG_GLENUM_VALUE(SOME_ENUM))
// ...
//
// As that undermines the debug checks that were implemented in the ==, and !=
// operators. If you see code like this it should be treated with suspicion.
//
// Background:
// ===========
//
// This macro is the first step in an effort to make the WebGL code safer.
// Many of the different functions take GLenum as their parameter which leads
// to bugs because of subtle differences in the enums purpose. For example there
// are two types of 'texture targets'. One is the texture binding locations:
//
// GL_TEXTURE_2D
// GL_TEXTURE_CUBE_MAP
//
// Yet, this is not the same as texture image targets:
//
// GL_TEXTURE_2D
// GL_TEXTURE_CUBE_MAP_POSITIVE_X
// GL_TEXTURE_CUBE_MAP_NEGATIVE_X
// GL_TEXTURE_CUBE_MAP_POSITIVE_Y
// ...
//
// This subtle distinction has already led to many bugs in the texture code
// because of invalid assumptions about what type goes where. The macro below
// is an attempt at fixing this by providing a small wrapper around GLenum that
// validates its values.
//
// Comparison between STRONG_GLENUM's vs. enum classes
// ===================================================
//
// The present STRONG_GLENUM's differ from ordinary enum classes
// in that they assert at runtime that their values are legal, and in that they
// allow implicit conversion from integers to STRONG_GLENUM's but disallow
// implicit conversion from STRONG_GLENUM's to integers (enum classes are the opposite).
//
// When to use GLenum's vs. STRONG_GLENUM's vs. enum classes
// =========================================================
//
// Rule of thumb:
// * For unchecked GLenum constants, such as WebGL method parameters that haven't been
// validated yet, use GLenum.
// * For already-validated GLenum constants, use STRONG_GLENUM's.
// * For custom constants that aren't GL enum values, use enum classes.
/* Usage:
* ===========
*
* To create a new type from a set of GLenums do the following:
*
* STRONG_GLENUM_BEGIN(TypeName)
* STRONG_GLENUM_VALUE(ENUM1),
* STRONG_GLENUM_VALUE(ENUM2),
* ...
* STRONG_GLENUM_END()
*
* where TypeName is the name you want to give the type. Now simply use TypeName
* instead of GLenum. The enum values must be given without GL_ prefix.
*
* ~~~~~~~~~~~~~~~~
* Important Notes:
* ~~~~~~~~~~~~~~~~
*
* Boolean operators (==, !=) are provided in an effort to prevent some mistakes
* when using constants. For example we want to make sure that GL_ENUM_X is
* a valid value for the type in code like:
*
* if (myNewType == STRONG_GLENUM_VALUE(SOME_ENUM))
* ...
*
* The operators will assert that STRONG_GLENUM_VALUE(SOME_ENUM) is a value that
* myNewType can have.
*
* ----
*
* A get() method is provided to allow access to the underlying GLenum. This
* method should ideally only be called when passing parameters to the gl->fXXXX
* functions, and be used very minimally everywhere else.
*
* Definitely XXX - DO NOT DO - XXX:
*
* if (myNewType.get() == STRONG_GLENUM_VALUE(SOME_ENUM))
* ...
*
* As that undermines the debug checks that were implemented in the ==, and !=
* operators. If you see code like this it should be treated with suspicion.
*
* Background:
* ===========
*
* This macro is the first step in an effort to make the WebGL code safer.
* Many of the different functions take GLenum as their parameter which leads
* to bugs because of subtle differences in the enums purpose. For example there
* are two types of 'texture targets'. One is the texture binding locations:
*
* GL_TEXTURE_2D
* GL_TEXTURE_CUBE_MAP
*
* Yet, this is not the same as texture image targets:
*
* GL_TEXTURE_2D
* GL_TEXTURE_CUBE_MAP_POSITIVE_X
* GL_TEXTURE_CUBE_MAP_NEGATIVE_X
* GL_TEXTURE_CUBE_MAP_POSITIVE_Y
* ...
*
* This subtle distinction has already led to many bugs in the texture code
* because of invalid assumptions about what type goes where. The macro below
* is an attempt at fixing this by providing a small wrapper around GLenum that
* validates its values.
*
* Comparison between STRONG_GLENUM's vs. enum classes
* ===================================================
*
* The present STRONG_GLENUM's differ from ordinary enum classes
* in that they assert at runtime that their values are legal, and in that they
* allow implicit conversion from integers to STRONG_GLENUM's but disallow
* implicit conversion from STRONG_GLENUM's to integers (enum classes are the
* opposite).
*
* When to use GLenum's vs. STRONG_GLENUM's vs. enum classes
* =========================================================
*
* Rule of thumb:
* * For unchecked GLenum constants, such as WebGL method parameters that
* haven't been validated yet, use GLenum.
* * For already-validated GLenum constants, use STRONG_GLENUM's.
* * For custom constants that aren't GL enum values, use enum classes.
*/
template<typename Details>
class StrongGLenum MOZ_FINAL
@ -103,8 +104,7 @@ private:
GLenum mValue;
static void AssertOnceThatEnumValuesAreSorted()
{
static void AssertOnceThatEnumValuesAreSorted() {
#ifdef DEBUG
static bool alreadyChecked = false;
if (alreadyChecked) {
@ -133,8 +133,8 @@ public:
AssertOnceThatEnumValuesAreSorted();
}
MOZ_IMPLICIT StrongGLenum(GLenum aVal)
: mValue(aVal)
MOZ_IMPLICIT StrongGLenum(GLenum value)
: mValue(value)
{
AssertOnceThatEnumValuesAreSorted();
MOZ_ASSERT(IsValueLegal(mValue));
@ -208,9 +208,8 @@ bool operator!=(StrongGLenum<Details> a, GLenum b)
}; \
typedef StrongGLenum<NAME##Details> NAME;
/******************************************************************************
* Add your types after this comment
*****************************************************************************/
////////////////////////////////////////////////////////////////////////////////
// Add types below.
STRONG_GLENUM_BEGIN(TexImageTarget)
STRONG_GLENUM_VALUE(NONE),
@ -451,4 +450,4 @@ STRONG_GLENUM_BEGIN(BufferBinding)
STRONG_GLENUM_VALUE(ELEMENT_ARRAY_BUFFER),
STRONG_GLENUM_END(BufferBinding)
#endif
#endif // WEBGL_STRONG_TYPES_H_

Просмотреть файл

@ -7,10 +7,10 @@
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
using namespace mozilla;
namespace mozilla {
WebGLSync::WebGLSync(WebGLContext* context) :
WebGLContextBoundObject(context)
WebGLSync::WebGLSync(WebGLContext* webgl):
WebGLContextBoundObject(webgl)
{
MOZ_CRASH("Not Implemented.");
}
@ -34,7 +34,7 @@ WebGLSync::GetParentObject() const
// -------------------------------------------------------------------------
// IMPLEMENT NS
JSObject*
WebGLSync::WrapObject(JSContext *cx)
WebGLSync::WrapObject(JSContext* cx)
{
return dom::WebGLSyncBinding::Wrap(cx, this);
}
@ -42,3 +42,5 @@ WebGLSync::WrapObject(JSContext *cx)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSync)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLSync, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLSync, Release);
} // namespace mozilla

Просмотреть файл

@ -3,14 +3,12 @@
* 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 WEBGLSYNC_H_
#define WEBGLSYNC_H_
#include "WebGLObjectModel.h"
#include "nsWrapperCache.h"
#ifndef WEBGL_SYNC_H_
#define WEBGL_SYNC_H_
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLObjectModel.h"
namespace mozilla {
@ -23,24 +21,20 @@ class WebGLSync MOZ_FINAL
friend class WebGL2Context;
public:
explicit WebGLSync(WebGLContext* aContext);
explicit WebGLSync(WebGLContext* webgl);
void Delete();
WebGLContext* GetParentObject() const;
// -------------------------------------------------------------------------
// IMPLEMENT NS
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSync)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSync)
private:
~WebGLSync();
};
} // namespace mozilla
#endif // !WEBGLSYNC_H_
#endif // WEBGL_SYNC_H_

Просмотреть файл

@ -180,14 +180,14 @@ class WebGLImageConverter
const ptrdiff_t srcStrideInElements = mSrcStride / sizeof(SrcType);
const ptrdiff_t dstStrideInElements = mDstStride / sizeof(DstType);
const SrcType *srcRowStart = static_cast<const SrcType*>(mSrcStart);
DstType *dstRowStart = static_cast<DstType*>(mDstStart);
const SrcType* srcRowStart = static_cast<const SrcType*>(mSrcStart);
DstType* dstRowStart = static_cast<DstType*>(mDstStart);
// the loop performing the texture format conversion
for (size_t i = 0; i < mHeight; ++i) {
const SrcType *srcRowEnd = srcRowStart + mWidth * NumElementsPerSrcTexel;
const SrcType *srcPtr = srcRowStart;
DstType *dstPtr = dstRowStart;
const SrcType* srcRowEnd = srcRowStart + mWidth * NumElementsPerSrcTexel;
const SrcType* srcPtr = srcRowStart;
DstType* dstPtr = dstRowStart;
while (srcPtr != srcRowEnd) {
// convert a single texel. We proceed in 3 steps: unpack the source texel
// so the corresponding interchange format (e.g. unpack RGB565 to RGBA8),
@ -327,7 +327,7 @@ public:
bool
WebGLContext::ConvertImage(size_t width, size_t height, size_t srcStride, size_t dstStride,
const uint8_t* src, uint8_t *dst,
const uint8_t* src, uint8_t* dst,
WebGLTexelFormat srcFormat, bool srcPremultiplied,
WebGLTexelFormat dstFormat, bool dstPremultiplied,
size_t dstTexelSize)

Просмотреть файл

@ -5,27 +5,26 @@
#include "WebGLTexture.h"
#include <algorithm>
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/Scoped.h"
#include "ScopedGLHelpers.h"
#include "WebGLContext.h"
#include "WebGLContextUtils.h"
#include "WebGLTexelConversions.h"
#include <algorithm>
#include "mozilla/MathAlgorithms.h"
using namespace mozilla;
namespace mozilla {
JSObject*
WebGLTexture::WrapObject(JSContext* cx) {
return dom::WebGLTextureBinding::Wrap(cx, this);
}
WebGLTexture::WebGLTexture(WebGLContext* context, GLuint tex)
WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex)
: WebGLBindableName<TexTarget>(tex)
, WebGLContextBoundObject(context)
, WebGLContextBoundObject(webgl)
, mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR)
, mMagFilter(LOCAL_GL_LINEAR)
, mWrapS(LOCAL_GL_REPEAT)
@ -42,7 +41,8 @@ WebGLTexture::WebGLTexture(WebGLContext* context, GLuint tex)
}
void
WebGLTexture::Delete() {
WebGLTexture::Delete()
{
mImageInfos.Clear();
mContext->MakeContextCurrent();
mContext->gl->fDeleteTextures(1, &mGLName);
@ -50,27 +50,32 @@ WebGLTexture::Delete() {
}
size_t
WebGLTexture::ImageInfo::MemoryUsage() const {
WebGLTexture::ImageInfo::MemoryUsage() const
{
if (mImageDataStatus == WebGLImageDataStatus::NoImageData)
return 0;
size_t bitsPerTexel = GetBitsPerTexel(mEffectiveInternalFormat);
return size_t(mWidth) * size_t(mHeight) * size_t(mDepth) * bitsPerTexel / 8;
}
size_t
WebGLTexture::MemoryUsage() const {
WebGLTexture::MemoryUsage() const
{
if (IsDeleted())
return 0;
size_t result = 0;
for(size_t face = 0; face < mFacesCount; face++) {
for(size_t level = 0; level <= mMaxLevelWithCustomImages; level++)
for(size_t level = 0; level <= mMaxLevelWithCustomImages; level++) {
result += ImageInfoAtFace(face, level).MemoryUsage();
}
}
return result;
}
static inline size_t
MipmapLevelsForSize(const WebGLTexture::ImageInfo &info)
MipmapLevelsForSize(const WebGLTexture::ImageInfo& info)
{
GLsizei size = std::max(std::max(info.Width(), info.Height()), info.Depth());
@ -89,7 +94,8 @@ WebGLTexture::DoesMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImage
return false;
// We want a copy here so we can modify it temporarily.
ImageInfo expected = ImageInfoAt(texImageTarget, EffectiveBaseMipmapLevel());
ImageInfo expected = ImageInfoAt(texImageTarget,
EffectiveBaseMipmapLevel());
if (!expected.IsPositive())
return false;
@ -102,7 +108,9 @@ WebGLTexture::DoesMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImage
// Checks if custom images are all defined up to the highest level and
// have the expected dimensions.
for (size_t level = EffectiveBaseMipmapLevel(); level <= EffectiveMaxMipmapLevel(); ++level) {
for (size_t level = EffectiveBaseMipmapLevel();
level <= EffectiveMaxMipmapLevel(); ++level)
{
const ImageInfo& actual = ImageInfoAt(texImageTarget, level);
if (actual != expected)
return false;
@ -111,8 +119,8 @@ WebGLTexture::DoesMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImage
expected.mHeight = std::max(1, expected.mHeight / 2);
expected.mDepth = std::max(1, expected.mDepth / 2);
// if the current level has size 1x1, we can stop here: the spec doesn't seem to forbid the existence
// of extra useless levels.
// If the current level has size 1x1, we can stop here: The spec doesn't
// seem to forbid the existence of extra useless levels.
if (actual.mWidth == 1 &&
actual.mHeight == 1 &&
actual.mDepth == 1)
@ -125,61 +133,72 @@ WebGLTexture::DoesMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImage
}
void
WebGLTexture::Bind(TexTarget aTexTarget) {
// this function should only be called by bindTexture().
// it assumes that the GL context is already current.
WebGLTexture::Bind(TexTarget texTarget)
{
// This function should only be called by bindTexture(). It assumes that the
// GL context is already current.
bool firstTimeThisTextureIsBound = !HasEverBeenBound();
if (firstTimeThisTextureIsBound) {
BindTo(aTexTarget);
} else if (aTexTarget != Target()) {
mContext->ErrorInvalidOperation("bindTexture: this texture has already been bound to a different target");
// very important to return here before modifying texture state! This was the place when I lost a whole day figuring
// very strange 'invalid write' crashes.
BindTo(texTarget);
} else if (texTarget != Target()) {
mContext->ErrorInvalidOperation("bindTexture: This texture has already"
" been bound to a different target.");
// Very important to return here before modifying texture state! This
// was the place when I lost a whole day figuring very strange "invalid
// write" crashes.
return;
}
GLuint name = GLName();
mContext->gl->fBindTexture(aTexTarget.get(), name);
mContext->gl->fBindTexture(texTarget.get(), name);
if (firstTimeThisTextureIsBound) {
mFacesCount = (aTexTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? 6 : 1;
mFacesCount = (texTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? 6 : 1;
EnsureMaxLevelWithCustomImagesAtLeast(0);
SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
// thanks to the WebKit people for finding this out: GL_TEXTURE_WRAP_R is not
// present in GLES 2, but is present in GL and it seems as if for cube maps
// we need to set it to GL_CLAMP_TO_EDGE to get the expected GLES behavior.
if (mTarget == LOCAL_GL_TEXTURE_CUBE_MAP && !mContext->gl->IsGLES())
mContext->gl->fTexParameteri(aTexTarget.get(), LOCAL_GL_TEXTURE_WRAP_R, LOCAL_GL_CLAMP_TO_EDGE);
// Thanks to the WebKit people for finding this out: GL_TEXTURE_WRAP_R
// is not present in GLES 2, but is present in GL and it seems as if for
// cube maps we need to set it to GL_CLAMP_TO_EDGE to get the expected
// GLES behavior.
if (mTarget == LOCAL_GL_TEXTURE_CUBE_MAP && !mContext->gl->IsGLES()) {
mContext->gl->fTexParameteri(texTarget.get(),
LOCAL_GL_TEXTURE_WRAP_R,
LOCAL_GL_CLAMP_TO_EDGE);
}
}
}
void
WebGLTexture::SetImageInfo(TexImageTarget aTexImageTarget, GLint aLevel,
GLsizei aWidth, GLsizei aHeight, GLsizei aDepth,
TexInternalFormat aEffectiveInternalFormat, WebGLImageDataStatus aStatus)
WebGLTexture::SetImageInfo(TexImageTarget texImageTarget, GLint level,
GLsizei width, GLsizei height, GLsizei depth,
TexInternalFormat effectiveInternalFormat,
WebGLImageDataStatus status)
{
MOZ_ASSERT(aDepth == 1 || aTexImageTarget == LOCAL_GL_TEXTURE_3D);
MOZ_ASSERT(TexImageTargetToTexTarget(aTexImageTarget) == mTarget);
MOZ_ASSERT(depth == 1 || texImageTarget == LOCAL_GL_TEXTURE_3D);
MOZ_ASSERT(TexImageTargetToTexTarget(texImageTarget) == mTarget);
EnsureMaxLevelWithCustomImagesAtLeast(aLevel);
EnsureMaxLevelWithCustomImagesAtLeast(level);
ImageInfoAt(aTexImageTarget, aLevel) = ImageInfo(aWidth, aHeight, aDepth, aEffectiveInternalFormat, aStatus);
ImageInfoAt(texImageTarget, level) = ImageInfo(width, height, depth,
effectiveInternalFormat,
status);
if (aLevel > 0)
if (level > 0)
SetCustomMipmap();
// Invalidate framebuffer status cache
// Invalidate framebuffer status cache.
NotifyFBsStatusChanged();
SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
}
void
WebGLTexture::SetGeneratedMipmap() {
WebGLTexture::SetGeneratedMipmap()
{
if (!mHaveGeneratedMipmap) {
mHaveGeneratedMipmap = true;
SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
@ -187,33 +206,40 @@ WebGLTexture::SetGeneratedMipmap() {
}
void
WebGLTexture::SetCustomMipmap() {
WebGLTexture::SetCustomMipmap()
{
if (mHaveGeneratedMipmap) {
if (!IsMipmapRangeValid())
return;
// If we were in GeneratedMipmap mode and are now switching to CustomMipmap mode,
// we now need to compute all the mipmap image info.
// If we were in GeneratedMipmap mode and are now switching to
// CustomMipmap mode, we now need to compute all the mipmap image info.
ImageInfo imageInfo = ImageInfoAtFace(0, EffectiveBaseMipmapLevel());
NS_ASSERTION(mContext->IsWebGL2() || imageInfo.IsPowerOfTwo(),
"this texture is NPOT, so how could GenerateMipmap() ever accept it?");
MOZ_ASSERT(mContext->IsWebGL2() || imageInfo.IsPowerOfTwo(),
"This texture is NPOT, so how could GenerateMipmap() ever"
" accept it?");
size_t maxLevel = MipmapLevelsForSize(imageInfo);
EnsureMaxLevelWithCustomImagesAtLeast(EffectiveBaseMipmapLevel() + maxLevel);
size_t maxRelativeLevel = MipmapLevelsForSize(imageInfo);
size_t maxLevel = EffectiveBaseMipmapLevel() + maxRelativeLevel;
EnsureMaxLevelWithCustomImagesAtLeast(maxLevel);
for (size_t level = EffectiveBaseMipmapLevel() + 1; level <= EffectiveMaxMipmapLevel(); ++level) {
for (size_t level = EffectiveBaseMipmapLevel() + 1;
level <= EffectiveMaxMipmapLevel(); ++level)
{
imageInfo.mWidth = std::max(imageInfo.mWidth / 2, 1);
imageInfo.mHeight = std::max(imageInfo.mHeight / 2, 1);
imageInfo.mDepth = std::max(imageInfo.mDepth / 2, 1);
for(size_t face = 0; face < mFacesCount; ++face)
for(size_t face = 0; face < mFacesCount; ++face) {
ImageInfoAtFace(face, level) = imageInfo;
}
}
}
mHaveGeneratedMipmap = false;
}
bool
WebGLTexture::AreAllLevel0ImageInfosEqual() const {
WebGLTexture::AreAllLevel0ImageInfosEqual() const
{
for (size_t face = 1; face < mFacesCount; ++face) {
if (ImageInfoAtFace(face, 0) != ImageInfoAtFace(0, 0))
return false;
@ -222,28 +248,36 @@ WebGLTexture::AreAllLevel0ImageInfosEqual() const {
}
bool
WebGLTexture::IsMipmapComplete() const {
WebGLTexture::IsMipmapComplete() const
{
MOZ_ASSERT(mTarget == LOCAL_GL_TEXTURE_2D ||
mTarget == LOCAL_GL_TEXTURE_3D);
return DoesMipmapHaveAllLevelsConsistentlyDefined(LOCAL_GL_TEXTURE_2D);
}
bool
WebGLTexture::IsCubeComplete() const {
WebGLTexture::IsCubeComplete() const
{
MOZ_ASSERT(mTarget == LOCAL_GL_TEXTURE_CUBE_MAP);
const ImageInfo &first = ImageInfoAt(LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0);
const ImageInfo& first = ImageInfoAt(LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X,
0);
if (!first.IsPositive() || !first.IsSquare())
return false;
return AreAllLevel0ImageInfosEqual();
}
bool
WebGLTexture::IsMipmapCubeComplete() const {
if (!IsCubeComplete()) // in particular, this checks that this is a cube map
WebGLTexture::IsMipmapCubeComplete() const
{
// In particular, this checks that this is a cube map:
if (!IsCubeComplete())
return false;
for (int i = 0; i < 6; i++) {
const TexImageTarget face = TexImageTargetForTargetAndFace(LOCAL_GL_TEXTURE_CUBE_MAP, i);
const TexImageTarget face = TexImageTargetForTargetAndFace(LOCAL_GL_TEXTURE_CUBE_MAP,
i);
if (!DoesMipmapHaveAllLevelsConsistentlyDefined(face))
return false;
}
@ -262,10 +296,10 @@ WebGLTexture::IsMipmapRangeValid() const
}
WebGLTextureFakeBlackStatus
WebGLTexture::ResolvedFakeBlackStatus() {
if (MOZ_LIKELY(mFakeBlackStatus != WebGLTextureFakeBlackStatus::Unknown)) {
WebGLTexture::ResolvedFakeBlackStatus()
{
if (MOZ_LIKELY(mFakeBlackStatus != WebGLTextureFakeBlackStatus::Unknown))
return mFakeBlackStatus;
}
// Determine if the texture needs to be faked as a black texture.
// See 3.8.2 Shader Execution in the OpenGL ES 2.0.24 spec, and 3.8.13 in
@ -274,86 +308,106 @@ WebGLTexture::ResolvedFakeBlackStatus() {
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
return mFakeBlackStatus;
}
for (size_t face = 0; face < mFacesCount; ++face) {
if (ImageInfoAtFace(face, EffectiveBaseMipmapLevel()).mImageDataStatus == WebGLImageDataStatus::NoImageData) {
// In case of undefined texture image, we don't print any message because this is a very common
// and often legitimate case (asynchronous texture loading).
WebGLImageDataStatus status = ImageInfoAtFace(face, EffectiveBaseMipmapLevel()).mImageDataStatus;
if (status == WebGLImageDataStatus::NoImageData) {
// In case of undefined texture image, we don't print any message
// because this is a very common and often legitimate case
// (asynchronous texture loading).
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
return mFakeBlackStatus;
}
}
const char *msg_rendering_as_black
= "A texture is going to be rendered as if it were black, as per the OpenGL ES 2.0.24 spec section 3.8.2, "
"because it";
const char preamble[] = "A texture is going to be rendered as if it were"
" black, as per the OpenGL ES 2.0.24 spec section"
" 3.8.2, because it";
if (mTarget == LOCAL_GL_TEXTURE_2D ||
mTarget == LOCAL_GL_TEXTURE_3D)
{
int dim = mTarget == LOCAL_GL_TEXTURE_2D ? 2 : 3;
if (DoesMinFilterRequireMipmap())
{
if (DoesMinFilterRequireMipmap()) {
if (!IsMipmapComplete()) {
mContext->GenerateWarning
("%s is a %dD texture, with a minification filter requiring a mipmap, "
"and is not mipmap complete (as defined in section 3.7.10).", msg_rendering_as_black, dim);
mContext->GenerateWarning("%s is a %dD texture, with a"
" minification filter requiring a"
" mipmap, and is not mipmap complete"
" (as defined in section 3.7.10).",
preamble, dim);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
} else if (!mContext->IsWebGL2() && !ImageInfoBase().IsPowerOfTwo()) {
mContext->GenerateWarning
("%s is a %dD texture, with a minification filter requiring a mipmap, "
"and either its width or height is not a power of two.", msg_rendering_as_black);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
}
}
else // no mipmap required
} else if (!mContext->IsWebGL2() &&
!ImageInfoBase().IsPowerOfTwo())
{
mContext->GenerateWarning("%s is a %dD texture, with a"
" minification filter requiring a"
" mipmap, and either its width or"
" height is not a power of two.",
preamble, dim);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
}
} else {
// No mipmap required here.
if (!ImageInfoBase().IsPositive()) {
mContext->GenerateWarning
("%s is a %dD texture and its width or height is equal to zero.",
msg_rendering_as_black, dim);
mContext->GenerateWarning("%s is a %dD texture and its width or"
" height is equal to zero.",
preamble, dim);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
} else if (!AreBothWrapModesClampToEdge() && !mContext->IsWebGL2() && !ImageInfoBase().IsPowerOfTwo()) {
mContext->GenerateWarning
("%s is a %dD texture, with a minification filter not requiring a mipmap, "
"with its width or height not a power of two, and with a wrap mode "
"different from CLAMP_TO_EDGE.", msg_rendering_as_black, dim);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
}
}
}
else // cube map
} else if (!AreBothWrapModesClampToEdge() &&
!mContext->IsWebGL2() &&
!ImageInfoBase().IsPowerOfTwo())
{
mContext->GenerateWarning("%s is a %dD texture, with a"
" minification filter not requiring a"
" mipmap, with its width or height"
" not a power of two, and with a wrap"
" mode different from CLAMP_TO_EDGE.",
preamble, dim);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
}
}
} else {
// Cube map
bool legalImageSize = true;
if (!mContext->IsWebGL2()) {
for (size_t face = 0; face < mFacesCount; ++face)
legalImageSize &= ImageInfoAtFace(face, 0).IsPowerOfTwo();
}
if (DoesMinFilterRequireMipmap())
{
if (DoesMinFilterRequireMipmap()) {
if (!IsMipmapCubeComplete()) {
mContext->GenerateWarning("%s is a cube map texture, with a minification filter requiring a mipmap, "
"and is not mipmap cube complete (as defined in section 3.7.10).",
msg_rendering_as_black);
mContext->GenerateWarning("%s is a cube map texture, with a"
" minification filter requiring a"
" mipmap, and is not mipmap cube"
" complete (as defined in section"
" 3.7.10).", preamble);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
} else if (!legalImageSize) {
mContext->GenerateWarning("%s is a cube map texture, with a minification filter requiring a mipmap, "
"and either the width or the height of some level 0 image is not a power of two.",
msg_rendering_as_black);
mContext->GenerateWarning("%s is a cube map texture, with a"
" minification filter requiring a"
" mipmap, and either the width or the"
" height of some level 0 image is not"
" a power of two.", preamble);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
}
}
else // no mipmap required
{
if (!IsCubeComplete()) {
mContext->GenerateWarning("%s is a cube map texture, with a minification filter not requiring a mipmap, "
"and is not cube complete (as defined in section 3.7.10).",
msg_rendering_as_black);
mContext->GenerateWarning("%s is a cube map texture, with a"
" minification filter not requiring a"
" mipmap, and is not cube complete"
" (as defined in section 3.7.10).",
preamble);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
} else if (!AreBothWrapModesClampToEdge() && !legalImageSize) {
mContext->GenerateWarning("%s is a cube map texture, with a minification filter not requiring a mipmap, "
"with some level 0 image having width or height not a power of two, and with a wrap mode "
"different from CLAMP_TO_EDGE.", msg_rendering_as_black);
mContext->GenerateWarning("%s is a cube map texture, with a"
" minification filter not requiring a"
" mipmap, with some level 0 image"
" having width or height not a power"
" of two, and with a wrap mode"
" different from CLAMP_TO_EDGE.",
preamble);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
}
}
@ -361,46 +415,41 @@ WebGLTexture::ResolvedFakeBlackStatus() {
TexType type = TypeFromInternalFormat(ImageInfoBase().mEffectiveInternalFormat);
const char* badFormatText = nullptr;
const char* extText = nullptr;
if (type == LOCAL_GL_FLOAT &&
!Context()->IsExtensionEnabled(WebGLExtensionID::OES_texture_float_linear))
{
if (mMinFilter == LOCAL_GL_LINEAR ||
mMinFilter == LOCAL_GL_LINEAR_MIPMAP_LINEAR ||
mMinFilter == LOCAL_GL_LINEAR_MIPMAP_NEAREST ||
mMinFilter == LOCAL_GL_NEAREST_MIPMAP_LINEAR)
{
mContext->GenerateWarning("%s is a texture with a linear minification filter, "
"which is not compatible with gl.FLOAT by default. "
"Try enabling the OES_texture_float_linear extension if supported.", msg_rendering_as_black);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
}
else if (mMagFilter == LOCAL_GL_LINEAR)
{
mContext->GenerateWarning("%s is a texture with a linear magnification filter, "
"which is not compatible with gl.FLOAT by default. "
"Try enabling the OES_texture_float_linear extension if supported.", msg_rendering_as_black);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
}
badFormatText = "FLOAT";
extText = "OES_texture_float_linear";
} else if (type == LOCAL_GL_HALF_FLOAT &&
!Context()->IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float_linear))
{
badFormatText = "HALF_FLOAT";
extText = "OES_texture_half_float_linear";
}
const char* badFilterText = nullptr;
if (badFormatText) {
if (mMinFilter == LOCAL_GL_LINEAR ||
mMinFilter == LOCAL_GL_LINEAR_MIPMAP_LINEAR ||
mMinFilter == LOCAL_GL_LINEAR_MIPMAP_NEAREST ||
mMinFilter == LOCAL_GL_NEAREST_MIPMAP_LINEAR)
{
mContext->GenerateWarning("%s is a texture with a linear minification filter, "
"which is not compatible with gl.HALF_FLOAT by default. "
"Try enabling the OES_texture_half_float_linear extension if supported.", msg_rendering_as_black);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
badFilterText = "minification";
} else if (mMagFilter == LOCAL_GL_LINEAR) {
badFilterText = "magnification";
}
else if (mMagFilter == LOCAL_GL_LINEAR)
{
mContext->GenerateWarning("%s is a texture with a linear magnification filter, "
"which is not compatible with gl.HALF_FLOAT by default. "
"Try enabling the OES_texture_half_float_linear extension if supported.", msg_rendering_as_black);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
}
if (badFilterText) {
mContext->GenerateWarning("%s is a texture with a linear %s filter,"
" which is not compatible with format %s by"
" default. Try enabling the %s extension, if"
" supported.", preamble, badFilterText,
badFormatText, extText);
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
}
// We have exhausted all cases of incomplete textures, where we would need opaque black.
@ -408,7 +457,8 @@ WebGLTexture::ResolvedFakeBlackStatus() {
bool hasUninitializedImageData = false;
for (size_t level = 0; level <= mMaxLevelWithCustomImages; ++level) {
for (size_t face = 0; face < mFacesCount; ++face) {
hasUninitializedImageData |= (ImageInfoAtFace(face, level).mImageDataStatus == WebGLImageDataStatus::UninitializedImageData);
bool cur = (ImageInfoAtFace(face, level).mImageDataStatus == WebGLImageDataStatus::UninitializedImageData);
hasUninitializedImageData |= cur;
}
}
@ -427,16 +477,22 @@ WebGLTexture::ResolvedFakeBlackStatus() {
}
if (hasAnyInitializedImageData) {
// The texture contains some initialized image data, and some uninitialized image data.
// In this case, we have no choice but to initialize all image data now. Fortunately,
// in this case we know that we can't be dealing with a depth texture per WEBGL_depth_texture
// and ANGLE_depth_texture (which allow only one image per texture) so we can assume that
// glTexImage2D is able to upload data to images.
for (size_t level = 0; level <= mMaxLevelWithCustomImages; ++level) {
/* The texture contains some initialized image data, and some
* uninitialized image data. In this case, we have no choice but to
* initialize all image data now. Fortunately, in this case we know
* that we can't be dealing with a depth texture per
* WEBGL_depth_texture and ANGLE_depth_texture (which allow only one
* image per texture) so we can assume that glTexImage2D is able to
* upload data to images.
*/
for (size_t level = 0; level <= mMaxLevelWithCustomImages; ++level)
{
for (size_t face = 0; face < mFacesCount; ++face) {
TexImageTarget imageTarget = TexImageTargetForTargetAndFace(mTarget, face);
TexImageTarget imageTarget = TexImageTargetForTargetAndFace(mTarget,
face);
const ImageInfo& imageInfo = ImageInfoAt(imageTarget, level);
if (imageInfo.mImageDataStatus == WebGLImageDataStatus::UninitializedImageData) {
if (imageInfo.mImageDataStatus == WebGLImageDataStatus::UninitializedImageData)
{
EnsureNoUninitializedImageData(imageTarget, level);
}
}
@ -459,11 +515,10 @@ WebGLTexture::ResolvedFakeBlackStatus() {
return mFakeBlackStatus;
}
static bool
ClearByMask(WebGLContext* context, GLbitfield mask)
ClearByMask(WebGLContext* webgl, GLbitfield mask)
{
gl::GLContext* gl = context->GL();
gl::GLContext* gl = webgl->GL();
MOZ_ASSERT(gl->IsCurrent());
GLenum status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
@ -475,20 +530,20 @@ ClearByMask(WebGLContext* context, GLbitfield mask)
colorAttachmentsMask[0] = true;
}
context->ForceClearFramebufferWithDefaultValues(mask, colorAttachmentsMask);
webgl->ForceClearFramebufferWithDefaultValues(mask, colorAttachmentsMask);
return true;
}
// `mask` from glClear.
static bool
ClearWithTempFB(WebGLContext* context, GLuint tex,
ClearWithTempFB(WebGLContext* webgl, GLuint tex,
TexImageTarget texImageTarget, GLint level,
TexInternalFormat baseInternalFormat,
GLsizei width, GLsizei height)
{
MOZ_ASSERT(texImageTarget == LOCAL_GL_TEXTURE_2D);
gl::GLContext* gl = context->GL();
gl::GLContext* gl = webgl->GL();
MOZ_ASSERT(gl->IsCurrent());
gl::ScopedFramebuffer fb(gl);
@ -528,7 +583,7 @@ ClearWithTempFB(WebGLContext* context, GLuint tex,
}
MOZ_ASSERT(mask);
if (ClearByMask(context, mask))
if (ClearByMask(webgl, mask))
return true;
// Failed to simply build an FB from the tex, but maybe it needs a
@ -552,12 +607,13 @@ ClearWithTempFB(WebGLContext* context, GLuint tex,
mask |= LOCAL_GL_COLOR_BUFFER_BIT;
// Last chance!
return ClearByMask(context, mask);
return ClearByMask(webgl, mask);
}
void
WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget, GLint level)
WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget,
GLint level)
{
const ImageInfo& imageInfo = ImageInfoAt(imageTarget, level);
if (!imageInfo.HasUninitializedImageData())
@ -565,15 +621,14 @@ WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget, GLint l
mContext->MakeContextCurrent();
// Try to clear with glCLear.
// Try to clear with glClear.
if (imageTarget == LOCAL_GL_TEXTURE_2D) {
bool cleared = ClearWithTempFB(mContext, GLName(),
imageTarget, level,
bool cleared = ClearWithTempFB(mContext, GLName(), imageTarget, level,
imageInfo.mEffectiveInternalFormat,
imageInfo.mHeight, imageInfo.mWidth);
if (cleared) {
SetImageDataStatus(imageTarget, level, WebGLImageDataStatus::InitializedImageData);
SetImageDataStatus(imageTarget, level,
WebGLImageDataStatus::InitializedImageData);
return;
}
}
@ -582,8 +637,9 @@ WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget, GLint l
gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget.get());
size_t bitspertexel = GetBitsPerTexel(imageInfo.mEffectiveInternalFormat);
MOZ_ASSERT((bitspertexel % 8) == 0); // that would only happen for compressed images, which
// cannot use deferred initialization.
MOZ_ASSERT((bitspertexel % 8) == 0); // That would only happen for
// compressed images, which cannot use
// deferred initialization.
size_t bytespertexel = bitspertexel / 8;
CheckedUint32 checked_byteLength
= WebGLContext::GetImageSize(
@ -592,42 +648,48 @@ WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget, GLint l
imageInfo.mDepth,
bytespertexel,
mContext->mPixelStoreUnpackAlignment);
MOZ_ASSERT(checked_byteLength.isValid()); // should have been checked earlier
MOZ_ASSERT(checked_byteLength.isValid()); // Should have been checked
// earlier.
UniquePtr<uint8_t> zeros((uint8_t*)moz_xcalloc(1, checked_byteLength.value())); // Infallible for now.
// Infallible for now.
UniquePtr<uint8_t> zeros((uint8_t*)moz_xcalloc(1,
checked_byteLength.value()));
gl::GLContext* gl = mContext->gl;
GLenum driverInternalFormat = LOCAL_GL_NONE;
GLenum driverFormat = LOCAL_GL_NONE;
GLenum driverType = LOCAL_GL_NONE;
DriverFormatsFromEffectiveInternalFormat(gl, imageInfo.mEffectiveInternalFormat,
&driverInternalFormat, &driverFormat, &driverType);
DriverFormatsFromEffectiveInternalFormat(gl,
imageInfo.mEffectiveInternalFormat,
&driverInternalFormat,
&driverFormat, &driverType);
mContext->GetAndFlushUnderlyingGLErrors();
if (imageTarget == LOCAL_GL_TEXTURE_3D) {
MOZ_ASSERT(mImmutable, "Shouldn't be possible to have non-immutable-format 3D textures in WebGL");
gl->fTexSubImage3D(imageTarget.get(), level, 0, 0, 0,
imageInfo.mWidth, imageInfo.mHeight, imageInfo.mDepth,
driverFormat, driverType,
zeros.get());
MOZ_ASSERT(mImmutable,
"Shouldn't be possible to have non-immutable-format 3D"
" textures in WebGL");
gl->fTexSubImage3D(imageTarget.get(), level, 0, 0, 0, imageInfo.mWidth,
imageInfo.mHeight, imageInfo.mDepth, driverFormat,
driverType, zeros.get());
} else {
if (mImmutable) {
gl->fTexSubImage2D(imageTarget.get(), level, 0, 0,
imageInfo.mWidth, imageInfo.mHeight,
driverFormat, driverType,
gl->fTexSubImage2D(imageTarget.get(), level, 0, 0, imageInfo.mWidth,
imageInfo.mHeight, driverFormat, driverType,
zeros.get());
} else {
gl->fTexImage2D(imageTarget.get(), level, driverInternalFormat,
imageInfo.mWidth, imageInfo.mHeight,
0, driverFormat, driverType,
zeros.get());
imageInfo.mWidth, imageInfo.mHeight, 0,
driverFormat, driverType, zeros.get());
}
}
GLenum error = mContext->GetAndFlushUnderlyingGLErrors();
if (error) {
// Should only be OUT_OF_MEMORY. Anyway, there's no good way to recover from this here.
// Should only be OUT_OF_MEMORY. Anyway, there's no good way to recover
// from this here.
printf_stderr("Error: 0x%4x\n", error);
MOZ_CRASH(); // errors on texture upload have been related to video memory exposure in the past.
MOZ_CRASH(); // Errors on texture upload have been related to video
// memory exposure in the past.
}
SetImageDataStatus(imageTarget, level, WebGLImageDataStatus::InitializedImageData);
@ -644,3 +706,5 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTexture)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLTexture, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLTexture, Release)
} // namespace mozilla

Просмотреть файл

@ -3,27 +3,27 @@
* 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 WEBGLTEXTURE_H_
#define WEBGLTEXTURE_H_
#ifndef WEBGL_TEXTURE_H_
#define WEBGL_TEXTURE_H_
#include <algorithm>
#include "mozilla/Assertions.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/LinkedList.h"
#include "nsAlgorithm.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLFramebufferAttachable.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
#include "nsWrapperCache.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/LinkedList.h"
#include "mozilla/Assertions.h"
#include <algorithm>
#include "nsAlgorithm.h"
namespace mozilla {
// Zero is not an integer power of two.
inline bool is_pot_assuming_nonnegative(GLsizei x)
inline bool
IsPOTAssumingNonnegative(GLsizei x)
{
MOZ_ASSERT(x >= 0);
return x && (x & (x-1)) == 0;
}
@ -38,15 +38,15 @@ class WebGLTexture MOZ_FINAL
, public WebGLFramebufferAttachable
{
public:
explicit WebGLTexture(WebGLContext* aContext, GLuint tex);
explicit WebGLTexture(WebGLContext* webgl, GLuint tex);
void Delete();
WebGLContext *GetParentObject() const {
WebGLContext* GetParentObject() const {
return Context();
}
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTexture)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTexture)
@ -59,11 +59,10 @@ protected:
friend class WebGLContext;
friend class WebGLFramebuffer;
// we store information about the various images that are part of
// this texture (cubemap faces, mipmap levels)
// We store information about the various images that are part of this
// texture. (cubemap faces, mipmap levels)
public:
class ImageInfo
: public WebGLRectangleObject
{
@ -74,9 +73,7 @@ public:
, mImageDataStatus(WebGLImageDataStatus::NoImageData)
{}
ImageInfo(GLsizei width,
GLsizei height,
GLsizei depth,
ImageInfo(GLsizei width, GLsizei height, GLsizei depth,
TexInternalFormat effectiveInternalFormat,
WebGLImageDataStatus status)
: WebGLRectangleObject(width, height)
@ -105,27 +102,28 @@ public:
return mWidth > 0 && mHeight > 0 && mDepth > 0;
}
bool IsPowerOfTwo() const {
return is_pot_assuming_nonnegative(mWidth) &&
is_pot_assuming_nonnegative(mHeight); // negative sizes should never happen (caught in texImage2D...)
MOZ_ASSERT(mWidth >= 0);
MOZ_ASSERT(mHeight >= 0);
return IsPOTAssumingNonnegative(mWidth) &&
IsPOTAssumingNonnegative(mHeight);
}
bool HasUninitializedImageData() const {
return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData;
}
size_t MemoryUsage() const;
TexInternalFormat EffectiveInternalFormat() const { return mEffectiveInternalFormat; }
TexInternalFormat EffectiveInternalFormat() const {
return mEffectiveInternalFormat;
}
GLsizei Depth() const { return mDepth; }
protected:
/*
* This is the "effective internal format" of the texture,
* an official OpenGL spec concept, see
* OpenGL ES 3.0.3 spec, section 3.8.3, page 126 and below.
*/
// This is the "effective internal format" of the texture, an official
// OpenGL spec concept, see OpenGL ES 3.0.3 spec, section 3.8.3, page
// 126 and below.
TexInternalFormat mEffectiveInternalFormat;
/*
* Used only for 3D textures.
/* Used only for 3D textures.
* Note that mWidth and mHeight are inherited from WebGLRectangleObject.
* It's a pity to store a useless mDepth on non-3D texture images, but
* the size of GLsizei is negligible compared to the typical size of a texture image.
@ -148,9 +146,12 @@ private:
}
ImageInfo& ImageInfoAtFace(size_t face, GLint level) {
MOZ_ASSERT(face < mFacesCount, "wrong face index, must be 0 for TEXTURE_2D or TEXTURE_3D, and at most 5 for cube maps");
MOZ_ASSERT(face < mFacesCount,
"Wrong face index, must be 0 for TEXTURE_2D or TEXTURE_3D,"
" and at most 5 for cube maps.");
// no need to check level as a wrong value would be caught by ElementAt().
// No need to check level as a wrong value would be caught by
// ElementAt().
return mImageInfos.ElementAt(level * mFacesCount + face);
}
@ -166,7 +167,8 @@ public:
return ImageInfoAtFace(face, level);
}
const ImageInfo& ImageInfoAt(TexImageTarget imageTarget, GLint level) const {
const ImageInfo& ImageInfoAt(TexImageTarget imageTarget, GLint level) const
{
return const_cast<WebGLTexture*>(this)->ImageInfoAt(imageTarget, level);
}
@ -188,22 +190,24 @@ public:
size_t MemoryUsage() const;
void SetImageDataStatus(TexImageTarget imageTarget, GLint level, WebGLImageDataStatus newStatus) {
void SetImageDataStatus(TexImageTarget imageTarget, GLint level,
WebGLImageDataStatus newStatus)
{
MOZ_ASSERT(HasImageInfoAt(imageTarget, level));
ImageInfo& imageInfo = ImageInfoAt(imageTarget, level);
// there is no way to go from having image data to not having any
// There is no way to go from having image data to not having any.
MOZ_ASSERT(newStatus != WebGLImageDataStatus::NoImageData ||
imageInfo.mImageDataStatus == WebGLImageDataStatus::NoImageData);
if (imageInfo.mImageDataStatus != newStatus) {
if (imageInfo.mImageDataStatus != newStatus)
SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
}
imageInfo.mImageDataStatus = newStatus;
}
void EnsureNoUninitializedImageData(TexImageTarget imageTarget, GLint level);
protected:
TexMinFilter mMinFilter;
TexMagFilter mMagFilter;
TexWrap mWrapS, mWrapT;
@ -211,59 +215,63 @@ protected:
size_t mFacesCount, mMaxLevelWithCustomImages;
nsTArray<ImageInfo> mImageInfos;
bool mHaveGeneratedMipmap; // set by generateMipmap
bool mImmutable; // set by texStorage*
bool mHaveGeneratedMipmap; // Set by generateMipmap
bool mImmutable; // Set by texStorage*
size_t mBaseMipmapLevel; // set by texParameter (defaults to 0)
size_t mMaxMipmapLevel; // set by texParameter (defaults to 1000)
size_t mBaseMipmapLevel; // Set by texParameter (defaults to 0)
size_t mMaxMipmapLevel; // Set by texParameter (defaults to 1000)
WebGLTextureFakeBlackStatus mFakeBlackStatus;
void EnsureMaxLevelWithCustomImagesAtLeast(size_t aMaxLevelWithCustomImages) {
mMaxLevelWithCustomImages = std::max(mMaxLevelWithCustomImages, aMaxLevelWithCustomImages);
void EnsureMaxLevelWithCustomImagesAtLeast(size_t maxLevelWithCustomImages) {
mMaxLevelWithCustomImages = std::max(mMaxLevelWithCustomImages,
maxLevelWithCustomImages);
mImageInfos.EnsureLengthAtLeast((mMaxLevelWithCustomImages + 1) * mFacesCount);
}
bool CheckFloatTextureFilterParams() const {
// Without OES_texture_float_linear, only NEAREST and NEAREST_MIMPAMP_NEAREST are supported
return (mMagFilter == LOCAL_GL_NEAREST) &&
(mMinFilter == LOCAL_GL_NEAREST || mMinFilter == LOCAL_GL_NEAREST_MIPMAP_NEAREST);
// Without OES_texture_float_linear, only NEAREST and
// NEAREST_MIMPAMP_NEAREST are supported.
return mMagFilter == LOCAL_GL_NEAREST &&
(mMinFilter == LOCAL_GL_NEAREST ||
mMinFilter == LOCAL_GL_NEAREST_MIPMAP_NEAREST);
}
bool AreBothWrapModesClampToEdge() const {
return mWrapS == LOCAL_GL_CLAMP_TO_EDGE && mWrapT == LOCAL_GL_CLAMP_TO_EDGE;
return mWrapS == LOCAL_GL_CLAMP_TO_EDGE &&
mWrapT == LOCAL_GL_CLAMP_TO_EDGE;
}
bool DoesMipmapHaveAllLevelsConsistentlyDefined(TexImageTarget texImageTarget) const;
public:
void Bind(TexTarget texTarget);
void Bind(TexTarget aTexTarget);
void SetImageInfo(TexImageTarget target, GLint level, GLsizei width,
GLsizei height, GLsizei depth, TexInternalFormat format,
WebGLImageDataStatus status);
void SetImageInfo(TexImageTarget aTarget, GLint aLevel,
GLsizei aWidth, GLsizei aHeight, GLsizei aDepth,
TexInternalFormat aFormat, WebGLImageDataStatus aStatus);
void SetMinFilter(TexMinFilter aMinFilter) {
mMinFilter = aMinFilter;
void SetMinFilter(TexMinFilter minFilter) {
mMinFilter = minFilter;
SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
}
void SetMagFilter(TexMagFilter aMagFilter) {
mMagFilter = aMagFilter;
void SetMagFilter(TexMagFilter magFilter) {
mMagFilter = magFilter;
SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
}
void SetWrapS(TexWrap aWrapS) {
mWrapS = aWrapS;
void SetWrapS(TexWrap wrapS) {
mWrapS = wrapS;
SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
}
void SetWrapT(TexWrap aWrapT) {
mWrapT = aWrapT;
void SetWrapT(TexWrap wrapT) {
mWrapT = wrapT;
SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
}
TexMinFilter MinFilter() const { return mMinFilter; }
bool DoesMinFilterRequireMipmap() const {
return !(mMinFilter == LOCAL_GL_NEAREST || mMinFilter == LOCAL_GL_LINEAR);
return !(mMinFilter == LOCAL_GL_NEAREST ||
mMinFilter == LOCAL_GL_LINEAR);
}
void SetGeneratedMipmap();
@ -298,8 +306,10 @@ public:
return mBaseMipmapLevel;
}
size_t EffectiveMaxMipmapLevel() const {
if (IsImmutable())
return mozilla::clamped(mMaxMipmapLevel, EffectiveBaseMipmapLevel(), mMaxLevelWithCustomImages);
if (IsImmutable()) {
return mozilla::clamped(mMaxMipmapLevel, EffectiveBaseMipmapLevel(),
mMaxLevelWithCustomImages);
}
return std::min(mMaxMipmapLevel, mMaxLevelWithCustomImages);
}
bool IsMipmapRangeValid() const;
@ -329,4 +339,4 @@ TexImageTargetForTargetAndFace(TexTarget target, size_t face)
} // namespace mozilla
#endif
#endif // WEBGL_TEXTURE_H_

Просмотреть файл

@ -3,18 +3,17 @@
* 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 "WebGL2Context.h"
#include "WebGLTransformFeedback.h"
#include "GLContext.h"
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
#include "WebGL2Context.h"
using namespace mozilla;
namespace mozilla {
WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* context)
WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* webgl)
: WebGLBindableName<GLenum>(0)
, WebGLContextBoundObject(context)
, WebGLContextBoundObject(webgl)
{
MOZ_CRASH("Not Implemented.");
}
@ -45,3 +44,5 @@ WebGLTransformFeedback::WrapObject(JSContext* cx)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTransformFeedback)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLTransformFeedback, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLTransformFeedback, Release)
} // namespace mozilla

Просмотреть файл

@ -3,15 +3,13 @@
* 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 WEBGLTRANSFORMFEEDBACK_H_
#define WEBGLTRANSFORMFEEDBACK_H_
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "nsWrapperCache.h"
#ifndef WEBGL_TRANSFORM_FEEDBACK_H_
#define WEBGL_TRANSFORM_FEEDBACK_H_
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
namespace mozilla {
@ -25,24 +23,19 @@ class WebGLTransformFeedback MOZ_FINAL
friend class WebGLContext;
public:
explicit WebGLTransformFeedback(WebGLContext* aContext);
explicit WebGLTransformFeedback(WebGLContext* webgl);
void Delete();
WebGLContext* GetParentObject() const;
// -------------------------------------------------------------------------
// IMPLEMENT NS
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTransformFeedback)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTransformFeedback)
private:
~WebGLTransformFeedback();
};
}
} // namespace mozilla
#endif // !WEBGLTRANSFORMFEEDBACK_H_
#endif // WEBGL_TRANSFORM_FEEDBACK_H_

Просмотреть файл

@ -3,21 +3,25 @@
* 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 "WebGLUniformLocation.h"
#include "WebGLShader.h"
#include "WebGLProgram.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
using namespace mozilla;
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLContext.h"
#include "WebGLProgram.h"
#include "WebGLShader.h"
namespace mozilla {
JSObject*
WebGLUniformLocation::WrapObject(JSContext *cx)
WebGLUniformLocation::WrapObject(JSContext* cx)
{
return dom::WebGLUniformLocationBinding::Wrap(cx, this);
}
WebGLUniformLocation::WebGLUniformLocation(WebGLContext *context, WebGLProgram *program, GLint location, const WebGLUniformInfo& info)
WebGLUniformLocation::WebGLUniformLocation(WebGLContext* context,
WebGLProgram* program,
GLint location,
const WebGLUniformInfo& info)
: WebGLContextBoundObject(context)
, mProgram(program)
, mProgramGeneration(program->Generation())
@ -31,3 +35,5 @@ NS_IMPL_CYCLE_COLLECTION(WebGLUniformLocation, mProgram)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLUniformLocation, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLUniformLocation, Release)
} // namespace mozilla

Просмотреть файл

@ -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 WEBGLUNIFORMLOCATION_H_
#define WEBGLUNIFORMLOCATION_H_
#ifndef WEBGL_UNIFORM_LOCATION_H_
#define WEBGL_UNIFORM_LOCATION_H_
#include "WebGLObjectModel.h"
#include "WebGLUniformInfo.h"
@ -17,27 +17,27 @@ class WebGLUniformLocation MOZ_FINAL
: public WebGLContextBoundObject
{
public:
WebGLUniformLocation(WebGLContext *context, WebGLProgram *program, GLint location, const WebGLUniformInfo& info);
WebGLUniformLocation(WebGLContext* context, WebGLProgram* program,
GLint location, const WebGLUniformInfo& info);
// needed for certain helper functions like ValidateObject.
// WebGLUniformLocation's can't be 'Deleted' in the WebGL sense.
bool IsDeleted() const { return false; }
const WebGLUniformInfo &Info() const { return mInfo; }
const WebGLUniformInfo& Info() const { return mInfo; }
WebGLProgram *Program() const { return mProgram; }
WebGLProgram* Program() const { return mProgram; }
GLint Location() const { return mLocation; }
uint32_t ProgramGeneration() const { return mProgramGeneration; }
int ElementSize() const { return mElementSize; }
JSObject* WrapObject(JSContext *cx);
JSObject* WrapObject(JSContext* cx);
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLUniformLocation)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(WebGLUniformLocation)
protected:
~WebGLUniformLocation() {
}
~WebGLUniformLocation() { }
// nsRefPtr, not WebGLRefPtr, so that we don't prevent the program from being explicitly deleted.
// we just want to avoid having a dangling pointer.
@ -52,4 +52,4 @@ protected:
} // namespace mozilla
#endif
#endif // WEBGL_UNIFORM_LOCATION_H_

Просмотреть файл

@ -24,8 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef WEBGLVALIDATESTRINGS_H_
#define WEBGLVALIDATESTRINGS_H_
#ifndef WEBGL_VALIDATE_STRINGS_H_
#define WEBGL_VALIDATE_STRINGS_H_
#include "WebGLContext.h"
@ -45,7 +45,8 @@ namespace mozilla {
return true;
}
// Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
// Horizontal tab, line feed, vertical tab, form feed, carriage return
// are also valid.
if (c >= 9 && c <= 13) {
return true;
}
@ -58,13 +59,13 @@ namespace mozilla {
// implementations not expecting characters outside the GLSL ES set.
class StripComments {
public:
explicit StripComments(const nsAString& aStr)
explicit StripComments(const nsAString& str)
: m_parseState(BeginningOfLine)
, m_end(aStr.EndReading())
, m_current(aStr.BeginReading())
, m_end(str.EndReading())
, m_current(str.BeginReading())
, m_position(0)
{
m_result.SetLength(aStr.Length());
m_result.SetLength(str.Length());
parse();
}
@ -246,6 +247,6 @@ namespace mozilla {
/****** END CODE TAKEN FROM WEBKIT ******/
} // end namespace mozilla
} // namespace mozilla
#endif // WEBGLVALIDATESTRINGS_H_
#endif // WEBGL_VALIDATE_STRINGS_H_

Просмотреть файл

@ -5,38 +5,38 @@
#include "WebGLVertexArray.h"
#include "WebGLContext.h"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "WebGLBuffer.h"
#include "WebGLContext.h"
#include "WebGLVertexArrayGL.h"
#include "WebGLVertexArrayFake.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "GLContext.h"
using namespace mozilla;
namespace mozilla {
JSObject*
WebGLVertexArray::WrapObject(JSContext *cx) {
WebGLVertexArray::WrapObject(JSContext* cx)
{
return dom::WebGLVertexArrayBinding::Wrap(cx, this);
}
WebGLVertexArray::WebGLVertexArray(WebGLContext* context)
WebGLVertexArray::WebGLVertexArray(WebGLContext* webgl)
: WebGLBindable<VAOBinding>()
, WebGLContextBoundObject(context)
, WebGLContextBoundObject(webgl)
, mGLName(0)
{
context->mVertexArrays.insertBack(this);
mContext->mVertexArrays.insertBack(this);
}
WebGLVertexArray*
WebGLVertexArray::Create(WebGLContext* context)
WebGLVertexArray::Create(WebGLContext* webgl)
{
WebGLVertexArray* array;
if (context->gl->IsSupported(gl::GLFeature::vertex_array_object)) {
array = new WebGLVertexArrayGL(context);
if (webgl->gl->IsSupported(gl::GLFeature::vertex_array_object)) {
array = new WebGLVertexArrayGL(webgl);
} else {
array = new WebGLVertexArrayFake(context);
array = new WebGLVertexArrayFake(webgl);
}
return array;
}
@ -66,3 +66,5 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLVertexArray,
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLVertexArray, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLVertexArray, Release)
} // namespace mozilla

Просмотреть файл

@ -3,18 +3,16 @@
* 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 WEBGLVERTEXARRAY_H_
#define WEBGLVERTEXARRAY_H_
#include "WebGLBindableName.h"
#include "WebGLObjectModel.h"
#include "WebGLBuffer.h"
#include "WebGLVertexAttribData.h"
#include "WebGLStrongTypes.h"
#include "nsWrapperCache.h"
#ifndef WEBGL_VERTEX_ARRAY_H_
#define WEBGL_VERTEX_ARRAY_H_
#include "mozilla/LinkedList.h"
#include "nsWrapperCache.h"
#include "WebGLBindableName.h"
#include "WebGLBuffer.h"
#include "WebGLObjectModel.h"
#include "WebGLStrongTypes.h"
#include "WebGLVertexAttribData.h"
namespace mozilla {
@ -27,74 +25,57 @@ class WebGLVertexArray
, public LinkedListElement<WebGLVertexArray>
, public WebGLContextBoundObject
{
// -----------------------------------------------------------------------------
// PUBLIC
public:
static WebGLVertexArray* Create(WebGLContext* context);
static WebGLVertexArray* Create(WebGLContext* webgl);
void BindVertexArray() {
/* Bind to dummy value to signal that this vertex array has
ever been bound */
// Bind to dummy value to signal that this vertex array has ever been
// bound.
BindTo(LOCAL_GL_VERTEX_ARRAY_BINDING);
BindVertexArrayImpl();
};
virtual void GenVertexArray() = 0;
virtual void BindVertexArrayImpl() = 0;
// -------------------------------------------------------------------------
// IMPLEMENT PARENT CLASSES
void Delete();
virtual void DeleteImpl() = 0;
void EnsureAttrib(GLuint index);
bool HasAttrib(GLuint index) const {
return index < mAttribs.Length();
}
bool IsAttribArrayEnabled(GLuint index) const {
return HasAttrib(index) && mAttribs[index].enabled;
}
// Implement parent classes:
void Delete();
WebGLContext* GetParentObject() const {
return Context();
}
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLVertexArray)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLVertexArray)
// -------------------------------------------------------------------------
// MEMBER FUNCTIONS
GLuint GLName() const { return mGLName; }
void EnsureAttrib(GLuint index);
bool HasAttrib(GLuint index) {
return index < mAttribs.Length();
}
bool IsAttribArrayEnabled(GLuint index) {
return HasAttrib(index) && mAttribs[index].enabled;
}
// -----------------------------------------------------------------------------
// PROTECTED
protected:
explicit WebGLVertexArray(WebGLContext* aContext);
explicit WebGLVertexArray(WebGLContext* webgl);
virtual ~WebGLVertexArray() {
MOZ_ASSERT(IsDeleted());
};
// -------------------------------------------------------------------------
// MEMBERS
}
GLuint mGLName;
nsTArray<WebGLVertexAttribData> mAttribs;
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;
// -------------------------------------------------------------------------
// FRIENDSHIPS
friend class WebGLVertexArrayFake;
friend class WebGLContext;
friend class WebGLVertexArrayFake;
};
} // namespace mozilla
#endif
#endif // WEBGL_VERTEX_ARRAY_H_

Просмотреть файл

@ -5,8 +5,8 @@
#include "WebGLVertexArrayFake.h"
#include "WebGLContext.h"
#include "GLContext.h"
#include "WebGLContext.h"
namespace mozilla {
@ -29,26 +29,24 @@ WebGLVertexArrayFake::BindVertexArrayImpl()
mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, vd.buf);
gl->fVertexAttribPointer(i, vd.size, vd.type, vd.normalized,
vd.stride, reinterpret_cast<void*>(vd.byteOffset));
gl->fVertexAttribPointer(i, vd.size, vd.type, vd.normalized, vd.stride,
reinterpret_cast<void*>(vd.byteOffset));
if (vd.enabled) {
if (vd.enabled)
gl->fEnableVertexAttribArray(i);
} else {
else
gl->fDisableVertexAttribArray(i);
}
}
for (size_t i = mAttribs.Length(); i < prevVertexArray->mAttribs.Length(); ++i) {
size_t len = prevVertexArray->mAttribs.Length();
for (size_t i = mAttribs.Length(); i < len; ++i) {
const WebGLVertexAttribData& vd = prevVertexArray->mAttribs[i];
if (vd.enabled) {
if (vd.enabled)
gl->fDisableVertexAttribArray(i);
}
}
mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, prevBuffer);
}
} // namespace mozilla

Просмотреть файл

@ -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 WEBGLVERTEXARRAYFAKE_H_
#define WEBGLVERTEXARRAYFAKE_H_
#ifndef WEBGL_VERTEX_ARRAY_FAKE_H_
#define WEBGL_VERTEX_ARRAY_FAKE_H_
#include "WebGLVertexArray.h"
@ -15,12 +15,12 @@ class WebGLVertexArrayFake MOZ_FINAL
{
public:
virtual void BindVertexArrayImpl() MOZ_OVERRIDE;
virtual void DeleteImpl() MOZ_OVERRIDE { };
virtual void GenVertexArray() MOZ_OVERRIDE { };
virtual void DeleteImpl() MOZ_OVERRIDE {};
virtual void GenVertexArray() MOZ_OVERRIDE {};
private:
explicit WebGLVertexArrayFake(WebGLContext* aContext)
: WebGLVertexArray(aContext)
explicit WebGLVertexArrayFake(WebGLContext* webgl)
: WebGLVertexArray(webgl)
{ }
~WebGLVertexArrayFake() {
@ -32,4 +32,4 @@ private:
} // namespace mozilla
#endif
#endif // WEBGL_VERTEX_ARRAY_FAKE_H_

Просмотреть файл

@ -5,8 +5,8 @@
#include "WebGLVertexArrayGL.h"
#include "WebGLContext.h"
#include "GLContext.h"
#include "WebGLContext.h"
namespace mozilla {

Просмотреть файл

@ -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 WEBGLVERTEXARRAYGL_H_
#define WEBGLVERTEXARRAYGL_H_
#ifndef WEBGL_VERTEX_ARRAY_GL_H_
#define WEBGL_VERTEX_ARRAY_GL_H_
#include "WebGLVertexArray.h"
@ -19,8 +19,8 @@ public:
virtual void GenVertexArray() MOZ_OVERRIDE;
private:
explicit WebGLVertexArrayGL(WebGLContext* aContext)
: WebGLVertexArray(aContext)
explicit WebGLVertexArrayGL(WebGLContext* webgl)
: WebGLVertexArray(webgl)
{ }
~WebGLVertexArrayGL() {
@ -32,4 +32,4 @@ private:
} // namespace mozilla
#endif
#endif // WEBGL_VERTEX_ARRAY_GL_H_

Просмотреть файл

@ -3,14 +3,18 @@
* 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 WEBGLVERTEXATTRIBDATA_H_
#define WEBGLVERTEXATTRIBDATA_H_
#ifndef WEBGL_VERTEX_ATTRIB_DATA_H_
#define WEBGL_VERTEX_ATTRIB_DATA_H_
#include "GLDefs.h"
#include "WebGLObjectModel.h"
namespace mozilla {
class WebGLBuffer;
struct WebGLVertexAttribData {
struct WebGLVertexAttribData
{
// note that these initial values are what GL initializes vertex attribs to
WebGLVertexAttribData()
: buf(0)
@ -21,7 +25,7 @@ struct WebGLVertexAttribData {
, type(LOCAL_GL_FLOAT)
, enabled(false)
, normalized(false)
{ }
{}
WebGLRefPtr<WebGLBuffer> buf;
GLuint stride;
@ -36,20 +40,20 @@ struct WebGLVertexAttribData {
switch(type) {
case LOCAL_GL_BYTE:
return sizeof(GLbyte);
break;
case LOCAL_GL_UNSIGNED_BYTE:
return sizeof(GLubyte);
break;
case LOCAL_GL_SHORT:
return sizeof(GLshort);
break;
case LOCAL_GL_UNSIGNED_SHORT:
return sizeof(GLushort);
break;
// XXX case LOCAL_GL_FIXED:
// case LOCAL_GL_FIXED:
case LOCAL_GL_FLOAT:
return sizeof(GLfloat);
break;
default:
NS_ERROR("Should never get here!");
return 0;
@ -57,25 +61,28 @@ struct WebGLVertexAttribData {
}
GLuint actualStride() const {
if (stride) return stride;
if (stride)
return stride;
return size * componentSize();
}
};
} // namespace mozilla
inline void ImplCycleCollectionUnlink(mozilla::WebGLVertexAttribData& aField)
inline void
ImplCycleCollectionUnlink(mozilla::WebGLVertexAttribData& field)
{
aField.buf = nullptr;
field.buf = nullptr;
}
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
mozilla::WebGLVertexAttribData& aField,
const char* aName,
uint32_t aFlags = 0)
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback,
mozilla::WebGLVertexAttribData& field,
const char* name,
uint32_t flags = 0)
{
CycleCollectionNoteChild(aCallback, aField.buf.get(), aName, aFlags);
CycleCollectionNoteChild(callback, field.buf.get(), name, flags);
}
#endif
#endif // WEBGL_VERTEX_ATTRIB_DATA_H_

Просмотреть файл

@ -16,7 +16,8 @@ using namespace mozilla;
int gTestsPassed = 0;
void VerifyImplFunction(bool condition, const char* file, int line)
void
VerifyImplFunction(bool condition, const char* file, int line)
{
if (condition) {
gTestsPassed++;
@ -29,7 +30,9 @@ void VerifyImplFunction(bool condition, const char* file, int line)
#define VERIFY(condition) \
VerifyImplFunction((condition), __FILE__, __LINE__)
void MakeRandomVector(nsTArray<uint8_t>& a, size_t size) {
void
MakeRandomVector(nsTArray<uint8_t>& a, size_t size)
{
a.SetLength(size);
// only the most-significant bits of rand() are reasonably random.
// RAND_MAX can be as low as 0x7fff, and we need 8 bits for the result, so we can only
@ -39,17 +42,18 @@ void MakeRandomVector(nsTArray<uint8_t>& a, size_t size) {
}
template<typename T>
T RandomInteger(T a, T b)
T
RandomInteger(T a, T b)
{
T result(a + rand() % (b - a + 1));
return result;
}
template<typename T>
GLenum GLType()
GLenum
GLType()
{
switch (sizeof(T))
{
switch (sizeof(T)) {
case 4: return LOCAL_GL_UNSIGNED_INT;
case 2: return LOCAL_GL_UNSIGNED_SHORT;
case 1: return LOCAL_GL_UNSIGNED_BYTE;
@ -59,12 +63,9 @@ GLenum GLType()
}
}
void CheckValidate(bool expectSuccess,
WebGLElementArrayCache& c,
GLenum type,
uint32_t maxAllowed,
size_t first,
size_t count)
void
CheckValidate(bool expectSuccess, WebGLElementArrayCache& c, GLenum type,
uint32_t maxAllowed, size_t first, size_t count)
{
uint32_t out_upperBound = 0;
const bool success = c.Validate(type, maxAllowed, first, count, &out_upperBound);
@ -77,7 +78,8 @@ void CheckValidate(bool expectSuccess,
}
template<typename T>
void CheckValidateOneTypeVariousBounds(WebGLElementArrayCache& c, size_t firstByte, size_t countBytes)
void
CheckValidateOneTypeVariousBounds(WebGLElementArrayCache& c, size_t firstByte, size_t countBytes)
{
size_t first = firstByte / sizeof(T);
size_t count = countBytes / sizeof(T);
@ -106,7 +108,8 @@ void CheckValidateAllTypes(WebGLElementArrayCache& c, size_t firstByte, size_t c
}
template<typename T>
void CheckSanity()
void
CheckSanity()
{
const size_t numElems = 64; // should be significantly larger than tree leaf size to
// ensure we exercise some nontrivial tree-walking
@ -142,7 +145,8 @@ void CheckSanity()
}
template<typename T>
void CheckUintOverflow()
void
CheckUintOverflow()
{
// This test is only for integer types smaller than uint32_t
static_assert(sizeof(T) < sizeof(uint32_t), "This test is only for integer types \
@ -169,7 +173,8 @@ void CheckUintOverflow()
CheckValidate(false, c, type, 0, 0, numElems);
}
int main(int argc, char *argv[])
int
main(int argc, char* argv[])
{
srand(0); // do not want a random seed here.

Просмотреть файл

@ -4,6 +4,9 @@
# 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/.
# http://support.microsoft.com/kb/143208
DEFINES['NOMINMAX'] = True
GeckoCppUnitTests([
'TestWebGLElementArrayCache',
])

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше