Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: skia/ext/bitmap_platform_device_linux.cc

Issue 59133008: ozone: Support building without cairo (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase & fix whitespace Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « skia/ext/bitmap_platform_device_linux.h ('k') | skia/ext/bitmap_platform_device_skia.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "skia/ext/bitmap_platform_device_linux.h"
6 #include "skia/ext/bitmap_platform_device_data.h"
7 #include "skia/ext/platform_canvas.h"
8
9 #if defined(OS_OPENBSD)
10 #include <cairo.h>
11 #else
12 #include <cairo/cairo.h>
13 #endif
14
15 namespace skia {
16
17 namespace {
18
19 void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) {
20 cairo_matrix_t cairo_matrix;
21 cairo_matrix_init(&cairo_matrix,
22 SkScalarToFloat(matrix.getScaleX()),
23 SkScalarToFloat(matrix.getSkewY()),
24 SkScalarToFloat(matrix.getSkewX()),
25 SkScalarToFloat(matrix.getScaleY()),
26 SkScalarToFloat(matrix.getTranslateX()),
27 SkScalarToFloat(matrix.getTranslateY()));
28 cairo_set_matrix(context, &cairo_matrix);
29 }
30
31 void LoadClipToContext(cairo_t* context, const SkRegion& clip) {
32 cairo_reset_clip(context);
33
34 // TODO(brettw) support non-rect clips.
35 SkIRect bounding = clip.getBounds();
36 cairo_rectangle(context, bounding.fLeft, bounding.fTop,
37 bounding.fRight - bounding.fLeft,
38 bounding.fBottom - bounding.fTop);
39 cairo_clip(context);
40 }
41
42 } // namespace
43
44 BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData(
45 cairo_surface_t* surface)
46 : surface_(surface),
47 config_dirty_(true),
48 transform_(SkMatrix::I()) { // Want to load the config next time.
49 bitmap_context_ = cairo_create(surface);
50 }
51
52 BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() {
53 cairo_destroy(bitmap_context_);
54 cairo_surface_destroy(surface_);
55 }
56
57 void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
58 const SkMatrix& transform,
59 const SkRegion& region) {
60 transform_ = transform;
61 clip_region_ = region;
62 config_dirty_ = true;
63 }
64
65 void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() {
66 if (!config_dirty_ || !bitmap_context_)
67 return; // Nothing to do.
68 config_dirty_ = false;
69
70 // Load the identity matrix since this is what our clip is relative to.
71 cairo_matrix_t cairo_matrix;
72 cairo_matrix_init_identity(&cairo_matrix);
73 cairo_set_matrix(bitmap_context_, &cairo_matrix);
74
75 LoadClipToContext(bitmap_context_, clip_region_);
76 LoadMatrixToContext(bitmap_context_, transform_);
77 }
78
79 // We use this static factory function instead of the regular constructor so
80 // that we can create the pixel data before calling the constructor. This is
81 // required so that we can call the base class' constructor with the pixel
82 // data.
83 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
84 bool is_opaque,
85 cairo_surface_t* surface) {
86 if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
87 cairo_surface_destroy(surface);
88 return NULL;
89 }
90 SkBitmap bitmap;
91 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height,
92 cairo_image_surface_get_stride(surface),
93 is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
94 bitmap.setPixels(cairo_image_surface_get_data(surface));
95
96 // The device object will take ownership of the graphics context.
97 return new BitmapPlatformDevice
98 (bitmap, new BitmapPlatformDeviceData(surface));
99 }
100
101 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
102 bool is_opaque) {
103 // This initializes the bitmap to all zeros.
104 cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
105 width, height);
106
107 BitmapPlatformDevice* device = Create(width, height, is_opaque, surface);
108
109 #ifndef NDEBUG
110 if (device && is_opaque) // Fill with bright bluish green
111 device->eraseColor(SkColorSetARGB(255, 0, 255, 128));
112 #endif
113
114 return device;
115 }
116
117 BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
118 int height,
119 bool is_opaque) {
120 // The Linux port always constructs initialized bitmaps, so there is no extra
121 // work to perform here.
122 return Create(width, height, is_opaque);
123 }
124
125 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
126 bool is_opaque,
127 uint8_t* data) {
128 cairo_surface_t* surface = cairo_image_surface_create_for_data(
129 data, CAIRO_FORMAT_ARGB32, width, height,
130 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
131
132 return Create(width, height, is_opaque, surface);
133 }
134
135 // The device will own the bitmap, which corresponds to also owning the pixel
136 // data. Therefore, we do not transfer ownership to the SkBitmapDevice's bitmap.
137 BitmapPlatformDevice::BitmapPlatformDevice(
138 const SkBitmap& bitmap,
139 BitmapPlatformDeviceData* data)
140 : SkBitmapDevice(bitmap),
141 data_(data) {
142 SetPlatformDevice(this, this);
143 }
144
145 BitmapPlatformDevice::~BitmapPlatformDevice() {
146 }
147
148 SkBaseDevice* BitmapPlatformDevice::onCreateCompatibleDevice(
149 SkBitmap::Config config, int width, int height, bool isOpaque,
150 Usage /*usage*/) {
151 SkASSERT(config == SkBitmap::kARGB_8888_Config);
152 return BitmapPlatformDevice::Create(width, height, isOpaque);
153 }
154
155 cairo_t* BitmapPlatformDevice::BeginPlatformPaint() {
156 data_->LoadConfig();
157 cairo_t* cairo = data_->bitmap_context();
158 cairo_surface_t* surface = cairo_get_target(cairo);
159 // Tell cairo to flush anything it has pending.
160 cairo_surface_flush(surface);
161 // Tell Cairo that we (probably) modified (actually, will modify) its pixel
162 // buffer directly.
163 cairo_surface_mark_dirty(surface);
164 return cairo;
165 }
166
167 void BitmapPlatformDevice::DrawToNativeContext(
168 PlatformSurface surface, int x, int y, const PlatformRect* src_rect) {
169 // Should never be called on Linux.
170 SkASSERT(false);
171 }
172
173 void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
174 const SkRegion& region,
175 const SkClipStack&) {
176 data_->SetMatrixClip(transform, region);
177 }
178
179 // PlatformCanvas impl
180
181 SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque,
182 uint8_t* data, OnFailureType failureType) {
183 skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef(
184 BitmapPlatformDevice::Create(width, height, is_opaque, data));
185 return CreateCanvas(dev, failureType);
186 }
187
188 // Port of PlatformBitmap to linux
189 PlatformBitmap::~PlatformBitmap() {
190 cairo_destroy(surface_);
191 }
192
193 bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) {
194 // The SkBitmap allocates and owns the bitmap memory; PlatformBitmap owns the
195 // cairo drawing context tied to the bitmap. The SkBitmap's pixelRef can
196 // outlive the PlatformBitmap if additional copies are made.
197 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
198 bitmap_.setConfig(SkBitmap::kARGB_8888_Config, width, height, stride,
199 is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
200 if (!bitmap_.allocPixels()) // Using the default allocator.
201 return false;
202
203 cairo_surface_t* surf = cairo_image_surface_create_for_data(
204 reinterpret_cast<unsigned char*>(bitmap_.getPixels()),
205 CAIRO_FORMAT_ARGB32,
206 width,
207 height,
208 stride);
209 if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) {
210 cairo_surface_destroy(surf);
211 return false;
212 }
213
214 surface_ = cairo_create(surf);
215 cairo_surface_destroy(surf);
216 return true;
217 }
218
219 } // namespace skia
OLDNEW
« no previous file with comments | « skia/ext/bitmap_platform_device_linux.h ('k') | skia/ext/bitmap_platform_device_skia.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698