make sure screenshot are in a format supported by Bitmap.java
Change-Id: Ic3ab7db31f1810ea19aac55d448dd1d4d6c419e4
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index ec10536..66b1f05 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -62,13 +62,16 @@
class ScreenshotPixelRef : public SkPixelRef {
public:
ScreenshotPixelRef(SkColorTable* ctable) {
- fCTable = ctable;
+ mCTable = ctable;
+ mPixels = NULL;
+ mFormat = 0;
SkSafeRef(ctable);
setImmutable();
}
virtual ~ScreenshotPixelRef() {
- SkSafeUnref(fCTable);
+ SkSafeUnref(mCTable);
+ delete [] mPixels;
}
status_t update(const sp<IBinder>& display, int width, int height,
@@ -78,34 +81,78 @@
? mScreenshot.update(display, width, height)
: mScreenshot.update(display, width, height, minLayer, maxLayer))
: mScreenshot.update(display);
- if (res != NO_ERROR) {
- return res;
- }
+ if (res == NO_ERROR) {
+ mWidth = mScreenshot.getWidth();
+ mHeight = mScreenshot.getHeight();
+ mStride = mScreenshot.getStride();
+ mFormat = mScreenshot.getFormat();
+ switch (mFormat) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ break;
- return NO_ERROR;
+ case HAL_PIXEL_FORMAT_BGRA_8888: {
+ // common format not supported by Bitmap.java
+ size_t w = mScreenshot.getWidth();
+ size_t h = mScreenshot.getHeight();
+ size_t s = mScreenshot.getStride();
+
+ mPixels = new uint32_t[s*h];
+ if (mPixels == NULL) {
+ res = NO_MEMORY;
+ break;
+ }
+
+ uint32_t const* src = (uint32_t const*)mScreenshot.getPixels();
+ uint32_t* dst = mPixels;
+ for (size_t y=0 ; y<h ; y++) {
+ for (size_t x=0 ; x<w ; x++) {
+ // convert BGRA (0xARGB) to RGBA (0xABGR)
+ uint32_t pixel = src[x];
+ dst[x] = (pixel & 0xFF00FF00) |
+ ((pixel >> 16) & 0xFF) |
+ ((pixel << 16) & 0xFF0000);
+ }
+ src += s;
+ dst += s;
+ }
+
+ mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+ mScreenshot.release();
+ } break;
+
+ default:
+ // ugh. that's a real problem
+ res = BAD_VALUE;
+ mScreenshot.release();
+ break;
+ }
+ }
+ return res;
}
uint32_t getWidth() const {
- return mScreenshot.getWidth();
+ return mWidth;
}
uint32_t getHeight() const {
- return mScreenshot.getHeight();
+ return mHeight;
}
uint32_t getStride() const {
- return mScreenshot.getStride();
+ return mStride;
}
uint32_t getFormat() const {
- return mScreenshot.getFormat();
+ return mFormat;
}
protected:
// overrides from SkPixelRef
virtual void* onLockPixels(SkColorTable** ct) {
- *ct = fCTable;
- return (void*)mScreenshot.getPixels();
+ *ct = mCTable;
+ return mPixels ? (void*)mPixels : (void*)mScreenshot.getPixels();
}
virtual void onUnlockPixels() {
@@ -114,7 +161,12 @@
SK_DECLARE_UNFLATTENABLE_OBJECT()
private:
ScreenshotClient mScreenshot;
- SkColorTable* fCTable;
+ SkColorTable* mCTable;
+ uint32_t* mPixels;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mStride;
+ uint32_t mFormat;
typedef SkPixelRef INHERITED;
};