Bug 980035 - Support 16bit volatile buffer backed decoded images, r=seth
authorMichael Wu <mwu@mozilla.com>
Tue, 25 Feb 2014 05:57:41 -0500
changeset 190832 efba9e32aca15069e1df351a988a66f67ee27e4d
parent 190831 74bfbc2f55c091e1e71d1fffdd58455ad5aa8d5f
child 190833 e09f4b94cf29e637326767738cb7727975707b35
push idunknown
push userunknown
push dateunknown
reviewersseth
bugs980035
milestone30.0a1
Bug 980035 - Support 16bit volatile buffer backed decoded images, r=seth
image/src/imgFrame.cpp
--- a/image/src/imgFrame.cpp
+++ b/image/src/imgFrame.cpp
@@ -341,18 +341,43 @@ nsresult imgFrame::Optimize()
 #endif
 
 #ifdef XP_MACOSX
   if (mQuartzSurface) {
     mQuartzSurface->Flush();
   }
 #endif
 
+#ifdef ANDROID
+  gfxImageFormat optFormat =
+    gfxPlatform::GetPlatform()->
+      OptimalFormatForContent(gfxASurface::ContentFromFormat(mFormat));
+
+  if (optFormat == gfxImageFormat::RGB16_565) {
+    RefPtr<VolatileBuffer> buf =
+      LockedImageSurface::AllocateBuffer(mSize, optFormat);
+    if (!buf)
+      return NS_OK;
+
+    nsRefPtr<gfxImageSurface> surf =
+      LockedImageSurface::CreateSurface(buf, mSize, optFormat);
+
+    gfxContext ctx(surf);
+    ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
+    ctx.SetSource(mImageSurface);
+    ctx.Paint();
+
+    mImageSurface = surf;
+    mVBuf = buf;
+    mFormat = optFormat;
+  }
+#else
   if (mOptSurface == nullptr)
     mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface, mFormat);
+#endif
 
   if (mOptSurface) {
     mVBuf = nullptr;
     mImageSurface = nullptr;
 #ifdef USE_WIN_SURFACE
     mWinSurface = nullptr;
 #endif
 #ifdef XP_MACOSX
@@ -627,35 +652,47 @@ nsresult imgFrame::LockImageData()
     if (mVBuf) {
       VolatileBufferPtr<uint8_t> ref(mVBuf);
       if (ref.WasBufferPurged())
         return NS_ERROR_FAILURE;
 
       mImageSurface = LockedImageSurface::CreateSurface(mVBuf, mSize, mFormat);
       if (!mImageSurface || mImageSurface->CairoStatus())
         return NS_ERROR_OUT_OF_MEMORY;
-    } else if (mOptSurface || mSinglePixel) {
+    }
+    if (mOptSurface || mSinglePixel || mFormat == gfxImageFormat::RGB16_565) {
+      gfxImageFormat format = mFormat;
+      if (mFormat == gfxImageFormat::RGB16_565)
+        format = gfxImageFormat::ARGB32;
+
       // Recover the pixels
-      mVBuf = LockedImageSurface::AllocateBuffer(mSize, mFormat);
-      if (!mVBuf) {
+      RefPtr<VolatileBuffer> buf =
+        LockedImageSurface::AllocateBuffer(mSize, format);
+      if (!buf) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
 
-      mImageSurface = LockedImageSurface::CreateSurface(mVBuf, mSize, mFormat);
-      if (!mImageSurface || mImageSurface->CairoStatus())
+      RefPtr<gfxImageSurface> surf =
+        LockedImageSurface::CreateSurface(buf, mSize, mFormat);
+      if (!surf || surf->CairoStatus())
         return NS_ERROR_OUT_OF_MEMORY;
 
-      gfxContext context(mImageSurface);
+      gfxContext context(surf);
       context.SetOperator(gfxContext::OPERATOR_SOURCE);
       if (mSinglePixel)
         context.SetDeviceColor(mSinglePixelColor);
+      else if (mFormat == gfxImageFormat::RGB16_565)
+        context.SetSource(mImageSurface);
       else
         context.SetSource(mOptSurface);
       context.Paint();
 
+      mFormat = format;
+      mVBuf = buf;
+      mImageSurface = surf;
       mOptSurface = nullptr;
 #ifdef USE_WIN_SURFACE
       mWinSurface = nullptr;
 #endif
 #ifdef XP_MACOSX
       mQuartzSurface = nullptr;
 #endif
     }