Bug 818060 - Add a memory reporter for graphics textures. r=BenWa,njn

This commit is contained in:
Kartikaya Gupta 2012-12-16 19:16:26 -05:00
Родитель 556c152c54
Коммит 5ed801d300
5 изменённых файлов: 119 добавлений и 3 удалений

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

@ -25,6 +25,8 @@
#include "GLTextureImage.h"
#include "nsIMemoryReporter.h"
using namespace mozilla::gfx;
namespace mozilla {
@ -88,6 +90,33 @@ static const char *sExtensionNames[] = {
nullptr
};
static int64_t sTextureMemoryUsage = 0;
static int64_t
GetTextureMemoryUsage()
{
return sTextureMemoryUsage;
}
void
GLContext::UpdateTextureMemoryUsage(MemoryUse action, GLenum format, GLenum type, uint16_t tileSize)
{
uint32_t bytesPerTexel = mozilla::gl::GetBitsPerTexel(format, type) / 8;
int64_t bytes = (int64_t)(tileSize * tileSize * bytesPerTexel);
if (action == MemoryFreed) {
sTextureMemoryUsage -= bytes;
} else {
sTextureMemoryUsage += bytes;
}
}
NS_MEMORY_REPORTER_IMPLEMENT(TextureMemoryUsage,
"gfx-textures",
KIND_OTHER,
UNITS_BYTES,
GetTextureMemoryUsage,
"Memory used for storing GL textures.")
/*
* XXX - we should really know the ARB/EXT variants of these
* instead of only handling the symbol if it's exposed directly.
@ -644,6 +673,7 @@ void
GLContext::PlatformStartup()
{
CacheCanUploadNPOT();
NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(TextureMemoryUsage));
}
void

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

@ -2914,6 +2914,20 @@ public:
nsTArray<NamedResource> mTrackedBuffers;
#endif
public:
enum MemoryUse {
// when memory being allocated is reported to a memory reporter
MemoryAllocated,
// when memory being freed is reported to a memory reporter
MemoryFreed
};
// When memory is used/freed for tile textures, call this method
// to update the value reported by the memory reporter.
static void UpdateTextureMemoryUsage(MemoryUse action,
GLenum format,
GLenum type,
uint16_t tileSize);
};
inline bool
@ -3108,6 +3122,8 @@ protected:
}
};
uint32_t GetBitsPerTexel(GLenum format, GLenum type);
} /* namespace gl */
} /* namespace mozilla */

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

@ -419,6 +419,63 @@ GLContext::BlitTextureToTexture(GLuint srcTex, GLuint destTex,
srcSize, destSize);
}
uint32_t GetBitsPerTexel(GLenum format, GLenum type)
{
// If there is no defined format or type, we're not taking up any memory
if (!format || !type) {
return 0;
}
if (format == LOCAL_GL_DEPTH_COMPONENT) {
if (type == LOCAL_GL_UNSIGNED_SHORT)
return 2;
else if (type == LOCAL_GL_UNSIGNED_INT)
return 4;
} else if (format == LOCAL_GL_DEPTH_STENCIL) {
if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
return 4;
}
if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
int multiplier = type == LOCAL_GL_FLOAT ? 32 : 8;
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;
case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
return 2;
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case LOCAL_GL_ATC_RGB:
case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
return 4;
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
return 8;
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 16;
}
MOZ_ASSERT(false);
return 0;
}
} /* namespace gl */
} /* namespace mozilla */

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

@ -21,9 +21,7 @@ TiledLayerBufferOGL::~TiledLayerBufferOGL()
mContext->MakeCurrent();
for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
if (mRetainedTiles[i] == GetPlaceholderTile())
continue;
mContext->fDeleteTextures(1, &mRetainedTiles[i].mTextureHandle);
ReleaseTile(mRetainedTiles[i]);
}
}
@ -34,6 +32,8 @@ TiledLayerBufferOGL::ReleaseTile(TiledTexture aTile)
if (aTile == GetPlaceholderTile())
return;
mContext->fDeleteTextures(1, &aTile.mTextureHandle);
GLContext::UpdateTextureMemoryUsage(GLContext::MemoryFreed, aTile.mFormat, GetTileType(aTile), GetTileLength());
}
void
@ -59,6 +59,13 @@ TiledLayerBufferOGL::Upload(const BasicTiledLayerBuffer* aMainMemoryTiledBuffer,
#endif
}
GLenum
TiledLayerBufferOGL::GetTileType(TiledTexture aTile)
{
// Deduce the type that was assigned in GetFormatAndTileForImageFormat
return aTile.mFormat == LOCAL_GL_RGB ? LOCAL_GL_UNSIGNED_SHORT_5_6_5 : LOCAL_GL_UNSIGNED_BYTE;
}
void
TiledLayerBufferOGL::GetFormatAndTileForImageFormat(gfxASurface::gfxImageFormat aFormat,
GLenum& aOutFormat,
@ -91,6 +98,9 @@ TiledLayerBufferOGL::ValidateTile(TiledTexture aTile,
mContext->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
} else {
mContext->fBindTexture(LOCAL_GL_TEXTURE_2D, aTile.mTextureHandle);
// We're re-using a texture, but the format may change. Update the memory
// reporter with a free and alloc (below) using the old and new formats.
GLContext::UpdateTextureMemoryUsage(GLContext::MemoryFreed, aTile.mFormat, GetTileType(aTile), GetTileLength());
}
nsRefPtr<gfxReusableSurfaceWrapper> reusableSurface = mMainMemoryTiledBuffer->GetTile(aTileOrigin).mSurface.get();
@ -102,6 +112,8 @@ TiledLayerBufferOGL::ValidateTile(TiledTexture aTile,
GetTileLength(), GetTileLength(), 0,
format, type, buf);
GLContext::UpdateTextureMemoryUsage(GLContext::MemoryAllocated, format, type, GetTileLength());
aTile.mFormat = format;
#ifdef GFX_TILEDLAYER_PREF_WARNINGS

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

@ -100,6 +100,7 @@ private:
const BasicTiledLayerBuffer* mMainMemoryTiledBuffer;
gfxSize mFrameResolution;
GLenum GetTileType(TiledTexture aTile);
void GetFormatAndTileForImageFormat(gfxASurface::gfxImageFormat aFormat,
GLenum& aOutFormat,
GLenum& aOutType);