Bug 771350, part 1: Add GLContext::CreateDirectTextureImage and OpenDescriptorForTexturing to more easily support direct texturing without updates. r=vlad

This commit is contained in:
Chris Jones 2012-07-23 16:58:37 -07:00
parent 8b5433e465
commit f66164ac60
8 changed files with 157 additions and 12 deletions

View File

@ -39,6 +39,10 @@ typedef char realGLboolean;
#include "mozilla/mozalloc.h"
namespace android {
class GraphicBuffer;
}
namespace mozilla {
namespace layers {
class LayerManagerOGL;
@ -746,6 +750,10 @@ public:
virtual bool BindExternalBuffer(GLuint texture, void* buffer) { return false; }
virtual bool UnbindExternalBuffer(GLuint texture) { return false; }
virtual already_AddRefed<TextureImage>
CreateDirectTextureImage(android::GraphicBuffer* aBuffer, GLenum aWrapMode)
{ return nsnull; }
/*
* Offscreen support API
*/

View File

@ -310,7 +310,6 @@ public:
}
#ifdef MOZ_WIDGET_GONK
gUseBackingSurface = Preferences::GetBool("gfx.gralloc.enabled", false);
char propValue[PROPERTY_VALUE_MAX];
property_get("ro.build.version.sdk", propValue, "0");
if (atoi(propValue) < 15)
@ -442,6 +441,11 @@ public:
#endif
}
#ifdef MOZ_WIDGET_GONK
virtual already_AddRefed<TextureImage>
CreateDirectTextureImage(GraphicBuffer* aBuffer, GLenum aWrapMode) MOZ_OVERRIDE;
#endif
bool MakeCurrentImpl(bool aForce = false) {
bool succeeded = true;
@ -1204,6 +1208,23 @@ PixelFormatForImage(gfxASurface::gfxImageFormat aFormat)
}
return 0;
}
static gfxASurface::gfxContentType
ContentTypeForPixelFormat(PixelFormat aFormat)
{
switch (aFormat) {
case PIXEL_FORMAT_L_8:
return gfxASurface::CONTENT_ALPHA;
case PIXEL_FORMAT_RGBA_8888:
return gfxASurface::CONTENT_COLOR_ALPHA;
case PIXEL_FORMAT_RGBX_8888:
case PIXEL_FORMAT_RGB_565:
return gfxASurface::CONTENT_COLOR;
default:
MOZ_NOT_REACHED("Unknown content type for gralloc pixel format");
}
return gfxASurface::CONTENT_COLOR;
}
#endif
static GLenum
@ -1231,7 +1252,8 @@ public:
GLenum aWrapMode,
ContentType aContentType,
GLContext* aContext,
TextureImage::Flags aFlags = TextureImage::NoFlags)
Flags aFlags = TextureImage::NoFlags,
TextureState aTextureState = Created)
: TextureImage(aSize, aWrapMode, aContentType, aFlags)
, mGLContext(aContext)
, mUpdateFormat(gfxASurface::ImageFormatUnknown)
@ -1239,7 +1261,7 @@ public:
, mTexture(aTexture)
, mSurface(nsnull)
, mConfig(nsnull)
, mTextureState(Created)
, mTextureState(aTextureState)
, mBound(false)
, mIsLocked(false)
{
@ -1855,6 +1877,43 @@ protected:
}
};
#ifdef MOZ_WIDGET_GONK
class DirectTextureImageEGL
: public TextureImageEGL
{
public:
DirectTextureImageEGL(GLuint aTexture,
sp<GraphicBuffer> aGraphicBuffer,
GLenum aWrapMode,
GLContext* aContext)
: TextureImageEGL(aTexture,
nsIntSize(aGraphicBuffer->getWidth(), aGraphicBuffer->getHeight()),
aWrapMode,
ContentTypeForPixelFormat(aGraphicBuffer->getPixelFormat()),
aContext,
ForceSingleTile,
Valid)
{
mGraphicBuffer = aGraphicBuffer;
const int eglImageAttributes[] =
{ LOCAL_EGL_IMAGE_PRESERVED, LOCAL_EGL_TRUE,
LOCAL_EGL_NONE, LOCAL_EGL_NONE };
mEGLImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(),
EGL_NO_CONTEXT,
EGL_NATIVE_BUFFER_ANDROID,
mGraphicBuffer->getNativeBuffer(),
eglImageAttributes);
if (!mEGLImage) {
LOG("Could not create EGL images: ERROR (0x%04x)", sEGLLibrary.fGetError());
}
}
};
#endif // MOZ_WIDGET_GONK
already_AddRefed<TextureImage>
GLContextEGL::CreateTextureImage(const nsIntSize& aSize,
TextureImage::ContentType aContentType,
@ -1865,6 +1924,30 @@ GLContextEGL::CreateTextureImage(const nsIntSize& aSize,
return t.forget();
}
#ifdef MOZ_WIDGET_GONK
already_AddRefed<TextureImage>
GLContextEGL::CreateDirectTextureImage(GraphicBuffer* aBuffer,
GLenum aWrapMode)
{
MakeCurrent();
GLuint texture;
fGenTextures(1, &texture);
nsRefPtr<TextureImage> texImage(
new DirectTextureImageEGL(texture, aBuffer, aWrapMode, this));
texImage->BindTexture(LOCAL_GL_TEXTURE0);
GLint texfilter = LOCAL_GL_LINEAR;
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, aWrapMode);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, aWrapMode);
return texImage.forget();
}
#endif // MOZ_WIDGET_GONK
already_AddRefed<TextureImage>
GLContextEGL::TileGenFunc(const nsIntSize& aSize,
TextureImage::ContentType aContentType,

View File

@ -75,6 +75,14 @@ ShadowLayerManager::PlatformDestroySharedSurface(SurfaceDescriptor*)
return false;
}
/*static*/ already_AddRefed<TextureImage>
ShadowLayerManager::OpenDescriptorForDirectTexturing(GLContext*,
const SurfaceDescriptor&,
GLenum)
{
return nsnull;
}
/*static*/ void
ShadowLayerManager::PlatformSyncBeforeReplyUpdate()
{

View File

@ -170,6 +170,24 @@ GrallocBufferActor::Create(const gfxIntSize& aSize,
return actor;
}
/*static*/ already_AddRefed<TextureImage>
ShadowLayerManager::OpenDescriptorForDirectTexturing(GLContext* aGL,
const SurfaceDescriptor& aDescriptor,
GLenum aWrapMode)
{
if (SurfaceDescriptor::TSurfaceDescriptorGralloc != aDescriptor.type()) {
return nsnull;
}
sp<GraphicBuffer> buffer = GrallocBufferActor::GetFrom(aDescriptor);
return aGL->CreateDirectTextureImage(buffer.get(), aWrapMode);
}
/*static*/ void
ShadowLayerManager::PlatformSyncBeforeReplyUpdate()
{
// Nothing to be done for gralloc.
}
bool
ShadowLayerManager::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface)
{
@ -323,8 +341,7 @@ ShadowLayerForwarder::PlatformCloseDescriptor(const SurfaceDescriptor& aDescript
return false;
}
sp<GraphicBuffer> buffer =
GrallocBufferActor::GetFrom(aDescriptor);
sp<GraphicBuffer> buffer = GrallocBufferActor::GetFrom(aDescriptor);
// If the buffer wasn't lock()d, this probably blows up. But since
// PlatformCloseDescriptor() is private and only used by
// AutoOpenSurface, we want to know if the logic is wrong there.
@ -338,11 +355,5 @@ ShadowLayerForwarder::PlatformSyncBeforeUpdate()
// Nothing to be done for gralloc.
}
/*static*/ void
ShadowLayerManager::PlatformSyncBeforeReplyUpdate()
{
// Nothing to be done for gralloc.
}
} // namespace layers
} // namespace mozilla

