Merge change I8d2de438 into eclair
* changes:
fix [2143798] Need to figure out how to do video
This commit is contained in:
@@ -66,7 +66,11 @@ public:
|
||||
GraphicBuffer();
|
||||
|
||||
// creates w * h buffer
|
||||
GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t ssage);
|
||||
GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage);
|
||||
|
||||
// create a buffer from an existing handle
|
||||
GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage,
|
||||
uint32_t stride, native_handle_t* handle, bool keepOwnership);
|
||||
|
||||
// return status
|
||||
status_t initCheck() const;
|
||||
@@ -94,9 +98,15 @@ protected:
|
||||
GraphicBuffer(const Parcel& reply);
|
||||
virtual ~GraphicBuffer();
|
||||
|
||||
enum {
|
||||
ownNone = 0,
|
||||
ownHandle = 1,
|
||||
ownData = 2,
|
||||
};
|
||||
|
||||
inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
|
||||
inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
|
||||
bool mOwner;
|
||||
uint8_t mOwner;
|
||||
|
||||
private:
|
||||
friend class Surface;
|
||||
|
||||
@@ -256,12 +256,16 @@ void DisplayHardware::init(uint32_t dpy)
|
||||
if (strstr(gl_extensions, "GL_OES_draw_texture")) {
|
||||
mFlags |= DRAW_TEXTURE_EXTENSION;
|
||||
}
|
||||
#ifdef EGL_ANDROID_image_native_buffer
|
||||
if (strstr( gl_extensions, "GL_OES_EGL_image") &&
|
||||
(strstr(egl_extensions, "EGL_KHR_image_base") ||
|
||||
strstr(egl_extensions, "EGL_KHR_image")) &&
|
||||
strstr(egl_extensions, "EGL_ANDROID_image_native_buffer")) {
|
||||
mFlags |= DIRECT_TEXTURE;
|
||||
}
|
||||
#else
|
||||
#warning "EGL_ANDROID_image_native_buffer not supported"
|
||||
#endif
|
||||
|
||||
// Unbind the context from this thread
|
||||
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
@@ -130,62 +130,6 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t Layer::initializeEglImageLocked(
|
||||
const sp<GraphicBuffer>& buffer, Texture* texture)
|
||||
{
|
||||
status_t err = NO_ERROR;
|
||||
|
||||
// we need to recreate the texture
|
||||
EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
|
||||
|
||||
// free the previous image
|
||||
if (texture->image != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(dpy, texture->image);
|
||||
texture->image = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
// construct an EGL_NATIVE_BUFFER_ANDROID
|
||||
android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
|
||||
|
||||
// create the new EGLImageKHR
|
||||
const EGLint attrs[] = {
|
||||
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
|
||||
EGL_NONE, EGL_NONE
|
||||
};
|
||||
texture->image = eglCreateImageKHR(
|
||||
dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
|
||||
(EGLClientBuffer)clientBuf, attrs);
|
||||
|
||||
LOGE_IF(texture->image == EGL_NO_IMAGE_KHR,
|
||||
"eglCreateImageKHR() failed. err=0x%4x",
|
||||
eglGetError());
|
||||
|
||||
if (texture->image != EGL_NO_IMAGE_KHR) {
|
||||
glBindTexture(GL_TEXTURE_2D, texture->name);
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
|
||||
(GLeglImageOES)texture->image);
|
||||
GLint error = glGetError();
|
||||
if (UNLIKELY(error != GL_NO_ERROR)) {
|
||||
// this failed, for instance, because we don't support NPOT.
|
||||
// FIXME: do something!
|
||||
LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
|
||||
"failed err=0x%04x",
|
||||
this, texture->image, error);
|
||||
mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
|
||||
err = INVALID_OPERATION;
|
||||
} else {
|
||||
// Everything went okay!
|
||||
texture->NPOTAdjust = false;
|
||||
texture->dirty = false;
|
||||
texture->width = clientBuf->width;
|
||||
texture->height = clientBuf->height;
|
||||
}
|
||||
} else {
|
||||
err = INVALID_OPERATION;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void Layer::reloadTexture(const Region& dirty)
|
||||
{
|
||||
Mutex::Autolock _l(mLock);
|
||||
@@ -199,10 +143,11 @@ void Layer::reloadTexture(const Region& dirty)
|
||||
mTextures[index].height = 0;
|
||||
}
|
||||
|
||||
#ifdef EGL_ANDROID_image_native_buffer
|
||||
if (mFlags & DisplayHardware::DIRECT_TEXTURE) {
|
||||
if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) {
|
||||
if (mTextures[index].dirty) {
|
||||
initializeEglImageLocked(buffer, &mTextures[index]);
|
||||
initializeEglImage(buffer, &mTextures[index]);
|
||||
}
|
||||
} else {
|
||||
if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width ||
|
||||
@@ -212,7 +157,7 @@ void Layer::reloadTexture(const Region& dirty)
|
||||
buffer->width, buffer->height, buffer->format,
|
||||
GraphicBuffer::USAGE_SW_WRITE_OFTEN |
|
||||
GraphicBuffer::USAGE_HW_TEXTURE);
|
||||
initializeEglImageLocked(
|
||||
initializeEglImage(
|
||||
mHybridBuffer, &mTextures[0]);
|
||||
}
|
||||
|
||||
@@ -279,7 +224,9 @@ void Layer::reloadTexture(const Region& dirty)
|
||||
buffer->unlock();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
|
||||
mTextures[i].image = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
@@ -85,8 +85,6 @@ private:
|
||||
}
|
||||
|
||||
void reloadTexture(const Region& dirty);
|
||||
status_t initializeEglImageLocked(
|
||||
const sp<GraphicBuffer>& buffer, Texture* texture);
|
||||
|
||||
uint32_t getEffectiveUsage(uint32_t usage) const;
|
||||
|
||||
|
||||
@@ -617,6 +617,63 @@ void LayerBase::loadTexture(Texture* texture,
|
||||
}
|
||||
}
|
||||
|
||||
status_t LayerBase::initializeEglImage(
|
||||
const sp<GraphicBuffer>& buffer, Texture* texture)
|
||||
{
|
||||
status_t err = NO_ERROR;
|
||||
|
||||
// we need to recreate the texture
|
||||
EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
|
||||
|
||||
// free the previous image
|
||||
if (texture->image != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(dpy, texture->image);
|
||||
texture->image = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
// construct an EGL_NATIVE_BUFFER_ANDROID
|
||||
android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
|
||||
|
||||
// create the new EGLImageKHR
|
||||
const EGLint attrs[] = {
|
||||
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
|
||||
EGL_NONE, EGL_NONE
|
||||
};
|
||||
texture->image = eglCreateImageKHR(
|
||||
dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
|
||||
(EGLClientBuffer)clientBuf, attrs);
|
||||
|
||||
LOGE_IF(texture->image == EGL_NO_IMAGE_KHR,
|
||||
"eglCreateImageKHR() failed. err=0x%4x",
|
||||
eglGetError());
|
||||
|
||||
if (texture->image != EGL_NO_IMAGE_KHR) {
|
||||
glBindTexture(GL_TEXTURE_2D, texture->name);
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
|
||||
(GLeglImageOES)texture->image);
|
||||
GLint error = glGetError();
|
||||
if (UNLIKELY(error != GL_NO_ERROR)) {
|
||||
// this failed, for instance, because we don't support NPOT.
|
||||
// FIXME: do something!
|
||||
LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
|
||||
"failed err=0x%04x",
|
||||
this, texture->image, error);
|
||||
mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
|
||||
err = INVALID_OPERATION;
|
||||
} else {
|
||||
// Everything went okay!
|
||||
texture->NPOTAdjust = false;
|
||||
texture->dirty = false;
|
||||
texture->width = clientBuf->width;
|
||||
texture->height = clientBuf->height;
|
||||
}
|
||||
} else {
|
||||
err = INVALID_OPERATION;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
int32_t LayerBaseClient::sIdentity = 0;
|
||||
|
||||
@@ -261,6 +261,8 @@ protected:
|
||||
void drawWithOpenGL(const Region& clip, const Texture& texture) const;
|
||||
void loadTexture(Texture* texture,
|
||||
const Region& dirty, const GGLSurface& t) const;
|
||||
status_t initializeEglImage(
|
||||
const sp<GraphicBuffer>& buffer, Texture* texture);
|
||||
|
||||
|
||||
sp<SurfaceFlinger> mFlinger;
|
||||
|
||||
@@ -339,12 +339,6 @@ LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
|
||||
mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);
|
||||
mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
|
||||
mLayer.forceVisibilityTransaction();
|
||||
|
||||
hw_module_t const* module;
|
||||
mBlitEngine = NULL;
|
||||
if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
|
||||
copybit_open(module, &mBlitEngine);
|
||||
}
|
||||
}
|
||||
|
||||
LayerBuffer::BufferSource::~BufferSource()
|
||||
@@ -352,8 +346,9 @@ LayerBuffer::BufferSource::~BufferSource()
|
||||
if (mTexture.name != -1U) {
|
||||
glDeleteTextures(1, &mTexture.name);
|
||||
}
|
||||
if (mBlitEngine) {
|
||||
copybit_close(mBlitEngine);
|
||||
if (mTexture.image != EGL_NO_IMAGE_KHR) {
|
||||
EGLDisplay dpy(mLayer.mFlinger->graphicPlane(0).getEGLDisplay());
|
||||
eglDestroyImageKHR(dpy, mTexture.image);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,122 +416,28 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const
|
||||
status_t err = NO_ERROR;
|
||||
NativeBuffer src(ourBuffer->getBuffer());
|
||||
const Rect transformedBounds(mLayer.getTransformedBounds());
|
||||
copybit_device_t* copybit = mBlitEngine;
|
||||
|
||||
if (copybit) {
|
||||
const int src_width = src.crop.r - src.crop.l;
|
||||
const int src_height = src.crop.b - src.crop.t;
|
||||
int W = transformedBounds.width();
|
||||
int H = transformedBounds.height();
|
||||
if (mLayer.getOrientation() & Transform::ROT_90) {
|
||||
int t(W); W=H; H=t;
|
||||
}
|
||||
if (UNLIKELY(mTexture.name == -1LU)) {
|
||||
mTexture.name = mLayer.createTexture();
|
||||
}
|
||||
|
||||
#ifdef EGL_ANDROID_get_render_buffer
|
||||
EGLDisplay dpy = eglGetCurrentDisplay();
|
||||
EGLSurface draw = eglGetCurrentSurface(EGL_DRAW);
|
||||
EGLClientBuffer clientBuf = eglGetRenderBufferANDROID(dpy, draw);
|
||||
android_native_buffer_t* nb = (android_native_buffer_t*)clientBuf;
|
||||
if (nb == 0) {
|
||||
err = BAD_VALUE;
|
||||
} else {
|
||||
copybit_image_t dst;
|
||||
dst.w = nb->width;
|
||||
dst.h = nb->height;
|
||||
dst.format = nb->format;
|
||||
dst.base = NULL; // unused by copybit on msm7k
|
||||
dst.handle = (native_handle_t *)nb->handle;
|
||||
#if defined(EGL_ANDROID_image_native_buffer)
|
||||
if (mLayer.mFlags & DisplayHardware::DIRECT_TEXTURE) {
|
||||
// NOTE: Assume the buffer is allocated with the proper USAGE flags
|
||||
sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
|
||||
src.crop.r, src.crop.b, src.img.format,
|
||||
GraphicBuffer::USAGE_HW_TEXTURE,
|
||||
src.img.w, src.img.handle, false);
|
||||
|
||||
/* With LayerBuffer, it is likely that we'll have to rescale the
|
||||
* surface, because this is often used for video playback or
|
||||
* camera-preview. Since we want these operation as fast as possible
|
||||
* we make sure we can use the 2D H/W even if it doesn't support
|
||||
* the requested scale factor, in which case we perform the scaling
|
||||
* in several passes. */
|
||||
|
||||
const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
|
||||
const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
|
||||
|
||||
float xscale = 1.0f;
|
||||
if (src_width > W*min) xscale = 1.0f / min;
|
||||
else if (src_width*mag < W) xscale = mag;
|
||||
|
||||
float yscale = 1.0f;
|
||||
if (src_height > H*min) yscale = 1.0f / min;
|
||||
else if (src_height*mag < H) yscale = mag;
|
||||
|
||||
if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) {
|
||||
const int tmp_w = floorf(src_width * xscale);
|
||||
const int tmp_h = floorf(src_height * yscale);
|
||||
|
||||
if (mTempBitmap==0 ||
|
||||
mTempBitmap->getWidth() < size_t(tmp_w) ||
|
||||
mTempBitmap->getHeight() < size_t(tmp_h)) {
|
||||
mTempBitmap.clear();
|
||||
mTempBitmap = new GraphicBuffer(
|
||||
tmp_w, tmp_h, src.img.format,
|
||||
GraphicBuffer::USAGE_HW_2D);
|
||||
err = mTempBitmap->initCheck();
|
||||
}
|
||||
|
||||
if (LIKELY(err == NO_ERROR)) {
|
||||
NativeBuffer tmp;
|
||||
tmp.img.w = tmp_w;
|
||||
tmp.img.h = tmp_h;
|
||||
tmp.img.format = src.img.format;
|
||||
tmp.img.handle = (native_handle_t*)mTempBitmap->getNativeBuffer()->handle;
|
||||
tmp.crop.l = 0;
|
||||
tmp.crop.t = 0;
|
||||
tmp.crop.r = tmp.img.w;
|
||||
tmp.crop.b = tmp.img.h;
|
||||
|
||||
region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b)));
|
||||
copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
|
||||
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
|
||||
copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
|
||||
err = copybit->stretch(copybit,
|
||||
&tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it);
|
||||
src = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
const Rect transformedBounds(mLayer.getTransformedBounds());
|
||||
const copybit_rect_t& drect =
|
||||
reinterpret_cast<const copybit_rect_t&>(transformedBounds);
|
||||
const State& s(mLayer.drawingState());
|
||||
region_iterator it(clip);
|
||||
|
||||
// pick the right orientation for this buffer
|
||||
int orientation = mLayer.getOrientation();
|
||||
if (UNLIKELY(mBufferHeap.transform)) {
|
||||
Transform rot90;
|
||||
GraphicPlane::orientationToTransfrom(
|
||||
ISurfaceComposer::eOrientation90, 0, 0, &rot90);
|
||||
const Transform& planeTransform(mLayer.graphicPlane(0).transform());
|
||||
const Layer::State& s(mLayer.drawingState());
|
||||
Transform tr(planeTransform * s.transform * rot90);
|
||||
orientation = tr.getOrientation();
|
||||
}
|
||||
|
||||
copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation);
|
||||
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
|
||||
copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
|
||||
|
||||
err = copybit->stretch(copybit,
|
||||
&dst, &src.img, &drect, &src.crop, &it);
|
||||
if (err != NO_ERROR) {
|
||||
LOGE("copybit failed (%s)", strerror(err));
|
||||
}
|
||||
}
|
||||
err = mLayer.initializeEglImage(graphicBuffer, &mTexture);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!copybit || err)
|
||||
{
|
||||
else {
|
||||
err = INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (err != NO_ERROR) {
|
||||
// OpenGL fall-back
|
||||
if (UNLIKELY(mTexture.name == -1LU)) {
|
||||
mTexture.name = mLayer.createTexture();
|
||||
}
|
||||
GLuint w = 0;
|
||||
GLuint h = 0;
|
||||
GGLSurface t;
|
||||
@@ -549,11 +450,11 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const
|
||||
t.data = (GGLubyte*)src.img.base;
|
||||
const Region dirty(Rect(t.width, t.height));
|
||||
mLayer.loadTexture(&mTexture, dirty, t);
|
||||
mTexture.transform = mBufferHeap.transform;
|
||||
mLayer.drawWithOpenGL(clip, mTexture);
|
||||
}
|
||||
}
|
||||
|
||||
mTexture.transform = mBufferHeap.transform;
|
||||
mLayer.drawWithOpenGL(clip, mTexture);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -132,7 +132,6 @@ private:
|
||||
size_t mBufferSize;
|
||||
mutable sp<GraphicBuffer> mTempBitmap;
|
||||
mutable LayerBase::Texture mTexture;
|
||||
copybit_device_t* mBlitEngine;
|
||||
};
|
||||
|
||||
class OverlaySource : public Source {
|
||||
|
||||
@@ -55,8 +55,8 @@ void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
|
||||
sHeight = h;
|
||||
sUseTexture = false;
|
||||
|
||||
#ifdef DIM_WITH_TEXTURE
|
||||
|
||||
#if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer)
|
||||
|
||||
#warning "using a texture to implement LayerDim"
|
||||
|
||||
/* On some h/w like msm7K, it is faster to use a texture because the
|
||||
@@ -69,7 +69,6 @@ void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
|
||||
uint32_t flags = hw.getFlags();
|
||||
|
||||
if (LIKELY(flags & DisplayHardware::DIRECT_TEXTURE)) {
|
||||
// TODO: api to pass the usage flags
|
||||
sp<GraphicBuffer> buffer = new GraphicBuffer(w, h, PIXEL_FORMAT_RGB_565,
|
||||
GraphicBuffer::USAGE_SW_WRITE_OFTEN |
|
||||
GraphicBuffer::USAGE_HW_TEXTURE);
|
||||
@@ -123,7 +122,7 @@ void LayerDim::onDraw(const Region& clip) const
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4x(0, 0, 0, alpha);
|
||||
|
||||
#ifdef DIM_WITH_TEXTURE
|
||||
#if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer)
|
||||
if (sUseTexture) {
|
||||
glBindTexture(GL_TEXTURE_2D, sTexId);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace android {
|
||||
// ===========================================================================
|
||||
|
||||
GraphicBuffer::GraphicBuffer()
|
||||
: BASE(), mOwner(false), mBufferMapper(GraphicBufferMapper::get()),
|
||||
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
|
||||
mInitCheck(NO_ERROR), mVStride(0), mIndex(-1)
|
||||
{
|
||||
width =
|
||||
@@ -50,7 +50,7 @@ GraphicBuffer::GraphicBuffer()
|
||||
|
||||
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
|
||||
PixelFormat reqFormat, uint32_t reqUsage)
|
||||
: BASE(), mOwner(false), mBufferMapper(GraphicBufferMapper::get()),
|
||||
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
|
||||
mInitCheck(NO_ERROR), mVStride(0), mIndex(-1)
|
||||
{
|
||||
width =
|
||||
@@ -62,8 +62,23 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
|
||||
mInitCheck = initSize(w, h, reqFormat, reqUsage);
|
||||
}
|
||||
|
||||
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
|
||||
PixelFormat inFormat, uint32_t inUsage,
|
||||
uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
|
||||
: BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
|
||||
mBufferMapper(GraphicBufferMapper::get()),
|
||||
mInitCheck(NO_ERROR), mVStride(0), mIndex(-1)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
stride = inStride;
|
||||
format = inFormat;
|
||||
usage = inUsage;
|
||||
handle = inHandle;
|
||||
}
|
||||
|
||||
GraphicBuffer::GraphicBuffer(const Parcel& data)
|
||||
: BASE(), mOwner(true), mBufferMapper(GraphicBufferMapper::get()),
|
||||
: BASE(), mOwner(ownHandle), mBufferMapper(GraphicBufferMapper::get()),
|
||||
mInitCheck(NO_ERROR), mVStride(0), mIndex(-1)
|
||||
{
|
||||
// we own the handle in this case
|
||||
@@ -83,10 +98,10 @@ GraphicBuffer::GraphicBuffer(const Parcel& data)
|
||||
GraphicBuffer::~GraphicBuffer()
|
||||
{
|
||||
if (handle) {
|
||||
if (mOwner) {
|
||||
if (mOwner == ownHandle) {
|
||||
native_handle_close(handle);
|
||||
native_handle_delete(const_cast<native_handle*>(handle));
|
||||
} else {
|
||||
} else if (mOwner == ownData) {
|
||||
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
|
||||
allocator.free(handle);
|
||||
}
|
||||
@@ -106,6 +121,9 @@ android_native_buffer_t* GraphicBuffer::getNativeBuffer() const
|
||||
status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f,
|
||||
uint32_t reqUsage)
|
||||
{
|
||||
if (mOwner != ownData)
|
||||
return INVALID_OPERATION;
|
||||
|
||||
if (handle) {
|
||||
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
|
||||
allocator.free(handle);
|
||||
|
||||
@@ -25,6 +25,13 @@ LOCAL_SRC_FILES:= \
|
||||
primitives.cpp.arm \
|
||||
vertex.cpp.arm
|
||||
|
||||
LOCAL_CFLAGS += -DLOG_TAG=\"libagl\"
|
||||
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
|
||||
LOCAL_CFLAGS += -fvisibility=hidden
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils libpixelflinger
|
||||
LOCAL_LDLIBS := -lpthread -ldl
|
||||
|
||||
ifeq ($(TARGET_ARCH),arm)
|
||||
LOCAL_SRC_FILES += fixed_asm.S iterators.S
|
||||
LOCAL_CFLAGS += -fstrict-aliasing
|
||||
@@ -38,15 +45,9 @@ endif
|
||||
ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1)
|
||||
LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS
|
||||
LOCAL_SRC_FILES += copybit.cpp
|
||||
LOCAL_SHARED_LIBRARIES += libui
|
||||
endif
|
||||
|
||||
LOCAL_CFLAGS += -DLOG_TAG=\"libagl\"
|
||||
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils libpixelflinger
|
||||
LOCAL_CFLAGS += -fvisibility=hidden
|
||||
|
||||
LOCAL_LDLIBS := -lpthread -ldl
|
||||
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
|
||||
LOCAL_MODULE:= libGLES_android
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include <hardware/copybit.h>
|
||||
#include <private/ui/android_natives_priv.h>
|
||||
|
||||
#include <ui/GraphicBuffer.h>
|
||||
#include <ui/Region.h>
|
||||
#include <ui/Rect.h>
|
||||
|
||||
|
||||
#define DEBUG_COPYBIT true
|
||||
|
||||
@@ -175,16 +179,6 @@ static bool copybit(GLint x, GLint y,
|
||||
dtdy /= screen_h;
|
||||
}
|
||||
dtdy = -dtdy; // see equation of dtdy above
|
||||
if (dsdx < c->copybits.minScale || dsdx > c->copybits.maxScale
|
||||
|| dtdy < c->copybits.minScale || dtdy > c->copybits.maxScale) {
|
||||
// The requested scale is out of the range the hardware
|
||||
// can support.
|
||||
LOGD_IF(DEBUG_COPYBIT,
|
||||
"scale out of range dsdx=%08x (Wcr=%d / w=%d), "
|
||||
"dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
|
||||
dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// copybit doesn't say anything about filtering, so we can't
|
||||
// discriminate. On msm7k, copybit will always filter.
|
||||
@@ -278,21 +272,93 @@ static bool copybit(GLint x, GLint y,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// LOGW("calling copybits");
|
||||
|
||||
copybit_device_t* copybit = c->copybits.blitEngine;
|
||||
copybit_image_t src;
|
||||
buffer_handle_t source_hnd = textureObject->buffer->handle;
|
||||
textureToCopyBitImage(&textureObject->surface, opFormat, source_hnd, &src);
|
||||
copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
|
||||
|
||||
/*
|
||||
* Below we perform extra passes needed to emulate things the h/w
|
||||
* cannot do.
|
||||
*/
|
||||
|
||||
const GLfixed minScaleInv = gglDivQ(0x10000, c->copybits.minScale, 16);
|
||||
const GLfixed maxScaleInv = gglDivQ(0x10000, c->copybits.maxScale, 16);
|
||||
|
||||
sp<GraphicBuffer> tempBitmap;
|
||||
|
||||
if (dsdx < maxScaleInv || dsdx > minScaleInv ||
|
||||
dtdy < maxScaleInv || dtdy > minScaleInv)
|
||||
{
|
||||
// The requested scale is out of the range the hardware
|
||||
// can support.
|
||||
LOGD_IF(DEBUG_COPYBIT,
|
||||
"scale out of range dsdx=%08x (Wcr=%d / w=%d), "
|
||||
"dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
|
||||
dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
|
||||
|
||||
int32_t xscale=0x10000, yscale=0x10000;
|
||||
if (dsdx > minScaleInv) xscale = c->copybits.minScale;
|
||||
else if (dsdx < maxScaleInv) xscale = c->copybits.maxScale;
|
||||
if (dtdy > minScaleInv) yscale = c->copybits.minScale;
|
||||
else if (dtdy < maxScaleInv) yscale = c->copybits.maxScale;
|
||||
dsdx = gglMulx(dsdx, xscale);
|
||||
dtdy = gglMulx(dtdy, yscale);
|
||||
|
||||
/* we handle only one step of resizing below. Handling an arbitrary
|
||||
* number is relatively easy (replace "if" above by "while"), but requires
|
||||
* two intermediate buffers and so far we never had the need.
|
||||
*/
|
||||
|
||||
if (dsdx < maxScaleInv || dsdx > minScaleInv ||
|
||||
dtdy < maxScaleInv || dtdy > minScaleInv) {
|
||||
LOGD_IF(DEBUG_COPYBIT,
|
||||
"scale out of range dsdx=%08x (Wcr=%d / w=%d), "
|
||||
"dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
|
||||
dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
|
||||
return false;
|
||||
}
|
||||
|
||||
const int tmp_w = gglMulx(srect.r - srect.l, xscale, 16);
|
||||
const int tmp_h = gglMulx(srect.b - srect.t, yscale, 16);
|
||||
|
||||
LOGD_IF(DEBUG_COPYBIT,
|
||||
"xscale=%08x, yscale=%08x, dsdx=%08x, dtdy=%08x, tmp_w=%d, tmp_h=%d",
|
||||
xscale, yscale, dsdx, dtdy, tmp_w, tmp_h);
|
||||
|
||||
tempBitmap = new GraphicBuffer(
|
||||
tmp_w, tmp_h, src.format,
|
||||
GraphicBuffer::USAGE_HW_2D);
|
||||
|
||||
status_t err = tempBitmap->initCheck();
|
||||
if (err == NO_ERROR) {
|
||||
copybit_image_t tmp_dst;
|
||||
copybit_rect_t tmp_rect;
|
||||
tmp_dst.w = tmp_w;
|
||||
tmp_dst.h = tmp_h;
|
||||
tmp_dst.format = src.format;
|
||||
tmp_dst.handle = (native_handle_t*)tempBitmap->getNativeBuffer()->handle;
|
||||
tmp_rect.l = 0;
|
||||
tmp_rect.t = 0;
|
||||
tmp_rect.r = tmp_dst.w;
|
||||
tmp_rect.b = tmp_dst.h;
|
||||
region_iterator tmp_it(Region(Rect(tmp_rect.r, tmp_rect.b)));
|
||||
copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
|
||||
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
|
||||
copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
|
||||
err = copybit->stretch(copybit,
|
||||
&tmp_dst, &src, &tmp_rect, &srect, &tmp_it);
|
||||
src = tmp_dst;
|
||||
srect = tmp_rect;
|
||||
}
|
||||
}
|
||||
|
||||
copybit_image_t dst;
|
||||
buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer;
|
||||
textureToCopyBitImage(&cbSurface, cbSurface.format, target_hnd, &dst);
|
||||
copybit_rect_t drect = {x, y, x+w, y+h};
|
||||
|
||||
copybit_image_t src;
|
||||
buffer_handle_t source_hnd = textureObject->buffer->handle;
|
||||
textureToCopyBitImage(&textureObject->surface, opFormat, source_hnd, &src);
|
||||
copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
|
||||
|
||||
copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
|
||||
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha);
|
||||
copybit->set_parameter(copybit, COPYBIT_DITHER,
|
||||
|
||||
Reference in New Issue
Block a user