зеркало из https://github.com/mozilla/gecko-dev.git
Bug 638549 - WebGL about:memory - part 1: initial implementation accounting for WebGLContexts and WebGLTextures - r=jrmuizel
This commit is contained in:
Родитель
5fbf73804b
Коммит
dac4fc3fb6
|
@ -73,6 +73,54 @@ using namespace mozilla;
|
|||
using namespace mozilla::gl;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
WebGLMemoryReporter* WebGLMemoryReporter::sUniqueInstance = nsnull;
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLTextureMemoryUsed,
|
||||
"webgl-texture-memory",
|
||||
KIND_OTHER,
|
||||
UNITS_BYTES,
|
||||
WebGLMemoryReporter::GetTextureMemoryUsed,
|
||||
"Memory used by WebGL textures. The OpenGL implementation is free to store these textures in either video memory or main memory.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLTextureCount,
|
||||
"webgl-texture-count",
|
||||
KIND_OTHER,
|
||||
UNITS_COUNT,
|
||||
WebGLMemoryReporter::GetTextureCount,
|
||||
"Number of WebGL textures.")
|
||||
|
||||
NS_MEMORY_REPORTER_IMPLEMENT(WebGLContextCount,
|
||||
"webgl-context-count",
|
||||
KIND_OTHER,
|
||||
UNITS_COUNT,
|
||||
WebGLMemoryReporter::GetContextCount,
|
||||
"Number of WebGL contexts.")
|
||||
|
||||
WebGLMemoryReporter* WebGLMemoryReporter::UniqueInstance()
|
||||
{
|
||||
if (!sUniqueInstance) {
|
||||
sUniqueInstance = new WebGLMemoryReporter;
|
||||
}
|
||||
return sUniqueInstance;
|
||||
}
|
||||
|
||||
WebGLMemoryReporter::WebGLMemoryReporter()
|
||||
: mTextureMemoryUsageReporter(new NS_MEMORY_REPORTER_NAME(WebGLTextureMemoryUsed))
|
||||
, mTextureCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLTextureCount))
|
||||
, mContextCountReporter(new NS_MEMORY_REPORTER_NAME(WebGLContextCount))
|
||||
{
|
||||
NS_RegisterMemoryReporter(mTextureMemoryUsageReporter);
|
||||
NS_RegisterMemoryReporter(mTextureCountReporter);
|
||||
NS_RegisterMemoryReporter(mContextCountReporter);
|
||||
}
|
||||
|
||||
WebGLMemoryReporter::~WebGLMemoryReporter()
|
||||
{
|
||||
NS_UnregisterMemoryReporter(mTextureMemoryUsageReporter);
|
||||
NS_UnregisterMemoryReporter(mTextureCountReporter);
|
||||
NS_UnregisterMemoryReporter(mContextCountReporter);
|
||||
}
|
||||
|
||||
nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
|
||||
|
||||
nsresult
|
||||
|
@ -165,11 +213,14 @@ WebGLContext::WebGLContext()
|
|||
// See OpenGL ES 2.0.25 spec, 6.2 State Tables, table 6.13
|
||||
mPixelStorePackAlignment = 4;
|
||||
mPixelStoreUnpackAlignment = 4;
|
||||
|
||||
WebGLMemoryReporter::AddWebGLContext(this);
|
||||
}
|
||||
|
||||
WebGLContext::~WebGLContext()
|
||||
{
|
||||
DestroyResourcesAndContext();
|
||||
WebGLMemoryReporter::RemoveWebGLContext(this);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "nsWeakReference.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
|
||||
#include "GLContextProvider.h"
|
||||
#include "Layers.h"
|
||||
|
@ -320,6 +321,8 @@ class WebGLContext :
|
|||
public nsICanvasRenderingContextInternal,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
friend class WebGLMemoryReporter;
|
||||
|
||||
public:
|
||||
WebGLContext();
|
||||
virtual ~WebGLContext();
|
||||
|
@ -468,6 +471,8 @@ protected:
|
|||
PRBool ValidateDrawModeEnum(WebGLenum mode, const char *info);
|
||||
PRBool ValidateAttribIndex(WebGLuint index, const char *info);
|
||||
PRBool ValidateStencilParamsForDrawCall();
|
||||
|
||||
static PRUint32 GetTexelSize(WebGLenum format, WebGLenum type);
|
||||
|
||||
void Invalidate();
|
||||
void DestroyResourcesAndContext();
|
||||
|
@ -909,6 +914,12 @@ protected:
|
|||
return is_pot_assuming_nonnegative(mWidth) &&
|
||||
is_pot_assuming_nonnegative(mHeight); // negative sizes should never happen (caught in texImage2D...)
|
||||
}
|
||||
PRInt64 MemoryUsage() const {
|
||||
if (!mIsDefined)
|
||||
return 0;
|
||||
PRInt64 texelSize = WebGLContext::GetTexelSize(mFormat, mType);
|
||||
return PRInt64(mWidth) * PRInt64(mHeight) * texelSize;
|
||||
}
|
||||
WebGLsizei mWidth, mHeight;
|
||||
WebGLenum mFormat, mType;
|
||||
PRBool mIsDefined;
|
||||
|
@ -939,6 +950,22 @@ public:
|
|||
return target == LOCAL_GL_TEXTURE_2D ? 0 : target - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
}
|
||||
|
||||
PRInt64 MemoryUsage() const {
|
||||
PRInt64 result = 0;
|
||||
for(size_t face = 0; face < mFacesCount; face++) {
|
||||
if (mHaveGeneratedMipmap) {
|
||||
// Each mipmap level is 1/4 the size of the previous level
|
||||
// 1 + x + x^2 + ... = 1/(1-x)
|
||||
// for x = 1/4, we get 1/(1-1/4) = 4/3
|
||||
result += ImageInfoAt(0, face).MemoryUsage() * 4 / 3;
|
||||
} else {
|
||||
for(size_t level = 0; level <= mMaxLevelWithCustomImages; level++)
|
||||
result += ImageInfoAt(level, face).MemoryUsage();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
WebGLenum mTarget;
|
||||
|
@ -2066,6 +2093,72 @@ WebGLContext::CanGetConcreteObject(const char *info,
|
|||
return GetConcreteObject(info, aInterface, &aConcreteObject, isNull, isDeleted, PR_FALSE);
|
||||
}
|
||||
|
||||
class WebGLMemoryReporter
|
||||
{
|
||||
WebGLMemoryReporter();
|
||||
~WebGLMemoryReporter();
|
||||
static WebGLMemoryReporter* sUniqueInstance;
|
||||
|
||||
// here we store plain pointers, not RefPtrs: we don't want the WebGLMemoryReporter unique instance to keep alive all
|
||||
// WebGLContexts ever created.
|
||||
typedef nsTArray<const WebGLContext*> ContextsArrayType;
|
||||
ContextsArrayType mContexts;
|
||||
|
||||
nsIMemoryReporter *mTextureMemoryUsageReporter;
|
||||
nsIMemoryReporter *mTextureCountReporter;
|
||||
nsIMemoryReporter *mContextCountReporter;
|
||||
|
||||
static WebGLMemoryReporter* UniqueInstance();
|
||||
|
||||
static ContextsArrayType & Contexts() { return UniqueInstance()->mContexts; }
|
||||
|
||||
public:
|
||||
|
||||
static void AddWebGLContext(const WebGLContext* c) {
|
||||
Contexts().AppendElement(c);
|
||||
}
|
||||
|
||||
static void RemoveWebGLContext(const WebGLContext* c) {
|
||||
ContextsArrayType & contexts = Contexts();
|
||||
contexts.RemoveElement(c);
|
||||
if (contexts.IsEmpty()) {
|
||||
delete sUniqueInstance;
|
||||
sUniqueInstance = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
static PLDHashOperator TextureMemoryUsageFunction(const PRUint32&, WebGLTexture *aValue, void *aData)
|
||||
{
|
||||
PRInt64 *result = (PRInt64*) aData;
|
||||
*result += aValue->MemoryUsage();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PRInt64 GetTextureMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
PRInt64 textureMemoryUsageForThisContext = 0;
|
||||
contexts[i]->mMapTextures.EnumerateRead(TextureMemoryUsageFunction, &textureMemoryUsageForThisContext);
|
||||
result += textureMemoryUsageForThisContext;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetTextureCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
result += contexts[i]->mMapTextures.Count();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetContextCount() {
|
||||
return Contexts().Length();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -328,6 +328,34 @@ PRBool WebGLContext::ValidateDrawModeEnum(WebGLenum mode, const char *info)
|
|||
}
|
||||
}
|
||||
|
||||
PRUint32 WebGLContext::GetTexelSize(WebGLenum format, WebGLenum type)
|
||||
{
|
||||
if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
|
||||
int multiplier = type == LOCAL_GL_FLOAT ? 4 : 1;
|
||||
switch (format) {
|
||||
case LOCAL_GL_ALPHA:
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
return 1 * multiplier;
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
return 2 * multiplier;
|
||||
case LOCAL_GL_RGB:
|
||||
return 3 * multiplier;
|
||||
case LOCAL_GL_RGBA:
|
||||
return 4 * multiplier;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
|
||||
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
|
||||
type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
NS_ABORT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRBool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
|
||||
PRUint32 *texelSize, const char *info)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче