Merge change I3b7d5cbe into eclair
* changes:
Copy the selection args when creating a CPO since callers often reuse the passed in array.
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 6880144..29531ca 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -865,7 +865,11 @@
}
// snapshot taken
-void CameraService::Client::handleShutter()
+void CameraService::Client::handleShutter(
+ image_rect_type *size // The width and height of yuv picture for
+ // registerBuffer. If this is NULL, use the picture
+ // size from parameters.
+)
{
// Play shutter sound.
if (mMediaPlayerClick.get() != NULL) {
@@ -889,12 +893,21 @@
if (mSurface != 0 && !mUseOverlay) {
int w, h;
CameraParameters params(mHardware->getParameters());
- params.getPictureSize(&w, &h);
uint32_t transform = 0;
if (params.getOrientation() == CameraParameters::CAMERA_ORIENTATION_PORTRAIT) {
LOGV("portrait mode");
transform = ISurface::BufferHeap::ROT_90;
}
+
+ if (size == NULL) {
+ params.getPictureSize(&w, &h);
+ } else {
+ w = size->width;
+ h = size->height;
+ w &= ~1;
+ h &= ~1;
+ LOGD("Snapshot image width=%d, height=%d", w, h);
+ }
ISurface::BufferHeap buffers(w, h, w, h,
PIXEL_FORMAT_YCbCr_420_SP, transform, 0, mHardware->getRawHeap());
@@ -1048,7 +1061,8 @@
switch (msgType) {
case CAMERA_MSG_SHUTTER:
- client->handleShutter();
+ // ext1 is the dimension of the yuv picture.
+ client->handleShutter((image_rect_type *)ext1);
break;
default:
sp<ICameraClient> c = client->mCameraClient;
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index 2fcf839..41c5d99 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -145,7 +145,7 @@
static sp<Client> getClientFromCookie(void* user);
void handlePreviewData(const sp<IMemory>&);
- void handleShutter();
+ void handleShutter(image_rect_type *image);
void handlePostview(const sp<IMemory>&);
void handleRawPicture(const sp<IMemory>&);
void handleCompressedPicture(const sp<IMemory>&);
diff --git a/include/ui/CameraHardwareInterface.h b/include/ui/CameraHardwareInterface.h
index af40f31..240c134 100644
--- a/include/ui/CameraHardwareInterface.h
+++ b/include/ui/CameraHardwareInterface.h
@@ -25,6 +25,15 @@
#include <ui/Overlay.h>
namespace android {
+/**
+ * The size of image for display.
+ */
+typedef struct image_rect_struct
+{
+ uint32_t width; /* Image width */
+ uint32_t height; /* Image height */
+} image_rect_type;
+
typedef void (*notify_callback)(int32_t msgType,
int32_t ext1,
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index 0c3d0ee..4b9e59b 100644
--- a/opengl/libagl/copybit.cpp
+++ b/opengl/libagl/copybit.cpp
@@ -154,6 +154,8 @@
int transform,
ogles_context_t* c)
{
+ status_t err = NO_ERROR;
+
// We assume checkContext has already been called and has already
// returned true.
@@ -200,6 +202,7 @@
const uint32_t enables = c->rasterizer.state.enables;
int planeAlpha = 255;
+ bool alphaPlaneWorkaround = false;
static const int tmu = 0;
texture_t& tev(c->rasterizer.state.texture[tmu]);
int32_t opFormat = textureObject->surface.format;
@@ -259,9 +262,10 @@
if (c->currentColorClamped.r == c->currentColorClamped.a &&
c->currentColorClamped.g == c->currentColorClamped.a &&
c->currentColorClamped.b == c->currentColorClamped.a) {
- // TODO: Need to emulate: RGBA source, color={a,a,a,a} / premult
- // and RGBA source, color={1,1,1,a} / regular-blending
- // (both are equivalent)
+ // TODO: RGBA source, color={1,1,1,a} / regular-blending
+ // is equivalent
+ alphaPlaneWorkaround = true;
+ break;
}
}
LOGD_IF(DEBUG_COPYBIT, "GGL_MODULATE");
@@ -331,13 +335,13 @@
tmp_w, tmp_h, src.format,
GraphicBuffer::USAGE_HW_2D);
- status_t err = tempBitmap->initCheck();
+ 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.format = tempBitmap->format;
tmp_dst.handle = (native_handle_t*)tempBitmap->getNativeBuffer()->handle;
tmp_rect.l = 0;
tmp_rect.t = 0;
@@ -359,13 +363,66 @@
textureToCopyBitImage(&cbSurface, cbSurface.format, target_hnd, &dst);
copybit_rect_t drect = {x, y, x+w, y+h};
- copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
- copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha);
- copybit->set_parameter(copybit, COPYBIT_DITHER,
- (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE);
- clipRectRegion it(c);
- status_t err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+ /* and now the alpha-plane hack. This handles the "Fade" case of a
+ * texture with an alpha channel.
+ */
+ if (alphaPlaneWorkaround) {
+ sp<GraphicBuffer> tempCb = new GraphicBuffer(
+ w, h, COPYBIT_FORMAT_RGB_565,
+ GraphicBuffer::USAGE_HW_2D);
+
+ err = tempCb->initCheck();
+
+ copybit_image_t tmpCbImg;
+ copybit_rect_t tmpCbRect;
+ tmpCbImg.w = w;
+ tmpCbImg.h = h;
+ tmpCbImg.format = tempCb->format;
+ tmpCbImg.handle = (native_handle_t*)tempCb->getNativeBuffer()->handle;
+ tmpCbRect.l = 0;
+ tmpCbRect.t = 0;
+ tmpCbRect.r = w;
+ tmpCbRect.b = h;
+
+ if (!err) {
+ // first make a copy of the destination buffer
+ region_iterator tmp_it(Region(Rect(w, h)));
+ 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,
+ &tmpCbImg, &dst, &tmpCbRect, &drect, &tmp_it);
+ }
+ if (!err) {
+ // then proceed as usual, but without the alpha plane
+ copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
+ copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
+ copybit->set_parameter(copybit, COPYBIT_DITHER,
+ (enables & GGL_ENABLE_DITHER) ?
+ COPYBIT_ENABLE : COPYBIT_DISABLE);
+ clipRectRegion it(c);
+ err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+ }
+ if (!err) {
+ // finally copy back the destination on top with 1-alphaplane
+ int invPlaneAlpha = 0xFF - fixedToByte(c->currentColorClamped.a);
+ clipRectRegion it(c);
+ copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+ copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, invPlaneAlpha);
+ copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+ err = copybit->stretch(copybit,
+ &dst, &tmpCbImg, &drect, &tmpCbRect, &it);
+ }
+ } else {
+ copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
+ copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha);
+ copybit->set_parameter(copybit, COPYBIT_DITHER,
+ (enables & GGL_ENABLE_DITHER) ?
+ COPYBIT_ENABLE : COPYBIT_DISABLE);
+ clipRectRegion it(c);
+ err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+ }
if (err != NO_ERROR) {
c->textures.tmu[0].texture->try_copybit = false;
}