зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to b2g-inbound
This commit is contained in:
Коммит
c8aea269d3
|
@ -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');
|
||||
|
|
13
configure.in
13
configure.in
|
@ -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',
|
||||
])
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче