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

Side by Side Diff: Source/WebCore/platform/graphics/clutter/GraphicsLayerActor.cpp

Issue 13724012: Remove Cairo support. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 8 months 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
OLDNEW
(Empty)
1 /*
2 * Copyright 2011, 2012, 2013 Collabora Limited
3 * Copyright (C) 2012 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU Lesser General Public License,
7 * version 2.1, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT ANY
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 */
19
20 #include "config.h"
21
22 #if USE(ACCELERATED_COMPOSITING)
23
24 #include "GraphicsLayerActor.h"
25
26 #include "GraphicsContext.h"
27 #include "GraphicsLayerClutter.h"
28 #include "PlatformClutterLayerClient.h"
29 #include "PlatformContextCairo.h"
30 #include "RefPtrCairo.h"
31 #include "TransformationMatrix.h"
32 #include <wtf/text/CString.h>
33
34 using namespace WebCore;
35
36 G_DEFINE_TYPE(GraphicsLayerActor, graphics_layer_actor, CLUTTER_TYPE_ACTOR)
37
38 #define GRAPHICS_LAYER_ACTOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj) , GRAPHICS_LAYER_TYPE_ACTOR, GraphicsLayerActorPrivate))
39
40 struct _GraphicsLayerActorPrivate {
41 GraphicsLayerClutter::LayerType layerType;
42 gboolean allocating;
43
44 RefPtr<cairo_surface_t> surface;
45
46 PlatformClutterLayerClient* layerClient;
47
48 bool flatten;
49 bool drawsContent;
50
51 float scrollX;
52 float scrollY;
53
54 float translateX;
55 float translateY;
56 };
57
58 enum {
59 Property0,
60
61 PropertyTranslateX,
62 PropertyTranslateY,
63
64 PropertyLast
65 };
66
67 static void graphicsLayerActorAllocate(ClutterActor*, const ClutterActorBox*, Cl utterAllocationFlags);
68 static void graphicsLayerActorApplyTransform(ClutterActor*, CoglMatrix*);
69 static void graphicsLayerActorDispose(GObject*);
70 static void graphicsLayerActorGetProperty(GObject*, guint propID, GValue*, GPara mSpec*);
71 static void graphicsLayerActorSetProperty(GObject*, guint propID, const GValue*, GParamSpec*);
72 static void graphicsLayerActorPaint(ClutterActor*);
73
74 static void graphicsLayerActorAdded(ClutterContainer*, ClutterActor*, gpointer d ata);
75 static void graphicsLayerActorRemoved(ClutterContainer*, ClutterActor*, gpointer data);
76 static gboolean graphicsLayerActorDraw(ClutterCanvas*, cairo_t*, gint width, gin t height, GraphicsLayerActor*);
77 static void graphicsLayerActorUpdateTexture(GraphicsLayerActor*);
78 static void drawLayerContents(ClutterActor*, GraphicsContext&);
79
80 static void graphics_layer_actor_class_init(GraphicsLayerActorClass* klass)
81 {
82 GObjectClass* objectClass = G_OBJECT_CLASS(klass);
83 ClutterActorClass* actorClass = CLUTTER_ACTOR_CLASS(klass);
84
85 objectClass->get_property = graphicsLayerActorGetProperty;
86 objectClass->set_property = graphicsLayerActorSetProperty;
87 objectClass->dispose = graphicsLayerActorDispose;
88 actorClass->apply_transform = graphicsLayerActorApplyTransform;
89 actorClass->allocate = graphicsLayerActorAllocate;
90 actorClass->paint = graphicsLayerActorPaint;
91
92 g_type_class_add_private(klass, sizeof(GraphicsLayerActorPrivate));
93
94 GParamSpec* pspec = g_param_spec_float("translate-x", "Translate X", "Transl ation value for the X axis", -G_MAXFLOAT, G_MAXFLOAT, 0.0, static_cast<GParamFla gs>(G_PARAM_READWRITE));
95 g_object_class_install_property(objectClass, PropertyTranslateX, pspec);
96
97 pspec = g_param_spec_float("translate-y", "Translate Y", "Translation value for the Y ayis", -G_MAXFLOAT, G_MAXFLOAT, 0.0, static_cast<GParamFlags>(G_PARAM_ READWRITE));
98 g_object_class_install_property(objectClass, PropertyTranslateY, pspec);
99 }
100
101 static void graphics_layer_actor_init(GraphicsLayerActor* self)
102 {
103 self->priv = GRAPHICS_LAYER_ACTOR_GET_PRIVATE(self);
104
105 clutter_actor_set_reactive(CLUTTER_ACTOR(self), FALSE);
106
107 self->priv->flatten = true;
108
109 // Default used by GraphicsLayer.
110 graphicsLayerActorSetAnchorPoint(self, 0.5, 0.5, 0.0);
111
112 g_signal_connect(self, "actor-added", G_CALLBACK(graphicsLayerActorAdded), 0 );
113 g_signal_connect(self, "actor-removed", G_CALLBACK(graphicsLayerActorRemoved ), 0);
114 }
115
116 static void graphicsLayerActorSetProperty(GObject* object, guint propID, const G Value* value, GParamSpec* pspec)
117 {
118 GraphicsLayerActor* layer = GRAPHICS_LAYER_ACTOR(object);
119
120 switch (propID) {
121 case PropertyTranslateX:
122 graphicsLayerActorSetTranslateX(layer, g_value_get_float(value));
123 break;
124 case PropertyTranslateY:
125 graphicsLayerActorSetTranslateY(layer, g_value_get_float(value));
126 break;
127 default:
128 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, pspec);
129 }
130 }
131
132 static void graphicsLayerActorGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* pspec)
133 {
134 GraphicsLayerActor* layer = GRAPHICS_LAYER_ACTOR(object);
135
136 switch (propID) {
137 case PropertyTranslateX:
138 g_value_set_float(value, graphicsLayerActorGetTranslateX(layer));
139 break;
140 case PropertyTranslateY:
141 g_value_set_float(value, graphicsLayerActorGetTranslateY(layer));
142 break;
143 default:
144 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, pspec);
145 }
146 }
147
148
149 static void graphicsLayerActorDispose(GObject* object)
150 {
151 GraphicsLayerActor* layer = GRAPHICS_LAYER_ACTOR(object);
152 GraphicsLayerActorPrivate* priv = layer->priv;
153
154 priv->surface.clear();
155
156 G_OBJECT_CLASS(graphics_layer_actor_parent_class)->dispose(object);
157 }
158
159 // Copied from cairo.
160 #define MAX_IMAGE_SIZE 32767
161
162 static void graphicsLayerActorAllocate(ClutterActor* self, const ClutterActorBox * box, ClutterAllocationFlags flags)
163 {
164 GraphicsLayerActor* layer = GRAPHICS_LAYER_ACTOR(self);
165 GraphicsLayerActorPrivate* priv = layer->priv;
166
167 priv->allocating = TRUE;
168
169 CLUTTER_ACTOR_CLASS(graphics_layer_actor_parent_class)->allocate(self, box, flags);
170
171 ClutterContent* canvas = clutter_actor_get_content(self);
172 if (canvas)
173 clutter_canvas_set_size(CLUTTER_CANVAS(canvas), clutter_actor_get_width( self), clutter_actor_get_height(self));
174
175 // FIXME: maybe we can cache children allocation and not call
176 // allocate on them this often?
177 for (GList* list = layer->children; list; list = list->next) {
178 ClutterActor* child = CLUTTER_ACTOR(list->data);
179
180 float childWidth = clutter_actor_get_width(child);
181 float childHeight = clutter_actor_get_height(child);
182
183 ClutterActorBox childBox;
184 childBox.x1 = clutter_actor_get_x(child);
185 childBox.y1 = clutter_actor_get_y(child);
186 childBox.x2 = childBox.x1 + childWidth;
187 childBox.y2 = childBox.y1 + childHeight;
188
189 clutter_actor_allocate(child, &childBox, flags);
190 }
191
192 priv->allocating = FALSE;
193 }
194
195 static void graphicsLayerActorApplyTransform(ClutterActor* actor, CoglMatrix* ma trix)
196 {
197 GraphicsLayerActorPrivate* priv = GRAPHICS_LAYER_ACTOR(actor)->priv;
198
199 // Apply translation and scrolling as a single translation. These
200 // need to come before anything else, otherwise they'll be
201 // affected by other operations such as scaling, which is not what
202 // we want.
203 float translateX = priv->scrollX + priv->translateX;
204 float translateY = priv->scrollY + priv->translateY;
205
206 if (translateX || translateY)
207 cogl_matrix_translate(matrix, translateX, translateY, 0);
208
209 CoglMatrix modelViewTransform = TransformationMatrix();
210 CLUTTER_ACTOR_CLASS(graphics_layer_actor_parent_class)->apply_transform(acto r, &modelViewTransform);
211
212 if (priv->flatten)
213 modelViewTransform = TransformationMatrix(&modelViewTransform).to2dTrans form();
214 cogl_matrix_multiply(matrix, matrix, &modelViewTransform);
215 }
216
217 static void graphicsLayerActorPaint(ClutterActor* actor)
218 {
219 GraphicsLayerActor* graphicsLayer = GRAPHICS_LAYER_ACTOR(actor);
220
221 for (GList* list = graphicsLayer->children; list; list = list->next) {
222 ClutterActor* child = CLUTTER_ACTOR(list->data);
223 clutter_actor_paint(child);
224 }
225 }
226
227 static gboolean graphicsLayerActorDraw(ClutterCanvas* texture, cairo_t* cr, gint width, gint height, GraphicsLayerActor* layer)
228 {
229 if (!width || !height)
230 return FALSE;
231
232 GraphicsLayerActorPrivate* priv = layer->priv;
233 GraphicsContext context(cr);
234 context.clearRect(FloatRect(0, 0, width, height));
235
236 if (priv->surface) {
237 gint surfaceWidth = cairo_image_surface_get_width(priv->surface.get());
238 gint surfaceHeight = cairo_image_surface_get_height(priv->surface.get()) ;
239
240 FloatRect srcRect(0.0, 0.0, static_cast<float>(surfaceWidth), static_cas t<float>(surfaceHeight));
241 FloatRect destRect(0.0, 0.0, width, height);
242 context.platformContext()->drawSurfaceToContext(priv->surface.get(), des tRect, srcRect, &context);
243 }
244
245 if (priv->layerType == GraphicsLayerClutter::LayerTypeWebLayer)
246 drawLayerContents(CLUTTER_ACTOR(layer), context);
247
248 return TRUE;
249 }
250
251 static void graphicsLayerActorAdded(ClutterContainer* container, ClutterActor* a ctor, gpointer data)
252 {
253 GraphicsLayerActor* graphicsLayer = GRAPHICS_LAYER_ACTOR(container);
254 graphicsLayer->children = g_list_append(graphicsLayer->children, actor);
255 }
256
257 static void graphicsLayerActorRemoved(ClutterContainer* container, ClutterActor* actor, gpointer data)
258 {
259 GraphicsLayerActor* graphicsLayer = GRAPHICS_LAYER_ACTOR(container);
260 graphicsLayer->children = g_list_remove(graphicsLayer->children, actor);
261 }
262
263 static void graphicsLayerActorUpdateTexture(GraphicsLayerActor* layer)
264 {
265 GraphicsLayerActorPrivate* priv = layer->priv;
266 ASSERT(priv->layerType != GraphicsLayerClutter::LayerTypeVideoLayer);
267
268 ClutterActor* actor = CLUTTER_ACTOR(layer);
269 ClutterContent* canvas = clutter_actor_get_content(actor);
270 if (canvas) {
271 // Nothing needs a texture, remove the one we have, if any.
272 if (!priv->drawsContent && !priv->surface) {
273 g_signal_handlers_disconnect_by_func(canvas, reinterpret_cast<void*> (graphicsLayerActorDraw), layer);
274 g_object_unref(canvas);
275 }
276 return;
277 }
278
279 // We should have a texture, so create one.
280 int width = ceilf(clutter_actor_get_width(actor));
281 int height = ceilf(clutter_actor_get_height(actor));
282
283 canvas = clutter_canvas_new();
284 clutter_actor_set_content(actor, canvas);
285 clutter_canvas_set_size(CLUTTER_CANVAS(canvas), width > 0 ? width : 1, heigh t > 0 ? height : 1);
286 g_object_unref(canvas);
287
288 g_signal_connect(canvas, "draw", G_CALLBACK(graphicsLayerActorDraw), layer);
289 }
290
291 // Draw content into the layer.
292 static void drawLayerContents(ClutterActor* actor, GraphicsContext& context)
293 {
294 GraphicsLayerActorPrivate* priv = GRAPHICS_LAYER_ACTOR(actor)->priv;
295
296 if (!priv->drawsContent || !priv->layerClient)
297 return;
298
299 int width = static_cast<int>(clutter_actor_get_width(actor));
300 int height = static_cast<int>(clutter_actor_get_height(actor));
301 IntRect clip(0, 0, width, height);
302
303 // Apply the painted content to the layer.
304 priv->layerClient->platformClutterLayerPaintContents(context, clip);
305 }
306
307
308 GraphicsLayerActor* graphicsLayerActorNew(GraphicsLayerClutter::LayerType type)
309 {
310 GraphicsLayerActor* layer = GRAPHICS_LAYER_ACTOR(g_object_new(GRAPHICS_LAYER _TYPE_ACTOR, 0));
311 GraphicsLayerActorPrivate* priv = layer->priv;
312
313 priv->layerType = type;
314 if (priv->layerType == GraphicsLayerClutter::LayerTypeTransformLayer)
315 priv->flatten = false;
316
317 return layer;
318 }
319
320 GraphicsLayerActor* graphicsLayerActorNewWithClient(GraphicsLayerClutter::LayerT ype type, PlatformClutterLayerClient* layerClient)
321 {
322 GraphicsLayerActor* layer = graphicsLayerActorNew(type);
323 graphicsLayerActorSetClient(layer, layerClient);
324
325 return layer;
326 }
327
328 void graphicsLayerActorSetClient(GraphicsLayerActor* layer, PlatformClutterLayer Client* client)
329 {
330 layer->priv->layerClient = client;
331 }
332
333 PlatformClutterLayerClient* graphicsLayerActorGetClient(GraphicsLayerActor* laye r)
334 {
335 return layer->priv->layerClient;
336 }
337
338 void graphicsLayerActorRemoveAll(GraphicsLayerActor* layer)
339 {
340 g_return_if_fail(GRAPHICS_LAYER_IS_ACTOR(layer));
341
342 GList* children = clutter_actor_get_children(CLUTTER_ACTOR(layer));
343 for (; children; children = children->next)
344 clutter_actor_remove_child(CLUTTER_ACTOR(layer), CLUTTER_ACTOR(children- >data));
345 }
346
347 cairo_surface_t* graphicsLayerActorGetSurface(GraphicsLayerActor* layer)
348 {
349 GraphicsLayerActorPrivate* priv = layer->priv;
350 ASSERT(priv->surface);
351 return priv->surface.get();
352 }
353
354 void graphicsLayerActorSetSurface(GraphicsLayerActor* layer, cairo_surface_t* su rface)
355 {
356 GraphicsLayerActorPrivate* priv = layer->priv;
357 priv->surface = surface;
358 graphicsLayerActorUpdateTexture(layer);
359 }
360
361 void graphicsLayerActorInvalidateRectangle(GraphicsLayerActor* layer, const Floa tRect& dirtyRect)
362 {
363 ClutterContent* canvas = clutter_actor_get_content(CLUTTER_ACTOR(layer));
364 if (!canvas)
365 return;
366
367 // FIXME: Need to invalidate a specific area?
368 clutter_content_invalidate(canvas);
369 }
370
371 void graphicsLayerActorSetAnchorPoint(GraphicsLayerActor* layer, float x, float y, float z)
372 {
373 ClutterActor* actor = CLUTTER_ACTOR(layer);
374 clutter_actor_set_pivot_point(actor, x, y);
375 clutter_actor_set_pivot_point_z(actor, z);
376 }
377
378 void graphicsLayerActorGetAnchorPoint(GraphicsLayerActor* layer, float* x, float * y, float* z)
379 {
380 ASSERT(x && y);
381
382 ClutterActor* actor = CLUTTER_ACTOR(layer);
383 clutter_actor_get_pivot_point(actor, x, y);
384 if (z)
385 *z = clutter_actor_get_pivot_point_z(actor);
386 }
387
388 void graphicsLayerActorSetScrollPosition(GraphicsLayerActor* layer, float x, flo at y)
389 {
390 if (x > 0 || y > 0)
391 return;
392
393 GraphicsLayerActorPrivate* priv = layer->priv;
394 priv->scrollX = x;
395 priv->scrollY = y;
396
397 clutter_actor_queue_redraw(CLUTTER_ACTOR(layer));
398 }
399
400 gint graphicsLayerActorGetnChildren(GraphicsLayerActor* layer)
401 {
402 ASSERT(GRAPHICS_LAYER_IS_ACTOR(layer));
403
404 return g_list_length(layer->children);
405 }
406
407 void graphicsLayerActorReplaceSublayer(GraphicsLayerActor* layer, ClutterActor* oldChildLayer, ClutterActor* newChildLayer)
408 {
409 ASSERT(GRAPHICS_LAYER_IS_ACTOR(layer));
410 ASSERT(CLUTTER_IS_ACTOR(oldChildLayer));
411 ASSERT(CLUTTER_IS_ACTOR(newChildLayer));
412
413 clutter_actor_remove_child(CLUTTER_ACTOR(layer), oldChildLayer);
414 clutter_actor_add_child(CLUTTER_ACTOR(layer), newChildLayer);
415 }
416
417 void graphicsLayerActorInsertSublayer(GraphicsLayerActor* layer, ClutterActor* c hildLayer, gint index)
418 {
419 ASSERT(GRAPHICS_LAYER_IS_ACTOR(layer));
420 ASSERT(CLUTTER_IS_ACTOR(childLayer));
421
422 g_object_ref(childLayer);
423
424 layer->children = g_list_insert(layer->children, childLayer, index);
425 ASSERT(!clutter_actor_get_parent(childLayer));
426 clutter_actor_add_child(CLUTTER_ACTOR(layer), childLayer);
427 clutter_actor_queue_relayout(CLUTTER_ACTOR(layer));
428
429 g_object_unref(childLayer);
430 }
431
432 void graphicsLayerActorSetSublayers(GraphicsLayerActor* layer, GraphicsLayerActo rList& subLayers)
433 {
434 if (!subLayers.size()) {
435 graphicsLayerActorRemoveAll(layer);
436 return;
437 }
438
439 ClutterActor* newParentActor = CLUTTER_ACTOR(layer);
440 for (size_t i = 0; i < subLayers.size(); ++i) {
441 ClutterActor* childActor = CLUTTER_ACTOR(subLayers[i].get());
442 ClutterActor* oldParentActor = clutter_actor_get_parent(childActor);
443 if (oldParentActor) {
444 if (oldParentActor == newParentActor)
445 continue;
446 clutter_actor_remove_child(oldParentActor, childActor);
447 }
448 clutter_actor_add_child(newParentActor, childActor);
449 }
450 }
451
452 void graphicsLayerActorRemoveFromSuperLayer(GraphicsLayerActor* layer)
453 {
454 ClutterActor* actor = CLUTTER_ACTOR(layer);
455 ClutterActor* parentActor = clutter_actor_get_parent(actor);
456 if (!parentActor)
457 return;
458
459 clutter_actor_remove_child(parentActor, actor);
460 }
461
462 GraphicsLayerClutter::LayerType graphicsLayerActorGetLayerType(GraphicsLayerActo r* layer)
463 {
464 GraphicsLayerActorPrivate* priv = layer->priv;
465 return priv->layerType;
466 }
467
468 void graphicsLayerActorSetLayerType(GraphicsLayerActor* layer, GraphicsLayerClut ter::LayerType layerType)
469 {
470 GraphicsLayerActorPrivate* priv = layer->priv;
471 priv->layerType = layerType;
472 }
473
474 void graphicsLayerActorSetTranslateX(GraphicsLayerActor* layer, float value)
475 {
476 GraphicsLayerActorPrivate* priv = layer->priv;
477 priv->translateX = value;
478 clutter_actor_queue_redraw(CLUTTER_ACTOR(layer));
479 }
480
481 float graphicsLayerActorGetTranslateX(GraphicsLayerActor* layer)
482 {
483 GraphicsLayerActorPrivate* priv = layer->priv;
484 return priv->translateX;
485 }
486
487 void graphicsLayerActorSetTranslateY(GraphicsLayerActor* layer, float value)
488 {
489 GraphicsLayerActorPrivate* priv = layer->priv;
490 priv->translateY = value;
491 clutter_actor_queue_redraw(CLUTTER_ACTOR(layer));
492 }
493
494 float graphicsLayerActorGetTranslateY(GraphicsLayerActor* layer)
495 {
496 GraphicsLayerActorPrivate* priv = layer->priv;
497 return priv->translateY;
498 }
499
500 void graphicsLayerActorSetDrawsContent(GraphicsLayerActor* layer, bool drawsCont ent)
501 {
502 GraphicsLayerActorPrivate* priv = layer->priv;
503
504 if (drawsContent == priv->drawsContent)
505 return;
506
507 priv->drawsContent = drawsContent;
508
509 graphicsLayerActorUpdateTexture(layer);
510 }
511
512 gboolean graphicsLayerActorGetDrawsContent(GraphicsLayerActor* layer)
513 {
514 return layer->priv->drawsContent;
515 }
516
517 void graphicsLayerActorSetFlatten(GraphicsLayerActor* layer, bool flatten)
518 {
519 GraphicsLayerActorPrivate* priv = layer->priv;
520 if (flatten == priv->flatten)
521 return;
522
523 priv->flatten = flatten;
524 }
525
526 WebCore::PlatformClutterAnimation* graphicsLayerActorGetAnimationForKey(Graphics LayerActor* layer, const String key)
527 {
528 return static_cast<WebCore::PlatformClutterAnimation*>(g_object_get_data(G_O BJECT(layer), key.utf8().data()));
529 }
530
531 #endif // USE(ACCELERATED_COMPOSITING)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698