Index: skia/ext/platform_canvas.cc |
diff --git a/skia/ext/platform_canvas.cc b/skia/ext/platform_canvas.cc |
index de2daa6e7985040a5104261f2e67bcb1ff2c1875..81e35431a462bdaf0abd79180174ab9e8c64f972 100644 |
--- a/skia/ext/platform_canvas.cc |
+++ b/skia/ext/platform_canvas.cc |
@@ -7,6 +7,7 @@ |
#include "base/logging.h" |
#include "build/build_config.h" |
#include "skia/ext/platform_device.h" |
+#include "skia/ext/layer_allocator.h" |
#include "third_party/skia/include/core/SkMetaData.h" |
#include "third_party/skia/include/core/SkTypes.h" |
@@ -33,6 +34,80 @@ bool GetBoolMetaData(const SkCanvas& canvas, const char* key) { |
namespace skia { |
+#if defined(WIN32) |
+ |
+SkCanvas* CreatePlatformCanvas(int width, |
+ int height, |
+ bool is_opaque, |
+ HANDLE shared_section, |
+ OnFailureType failure_type); |
+ SkImageInfo info = SkImageInfo::MakeN32(width, height, |
+ is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); |
+ SkSurfaceProps props(0, kUnknown_SkPixelGeometry); |
+ |
+ LayerAllocator* allocator = new LayerAllocator; |
+ return allocator->createCanvas(info, props, static_cast<void*>(shared_section)).get(); |
+} |
+ |
+#elif defined(__APPLE__) |
+ |
+// TODO(fmalita): mac implementations using LayerAllocator |
+ |
+/* |
+SkCanvas* CreatePlatformCanvas(CGContextRef context, |
+ int width, |
+ int height, |
+ bool is_opaque, |
+ OnFailureType failure_type); |
+ |
+SkCanvas* CreatePlatformCanvas(int width, |
+ int height, |
+ bool is_opaque, |
+ uint8_t* context, |
+ OnFailureType failure_type); |
+*/ |
+ |
+#elif defined(USE_OZONE) |
+ |
+// Unlike all other linuxy versions, Chromecast doesn't have Cairo underneath; |
+// we give them a plain bitmap-backed canvas. |
+ |
+SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque, |
+ uint8_t* data, OnFailureType failureType) { |
+ SkImageInfo info = SkImageInfo::MakeN32(width, height, |
+ is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); |
+ SkSurfaceProps props(0, kUnknown_SkPixelGeometry); |
+ |
+ SkBitmap bitmap; |
+ bool success = false; |
+ if (data) |
+ success = bitmap.installPixels(info, data, info.minRowBytes()); |
+ else |
+ success = bitmap.tryAllocPixels(info); |
+ |
+ if (!success && failureType == CRASH_ON_FAILURE) |
+ SK_CRASH(); |
+ return new SkCanvas(bitmap, props); |
+} |
+ |
+#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ |
+ defined(__sun) || defined(ANDROID) |
+ |
+SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque, |
+ uint8_t* data, OnFailureType failureType) { |
+ SkImageInfo info = SkImageInfo::MakeN32(width, height, |
+ is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); |
+ SkSurfaceProps props(0, kUnknown_SkPixelGeometry); |
+ |
+ LayerAllocator* allocator = new LayerAllocator; |
+ if (!allocator && failureType == CRASH_ON_FAILURE) |
+ SK_CRASH(); |
+ |
+ return allocator->createCanvas(info, props, data).get(); |
+} |
+ |
+#endif |
+ |
SkBitmap ReadPixels(SkCanvas* canvas) { |
SkBitmap bitmap; |
bitmap.setInfo(canvas->imageInfo()); |
@@ -58,23 +133,15 @@ bool GetWritablePixels(SkCanvas* canvas, SkPixmap* result) { |
} |
bool SupportsPlatformPaint(const SkCanvas* canvas) { |
- return GetPlatformDevice(canvas->getTopDevice(true)) != nullptr; |
+ // Fragile: true only as long as Chrome *only* uses layer allocators |
+ // to allocate platform-specific raster backings. |
+ return canvas->getLayerAllocator() != nullptr; |
} |
size_t PlatformCanvasStrideForWidth(unsigned width) { |
return 4 * width; |
} |
-SkCanvas* CreateCanvas(const sk_sp<SkBaseDevice>& device, |
- OnFailureType failureType) { |
- if (!device) { |
- if (CRASH_ON_FAILURE == failureType) |
- SK_CRASH(); |
- return nullptr; |
- } |
- return new SkCanvas(device.get()); |
-} |
- |
SkMetaData& GetMetaData(const SkCanvas& canvas) { |
SkBaseDevice* device = canvas.getDevice(); |
DCHECK(device != nullptr); |
@@ -91,6 +158,8 @@ bool IsPreviewMetafile(const SkCanvas& canvas) { |
} |
CGContextRef GetBitmapContext(const SkCanvas& canvas) { |
+ // TODO(fmalita): mac implementation of LayerAllocator lets us |
+ // get rid of this last user of GetPlatformDevice. |
PlatformDevice* platform_device = |
GetPlatformDevice(canvas.getTopDevice(true)); |
SkIRect clip_bounds; |
@@ -106,15 +175,24 @@ CGContextRef GetBitmapContext(const SkCanvas& canvas) { |
ScopedPlatformPaint::ScopedPlatformPaint(SkCanvas* canvas) : |
canvas_(canvas), |
platform_surface_(nullptr) { |
- // TODO(tomhudson) we're assuming non-null canvas? |
- PlatformDevice* platform_device = GetPlatformDevice(canvas->getTopDevice(true)); |
- if (platform_device) { |
- // Compensate for drawing to a layer rather than the entire canvas |
- SkMatrix ctm; |
- SkIRect clip_bounds; |
- canvas->temporary_internal_describeTopLayer(&ctm, &clip_bounds); |
- platform_surface_ = platform_device->BeginPlatformPaint(ctm, clip_bounds); |
+ if (!canvas) { |
+ return; |
+ } |
+ |
+ SkRasterCanvasLayerAllocator* allocator = canvas->getLayerAllocator(); |
+ if (!allocator) { |
+ return; |
} |
+ |
+ // Need to use CTM & clip bounds to compensate for drawing to a layer |
+ // rather than the entire canvas. |
+ SkMatrix ctm; |
+ SkIRect clip_bounds; |
+ canvas->temporary_internal_describeTopLayer(&ctm, &clip_bounds); |
+ |
+ void* buffer = canvas->accessTopLayerPixels(nullptr, nullptr); |
+ platform_surface_ = |
+ (PlatformSurface) allocator->getNativeContext(buffer, ctm, clip_bounds); |
} |
} // namespace skia |