зеркало из https://github.com/mozilla/gecko-dev.git
Bug 670930 - Add Android direct texture implementation
--HG-- extra : rebase_source : eb3f095e2663c0ebc0a03117ec8883d66dd8f1b5
This commit is contained in:
Родитель
8efa6b018a
Коммит
41962bb189
|
@ -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_ */
|
Загрузка…
Ссылка в новой задаче