зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1265824 - Add a new texture source type "DirectMapTextureSource" r=mattwoodrow
The DirectMapTextureSource could let the compositor to read the buffer directly. That could get rid of some memory copy operations during texture uploading. MozReview-Commit-ID: CHhoR96P7VG --HG-- extra : rebase_source : 65c167644096a1b72fe5dfbb55837842f41377bb
This commit is contained in:
Родитель
14d6b57804
Коммит
40c168f2fd
|
@ -81,6 +81,7 @@ static const char* const sExtensionNames[] = {
|
|||
"GL_ANGLE_texture_compression_dxt5",
|
||||
"GL_ANGLE_timer_query",
|
||||
"GL_APPLE_client_storage",
|
||||
"GL_APPLE_fence",
|
||||
"GL_APPLE_framebuffer_multisample",
|
||||
"GL_APPLE_sync",
|
||||
"GL_APPLE_texture_range",
|
||||
|
@ -1080,6 +1081,15 @@ GLContext::LoadMoreSymbols(const char* prefix, bool trygl)
|
|||
fnLoadForExt(symbols, APPLE_texture_range);
|
||||
}
|
||||
|
||||
if (IsExtensionSupported(APPLE_fence)) {
|
||||
const SymLoadStruct symbols[] = {
|
||||
{ (PRFuncPtr*) &mSymbols.fFinishObjectAPPLE, { "FinishObjectAPPLE", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fTestObjectAPPLE, { "TestObjectAPPLE", nullptr } },
|
||||
END_SYMBOLS
|
||||
};
|
||||
fnLoadForExt(symbols, APPLE_fence);
|
||||
}
|
||||
|
||||
if (IsSupported(GLFeature::vertex_array_object)) {
|
||||
const SymLoadStruct coreSymbols[] = {
|
||||
{ (PRFuncPtr*) &mSymbols.fIsVertexArray, { "IsVertexArray", nullptr } },
|
||||
|
|
|
@ -380,6 +380,7 @@ public:
|
|||
ANGLE_texture_compression_dxt5,
|
||||
ANGLE_timer_query,
|
||||
APPLE_client_storage,
|
||||
APPLE_fence,
|
||||
APPLE_framebuffer_multisample,
|
||||
APPLE_sync,
|
||||
APPLE_texture_range,
|
||||
|
@ -3302,6 +3303,25 @@ public:
|
|||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// APPLE_fence
|
||||
|
||||
void fFinishObjectAPPLE(GLenum object, GLint name) {
|
||||
BEFORE_GL_CALL;
|
||||
ASSERT_SYMBOL_PRESENT(fFinishObjectAPPLE);
|
||||
mSymbols.fFinishObjectAPPLE(object, name);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
realGLboolean fTestObjectAPPLE(GLenum object, GLint name) {
|
||||
realGLboolean ret = false;
|
||||
BEFORE_GL_CALL;
|
||||
ASSERT_SYMBOL_PRESENT(fTestObjectAPPLE);
|
||||
ret = mSymbols.fTestObjectAPPLE(object, name);
|
||||
AFTER_GL_CALL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// prim_restart
|
||||
|
||||
|
|
|
@ -137,6 +137,8 @@ struct GLContextSymbols final
|
|||
void (GLAPIENTRY * fTexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei,
|
||||
GLsizei, GLenum, GLenum, const void*);
|
||||
void (GLAPIENTRY * fTextureRangeAPPLE)(GLenum, GLsizei, GLvoid*);
|
||||
void (GLAPIENTRY * fFinishObjectAPPLE)(GLenum, GLint);
|
||||
realGLboolean (GLAPIENTRY * fTestObjectAPPLE)(GLenum, GLint);
|
||||
void (GLAPIENTRY * fUniform1f)(GLint, GLfloat);
|
||||
void (GLAPIENTRY * fUniform1fv)(GLint, GLsizei, const GLfloat*);
|
||||
void (GLAPIENTRY * fUniform1i)(GLint, GLint);
|
||||
|
|
|
@ -183,6 +183,14 @@ public:
|
|||
|
||||
int NumCompositableRefs() const { return mCompositableCount; }
|
||||
|
||||
// Some texture sources could wrap the cpu buffer to gpu directly. Then,
|
||||
// we could get better performance of texture uploading.
|
||||
virtual bool IsDirectMap() { return false; }
|
||||
// The direct-map cpu buffer should be alive when gpu uses it. And it
|
||||
// should not be updated while gpu reads it. This Sync() function
|
||||
// implements this synchronized behavior.
|
||||
virtual void Sync() { }
|
||||
|
||||
protected:
|
||||
|
||||
RefPtr<TextureSource> mNextSibling;
|
||||
|
|
|
@ -309,6 +309,93 @@ GLTextureSource::IsValid() const
|
|||
return !!gl() && mTextureHandle != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// DirectMapTextureSource
|
||||
|
||||
DirectMapTextureSource::DirectMapTextureSource(TextureSourceProvider* aProvider,
|
||||
gfx::DataSourceSurface* aSurface)
|
||||
: GLTextureSource(aProvider,
|
||||
0,
|
||||
LOCAL_GL_TEXTURE_2D,
|
||||
aSurface->GetSize(),
|
||||
aSurface->GetFormat())
|
||||
{
|
||||
MOZ_ASSERT(aSurface);
|
||||
|
||||
UpdateInternal(aSurface, nullptr, nullptr, true);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectMapTextureSource::Update(gfx::DataSourceSurface* aSurface,
|
||||
nsIntRegion* aDestRegion,
|
||||
gfx::IntPoint* aSrcOffset)
|
||||
{
|
||||
if (!aSurface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return UpdateInternal(aSurface, aDestRegion, aSrcOffset, false);
|
||||
}
|
||||
|
||||
void
|
||||
DirectMapTextureSource::Sync()
|
||||
{
|
||||
gl()->MakeCurrent();
|
||||
if (!gl()->IsDestroyed()) {
|
||||
gl()->fFinishObjectAPPLE(LOCAL_GL_TEXTURE, mTextureHandle);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DirectMapTextureSource::UpdateInternal(gfx::DataSourceSurface* aSurface,
|
||||
nsIntRegion* aDestRegion,
|
||||
gfx::IntPoint* aSrcOffset,
|
||||
bool aInit)
|
||||
{
|
||||
gl()->MakeCurrent();
|
||||
|
||||
if (aInit) {
|
||||
gl()->fGenTextures(1, &mTextureHandle);
|
||||
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextureHandle);
|
||||
|
||||
gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D,
|
||||
LOCAL_GL_TEXTURE_STORAGE_HINT_APPLE,
|
||||
LOCAL_GL_STORAGE_CACHED_APPLE);
|
||||
|
||||
gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D,
|
||||
LOCAL_GL_TEXTURE_WRAP_S,
|
||||
LOCAL_GL_CLAMP_TO_EDGE);
|
||||
gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D,
|
||||
LOCAL_GL_TEXTURE_WRAP_T,
|
||||
LOCAL_GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mTextureHandle);
|
||||
|
||||
// APPLE_client_storage
|
||||
gl()->fPixelStorei(LOCAL_GL_UNPACK_CLIENT_STORAGE_APPLE, LOCAL_GL_TRUE);
|
||||
|
||||
nsIntRegion destRegion = aDestRegion ? *aDestRegion
|
||||
: IntRect(0, 0,
|
||||
aSurface->GetSize().width,
|
||||
aSurface->GetSize().height);
|
||||
gfx::IntPoint srcPoint = aSrcOffset ? *aSrcOffset
|
||||
: gfx::IntPoint(0, 0);
|
||||
mFormat = gl::UploadSurfaceToTexture(gl(),
|
||||
aSurface,
|
||||
destRegion,
|
||||
mTextureHandle,
|
||||
aSurface->GetSize(),
|
||||
nullptr,
|
||||
aInit,
|
||||
srcPoint,
|
||||
LOCAL_GL_TEXTURE0,
|
||||
LOCAL_GL_TEXTURE_2D);
|
||||
|
||||
gl()->fPixelStorei(LOCAL_GL_UNPACK_CLIENT_STORAGE_APPLE, LOCAL_GL_FALSE);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceTextureHost
|
||||
|
|
|
@ -224,7 +224,7 @@ protected:
|
|||
*
|
||||
* The shared texture handle is owned by the TextureHost.
|
||||
*/
|
||||
class GLTextureSource : public TextureSource
|
||||
class GLTextureSource : public DataTextureSource
|
||||
, public TextureSourceOGL
|
||||
{
|
||||
public:
|
||||
|
@ -234,7 +234,7 @@ public:
|
|||
gfx::IntSize aSize,
|
||||
gfx::SurfaceFormat aFormat);
|
||||
|
||||
~GLTextureSource();
|
||||
virtual ~GLTextureSource();
|
||||
|
||||
virtual const char* Name() const override { return "GLTextureSource"; }
|
||||
|
||||
|
@ -269,6 +269,13 @@ public:
|
|||
return mGL;
|
||||
}
|
||||
|
||||
virtual bool Update(gfx::DataSourceSurface* aSurface,
|
||||
nsIntRegion* aDestRegion = nullptr,
|
||||
gfx::IntPoint* aSrcOffset = nullptr) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
void DeleteTextureHandle();
|
||||
|
||||
|
@ -280,6 +287,33 @@ protected:
|
|||
gfx::SurfaceFormat mFormat;
|
||||
};
|
||||
|
||||
// This texture source try to wrap "aSurface" in ctor for compositor direct
|
||||
// access. Since we can't know the timing for gpu buffer access, the surface
|
||||
// should be alive until the ~ClientStorageTextureSource(). And if we try to
|
||||
// update the surface we mapped before, we need to call Sync() to make sure
|
||||
// the surface is not used by compositor.
|
||||
class DirectMapTextureSource : public GLTextureSource
|
||||
{
|
||||
public:
|
||||
DirectMapTextureSource(TextureSourceProvider* aProvider,
|
||||
gfx::DataSourceSurface* aSurface);
|
||||
|
||||
virtual bool Update(gfx::DataSourceSurface* aSurface,
|
||||
nsIntRegion* aDestRegion = nullptr,
|
||||
gfx::IntPoint* aSrcOffset = nullptr) override;
|
||||
|
||||
virtual bool IsDirectMap() override { return true; }
|
||||
|
||||
// Wait until this texture source is not used by the compositor.
|
||||
virtual void Sync() override;
|
||||
|
||||
private:
|
||||
bool UpdateInternal(gfx::DataSourceSurface* aSurface,
|
||||
nsIntRegion* aDestRegion,
|
||||
gfx::IntPoint* aSrcOffset,
|
||||
bool aInit);
|
||||
};
|
||||
|
||||
class GLTextureHost : public TextureHost
|
||||
{
|
||||
public:
|
||||
|
|
Загрузка…
Ссылка в новой задаче