Bug 981430 - Convert WinUtils consumer of imgIContainer::GetFrame to act on a Moz2D SourceSurface. r=mattwoodrow
authorJonathan Watt <jwatt@jwatt.org>
Mon, 10 Mar 2014 03:13:18 +0000
changeset 189884 c25dfac7ab7b1d4c14d20340991ebd5cb80f1a42
parent 189883 670c87ee6c7de87b639340fa80bf89865542b53b
child 189885 1624c45df0d9d0bfe685ce5704f5ae681bec3941
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs981430
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 981430 - Convert WinUtils consumer of imgIContainer::GetFrame to act on a Moz2D SourceSurface. r=mattwoodrow
widget/windows/WinUtils.cpp
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -1,20 +1,25 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sts=2 sw=2 et cin: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WinUtils.h"
+
+#include "gfxPlatform.h"
 #include "nsWindow.h"
 #include "nsWindowDefs.h"
 #include "KeyboardLayout.h"
 #include "nsIDOMMouseEvent.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/RefPtr.h"
 #include "mozilla/WindowsVersion.h"
 
 #ifdef MOZ_LOGGING
 #define FORCE_PR_LOG /* Allow logging in the release build */
 #endif // MOZ_LOGGING
 #include "prlog.h"
 
 #include "nsString.h"
@@ -44,16 +49,18 @@
 #include <textstor.h>
 #include "nsTextStore.h"
 #endif // #ifdef NS_ENABLE_TSF
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gWindowsLog = nullptr;
 #endif
 
+using namespace mozilla::gfx;
+
 namespace mozilla {
 namespace widget {
 
 NS_IMPL_ISUPPORTS1(myDownloadObserver, nsIDownloadObserver)
 #ifdef MOZ_PLACES
 NS_IMPL_ISUPPORTS1(AsyncFaviconDataReady, nsIFaviconDataCallback)
 #endif
 NS_IMPL_ISUPPORTS1(AsyncEncodeAndWriteIcon, nsIRunnable)
@@ -723,55 +730,73 @@ AsyncFaviconDataReady::OnComplete(nsIURI
   rv = imgtool->DecodeImageData(stream, aMimeType,
                                 getter_AddRefs(container));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRefPtr<gfxASurface> imgFrame =
     container->GetFrame(imgIContainer::FRAME_FIRST, 0);
   NS_ENSURE_TRUE(imgFrame, NS_ERROR_FAILURE);
 
-  nsRefPtr<gfxImageSurface> imageSurface;
-  gfxIntSize size;
+  RefPtr<SourceSurface> surface =
+    gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, imgFrame);
+  NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
+
+  RefPtr<DataSourceSurface> dataSurface;
+  IntSize size;
+
   if (mURLShortcut) {
-    imageSurface =
-      new gfxImageSurface(gfxIntSize(48, 48),
-                          gfxImageFormat::ARGB32);
-    gfxContext context(imageSurface);
-    context.SetOperator(gfxContext::OPERATOR_SOURCE);
-    context.SetColor(gfxRGBA(1, 1, 1, 1));
-    context.Rectangle(gfxRect(0, 0, 48, 48));
-    context.Fill();
+    // Create a 48x48 surface and paint the icon into the central 16x16 rect.
+    size.width = 48;
+    size.height = 48;
+    dataSurface =
+      Factory::CreateDataSourceSurface(size, SurfaceFormat::B8G8R8A8);
+    NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
+
+    DataSourceSurface::MappedSurface map;
+    if (!dataSurface->Map(DataSourceSurface::MapType::WRITE, &map)) {
+      return NS_ERROR_FAILURE;
+    }
 
-    context.Translate(gfxPoint(16, 16));
-    context.SetOperator(gfxContext::OPERATOR_OVER);
-    context.DrawSurface(imgFrame,  gfxSize(16, 16));
-    size = imageSurface->GetSize();
+    RefPtr<DrawTarget> dt =
+      Factory::CreateDrawTargetForData(BackendType::CAIRO,
+                                       map.mData,
+                                       dataSurface->GetSize(),
+                                       map.mStride,
+                                       dataSurface->GetFormat());
+    dt->FillRect(Rect(0, 0, size.width, size.height),
+                 ColorPattern(Color(1.0f, 1.0f, 1.0f, 1.0f)));
+    dt->DrawSurface(surface,
+                    Rect(16, 16, 16, 16),
+                    Rect(Point(0, 0),
+                         Size(surface->GetSize().width, surface->GetSize().height)));
+
+    dataSurface->Unmap();
   } else {
-    imageSurface = imgFrame->GetAsReadableARGB32ImageSurface();
     size.width = GetSystemMetrics(SM_CXSMICON);
     size.height = GetSystemMetrics(SM_CYSMICON);
     if (!size.width || !size.height) {
       size.width = 16;
       size.height = 16;
     }
+    dataSurface = surface->GetDataSurface();
   }
 
-  // Allocate a new buffer that we own and can use out of line in 
-  // another thread.  Copy the favicon raw data into it.
-  const fallible_t fallible = fallible_t();
-  uint8_t *data = new (fallible) uint8_t[imageSurface->GetDataSize()];
+  // Allocate a new buffer that we own and can use out of line in
+  // another thread.
+  uint8_t *data = SurfaceToPackedBGRA(dataSurface);
   if (!data) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
-  memcpy(data, imageSurface->Data(), imageSurface->GetDataSize());
+  int32_t stride = 4 * size.width;
+  int32_t dataLength = stride * size.height;
 
   // AsyncEncodeAndWriteIcon takes ownership of the heap allocated buffer
   nsCOMPtr<nsIRunnable> event = new AsyncEncodeAndWriteIcon(path, data,
-                                                            imageSurface->GetDataSize(),
-                                                            imageSurface->Stride(),
+                                                            dataLength,
+                                                            stride,
                                                             size.width,
                                                             size.height,
                                                             mURLShortcut);
   mIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
 
   return NS_OK;
 }
 #endif