Merge change I8d2de438 into eclair

* changes:
      fix [2143798] Need to figure out how to do video
This commit is contained in:
Android (Google) Code Review
2009-10-28 02:42:12 -04:00
12 changed files with 221 additions and 219 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}
// ---------------------------------------------------------------------------

View File

@@ -132,7 +132,6 @@ private:
size_t mBufferSize;
mutable sp<GraphicBuffer> mTempBitmap;
mutable LayerBase::Texture mTexture;
copybit_device_t* mBlitEngine;
};
class OverlaySource : public Source {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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,