mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
Implemented Async buffer copies for GLES2 using EGLImage
Run time loading of the library used this implementation:
e5f5d8fa1c/imagine/src/base/android/privateApi
This commit is contained in:
parent
5fd16a73b7
commit
fae25a494a
|
@ -0,0 +1,150 @@
|
|||
/* This file is part of Imagine.
|
||||
|
||||
Imagine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Imagine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Imagine. If not, see <http://www.gnu.org/licenses/> */
|
||||
|
||||
#include "gralloc.h"
|
||||
#include "GraphicBuffer.h"
|
||||
#include "Log.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
static gralloc_module_t const *grallocMod{};
|
||||
static alloc_device_t *allocDev{};
|
||||
|
||||
static void initAllocDev()
|
||||
{
|
||||
if(allocDev)
|
||||
return;
|
||||
if(!libhardware_dl())
|
||||
{
|
||||
LOG(LOG_ERROR,"Incompatible libhardware.so");
|
||||
return;
|
||||
}
|
||||
if(hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (hw_module_t const**)&grallocMod) != 0)
|
||||
{
|
||||
LOG(LOG_ERROR,"Can't load gralloc module");
|
||||
return;
|
||||
}
|
||||
gralloc_open((const hw_module_t*)grallocMod, &allocDev);
|
||||
if(!allocDev)
|
||||
{
|
||||
LOG(LOG_ERROR,"Can't load allocator device");
|
||||
return;
|
||||
}
|
||||
if(!allocDev->alloc || !allocDev->free)
|
||||
{
|
||||
LOG(LOG_ERROR,"Missing alloc/free functions");
|
||||
if(allocDev->common.close)
|
||||
gralloc_close(allocDev);
|
||||
else
|
||||
LOG(LOG_WARNING,"Missing device close function");
|
||||
allocDev = {};
|
||||
return;
|
||||
}
|
||||
LOG(LOG_MINIMAL,"alloc device:%p", allocDev);
|
||||
}
|
||||
|
||||
GraphicBuffer::GraphicBuffer()
|
||||
{
|
||||
initAllocDev();
|
||||
common.incRef = [](struct android_native_base_t *){ LOG(LOG_MINIMAL,"called incRef"); };
|
||||
common.decRef = [](struct android_native_base_t *){ LOG(LOG_MINIMAL,"called decRef"); };
|
||||
}
|
||||
|
||||
GraphicBuffer::~GraphicBuffer()
|
||||
{
|
||||
if(handle)
|
||||
{
|
||||
allocDev->free(allocDev, handle);
|
||||
}
|
||||
}
|
||||
|
||||
bool GraphicBuffer::reallocate(unsigned int w, unsigned int h, unsigned int f, unsigned int reqUsage)
|
||||
{
|
||||
if(handle && w == (unsigned int)width && h == (unsigned int)height && f == (unsigned int)format && reqUsage == (unsigned int)usage)
|
||||
return true;
|
||||
if(handle)
|
||||
{
|
||||
allocDev->free(allocDev, handle);
|
||||
handle = nullptr;
|
||||
}
|
||||
return initSize(w, h, f, reqUsage);
|
||||
}
|
||||
|
||||
bool GraphicBuffer::initSize(unsigned int w, unsigned int h, unsigned int f, unsigned int reqUsage)
|
||||
{
|
||||
auto err = allocDev->alloc(allocDev, w, h, f, reqUsage, &handle, &stride);
|
||||
if(!err)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
format = f;
|
||||
usage = reqUsage;
|
||||
return true;
|
||||
}
|
||||
LOG(LOG_ERROR,"alloc buffer failed: %s", std::strerror(-err));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GraphicBuffer::lock(unsigned int usage, void **vaddr)
|
||||
{
|
||||
return lock(usage, 0, 0, width, height, vaddr);
|
||||
}
|
||||
|
||||
bool GraphicBuffer::lock(unsigned int _usage, int _x0, int _y0, int _width, int _height, void **_vaddr)
|
||||
{
|
||||
if (_x0 < 0 || _width > width ||
|
||||
_y0 < 0 || _height > height)
|
||||
{
|
||||
LOG(LOG_ERROR,"locking pixels:[%d:%d:%d:%d] outside of buffer:%d,%d",
|
||||
_x0, _y0, _width, _height, width, height);
|
||||
return false;
|
||||
}
|
||||
auto err = grallocMod->lock(grallocMod, handle, _usage, _x0, _y0, _width, _height, _vaddr);
|
||||
return !err;
|
||||
}
|
||||
|
||||
void GraphicBuffer::unlock()
|
||||
{
|
||||
grallocMod->unlock(grallocMod, handle);
|
||||
}
|
||||
|
||||
unsigned int GraphicBuffer::getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
unsigned int GraphicBuffer::getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
unsigned int GraphicBuffer::getStride()
|
||||
{
|
||||
return stride;
|
||||
}
|
||||
|
||||
android_native_buffer_t *GraphicBuffer::getNativeBuffer()
|
||||
{
|
||||
return static_cast<android_native_buffer_t*>(this);
|
||||
}
|
||||
|
||||
bool GraphicBuffer::hasBufferMapper()
|
||||
{
|
||||
return allocDev;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
/* This file is part of Imagine.
|
||||
|
||||
Imagine is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Imagine is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Imagine. If not, see <http://www.gnu.org/licenses/> */
|
||||
|
||||
#include "gralloc.h"
|
||||
|
||||
// Wrapper for ANativeWindowBuffer (android_native_buffer_t)
|
||||
// similar to GraphicBuffer class in Android frameworks
|
||||
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
class GraphicBuffer : public android_native_buffer_t
|
||||
{
|
||||
public:
|
||||
GraphicBuffer();
|
||||
~GraphicBuffer();
|
||||
bool reallocate(unsigned int w, unsigned int h, unsigned int format, unsigned int usage);
|
||||
bool lock(unsigned int usage, void **vaddr);
|
||||
bool lock(unsigned int _usage, int _x0, int _y0, int _width, int _height, void **_vaddr);
|
||||
void unlock();
|
||||
unsigned int getWidth();
|
||||
unsigned int getHeight();
|
||||
unsigned int getStride();
|
||||
android_native_buffer_t *getNativeBuffer();
|
||||
static bool hasBufferMapper();
|
||||
|
||||
private:
|
||||
bool initSize(unsigned int w, unsigned int h, unsigned int format, unsigned int usage);
|
||||
};
|
||||
|
||||
}
|
359
src/Graphics/OpenGLContext/GraphicBufferPrivateApi/gralloc.h
Normal file
359
src/Graphics/OpenGLContext/GraphicBufferPrivateApi/gralloc.h
Normal file
|
@ -0,0 +1,359 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libhardware.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* pixel format definitions
|
||||
*/
|
||||
|
||||
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,
|
||||
|
||||
/* 0x8 - 0xFF range unavailable */
|
||||
|
||||
/*
|
||||
* 0x100 - 0x1FF
|
||||
*
|
||||
* This range is reserved for pixel formats that are specific to the HAL
|
||||
* implementation. Implementations can use any value in this range to
|
||||
* communicate video pixel formats between their HAL modules. These formats
|
||||
* must not have an alpha channel. Additionally, an EGLimage created from a
|
||||
* gralloc buffer of one of these formats must be supported for use with the
|
||||
* GL_OES_EGL_image_external OpenGL ES extension.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Android YUV format:
|
||||
*
|
||||
* This format is exposed outside of the HAL to software
|
||||
* decoders and applications.
|
||||
* EGLImageKHR must support it in conjunction with the
|
||||
* OES_EGL_image_external extension.
|
||||
*
|
||||
* YV12 is 4:2:0 YCrCb planar format comprised of a WxH Y plane followed
|
||||
* by (W/2) x (H/2) Cr and Cb planes.
|
||||
*
|
||||
* This format assumes
|
||||
* - an even width
|
||||
* - an even height
|
||||
* - a horizontal stride multiple of 16 pixels
|
||||
* - a vertical stride equal to the height
|
||||
*
|
||||
* y_size = stride * height
|
||||
* c_size = ALIGN(stride/2, 16) * height/2
|
||||
* size = y_size + c_size * 2
|
||||
* cr_offset = y_size
|
||||
* cb_offset = y_size + c_size
|
||||
*
|
||||
*/
|
||||
HAL_PIXEL_FORMAT_YV12 = 0x32315659, // YCrCb 4:2:0 Planar
|
||||
|
||||
|
||||
|
||||
/* Legacy formats (deprecated), used by ImageFormat.java */
|
||||
HAL_PIXEL_FORMAT_YCbCr_422_SP = 0x10, // NV16
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP = 0x11, // NV21
|
||||
HAL_PIXEL_FORMAT_YCbCr_422_I = 0x14, // YUY2
|
||||
};
|
||||
|
||||
// hardware/gralloc.h
|
||||
|
||||
#define GRALLOC_HARDWARE_MODULE_ID "gralloc"
|
||||
|
||||
#define GRALLOC_HARDWARE_GPU0 "gpu0"
|
||||
|
||||
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 = 0x00000C00,
|
||||
/* 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,
|
||||
};
|
||||
|
||||
|
||||
typedef const native_handle* buffer_handle_t;
|
||||
|
||||
/**
|
||||
* Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
|
||||
* and the fields of this data structure must begin with hw_module_t
|
||||
* followed by module specific information.
|
||||
*/
|
||||
typedef struct gralloc_module_t {
|
||||
struct hw_module_t common;
|
||||
|
||||
/*
|
||||
* (*registerBuffer)() must be called before a buffer_handle_t that has not
|
||||
* been created with (*alloc_device_t::alloc)() can be used.
|
||||
*
|
||||
* This is intended to be used with buffer_handle_t's that have been
|
||||
* received in this process through IPC.
|
||||
*
|
||||
* This function checks that the handle is indeed a valid one and prepares
|
||||
* it for use with (*lock)() and (*unlock)().
|
||||
*
|
||||
* It is not necessary to call (*registerBuffer)() on a handle created
|
||||
* with (*alloc_device_t::alloc)().
|
||||
*
|
||||
* returns an error if this buffer_handle_t is not valid.
|
||||
*/
|
||||
int (*registerBuffer)(struct gralloc_module_t const* module,
|
||||
buffer_handle_t handle);
|
||||
|
||||
/*
|
||||
* (*unregisterBuffer)() is called once this handle is no longer needed in
|
||||
* this process. After this call, it is an error to call (*lock)(),
|
||||
* (*unlock)(), or (*registerBuffer)().
|
||||
*
|
||||
* This function doesn't close or free the handle itself; this is done
|
||||
* by other means, usually through libcutils's native_handle_close() and
|
||||
* native_handle_free().
|
||||
*
|
||||
* It is an error to call (*unregisterBuffer)() on a buffer that wasn't
|
||||
* explicitly registered first.
|
||||
*/
|
||||
int (*unregisterBuffer)(struct gralloc_module_t const* module,
|
||||
buffer_handle_t handle);
|
||||
|
||||
/*
|
||||
* The (*lock)() method is called before a buffer is accessed for the
|
||||
* specified usage. This call may block, for instance if the h/w needs
|
||||
* to finish rendering or if CPU caches need to be synchronized.
|
||||
*
|
||||
* The caller promises to modify only pixels in the area specified
|
||||
* by (l,t,w,h).
|
||||
*
|
||||
* The content of the buffer outside of the specified area is NOT modified
|
||||
* by this call.
|
||||
*
|
||||
* If usage specifies GRALLOC_USAGE_SW_*, vaddr is filled with the address
|
||||
* of the buffer in virtual memory.
|
||||
*
|
||||
* THREADING CONSIDERATIONS:
|
||||
*
|
||||
* It is legal for several different threads to lock a buffer from
|
||||
* read access, none of the threads are blocked.
|
||||
*
|
||||
* However, locking a buffer simultaneously for write or read/write is
|
||||
* undefined, but:
|
||||
* - shall not result in termination of the process
|
||||
* - shall not block the caller
|
||||
* It is acceptable to return an error or to leave the buffer's content
|
||||
* into an indeterminate state.
|
||||
*
|
||||
* If the buffer was created with a usage mask incompatible with the
|
||||
* requested usage flags here, -EINVAL is returned.
|
||||
*
|
||||
*/
|
||||
|
||||
int (*lock)(struct gralloc_module_t const* module,
|
||||
buffer_handle_t handle, int usage,
|
||||
int l, int t, int w, int h,
|
||||
void** vaddr);
|
||||
|
||||
|
||||
/*
|
||||
* The (*unlock)() method must be called after all changes to the buffer
|
||||
* are completed.
|
||||
*/
|
||||
|
||||
int (*unlock)(struct gralloc_module_t const* module,
|
||||
buffer_handle_t handle);
|
||||
|
||||
|
||||
/* reserved for future use */
|
||||
int (*perform)(struct gralloc_module_t const* module,
|
||||
int operation, ... );
|
||||
|
||||
/* reserved for future use */
|
||||
void* reserved_proc[7];
|
||||
} gralloc_module_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Every device data structure must begin with hw_device_t
|
||||
* followed by module specific public methods and attributes.
|
||||
*/
|
||||
|
||||
typedef struct alloc_device_t {
|
||||
struct hw_device_t common;
|
||||
|
||||
/*
|
||||
* (*alloc)() Allocates a buffer in graphic memory with the requested
|
||||
* parameters and returns a buffer_handle_t and the stride in pixels to
|
||||
* allow the implementation to satisfy hardware constraints on the width
|
||||
* of a pixmap (eg: it may have to be multiple of 8 pixels).
|
||||
* The CALLER TAKES OWNERSHIP of the buffer_handle_t.
|
||||
*
|
||||
* Returns 0 on success or -errno on error.
|
||||
*/
|
||||
|
||||
int (*alloc)(struct alloc_device_t* dev,
|
||||
int w, int h, int format, int usage,
|
||||
buffer_handle_t* handle, int* stride);
|
||||
|
||||
/*
|
||||
* (*free)() Frees a previously allocated buffer.
|
||||
* Behavior is undefined if the buffer is still mapped in any process,
|
||||
* but shall not result in termination of the program or security breaches
|
||||
* (allowing a process to get access to another process' buffers).
|
||||
* THIS FUNCTION TAKES OWNERSHIP of the buffer_handle_t which becomes
|
||||
* invalid after the call.
|
||||
*
|
||||
* Returns 0 on success or -errno on error.
|
||||
*/
|
||||
int (*free)(struct alloc_device_t* dev,
|
||||
buffer_handle_t handle);
|
||||
|
||||
/* This hook is OPTIONAL.
|
||||
*
|
||||
* If non NULL it will be caused by SurfaceFlinger on dumpsys
|
||||
*/
|
||||
void (*dump)(struct alloc_device_t *dev, char *buff, int buff_len);
|
||||
|
||||
void* reserved_proc[7];
|
||||
} alloc_device_t;
|
||||
|
||||
|
||||
/** convenience API for opening and closing a supported device */
|
||||
|
||||
static inline int gralloc_open(const struct hw_module_t* module,
|
||||
struct alloc_device_t** device) {
|
||||
return module->methods->open(module,
|
||||
GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device);
|
||||
}
|
||||
|
||||
static inline int gralloc_close(struct alloc_device_t* device) {
|
||||
return device->common.close(&device->common);
|
||||
}
|
||||
|
||||
// ui/egl/android_natives.h
|
||||
|
||||
#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \
|
||||
(((unsigned)(a)<<24)|((unsigned)(b)<<16)|((unsigned)(c)<<8)|(unsigned)(d))
|
||||
|
||||
#define ANDROID_NATIVE_BUFFER_MAGIC \
|
||||
ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r')
|
||||
|
||||
|
||||
typedef struct android_native_base_t
|
||||
{
|
||||
/* a magic value defined by the actual EGL native type */
|
||||
int magic;
|
||||
|
||||
/* the sizeof() of the actual EGL native type */
|
||||
int version;
|
||||
|
||||
void* reserved[4];
|
||||
|
||||
/* reference-counting interface */
|
||||
void (*incRef)(struct android_native_base_t* base);
|
||||
void (*decRef)(struct android_native_base_t* base);
|
||||
} android_native_base_t;
|
||||
|
||||
// ui/android_native_buffer.h
|
||||
|
||||
struct android_native_buffer_t
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
constexpr android_native_buffer_t() :
|
||||
common{ANDROID_NATIVE_BUFFER_MAGIC, sizeof(android_native_buffer_t)},
|
||||
width{0}, height{0}, stride{0}, format{0}, usage{0}, reserved{}, handle{}, reserved_proc{}
|
||||
{}
|
||||
#endif
|
||||
|
||||
struct android_native_base_t common;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
int stride;
|
||||
int format;
|
||||
int usage;
|
||||
|
||||
void* reserved[2];
|
||||
|
||||
buffer_handle_t handle;
|
||||
|
||||
void* reserved_proc[8];
|
||||
};
|
||||
|
||||
// include/pixelflinger/format.h
|
||||
|
||||
enum GGLPixelFormat {
|
||||
// these constants need to match those
|
||||
// in graphics/PixelFormat.java, ui/PixelFormat.h, BlitHardware.h
|
||||
GGL_PIXEL_FORMAT_UNKNOWN = 0,
|
||||
GGL_PIXEL_FORMAT_NONE = 0,
|
||||
|
||||
GGL_PIXEL_FORMAT_RGBA_8888 = 1, // 4x8-bit ARGB
|
||||
GGL_PIXEL_FORMAT_RGBX_8888 = 2, // 3x8-bit RGB stored in 32-bit chunks
|
||||
GGL_PIXEL_FORMAT_RGB_888 = 3, // 3x8-bit RGB
|
||||
GGL_PIXEL_FORMAT_RGB_565 = 4, // 16-bit RGB
|
||||
GGL_PIXEL_FORMAT_BGRA_8888 = 5, // 4x8-bit BGRA
|
||||
GGL_PIXEL_FORMAT_RGBA_5551 = 6, // 16-bit RGBA
|
||||
GGL_PIXEL_FORMAT_RGBA_4444 = 7, // 16-bit RGBA
|
||||
|
||||
GGL_PIXEL_FORMAT_A_8 = 8, // 8-bit A
|
||||
GGL_PIXEL_FORMAT_L_8 = 9, // 8-bit L (R=G=B = L)
|
||||
GGL_PIXEL_FORMAT_LA_88 = 0xA, // 16-bit LA
|
||||
GGL_PIXEL_FORMAT_RGB_332 = 0xB, // 8-bit RGB (non paletted)
|
||||
|
||||
// reserved range. don't use.
|
||||
GGL_PIXEL_FORMAT_RESERVED_10 = 0x10,
|
||||
GGL_PIXEL_FORMAT_RESERVED_11 = 0x11,
|
||||
GGL_PIXEL_FORMAT_RESERVED_12 = 0x12,
|
||||
GGL_PIXEL_FORMAT_RESERVED_13 = 0x13,
|
||||
GGL_PIXEL_FORMAT_RESERVED_14 = 0x14,
|
||||
GGL_PIXEL_FORMAT_RESERVED_15 = 0x15,
|
||||
GGL_PIXEL_FORMAT_RESERVED_16 = 0x16,
|
||||
GGL_PIXEL_FORMAT_RESERVED_17 = 0x17,
|
||||
|
||||
// reserved/special formats
|
||||
GGL_PIXEL_FORMAT_Z_16 = 0x18,
|
||||
GGL_PIXEL_FORMAT_S_8 = 0x19,
|
||||
GGL_PIXEL_FORMAT_SZ_24 = 0x1A,
|
||||
GGL_PIXEL_FORMAT_SZ_8 = 0x1B,
|
||||
|
||||
// reserved range. don't use.
|
||||
GGL_PIXEL_FORMAT_RESERVED_20 = 0x20,
|
||||
GGL_PIXEL_FORMAT_RESERVED_21 = 0x21,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include "libhardware.h"
|
||||
#include "Log.h"
|
||||
|
||||
typedef int (*hw_get_moduleProto)(const char *id, const struct hw_module_t **module);
|
||||
|
||||
static hw_get_moduleProto hw_get_moduleSym = 0;
|
||||
|
||||
bool libhardware_dl()
|
||||
{
|
||||
if(hw_get_moduleSym)
|
||||
return true;
|
||||
void *libhardware = dlopen("libhardware.so", RTLD_LAZY);
|
||||
if(!libhardware)
|
||||
{
|
||||
LOG(LOG_ERROR, "libhardware not found");
|
||||
return false;
|
||||
}
|
||||
hw_get_moduleSym = (hw_get_moduleProto)dlsym(libhardware, "hw_get_module");
|
||||
if(!hw_get_moduleSym)
|
||||
{
|
||||
LOG(LOG_ERROR, "missing libhardware functions");
|
||||
dlclose(libhardware);
|
||||
hw_get_moduleSym = 0;
|
||||
return false;
|
||||
}
|
||||
LOG(LOG_ERROR, "libhardware symbols loaded");
|
||||
return true;
|
||||
}
|
||||
|
||||
int hw_get_module(const char *id, const struct hw_module_t **module)
|
||||
{
|
||||
assert(hw_get_moduleSym);
|
||||
return hw_get_moduleSym(id, module);
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool libhardware_dl();
|
||||
|
||||
// hardware/hardware.h
|
||||
|
||||
struct hw_module_t;
|
||||
struct hw_module_methods_t;
|
||||
struct hw_device_t;
|
||||
|
||||
/**
|
||||
* Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
|
||||
* and the fields of this data structure must begin with hw_module_t
|
||||
* followed by module specific information.
|
||||
*/
|
||||
typedef struct hw_module_t {
|
||||
/** tag must be initialized to HARDWARE_MODULE_TAG */
|
||||
uint32_t tag;
|
||||
|
||||
/** major version number for the module */
|
||||
uint16_t version_major;
|
||||
|
||||
/** minor version number of the module */
|
||||
uint16_t version_minor;
|
||||
|
||||
/** Identifier of module */
|
||||
const char *id;
|
||||
|
||||
/** Name of this module */
|
||||
const char *name;
|
||||
|
||||
/** Author/owner/implementor of the module */
|
||||
const char *author;
|
||||
|
||||
/** Modules methods */
|
||||
struct hw_module_methods_t* methods;
|
||||
|
||||
/** module's dso */
|
||||
void* dso;
|
||||
|
||||
/** padding to 128 bytes, reserved for future use */
|
||||
uint32_t reserved[32-7];
|
||||
|
||||
} hw_module_t;
|
||||
|
||||
typedef struct hw_module_methods_t {
|
||||
/** Open a specific device */
|
||||
int (*open)(const struct hw_module_t* module, const char* id,
|
||||
struct hw_device_t** device);
|
||||
|
||||
} hw_module_methods_t;
|
||||
|
||||
/**
|
||||
* Every device data structure must begin with hw_device_t
|
||||
* followed by module specific public methods and attributes.
|
||||
*/
|
||||
struct hw_device_t {
|
||||
/** tag must be initialized to HARDWARE_DEVICE_TAG */
|
||||
uint32_t tag;
|
||||
|
||||
/** version number for hw_device_t */
|
||||
uint32_t version;
|
||||
|
||||
/** reference to the module this device belongs to */
|
||||
struct hw_module_t* module;
|
||||
|
||||
/** padding reserved for future use */
|
||||
uint32_t reserved[12];
|
||||
|
||||
/** Close this device */
|
||||
int (*close)(struct hw_device_t* device);
|
||||
|
||||
};
|
||||
|
||||
int hw_get_module(const char *id, const struct hw_module_t **module);
|
||||
|
||||
// cutils/native_handle.h
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int version; /* sizeof(native_handle_t) */
|
||||
int numFds; /* number of file-descriptors at &data[0] */
|
||||
int numInts; /* number of ints at &data[numFds] */
|
||||
int data[0]; /* numFds + numInts ints */
|
||||
} native_handle_t;
|
||||
|
||||
/* keep the old definition for backward source-compatibility */
|
||||
typedef native_handle_t native_handle;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -10,9 +10,9 @@ using namespace graphics;
|
|||
ColorBufferReaderWithEGLImage::ColorBufferReaderWithEGLImage(CachedTexture *_pTexture, CachedBindTexture *_bindTexture)
|
||||
: graphics::ColorBufferReader(_pTexture)
|
||||
, m_bindTexture(_bindTexture)
|
||||
, m_image(0)
|
||||
{
|
||||
m_glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
||||
m_window = new GraphicBuffer();
|
||||
_initBuffers();
|
||||
}
|
||||
|
||||
|
@ -24,14 +24,14 @@ ColorBufferReaderWithEGLImage::~ColorBufferReaderWithEGLImage()
|
|||
|
||||
void ColorBufferReaderWithEGLImage::_initBuffers()
|
||||
{
|
||||
m_window->reallocate(m_pTexture->realWidth, m_pTexture->realHeight,
|
||||
PIXEL_FORMAT_RGBA_8888, GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE);
|
||||
m_window.reallocate(m_pTexture->realWidth, m_pTexture->realHeight,
|
||||
HAL_PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_TEXTURE);
|
||||
EGLint eglImgAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, EGL_NONE };
|
||||
|
||||
if(m_image == 0)
|
||||
{
|
||||
m_image = eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT,
|
||||
EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)m_window->getNativeBuffer(), eglImgAttrs);
|
||||
EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)m_window.getNativeBuffer(), eglImgAttrs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,13 +61,13 @@ u8 * ColorBufferReaderWithEGLImage::readPixels(s32 _x0, s32 _y0, u32 _width, u32
|
|||
int widthBytes = _width*colorFormatBytes;
|
||||
int strideBytes = m_pTexture->realWidth * colorFormatBytes;
|
||||
|
||||
m_window->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &ptr);
|
||||
m_window.lock(GRALLOC_USAGE_SW_READ_OFTEN, &ptr);
|
||||
|
||||
for (unsigned int lnIndex = 0; lnIndex < _height; ++lnIndex) {
|
||||
memcpy(pixelData + lnIndex*widthBytes, reinterpret_cast<char*>(ptr) + ((lnIndex + _y0)*strideBytes), widthBytes);
|
||||
}
|
||||
|
||||
m_window->unlock();
|
||||
m_window.unlock();
|
||||
} else {
|
||||
glReadPixels(_x0, _y0, _width, _height, colorFormat, colorType, pixelData);
|
||||
}
|
||||
|
|
|
@ -3,14 +3,12 @@
|
|||
#include <Graphics/ColorBufferReader.h>
|
||||
#include "opengl_CachedFunctions.h"
|
||||
|
||||
#include <ui/GraphicBuffer.h>
|
||||
#include <android/native_window.h>
|
||||
#include <Graphics/OpenGLContext/GraphicBUfferPrivateApi/GraphicBuffer.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, EGLImageKHR image);
|
||||
|
||||
using namespace android;
|
||||
|
||||
namespace opengl {
|
||||
|
||||
|
@ -28,7 +26,7 @@ private:
|
|||
void _initBuffers();
|
||||
|
||||
CachedBindTexture * m_bindTexture;
|
||||
GraphicBuffer* m_window;
|
||||
GraphicBuffer m_window{};
|
||||
EGLImageKHR m_image;
|
||||
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC m_glEGLImageTargetTexture2DOES;
|
||||
};
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
#include <assert.h>
|
||||
#include <Log.h>
|
||||
#include <Config.h>
|
||||
#include <Graphics/Parameters.h>
|
||||
#include "opengl_ContextImpl.h"
|
||||
#include "opengl_BufferedDrawer.h"
|
||||
#include "opengl_UnbufferedDrawer.h"
|
||||
#include "opengl_ColorBufferReaderWithPixelBuffer.h"
|
||||
#include "opengl_ColorBufferReaderWithBufferStorage.h"
|
||||
//#include "opengl_ColorBufferReaderWithEGLImage.h"
|
||||
#include "opengl_ColorBufferReaderWithEGLImage.h"
|
||||
#include "opengl_ColorBufferReaderWithReadPixels.h"
|
||||
#include "opengl_Utils.h"
|
||||
#include "GLSL/glsl_CombinerProgramBuilder.h"
|
||||
|
@ -297,17 +298,17 @@ graphics::PixelReadBuffer * ContextImpl::createPixelReadBuffer(size_t _sizeInByt
|
|||
|
||||
graphics::ColorBufferReader * ContextImpl::createColorBufferReader(CachedTexture * _pTexture)
|
||||
{
|
||||
/*
|
||||
#if defined(EGL) && defined(OS_ANDROID)
|
||||
return new ColorBufferReaderWithEGLImage(_pTexture, m_cachedFunctions->getCachedBindTexture());
|
||||
#endif*/
|
||||
|
||||
if (m_glInfo.bufferStorage)
|
||||
return new ColorBufferReaderWithBufferStorage(_pTexture, m_cachedFunctions->getCachedBindBuffer());
|
||||
|
||||
if (!m_glInfo.isGLES2)
|
||||
return new ColorBufferReaderWithPixelBuffer(_pTexture, m_cachedFunctions->getCachedBindBuffer());
|
||||
|
||||
#if defined(EGL) && defined(OS_ANDROID)
|
||||
if(config.frameBufferEmulation.copyToRDRAM == Config::ctAsync)
|
||||
return new ColorBufferReaderWithEGLImage(_pTexture, m_cachedFunctions->getCachedBindTexture());
|
||||
#endif
|
||||
|
||||
return new ColorBufferReaderWithReadPixels(_pTexture);
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ MY_LOCAL_SRC_FILES := \
|
|||
$(SRCDIR)/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/opengl_ColorBufferReaderWithReadPixels.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/opengl_ColorBufferReaderWithEGLImage.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/opengl_ContextImpl.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/opengl_GLInfo.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/opengl_Parameters.cpp \
|
||||
|
@ -105,7 +106,9 @@ MY_LOCAL_SRC_FILES := \
|
|||
$(SRCDIR)/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/GLSL/glsl_SpecialShadersFactory.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/GLSL/glsl_Utils.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/mupen64plus/mupen64plus_DisplayWindow.cpp
|
||||
$(SRCDIR)/Graphics/OpenGLContext/mupen64plus/mupen64plus_DisplayWindow.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/GraphicBufferPrivateApi/GraphicBuffer.cpp \
|
||||
$(SRCDIR)/Graphics/OpenGLContext/GraphicBufferPrivateApi/libhardware.cpp \
|
||||
|
||||
MY_LOCAL_CFLAGS := \
|
||||
$(COMMON_CFLAGS) \
|
||||
|
|
Loading…
Reference in New Issue
Block a user