Bug 670930 - Add Android direct texture implementation

--HG--
extra : rebase_source : eb3f095e2663c0ebc0a03117ec8883d66dd8f1b5
This commit is contained in:
James Willcox 2011-12-16 10:54:08 -05:00
Родитель 8efa6b018a
Коммит 41962bb189
5 изменённых файлов: 794 добавлений и 8 удалений

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

@ -1229,17 +1229,32 @@ public class GeckoAppShell
return accessibilityManager.isEnabled(); return accessibilityManager.isEnabled();
} }
public static void addPluginView(View view, public static void addPluginView(final View view,
double x, double y, final double x, final double y,
double w, double h) final double w, final double h) {
{
Log.i(LOGTAG, "addPluginView:" + view + " @ x:" + x + " y:" + y + " w:" + w + " h:" + h ) ; Log.i(LOGTAG, "addPluginView:" + view + " @ x:" + x + " y:" + y + " w:" + w + " h:" + h ) ;
GeckoApp.mAppContext.addPluginView(view, x, y, w, h); getMainHandler().post(new Runnable() {
public void run() {
try {
GeckoApp.mAppContext.addPluginView(view, x, y, w, h);
} catch (Exception e) {
Log.e(LOGTAG, "Failed to add plugin view: ", e);
}
}
});
} }
public static void removePluginView(View view) { public static void removePluginView(final View view) {
Log.i(LOGTAG, "remove view:" + view); Log.i(LOGTAG, "removePluginView:" + view);
GeckoApp.mAppContext.removePluginView(view); getMainHandler().post(new Runnable() {
public void run() {
try {
GeckoApp.mAppContext.removePluginView(view);
} catch (Exception e) {
Log.e(LOGTAG, "Failed to remove plugin view: ", e);
}
}
});
} }
public static Class<?> loadPluginClass(String className, String libName) { public static Class<?> loadPluginClass(String className, String libName) {

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

@ -0,0 +1,149 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Willcox <jwillcox@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "AndroidDirectTexture.h"
typedef gfxASurface::gfxImageFormat gfxImageFormat;
namespace mozilla {
AndroidDirectTexture::AndroidDirectTexture(PRUint32 width, PRUint32 height, PRUint32 usage,
gfxImageFormat format) :
mLock("AndroidDirectTexture.mLock")
, mNeedFlip(false)
, mWidth(width)
, mHeight(height)
, mFormat(format)
, mPendingReallocBuffer(NULL)
{
mFrontBuffer = new AndroidGraphicBuffer(width, height, usage, format);
mBackBuffer = new AndroidGraphicBuffer(width, height, usage, format);
}
AndroidDirectTexture::~AndroidDirectTexture()
{
if (mFrontBuffer) {
delete mFrontBuffer;
mFrontBuffer = NULL;
}
if (mBackBuffer) {
delete mBackBuffer;
mBackBuffer = NULL;
}
}
void
AndroidDirectTexture::ReallocPendingBuffer()
{
// We may have reallocated while the current back buffer was being
// used as the front buffer. If we have such a reallocation pending
// and the current back buffer is the target buffer, do it now.
//
// It is assumed that mLock is already acquired
if (mPendingReallocBuffer == mBackBuffer) {
mBackBuffer->Reallocate(mWidth, mHeight, mFormat);
mPendingReallocBuffer = NULL;
}
}
bool
AndroidDirectTexture::Lock(PRUint32 aUsage, unsigned char **bits)
{
mLock.Lock();
ReallocPendingBuffer();
return mBackBuffer->Lock(aUsage, bits);
}
bool
AndroidDirectTexture::Lock(PRUint32 aUsage, const nsIntRect& aRect, unsigned char **bits)
{
mLock.Lock();
ReallocPendingBuffer();
return mBackBuffer->Lock(aUsage, aRect, bits);
}
bool
AndroidDirectTexture::Unlock(bool aFlip)
{
if (aFlip) {
mNeedFlip = true;
}
bool result = mBackBuffer->Unlock();
mLock.Unlock();
return result;
}
bool
AndroidDirectTexture::Reallocate(PRUint32 aWidth, PRUint32 aHeight) {
return Reallocate(aWidth, aHeight, mFormat);
}
bool
AndroidDirectTexture::Reallocate(PRUint32 aWidth, PRUint32 aHeight, gfxASurface::gfxImageFormat aFormat)
{
MutexAutoLock lock(mLock);
// We only reallocate the current back buffer. The front buffer is likely
// in use, so we'll reallocate it on the first Lock() after it is rotated
// to the back.
bool result = mBackBuffer->Reallocate(aWidth, aHeight, aFormat);
if (result) {
mPendingReallocBuffer = mFrontBuffer;
}
return result;
}
bool
AndroidDirectTexture::Bind()
{
MutexAutoLock lock(mLock);
if (mNeedFlip) {
AndroidGraphicBuffer* tmp = mBackBuffer;
mBackBuffer = mFrontBuffer;
mFrontBuffer = tmp;
mNeedFlip = false;
}
return mFrontBuffer->Bind();
}
} /* mozilla */

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

@ -0,0 +1,90 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Willcox <jwillcox@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef AndroidDirectTexture_h_
#define AndroidDirectTexture_h_
#include "gfxASurface.h"
#include "nsRect.h"
#include "mozilla/Mutex.h"
#include "AndroidGraphicBuffer.h"
namespace mozilla {
/**
* This is a thread safe wrapper around AndroidGraphicBuffer that handles
* double buffering. Each call to Bind() flips the buffer when necessary.
*
* You need to be careful when destroying an instance of this class. If either
* buffer is locked by the application of the driver/hardware, bad things will
* happen. Be sure that the OpenGL texture is no longer on the screen.
*/
class AndroidDirectTexture
{
public:
AndroidDirectTexture(PRUint32 width, PRUint32 height, PRUint32 usage, gfxASurface::gfxImageFormat format);
virtual ~AndroidDirectTexture();
bool Lock(PRUint32 usage, unsigned char **bits);
bool Lock(PRUint32 usage, const nsIntRect& rect, unsigned char **bits);
bool Unlock(bool aFlip = true);
bool Reallocate(PRUint32 aWidth, PRUint32 aHeight);
bool Reallocate(PRUint32 aWidth, PRUint32 aHeight, gfxASurface::gfxImageFormat aFormat);
PRUint32 Width() { return mWidth; }
PRUint32 Height() { return mHeight; }
bool Bind();
private:
mozilla::Mutex mLock;
bool mNeedFlip;
PRUint32 mWidth;
PRUint32 mHeight;
gfxASurface::gfxImageFormat mFormat;
AndroidGraphicBuffer* mFrontBuffer;
AndroidGraphicBuffer* mBackBuffer;
AndroidGraphicBuffer* mPendingReallocBuffer;
void ReallocPendingBuffer();
};
} /* mozilla */
#endif /* AndroidDirectTexture_h_ */

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

@ -0,0 +1,433 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Willcox <jwillcox@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <dlfcn.h>
#include <android/log.h>
#include <GLES2/gl2.h>
#include "AndroidGraphicBuffer.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AndroidGraphicBuffer" , ## args)
#define EGL_NATIVE_BUFFER_ANDROID 0x3140
#define EGL_IMAGE_PRESERVED_KHR 0x30D2
typedef void* EGLContext;
typedef void* EGLImageKHR;
typedef void* EGLClientBuffer;
typedef void* EGLDisplay;
typedef PRUint32 EGLenum;
typedef PRInt32 EGLint;
typedef PRUint32 EGLBoolean;
typedef gfxASurface::gfxImageFormat gfxImageFormat;
#define EGL_TRUE 1
#define EGL_FALSE 0
#define EGL_NONE 0x3038
#define EGL_NO_CONTEXT (EGLContext)0
#define EGL_DEFAULT_DISPLAY (void*)0
#define ANDROID_LIBUI_PATH "/system/lib/libui.so"
#define ANDROID_GLES_PATH "/system/lib/libGLESv2.so"
#define ANDROID_EGL_PATH "/system/lib/libEGL.so"
// Really I have no idea, but this should be big enough
#define GRAPHIC_BUFFER_SIZE 1024
enum {
/* buffer is never read in software */
GRALLOC_USAGE_SW_READ_NEVER = 0x00000000,
/* buffer is rarely read in software */
GRALLOC_USAGE_SW_READ_RARELY = 0x00000002,
/* buffer is often read in software */
GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003,
/* mask for the software read values */
GRALLOC_USAGE_SW_READ_MASK = 0x0000000F,
/* buffer is never written in software */
GRALLOC_USAGE_SW_WRITE_NEVER = 0x00000000,
/* buffer is never written in software */
GRALLOC_USAGE_SW_WRITE_RARELY = 0x00000020,
/* buffer is never written in software */
GRALLOC_USAGE_SW_WRITE_OFTEN = 0x00000030,
/* mask for the software write values */
GRALLOC_USAGE_SW_WRITE_MASK = 0x000000F0,
/* buffer will be used as an OpenGL ES texture */
GRALLOC_USAGE_HW_TEXTURE = 0x00000100,
/* buffer will be used as an OpenGL ES render target */
GRALLOC_USAGE_HW_RENDER = 0x00000200,
/* buffer will be used by the 2D hardware blitter */
GRALLOC_USAGE_HW_2D = 0x00000400,
/* buffer will be used with the framebuffer device */
GRALLOC_USAGE_HW_FB = 0x00001000,
/* mask for the software usage bit-mask */
GRALLOC_USAGE_HW_MASK = 0x00001F00,
};
enum {
HAL_PIXEL_FORMAT_RGBA_8888 = 1,
HAL_PIXEL_FORMAT_RGBX_8888 = 2,
HAL_PIXEL_FORMAT_RGB_888 = 3,
HAL_PIXEL_FORMAT_RGB_565 = 4,
HAL_PIXEL_FORMAT_BGRA_8888 = 5,
HAL_PIXEL_FORMAT_RGBA_5551 = 6,
HAL_PIXEL_FORMAT_RGBA_4444 = 7,
};
typedef struct AndroidRect {
int32_t left;
int32_t top;
int32_t right;
int32_t bottom;
} AndroidRect;
static bool gTryRealloc = true;
static class GLFunctions
{
public:
GLFunctions() : mInitialized(false)
{
}
typedef EGLDisplay (* pfnGetDisplay)(void *display_id);
pfnGetDisplay fGetDisplay;
typedef EGLint (* pfnEGLGetError)(void);
pfnEGLGetError fEGLGetError;
typedef EGLImageKHR (* pfnCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
pfnCreateImageKHR fCreateImageKHR;
typedef EGLBoolean (* pfnDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
pfnDestroyImageKHR fDestroyImageKHR;
typedef void (* pfnImageTargetTexture2DOES)(GLenum target, EGLImageKHR image);
pfnImageTargetTexture2DOES fImageTargetTexture2DOES;
typedef void (* pfnBindTexture)(GLenum target, GLuint texture);
pfnBindTexture fBindTexture;
typedef GLenum (* pfnGLGetError)();
pfnGLGetError fGLGetError;
typedef void (*pfnGraphicBufferCtor)(void*, PRUint32 w, PRUint32 h, PRUint32 format, PRUint32 usage);
pfnGraphicBufferCtor fGraphicBufferCtor;
typedef void (*pfnGraphicBufferDtor)(void*);
pfnGraphicBufferDtor fGraphicBufferDtor;
typedef int (*pfnGraphicBufferLock)(void*, PRUint32 usage, unsigned char **addr);
pfnGraphicBufferLock fGraphicBufferLock;
typedef int (*pfnGraphicBufferLockRect)(void*, PRUint32 usage, const AndroidRect&, unsigned char **addr);
pfnGraphicBufferLockRect fGraphicBufferLockRect;
typedef int (*pfnGraphicBufferUnlock)(void*);
pfnGraphicBufferUnlock fGraphicBufferUnlock;
typedef void* (*pfnGraphicBufferGetNativeBuffer)(void*);
pfnGraphicBufferGetNativeBuffer fGraphicBufferGetNativeBuffer;
typedef int (*pfnGraphicBufferReallocate)(void*, PRUint32 w, PRUint32 h, PRUint32 format);
pfnGraphicBufferReallocate fGraphicBufferReallocate;
bool EnsureInitialized()
{
if (mInitialized) {
return true;
}
void *handle = dlopen(ANDROID_EGL_PATH, RTLD_LAZY);
if (!handle) {
LOG("Couldn't load EGL library");
return false;
}
fGetDisplay = (pfnGetDisplay)dlsym(handle, "eglGetDisplay");
fEGLGetError = (pfnEGLGetError)dlsym(handle, "eglGetError");
fCreateImageKHR = (pfnCreateImageKHR)dlsym(handle, "eglCreateImageKHR");
fDestroyImageKHR = (pfnDestroyImageKHR)dlsym(handle, "eglDestroyImageKHR");
if (!fGetDisplay || !fEGLGetError || !fCreateImageKHR || !fDestroyImageKHR) {
LOG("Failed to find some EGL functions");
return false;
}
handle = dlopen(ANDROID_GLES_PATH, RTLD_LAZY);
if (!handle) {
LOG("Couldn't load GL library");
return false;
}
fImageTargetTexture2DOES = (pfnImageTargetTexture2DOES)dlsym(handle, "glEGLImageTargetTexture2DOES");
fBindTexture = (pfnBindTexture)dlsym(handle, "glBindTexture");
fGLGetError = (pfnGLGetError)dlsym(handle, "glGetError");
if (!fImageTargetTexture2DOES || !fBindTexture || !fGLGetError) {
LOG("Failed to find some GL functions");
return false;
}
handle = dlopen(ANDROID_LIBUI_PATH, RTLD_LAZY);
if (!handle) {
LOG("Couldn't load libui.so");
return false;
}
fGraphicBufferCtor = (pfnGraphicBufferCtor)dlsym(handle, "_ZN7android13GraphicBufferC1Ejjij");
fGraphicBufferDtor = (pfnGraphicBufferDtor)dlsym(handle, "_ZN7android13GraphicBufferD1Ev");
fGraphicBufferLock = (pfnGraphicBufferLock)dlsym(handle, "_ZN7android13GraphicBuffer4lockEjPPv");
fGraphicBufferLockRect = (pfnGraphicBufferLockRect)dlsym(handle, "_ZN7android13GraphicBuffer4lockEjRKNS_4RectEPPv");
fGraphicBufferUnlock = (pfnGraphicBufferUnlock)dlsym(handle, "_ZN7android13GraphicBuffer6unlockEv");
fGraphicBufferGetNativeBuffer = (pfnGraphicBufferGetNativeBuffer)dlsym(handle, "_ZNK7android13GraphicBuffer15getNativeBufferEv");
fGraphicBufferReallocate = (pfnGraphicBufferReallocate)dlsym(handle, "_ZN7android13GraphicBuffer10reallocateEjjij");
if (!fGraphicBufferCtor || !fGraphicBufferDtor || !fGraphicBufferLock ||
!fGraphicBufferUnlock || !fGraphicBufferGetNativeBuffer) {
LOG("Failed to lookup some GraphicBuffer functions");
return false;
}
mInitialized = true;
return true;
}
private:
bool mInitialized;
} sGLFunctions;
namespace mozilla {
static bool ensureNoGLError(const char* name)
{
bool result = true;
GLuint error;
while ((error = glGetError()) != GL_NO_ERROR) {
LOG("GL error [%s]: %40x\n", name, error);
result = false;
}
return result;
}
AndroidGraphicBuffer::AndroidGraphicBuffer(PRUint32 width, PRUint32 height, PRUint32 usage,
gfxImageFormat format) :
mWidth(width)
, mHeight(height)
, mUsage(usage)
, mFormat(format)
, mHandle(0)
, mEGLImage(0)
{
}
AndroidGraphicBuffer::~AndroidGraphicBuffer()
{
DestroyBuffer();
}
void
AndroidGraphicBuffer::DestroyBuffer()
{
if (mHandle) {
if (sGLFunctions.EnsureInitialized()) {
sGLFunctions.fGraphicBufferDtor(mHandle);
}
free(mHandle);
mHandle = NULL;
}
if (mEGLImage) {
if (sGLFunctions.EnsureInitialized()) {
sGLFunctions.fDestroyImageKHR(sGLFunctions.fGetDisplay(EGL_DEFAULT_DISPLAY), mEGLImage);
mEGLImage = NULL;
}
}
}
bool
AndroidGraphicBuffer::EnsureBufferCreated(PRUint32 aWidth, PRUint32 aHeight, PRUint32 aUsage, gfxImageFormat aFormat)
{
if (!mHandle) {
mHandle = malloc(GRAPHIC_BUFFER_SIZE);
sGLFunctions.fGraphicBufferCtor(mHandle, mWidth, mHeight, GetAndroidFormat(aFormat), GetAndroidUsage(aUsage));
}
return true;
}
bool
AndroidGraphicBuffer::EnsureInitialized()
{
if (!sGLFunctions.EnsureInitialized()) {
return false;
}
EnsureBufferCreated(mWidth, mHeight, mUsage, mFormat);
return true;
}
bool
AndroidGraphicBuffer::Lock(PRUint32 aUsage, unsigned char **bits)
{
if (!EnsureInitialized())
return true;
return sGLFunctions.fGraphicBufferLock(mHandle, GetAndroidUsage(aUsage), bits) == 0;
}
bool
AndroidGraphicBuffer::Lock(PRUint32 aUsage, const nsIntRect& aRect, unsigned char **bits)
{
if (!EnsureInitialized())
return false;
AndroidRect rect;
rect.left = aRect.x;
rect.top = aRect.y;
rect.right = aRect.x + aRect.width;
rect.bottom = aRect.y + aRect.height;
return sGLFunctions.fGraphicBufferLockRect(mHandle, GetAndroidUsage(aUsage), rect, bits) == 0;
}
bool
AndroidGraphicBuffer::Unlock()
{
if (!EnsureInitialized())
return false;
return sGLFunctions.fGraphicBufferUnlock(mHandle) == 0;
}
bool
AndroidGraphicBuffer::Reallocate(PRUint32 aWidth, PRUint32 aHeight, gfxImageFormat aFormat)
{
if (!EnsureInitialized())
return false;
// Sometimes GraphicBuffer::reallocate just doesn't work. In those cases we'll just allocate a brand
// new buffer. If reallocate fails once, never try it again.
if (!gTryRealloc || sGLFunctions.fGraphicBufferReallocate(mHandle, aWidth, aHeight, GetAndroidFormat(aFormat)) != 0) {
DestroyBuffer();
EnsureBufferCreated(aWidth, aHeight, mUsage, aFormat);
gTryRealloc = false;
}
mWidth = aWidth;
mHeight = aHeight;
mFormat = aFormat;
return true;
}
PRUint32
AndroidGraphicBuffer::GetAndroidUsage(PRUint32 aUsage)
{
PRUint32 flags = 0;
if (aUsage & UsageSoftwareRead) {
flags |= GRALLOC_USAGE_SW_READ_OFTEN;
}
if (aUsage & UsageSoftwareWrite) {
flags |= GRALLOC_USAGE_SW_WRITE_OFTEN;
}
if (aUsage & UsageTexture) {
flags |= GRALLOC_USAGE_HW_TEXTURE;
}
if (aUsage & UsageTarget) {
flags |= GRALLOC_USAGE_HW_RENDER;
}
if (aUsage & Usage2D) {
flags |= GRALLOC_USAGE_HW_2D;
}
return flags;
}
PRUint32
AndroidGraphicBuffer::GetAndroidFormat(gfxImageFormat aFormat)
{
switch (aFormat) {
case gfxImageFormat::ImageFormatRGB24:
return HAL_PIXEL_FORMAT_RGBX_8888;
case gfxImageFormat::ImageFormatRGB16_565:
return HAL_PIXEL_FORMAT_RGB_565;
default:
return 0;
}
}
bool
AndroidGraphicBuffer::EnsureEGLImage()
{
if (mEGLImage)
return true;
if (!EnsureInitialized())
return false;
EGLint eglImgAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, EGL_NONE };
void* nativeBuffer = sGLFunctions.fGraphicBufferGetNativeBuffer(mHandle);
mEGLImage = sGLFunctions.fCreateImageKHR(sGLFunctions.fGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)nativeBuffer, eglImgAttrs);
return mEGLImage != NULL;
}
bool
AndroidGraphicBuffer::Bind()
{
if (!EnsureInitialized())
return false;
if (!EnsureEGLImage()) {
LOG("No valid EGLImage!");
return false;
}
sGLFunctions.fImageTargetTexture2DOES(GL_TEXTURE_2D, mEGLImage);
return ensureNoGLError("glEGLImageTargetTexture2DOES");
}
} /* mozilla */

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

@ -0,0 +1,99 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* James Willcox <jwillcox@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef AndroidGraphicBuffer_h_
#define AndroidGraphicBuffer_h_
#include "gfxASurface.h"
#include "nsRect.h"
namespace mozilla {
/**
* This class allows access to Android's direct texturing mechanism. Locking
* the buffer gives you a pointer you can read/write to directly. It is fully
* threadsafe, but you probably really want to use the AndroidDirectTexture
* class which will handle double buffering.
*
* In order to use the buffer in OpenGL, just call Bind() and it will attach
* to whatever texture is bound to GL_TEXTURE_2D.
*/
class AndroidGraphicBuffer
{
public:
enum {
UsageSoftwareRead = 1,
UsageSoftwareWrite = 1 << 1,
UsageTexture = 1 << 2,
UsageTarget = 1 << 3,
Usage2D = 1 << 4
};
AndroidGraphicBuffer(PRUint32 width, PRUint32 height, PRUint32 usage, gfxASurface::gfxImageFormat format);
virtual ~AndroidGraphicBuffer();
bool Lock(PRUint32 usage, unsigned char **bits);
bool Lock(PRUint32 usage, const nsIntRect& rect, unsigned char **bits);
bool Unlock();
bool Reallocate(PRUint32 aWidth, PRUint32 aHeight, gfxASurface::gfxImageFormat aFormat);
PRUint32 Width() { return mWidth; }
PRUint32 Height() { return mHeight; }
bool Bind();
private:
PRUint32 mWidth;
PRUint32 mHeight;
PRUint32 mUsage;
gfxASurface::gfxImageFormat mFormat;
bool EnsureInitialized();
bool EnsureEGLImage();
void DestroyBuffer();
bool EnsureBufferCreated(PRUint32 aWidth, PRUint32 aHeight, PRUint32 aUsage, gfxASurface::gfxImageFormat aFormat);
PRUint32 GetAndroidUsage(PRUint32 aUsage);
PRUint32 GetAndroidFormat(gfxASurface::gfxImageFormat aFormat);
void *mHandle;
void *mEGLImage;
};
} /* mozilla */
#endif /* AndroidGraphicBuffer_h_ */