1/*
2 * Copyright 2011,2012 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 <glib/gprintf.h>
32
33using namespace WebCore;
34
35G_DEFINE_TYPE(GraphicsLayerActor, graphics_layer_actor, CLUTTER_TYPE_RECTANGLE)
36
37#define GRAPHICS_LAYER_ACTOR_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GRAPHICS_LAYER_TYPE_ACTOR, GraphicsLayerActorPrivate))
38
39struct _GraphicsLayerActorPrivate {
40 GraphicsLayerClutter::LayerType layerType;
41 // Guard against changing size while allocating.
42 gboolean allocating;
43
44 ClutterActor* texture;
45 RefPtr<cairo_surface_t> surface;
46 CoglMatrix* matrix;
47
48 PlatformClutterLayerClient* layerClient;
49
50 gboolean drawsContent;
51
52 gfloat anchorX;
53 gfloat anchorY;
54 gfloat anchorZ;
55
56 gfloat scrollX;
57 gfloat scrollY;
58
59 float translateX;
60 float translateY;
61};
62
63enum {
64 PROP_0,
65
66 PROP_TRANSLATE_X,
67 PROP_TRANSLATE_Y,
68
69 PROP_LAST
70};
71
72static void graphicsLayerActorAllocate(ClutterActor*, const ClutterActorBox*, ClutterAllocationFlags);
73static void graphicsLayerActorApplyTransform(ClutterActor*, CoglMatrix*);
74static void graphicsLayerActorDispose(GObject*);
75static void graphicsLayerActorGetProperty(GObject*, guint propID, GValue*, GParamSpec*);
76static void graphicsLayerActorSetProperty(GObject*, guint propID, const GValue*, GParamSpec*);
77static void graphicsLayerActorPaint(ClutterActor*);
78static void graphicsLayerActorPick(ClutterActor*, const ClutterColor*);
79
80static void graphicsLayerActorAdded(ClutterContainer*, ClutterActor*, gpointer data);
81static void graphicsLayerActorRemoved(ClutterContainer*, ClutterActor*, gpointer data);
82static gboolean graphicsLayerActorDraw(ClutterCairoTexture*, cairo_t*, GraphicsLayerActor*);
83static void graphicsLayerActorUpdateTexture(GraphicsLayerActor*);
84static void graphicsLayerActorDrawLayerContents(ClutterActor*, GraphicsContext&);
85
86static void graphics_layer_actor_class_init(GraphicsLayerActorClass* klass)
87{
88 GObjectClass* objectClass = G_OBJECT_CLASS(klass);
89 ClutterActorClass* actorClass = CLUTTER_ACTOR_CLASS(klass);
90 GParamSpec* pspec;
91
92 objectClass->get_property = graphicsLayerActorGetProperty;
93 objectClass->set_property = graphicsLayerActorSetProperty;
94 objectClass->dispose = graphicsLayerActorDispose;
95 actorClass->apply_transform = graphicsLayerActorApplyTransform;
96 actorClass->allocate = graphicsLayerActorAllocate;
97 actorClass->paint = graphicsLayerActorPaint;
98 actorClass->pick = graphicsLayerActorPick;
99
100 g_type_class_add_private(klass, sizeof(GraphicsLayerActorPrivate));
101
102 pspec = g_param_spec_float("translate-x",
103 "Translate X",
104 "Translation value for the X axis",
105 -G_MAXFLOAT,
106 G_MAXFLOAT,
107 0.0,
108 static_cast<GParamFlags>(G_PARAM_READWRITE));
109 g_object_class_install_property(objectClass, PROP_TRANSLATE_X, pspec);
110
111 pspec = g_param_spec_float("translate-y",
112 "Translate Y",
113 "Translation value for the Y ayis",
114 -G_MAXFLOAT,
115 G_MAXFLOAT,
116 0.0,
117 static_cast<GParamFlags>(G_PARAM_READWRITE));
118 g_object_class_install_property(objectClass, PROP_TRANSLATE_Y, pspec);
119}
120
121static void graphics_layer_actor_init(GraphicsLayerActor* self)
122{
123 GraphicsLayerActorPrivate* priv = self->priv = GRAPHICS_LAYER_ACTOR_GET_PRIVATE(self);
124
125 clutter_actor_set_reactive(CLUTTER_ACTOR(self), FALSE);
126
127 // Default used by GraphicsLayer.
128 graphicsLayerActorSetAnchorPoint(self, 0.5, 0.5, 0.0);
129
130 priv->scrollX = 0.0;
131 priv->scrollY = 0.0;
132
133 priv->translateX = 0.0;
134 priv->translateY = 0.0;
135
136 priv->matrix = 0;
137
138 g_signal_connect(self, "actor-added", G_CALLBACK(graphicsLayerActorAdded), 0);
139 g_signal_connect(self, "actor-removed", G_CALLBACK(graphicsLayerActorRemoved), 0);
140}
141
142static void graphicsLayerActorSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* pspec)
143{
144 GraphicsLayerActor* layer = GRAPHICS_LAYER_ACTOR(object);
145
146 switch (propID) {
147 case PROP_TRANSLATE_X:
148 graphicsLayerActorSetTranslateX(layer, g_value_get_float(value));
149 break;
150 case PROP_TRANSLATE_Y:
151 graphicsLayerActorSetTranslateY(layer, g_value_get_float(value));
152 break;
153 default:
154 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, pspec);
155 }
156}
157
158static void graphicsLayerActorGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* pspec)
159{
160 GraphicsLayerActor* layer = GRAPHICS_LAYER_ACTOR(object);
161
162 switch (propID) {
163 case PROP_TRANSLATE_X:
164 g_value_set_float(value, graphicsLayerActorGetTranslateX(layer));
165 break;
166 case PROP_TRANSLATE_Y:
167 g_value_set_float(value, graphicsLayerActorGetTranslateY(layer));
168 break;
169 default:
170 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, pspec);
171 }
172}
173
174
175static void graphicsLayerActorDispose(GObject* object)
176{
177 GraphicsLayerActor* layer = GRAPHICS_LAYER_ACTOR(object);
178 GraphicsLayerActorPrivate* priv = layer->priv;
179
180 if (priv->texture) {
181 clutter_actor_destroy(priv->texture);
182 priv->texture = 0;
183 }
184
185 priv->surface.clear();
186
187 if (priv->matrix)
188 cogl_matrix_free(priv->matrix);
189
190 G_OBJECT_CLASS(graphics_layer_actor_parent_class)->dispose(object);
191}
192
193// Copied from cairo.
194#define MAX_IMAGE_SIZE 32767
195
196static void graphicsLayerActorAllocate(ClutterActor* self, const ClutterActorBox* box, ClutterAllocationFlags flags)
197{
198 GraphicsLayerActor* layer = GRAPHICS_LAYER_ACTOR(self);
199 GraphicsLayerActorPrivate* priv = layer->priv;
200
201 priv->allocating = TRUE;
202
203 CLUTTER_ACTOR_CLASS(graphics_layer_actor_parent_class)->allocate(self, box, flags);
204
205 if (priv->texture) {
206 // The texture occupies the whole area, but is positioned at 0,0
207 // relative to the layer actor.
208 ClutterActorBox textureBox = { 0.0, 0.0, box->x2 - box->x1, box->y2 - box->y1 };
209
210 // protect against 0x0
211 if (!textureBox.x2)
212 textureBox.x2 = 1;
213
214 if (!textureBox.y2)
215 textureBox.y2 = 1;
216
217 // FIXME: some pages make us create very big layers, which
218 // exceeds cairo's limits, check for that here.
219 if (textureBox.x2 > MAX_IMAGE_SIZE) {
220 g_warning("Layer %s has a width that exceeds cairo's limits: %.2f", clutter_actor_get_name(self), textureBox.x2);
221 textureBox.x2 = MAX_IMAGE_SIZE;
222 }
223
224 if (textureBox.y2 > MAX_IMAGE_SIZE) {
225 g_warning("Layer %s has a height that exceeds cairo's limits: %.2f", clutter_actor_get_name(self), textureBox.y2);
226 textureBox.y2 = MAX_IMAGE_SIZE;
227 }
228
229 clutter_actor_allocate(priv->texture, &textureBox, flags);
230 }
231
232 // FIXME: maybe we can cache children allocation and not call
233 // allocate on them this often?
234 for (GList* list = layer->children; list; list = list->next) {
235 ClutterActor* child = CLUTTER_ACTOR(list->data);
236
237 float childWidth = clutter_actor_get_width(child);
238 float childHeight = clutter_actor_get_height(child);
239
240 ClutterActorBox childBox;
241 childBox.x1 = clutter_actor_get_x(child);
242 childBox.y1 = clutter_actor_get_y(child);
243 childBox.x2 = childBox.x1 + childWidth;
244 childBox.y2 = childBox.y1 + childHeight;
245
246 clutter_actor_allocate(child, &childBox, flags);
247 }
248
249 priv->allocating = FALSE;
250}
251
252static void graphicsLayerActorApplyTransform(ClutterActor* actor, CoglMatrix* matrix)
253{
254 GraphicsLayerActorPrivate* priv = GRAPHICS_LAYER_ACTOR(actor)->priv;
255
256 // Apply translation and scrolling as a single translation. These
257 // need to come before anything else, otherwise they'll be
258 // affected by other operations such as scaling, which is not what
259 // we want.
260 gfloat translateX = priv->scrollX + priv->translateX;
261 gfloat translateY = priv->scrollY + priv->translateY;
262
263 if (translateX || translateY)
264 cogl_matrix_translate(matrix, translateX, translateY, 0);
265
266 CLUTTER_ACTOR_CLASS(graphics_layer_actor_parent_class)->apply_transform(actor, matrix);
267
268 gfloat width = clutter_actor_get_width(actor);
269 gfloat height = clutter_actor_get_height(actor);
270 if (width <= 1.0 || height <= 1.0)
271 return;
272
273 gfloat pivotX, pivotY;
274 pivotX = width * priv->anchorX;
275 pivotY = height * priv->anchorY;
276
277 if (priv->matrix) {
278 CoglMatrix* localMatrix;
279 // CSS3 tranform-style can be changed on the fly,
280 // so we have to copy priv->matrix in order to recover z-axis.
281 localMatrix = cogl_matrix_copy(priv->matrix);
282
283 cogl_matrix_translate(matrix, pivotX, pivotY, priv->anchorZ);
284 cogl_matrix_multiply(matrix, matrix, localMatrix);
285 cogl_matrix_translate(matrix, -pivotX, -pivotY, -priv->anchorZ);
286 cogl_matrix_free(localMatrix);
287 }
288}
289
290static void graphicsLayerActorPaint(ClutterActor* actor)
291{
292 GraphicsLayerActor* graphicsLayer = GRAPHICS_LAYER_ACTOR(actor);
293 GraphicsLayerActorPrivate* priv = GRAPHICS_LAYER_ACTOR(actor)->priv;
294
295 // Paint the texture in case we have a border. This will be the case when debugging borders
296 // are turned on that we want to see.
297 if (priv->texture)
298 clutter_actor_paint(priv->texture);
299
300 GList* list;
301 for (list = graphicsLayer->children; list; list = list->next) {
302 ClutterActor* child = CLUTTER_ACTOR(list->data);
303 clutter_actor_paint(child);
304 }
305}
306
307static void graphicsLayerActorPick(ClutterActor* actor, const ClutterColor* pick)
308{
309 GraphicsLayerActor* graphicsLayer = GRAPHICS_LAYER_ACTOR(actor);
310 GraphicsLayerActorPrivate* priv = graphicsLayer->priv;
311
312 CLUTTER_ACTOR_CLASS(graphics_layer_actor_parent_class)->pick(actor, pick);
313
314 if (priv->texture)
315 clutter_actor_paint(priv->texture);
316
317 GList* list;
318 for (list = graphicsLayer->children; list; list = list->next) {
319 ClutterActor* child = CLUTTER_ACTOR(list->data);
320 clutter_actor_paint(child);
321 }
322}
323
324static gboolean graphicsLayerActorDraw(ClutterCairoTexture* texture, cairo_t* cr, GraphicsLayerActor* layer)
325{
326 ClutterActor* actor = CLUTTER_ACTOR(layer);
327 gfloat width = clutter_actor_get_width(actor);
328 gfloat height = clutter_actor_get_height(actor);
329
330 if (!width || !height)
331 return FALSE;
332
333 GraphicsLayerActorPrivate* priv = layer->priv;
334 GraphicsContext context(cr);
335
336 clutter_cairo_texture_clear(texture);
337
338 if (priv->surface) {
339 gint surfaceWidth = cairo_image_surface_get_width(priv->surface.get());
340 gint surfaceHeight = cairo_image_surface_get_height(priv->surface.get());
341
342 FloatRect srcRect(0.0, 0.0, static_cast<float>(surfaceWidth), static_cast<float>(surfaceHeight));
343 FloatRect destRect(0.0, 0.0, width, height);
344 context.platformContext()->drawSurfaceToContext(priv->surface.get(), destRect, srcRect, &context);
345 }
346
347 if (priv->layerType == GraphicsLayerClutter::LayerTypeWebLayer)
348 graphicsLayerActorDrawLayerContents(actor, context);
349
350 return TRUE;
351}
352
353static void graphicsLayerActorAdded(ClutterContainer* container, ClutterActor* actor, gpointer data)
354{
355 GraphicsLayerActor* graphicsLayer = GRAPHICS_LAYER_ACTOR(container);
356 graphicsLayer->children = g_list_append(graphicsLayer->children, actor);
357}
358
359static void graphicsLayerActorRemoved(ClutterContainer* container, ClutterActor* actor, gpointer data)
360{
361 GraphicsLayerActor* graphicsLayer = GRAPHICS_LAYER_ACTOR(container);
362 graphicsLayer->children = g_list_remove(graphicsLayer->children, actor);
363}
364
365static void graphicsLayerActorUpdateTexture(GraphicsLayerActor* layer)
366{
367 GraphicsLayerActorPrivate* priv = layer->priv;
368 ASSERT(priv->layerType != GraphicsLayerClutter::LayerTypeVideoLayer);
369
370 // Nothing needs a texture, remove the one we have, if any.
371 if (!priv->drawsContent && !priv->surface) {
372 if (!priv->texture)
373 return;
374
375 g_signal_handlers_disconnect_by_func(priv->texture, reinterpret_cast<void*>(graphicsLayerActorDraw), layer);
376 clutter_actor_unparent(priv->texture);
377 priv->texture = 0;
378 return;
379 }
380
381 // We need a texture, but already have one!
382 if (priv->texture)
383 return;
384
385 // We need a texture, so create it.
386 ClutterActor* actor = CLUTTER_ACTOR(layer);
387 int width = ceilf(clutter_actor_get_width(actor));
388 int height = ceilf(clutter_actor_get_height(actor));
389
390 priv->texture = CLUTTER_ACTOR(g_object_new(CLUTTER_TYPE_CAIRO_TEXTURE,
391 "auto-resize", TRUE,
392 "surface-height", width > 0 ? width : 1,
393 "surface-width", height > 0 ? height : 1,
394 0));
395
396 clutter_actor_set_parent(priv->texture, actor);
397
398 g_signal_connect(priv->texture, "draw", G_CALLBACK(graphicsLayerActorDraw), layer);
399}
400
401// Draw content into the layer.
402static void graphicsLayerActorDrawLayerContents(ClutterActor* actor, GraphicsContext& context)
403{
404 GraphicsLayerActorPrivate* priv = GRAPHICS_LAYER_ACTOR(actor)->priv;
405
406 if (!priv->drawsContent || !priv->layerClient)
407 return;
408
409 gfloat width = clutter_actor_get_width(actor);
410 gfloat height = clutter_actor_get_height(actor);
411 IntRect clip(0, 0, width, height);
412
413 // Apply the painted content to the layer.
414 priv->layerClient->platformClutterLayerPaintContents(context, clip);
415}
416
417
418GraphicsLayerActor* graphicsLayerActorNew(GraphicsLayerClutter::LayerType type)
419{
420 GraphicsLayerActor* layer = GRAPHICS_LAYER_ACTOR(g_object_new(GRAPHICS_LAYER_TYPE_ACTOR, 0));
421 GraphicsLayerActorPrivate* priv = layer->priv;
422
423 priv->layerType = type;
424
425 // For video layers we don't want the cairo texture, but a regular one.
426 if (priv->layerType == GraphicsLayerClutter::LayerTypeVideoLayer) {
427 priv->texture = clutter_texture_new();
428 clutter_actor_set_parent(priv->texture, CLUTTER_ACTOR(layer));
429 }
430
431 return layer;
432}
433
434GraphicsLayerActor* graphicsLayerActorNewWithClient(GraphicsLayerClutter::LayerType type, PlatformClutterLayerClient* layerClient)
435{
436 GraphicsLayerActor* layer = graphicsLayerActorNew(type);
437 graphicsLayerActorSetClient(layer, layerClient);
438
439 return layer;
440}
441
442void graphicsLayerActorSetClient(GraphicsLayerActor* layer, PlatformClutterLayerClient* client)
443{
444 layer->priv->layerClient = client;
445}
446
447PlatformClutterLayerClient* graphicsLayerActorGetClient(GraphicsLayerActor* layer)
448{
449 return layer->priv->layerClient;
450}
451
452/*
453 * public API
454 */
455void graphicsLayerActorRemoveAll(GraphicsLayerActor* layer)
456{
457 g_return_if_fail(GRAPHICS_LAYER_IS_ACTOR(layer));
458
459 GList* children = clutter_actor_get_children(CLUTTER_ACTOR(layer));
460 for (; children; children = children->next) {
461 // We only want to remove sublayers, not our own composite actors.
462 if (children->data == layer->priv->texture)
463 continue;
464
465 clutter_actor_remove_child(CLUTTER_ACTOR(layer), CLUTTER_ACTOR(children->data));
466 }
467}
468
469cairo_surface_t* graphicsLayerActorGetSurface(GraphicsLayerActor* layer)
470{
471 GraphicsLayerActorPrivate* priv = layer->priv;
472 if (!priv->surface)
473 g_message("surface is null");
474
475 return priv->surface.get();
476}
477
478void graphicsLayerActorSetSurface(GraphicsLayerActor* layer, cairo_surface_t* surface)
479{
480 GraphicsLayerActorPrivate* priv = layer->priv;
481 priv->surface = surface;
482 graphicsLayerActorUpdateTexture(layer);
483}
484
485void graphicsLayerActorInvalidateRectangle(GraphicsLayerActor* layer, const FloatRect& dirtyRect)
486{
487 GraphicsLayerActorPrivate* priv = layer->priv;
488
489 if (!priv->texture)
490 return;
491
492 cairo_rectangle_int_t rect(enclosingIntRect(dirtyRect));
493 clutter_cairo_texture_invalidate_rectangle(CLUTTER_CAIRO_TEXTURE(priv->texture), &rect);
494}
495
496void graphicsLayerActorSetTransform(GraphicsLayerActor* layer, const CoglMatrix* matrix)
497{
498 GraphicsLayerActorPrivate* priv = layer->priv;
499
500 if (priv->matrix) {
501 cogl_matrix_free(priv->matrix);
502 priv->matrix = 0;
503 clutter_actor_queue_redraw(CLUTTER_ACTOR(layer));
504 }
505
506 CoglMatrix identity;
507 cogl_matrix_init_identity(&identity);
508 if (cogl_matrix_equal((CoglMatrix*)&identity, (CoglMatrix*)matrix))
509 return;
510
511 if (priv->matrix)
512 cogl_matrix_free(priv->matrix);
513
514 priv->matrix = cogl_matrix_copy(matrix);
515 clutter_actor_queue_redraw(CLUTTER_ACTOR(layer));
516}
517
518void graphicsLayerActorSetAnchorPoint(GraphicsLayerActor* layer, gfloat x, gfloat y, gfloat z)
519{
520 GraphicsLayerActorPrivate* priv = layer->priv;
521
522 priv->anchorX = x;
523 priv->anchorY = y;
524 priv->anchorZ = z;
525
526 ClutterActor* actor = CLUTTER_ACTOR(layer);
527
528 float width, height;
529 clutter_actor_get_size(actor, &width, &height);
530 clutter_actor_set_anchor_point(actor, width * priv->anchorX, height * priv->anchorY);
531}
532
533void graphicsLayerActorGetAnchorPoint(GraphicsLayerActor* layer, gfloat* x, gfloat* y, gfloat* z)
534{
535 GraphicsLayerActorPrivate* priv = layer->priv;
536 if (x)
537 *x = priv->anchorX;
538
539 if (y)
540 *y = priv->anchorY;
541
542 if (z)
543 *z = priv->anchorZ;
544}
545
546void graphicsLayerActorSetScrollPosition(GraphicsLayerActor* layer, gfloat x, gfloat y)
547{
548 GraphicsLayerActorPrivate* priv = layer->priv;
549
550 if (x > 0 || y > 0)
551 return;
552
553 priv->scrollX = x;
554 priv->scrollY = y;
555
556 clutter_actor_queue_redraw(CLUTTER_ACTOR(layer));
557}
558
559gint graphicsLayerActorGetnChildren(GraphicsLayerActor* layer)
560{
561 ASSERT(GRAPHICS_LAYER_IS_ACTOR(layer));
562
563 return g_list_length(layer->children);
564}
565
566void graphicsLayerActorReplaceSublayer(GraphicsLayerActor* layer, ClutterActor* oldChildLayer, ClutterActor* newChildLayer)
567{
568 ASSERT(GRAPHICS_LAYER_IS_ACTOR(layer));
569 ASSERT(CLUTTER_IS_ACTOR(oldChildLayer));
570 ASSERT(CLUTTER_IS_ACTOR(newChildLayer));
571
572 clutter_actor_remove_child(CLUTTER_ACTOR(layer), oldChildLayer);
573 clutter_actor_add_child(CLUTTER_ACTOR(layer), newChildLayer);
574}
575
576void graphicsLayerActorInsertSublayer(GraphicsLayerActor* layer, ClutterActor* childLayer, gint index)
577{
578 ASSERT(GRAPHICS_LAYER_IS_ACTOR(layer));
579 ASSERT(CLUTTER_IS_ACTOR(childLayer));
580
581 g_object_ref(childLayer);
582
583 layer->children = g_list_insert(layer->children, childLayer, index);
584 ASSERT(!clutter_actor_get_parent(childLayer));
585 clutter_actor_set_parent(childLayer, CLUTTER_ACTOR(layer));
586 clutter_actor_queue_relayout(CLUTTER_ACTOR(layer));
587
588 g_object_unref(childLayer);
589}
590
591void graphicsLayerActorSetSublayers(GraphicsLayerActor* layer, GraphicsLayerActorList& subLayers)
592{
593 if (!subLayers.size()) {
594 graphicsLayerActorRemoveAll(layer);
595 return;
596 }
597
598 for (size_t i = 0; i < subLayers.size(); ++i) {
599 ClutterActor* layerActor = CLUTTER_ACTOR(subLayers[i].get());
600 clutter_container_add_actor(CLUTTER_CONTAINER(layer), layerActor);
601 }
602}
603
604GraphicsLayerClutter::LayerType graphicsLayerActorGetLayerType(GraphicsLayerActor* layer)
605{
606 GraphicsLayerActorPrivate* priv = layer->priv;
607 return priv->layerType;
608}
609
610void graphicsLayerActorSetLayerType(GraphicsLayerActor* layer, GraphicsLayerClutter::LayerType layerType)
611{
612 GraphicsLayerActorPrivate* priv = layer->priv;
613 priv->layerType = layerType;
614}
615
616void graphicsLayerActorSetTranslateX(GraphicsLayerActor* layer, float value)
617{
618 GraphicsLayerActorPrivate* priv = layer->priv;
619 priv->translateX = value;
620 clutter_actor_queue_redraw(CLUTTER_ACTOR(layer));
621}
622
623float graphicsLayerActorGetTranslateX(GraphicsLayerActor* layer)
624{
625 GraphicsLayerActorPrivate* priv = layer->priv;
626 return priv->translateX;
627}
628
629void graphicsLayerActorSetTranslateY(GraphicsLayerActor* layer, float value)
630{
631 GraphicsLayerActorPrivate* priv = layer->priv;
632 priv->translateY = value;
633 clutter_actor_queue_redraw(CLUTTER_ACTOR(layer));
634}
635
636float graphicsLayerActorGetTranslateY(GraphicsLayerActor* layer)
637{
638 GraphicsLayerActorPrivate* priv = layer->priv;
639 return priv->translateY;
640}
641
642void graphicsLayerActorSetDrawsContent(GraphicsLayerActor* layer, gboolean drawsContent)
643{
644 GraphicsLayerActorPrivate* priv = layer->priv;
645
646 if (drawsContent == priv->drawsContent)
647 return;
648
649 priv->drawsContent = drawsContent;
650
651 graphicsLayerActorUpdateTexture(layer);
652}
653
654gboolean graphicsLayerActorGetDrawsContent(GraphicsLayerActor* layer)
655{
656 return layer->priv->drawsContent;
657}
658
659#endif // USE(ACCELERATED_COMPOSITING)