View File

@ -60,6 +60,7 @@ class GrallocBufferActor : public PGrallocBufferChild
, public PGrallocBufferParent
{
friend class ShadowLayerForwarder;
friend class ShadowLayerManager;
typedef android::GraphicBuffer GraphicBuffer;
public:

View File

@ -191,6 +191,15 @@ ShadowLayerManager::PlatformSyncBeforeReplyUpdate()
}
}
/*static*/ already_AddRefed<TextureImage>
ShadowLayerManager::OpenDescriptorForDirectTexturing(GLContext*,
const SurfaceDescriptor&,
GLenum)
{
// FIXME/bug XXXXXX: implement this using texture-from-pixmap
return nsnull;
}
bool
ShadowLayerManager::PlatformDestroySharedSurface(SurfaceDescriptor* aSurface)
{

View File

@ -557,7 +557,6 @@ ShadowLayerManager::DestroySharedSurface(SurfaceDescriptor* aSurface,
}
}
#if !defined(MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS)
bool
@ -619,6 +618,14 @@ ShadowLayerManager::PlatformDestroySharedSurface(SurfaceDescriptor*)
return false;
}
/*static*/ already_AddRefed<TextureImage>
ShadowLayerManager::OpenDescriptorForDirectTexturing(GLContext*,
const SurfaceDescriptor&,
GLenum)
{
return nsnull;
}
/*static*/ void
ShadowLayerManager::PlatformSyncBeforeReplyUpdate()
{

View File

@ -9,6 +9,7 @@
#define mozilla_layers_ShadowLayers_h 1
#include "gfxASurface.h"
#include "GLDefs.h"
#include "ImageLayers.h"
#include "LayersBackend.h"
@ -17,6 +18,13 @@
class gfxSharedImageSurface;
namespace mozilla {
namespace gl {
class GLContext;
class TextureImage;
}
using namespace gl;
namespace layers {
class Edit;
@ -402,6 +410,16 @@ public:
/** CONSTRUCTION PHASE ONLY */
virtual already_AddRefed<ShadowRefLayer> CreateShadowRefLayer() { return nsnull; }
/**
* Try to open |aDescriptor| for direct texturing. If the
* underlying surface supports direct texturing, a non-null
* TextureImage is returned. Otherwise null is returned.
*/
static already_AddRefed<TextureImage>
OpenDescriptorForDirectTexturing(GLContext* aContext,
const SurfaceDescriptor& aDescriptor,
GLenum aWrapMode);
static void PlatformSyncBeforeReplyUpdate();
void SetCompositorID(PRUint32 aID)