2
* Copyright (C) 2011 Apple Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
13
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
#if USE(ACCELERATED_COMPOSITING)
30
#include "PlatformCALayer.h"
32
#include "AbstractCACFLayerTreeHost.h"
34
#include "GraphicsContext.h"
35
#include "PlatformCALayerWinInternal.h"
36
#include <QuartzCore/CoreAnimationCF.h>
37
#include <WebKitSystemInterface/WebKitSystemInterface.h>
38
#include <wtf/CurrentTime.h>
39
#include <wtf/text/CString.h>
41
using namespace WebCore;
43
bool PlatformCALayer::isValueFunctionSupported()
48
void PlatformCALayer::setOwner(PlatformCALayerClient* owner)
53
static CFStringRef toCACFLayerType(PlatformCALayer::LayerType type)
55
return (type == PlatformCALayer::LayerTypeTransformLayer) ? kCACFTransformLayer : kCACFLayer;
58
static CFStringRef toCACFFilterType(PlatformCALayer::FilterType type)
61
case PlatformCALayer::Linear: return kCACFFilterLinear;
62
case PlatformCALayer::Nearest: return kCACFFilterNearest;
63
case PlatformCALayer::Trilinear: return kCACFFilterTrilinear;
68
static AbstractCACFLayerTreeHost* layerTreeHostForLayer(const PlatformCALayer* layer)
70
// We need the AbstractCACFLayerTreeHost associated with this layer, which is stored in the UserData of the CACFContext
71
void* userData = wkCACFLayerGetContextUserData(layer->platformLayer());
75
return static_cast<AbstractCACFLayerTreeHost*>(userData);
78
static PlatformCALayerWinInternal* intern(const PlatformCALayer* layer)
80
return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(layer->platformLayer()));
83
static PlatformCALayerWinInternal* intern(void* layer)
85
return static_cast<PlatformCALayerWinInternal*>(CACFLayerGetUserData(static_cast<CACFLayerRef>(layer)));
88
PassRefPtr<PlatformCALayer> PlatformCALayer::create(LayerType layerType, PlatformCALayerClient* owner)
90
return adoptRef(new PlatformCALayer(layerType, 0, owner));
93
PassRefPtr<PlatformCALayer> PlatformCALayer::create(void* platformLayer, PlatformCALayerClient* owner)
95
return adoptRef(new PlatformCALayer(LayerTypeCustom, static_cast<PlatformLayer*>(platformLayer), owner));
98
static void displayCallback(CACFLayerRef caLayer, CGContextRef context)
100
ASSERT_ARG(caLayer, CACFLayerGetUserData(caLayer));
101
intern(caLayer)->displayCallback(caLayer, context);
104
static void layoutSublayersProc(CACFLayerRef caLayer)
106
PlatformCALayer* layer = PlatformCALayer::platformCALayer(caLayer);
107
if (layer && layer->owner())
108
layer->owner()->platformCALayerLayoutSublayersOfLayer(layer);
111
PlatformCALayer::PlatformCALayer(LayerType layerType, PlatformLayer* layer, PlatformCALayerClient* owner)
115
m_layerType = LayerTypeCustom;
118
m_layerType = layerType;
119
m_layer.adoptCF(CACFLayerCreate(toCACFLayerType(layerType)));
121
// Create the PlatformCALayerWinInternal object and point to it in the userdata.
122
PlatformCALayerWinInternal* intern = new PlatformCALayerWinInternal(this);
123
CACFLayerSetUserData(m_layer.get(), intern);
125
// Set the display callback
126
CACFLayerSetDisplayCallback(m_layer.get(), displayCallback);
127
CACFLayerSetLayoutCallback(m_layer.get(), layoutSublayersProc);
131
PlatformCALayer::~PlatformCALayer()
134
removeAllSublayers();
136
// Get rid of the user data
137
PlatformCALayerWinInternal* layerIntern = intern(this);
138
CACFLayerSetUserData(m_layer.get(), 0);
143
PlatformCALayer* PlatformCALayer::platformCALayer(void* platformLayer)
148
PlatformCALayerWinInternal* layerIntern = intern(platformLayer);
149
return layerIntern ? layerIntern->owner() : 0;
152
PlatformLayer* PlatformCALayer::platformLayer() const
154
return m_layer.get();
157
PlatformCALayer* PlatformCALayer::rootLayer() const
159
AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
160
return host ? host->rootLayer() : 0;
163
void PlatformCALayer::animationStarted(CFTimeInterval beginTime)
165
// Update start time for any animation not yet started
166
CFTimeInterval cacfBeginTime = currentTimeToMediaTime(beginTime);
168
HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = m_animations.end();
169
for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = m_animations.begin(); it != end; ++it)
170
it->value->setActualStartTimeIfNeeded(cacfBeginTime);
173
m_owner->platformCALayerAnimationStarted(beginTime);
176
static void resubmitAllAnimations(PlatformCALayer* layer)
178
HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = layer->animations().end();
179
for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = layer->animations().begin(); it != end; ++it)
180
CACFLayerAddAnimation(layer->platformLayer(), it->key.createCFString().get(), it->value->platformAnimation());
183
void PlatformCALayer::ensureAnimationsSubmitted()
185
resubmitAllAnimations(this);
187
PlatformCALayerList children;
188
intern(this)->getSublayers(children);
189
for (size_t i = 0; i < children.size(); ++i)
190
children[i]->ensureAnimationsSubmitted();
193
void PlatformCALayer::setNeedsDisplay(const FloatRect* dirtyRect)
195
intern(this)->setNeedsDisplay(dirtyRect);
198
void PlatformCALayer::setNeedsCommit()
200
AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
202
host->layerTreeDidChange();
205
void PlatformCALayer::setContentsChanged()
207
// FIXME: There is no equivalent of setContentsChanged in CACF. For now I will
208
// set contents to 0 and then back to its original value to see if that
209
// kicks CACF into redisplaying.
210
RetainPtr<CFTypeRef> contents = CACFLayerGetContents(m_layer.get());
211
CACFLayerSetContents(m_layer.get(), 0);
212
CACFLayerSetContents(m_layer.get(), contents.get());
216
void PlatformCALayer::setNeedsLayout()
218
if (!m_owner || !m_owner->platformCALayerRespondsToLayoutChanges())
221
CACFLayerSetNeedsLayout(m_layer.get());
225
PlatformCALayer* PlatformCALayer::superlayer() const
227
return platformCALayer(CACFLayerGetSuperlayer(m_layer.get()));
230
void PlatformCALayer::removeFromSuperlayer()
232
CACFLayerRemoveFromSuperlayer(m_layer.get());
236
void PlatformCALayer::setSublayers(const PlatformCALayerList& list)
238
intern(this)->setSublayers(list);
241
void PlatformCALayer::removeAllSublayers()
243
intern(this)->removeAllSublayers();
246
void PlatformCALayer::appendSublayer(PlatformCALayer* layer)
248
// This must be in terms of insertSublayer instead of a direct call so PlatformCALayerInternal can override.
249
insertSublayer(layer, sublayerCount());
252
void PlatformCALayer::insertSublayer(PlatformCALayer* layer, size_t index)
254
intern(this)->insertSublayer(layer, index);
257
void PlatformCALayer::replaceSublayer(PlatformCALayer* reference, PlatformCALayer* newLayer)
259
// This must not use direct calls to allow PlatformCALayerInternal to override.
260
ASSERT_ARG(reference, reference);
261
ASSERT_ARG(reference, reference->superlayer() == this);
263
if (reference == newLayer)
266
int referenceIndex = intern(this)->indexOfSublayer(reference);
267
ASSERT(referenceIndex != -1);
268
if (referenceIndex == -1)
271
reference->removeFromSuperlayer();
274
newLayer->removeFromSuperlayer();
275
insertSublayer(newLayer, referenceIndex);
279
size_t PlatformCALayer::sublayerCount() const
281
return intern(this)->sublayerCount();
284
void PlatformCALayer::adoptSublayers(PlatformCALayer* source)
286
PlatformCALayerList sublayers;
287
intern(source)->getSublayers(sublayers);
289
// Use setSublayers() because it properly nulls out the superlayer pointers.
290
setSublayers(sublayers);
293
void PlatformCALayer::addAnimationForKey(const String& key, PlatformCAAnimation* animation)
295
// Add it to the animation list
296
m_animations.add(key, animation);
298
CACFLayerAddAnimation(m_layer.get(), key.createCFString().get(), animation->platformAnimation());
301
// Tell the host about it so we can fire the start animation event
302
AbstractCACFLayerTreeHost* host = layerTreeHostForLayer(this);
304
host->addPendingAnimatedLayer(this);
307
void PlatformCALayer::removeAnimationForKey(const String& key)
309
// Remove it from the animation list
310
m_animations.remove(key);
312
CACFLayerRemoveAnimation(m_layer.get(), key.createCFString().get());
314
// We don't "remove" a layer from AbstractCACFLayerTreeHost when it loses an animation.
315
// There may be other active animations on the layer and if an animation
316
// callback is fired on a layer without any animations no harm is done.
321
PassRefPtr<PlatformCAAnimation> PlatformCALayer::animationForKey(const String& key)
323
HashMap<String, RefPtr<PlatformCAAnimation> >::iterator it = m_animations.find(key);
324
if (it == m_animations.end())
330
PlatformCALayer* PlatformCALayer::mask() const
332
return platformCALayer(CACFLayerGetMask(m_layer.get()));
335
void PlatformCALayer::setMask(PlatformCALayer* layer)
337
CACFLayerSetMask(m_layer.get(), layer ? layer->platformLayer() : 0);
341
bool PlatformCALayer::isOpaque() const
343
return CACFLayerIsOpaque(m_layer.get());
346
void PlatformCALayer::setOpaque(bool value)
348
CACFLayerSetOpaque(m_layer.get(), value);
352
FloatRect PlatformCALayer::bounds() const
354
return CACFLayerGetBounds(m_layer.get());
357
void PlatformCALayer::setBounds(const FloatRect& value)
359
intern(this)->setBounds(value);
363
FloatPoint3D PlatformCALayer::position() const
365
CGPoint point = CACFLayerGetPosition(m_layer.get());
366
return FloatPoint3D(point.x, point.y, CACFLayerGetZPosition(m_layer.get()));
369
void PlatformCALayer::setPosition(const FloatPoint3D& value)
371
CACFLayerSetPosition(m_layer.get(), CGPointMake(value.x(), value.y()));
372
CACFLayerSetZPosition(m_layer.get(), value.z());
376
FloatPoint3D PlatformCALayer::anchorPoint() const
378
CGPoint point = CACFLayerGetAnchorPoint(m_layer.get());
379
float z = CACFLayerGetAnchorPointZ(m_layer.get());
380
return FloatPoint3D(point.x, point.y, z);
383
void PlatformCALayer::setAnchorPoint(const FloatPoint3D& value)
385
CACFLayerSetAnchorPoint(m_layer.get(), CGPointMake(value.x(), value.y()));
386
CACFLayerSetAnchorPointZ(m_layer.get(), value.z());
390
TransformationMatrix PlatformCALayer::transform() const
392
return CACFLayerGetTransform(m_layer.get());
395
void PlatformCALayer::setTransform(const TransformationMatrix& value)
397
CACFLayerSetTransform(m_layer.get(), value);
401
TransformationMatrix PlatformCALayer::sublayerTransform() const
403
return CACFLayerGetSublayerTransform(m_layer.get());
406
void PlatformCALayer::setSublayerTransform(const TransformationMatrix& value)
408
CACFLayerSetSublayerTransform(m_layer.get(), value);
412
TransformationMatrix PlatformCALayer::contentsTransform() const
414
// ContentsTransform is not used
415
return TransformationMatrix();
418
void PlatformCALayer::setContentsTransform(const TransformationMatrix&)
420
// ContentsTransform is not used
423
bool PlatformCALayer::isHidden() const
425
return CACFLayerIsHidden(m_layer.get());
428
void PlatformCALayer::setHidden(bool value)
430
CACFLayerSetHidden(m_layer.get(), value);
434
bool PlatformCALayer::isGeometryFlipped() const
436
return CACFLayerIsGeometryFlipped(m_layer.get());
439
void PlatformCALayer::setGeometryFlipped(bool value)
441
CACFLayerSetGeometryFlipped(m_layer.get(), value);
445
bool PlatformCALayer::isDoubleSided() const
447
return CACFLayerIsDoubleSided(m_layer.get());
450
void PlatformCALayer::setDoubleSided(bool value)
452
CACFLayerSetDoubleSided(m_layer.get(), value);
456
bool PlatformCALayer::masksToBounds() const
458
return CACFLayerGetMasksToBounds(m_layer.get());
461
void PlatformCALayer::setMasksToBounds(bool value)
463
CACFLayerSetMasksToBounds(m_layer.get(), value);
467
bool PlatformCALayer::acceleratesDrawing() const
472
void PlatformCALayer::setAcceleratesDrawing(bool)
476
CFTypeRef PlatformCALayer::contents() const
478
return CACFLayerGetContents(m_layer.get());
481
void PlatformCALayer::setContents(CFTypeRef value)
483
CACFLayerSetContents(m_layer.get(), value);
487
FloatRect PlatformCALayer::contentsRect() const
489
return CACFLayerGetContentsRect(m_layer.get());
492
void PlatformCALayer::setContentsRect(const FloatRect& value)
494
CACFLayerSetContentsRect(m_layer.get(), value);
498
void PlatformCALayer::setMinificationFilter(FilterType value)
500
CACFLayerSetMinificationFilter(m_layer.get(), toCACFFilterType(value));
503
void PlatformCALayer::setMagnificationFilter(FilterType value)
505
CACFLayerSetMagnificationFilter(m_layer.get(), toCACFFilterType(value));
509
Color PlatformCALayer::backgroundColor() const
511
return CACFLayerGetBackgroundColor(m_layer.get());
514
void PlatformCALayer::setBackgroundColor(const Color& value)
516
CGFloat components[4];
517
value.getRGBA(components[0], components[1], components[2], components[3]);
519
RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
520
RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
522
CACFLayerSetBackgroundColor(m_layer.get(), color.get());
526
float PlatformCALayer::borderWidth() const
528
return CACFLayerGetBorderWidth(m_layer.get());
531
void PlatformCALayer::setBorderWidth(float value)
533
CACFLayerSetBorderWidth(m_layer.get(), value);
537
Color PlatformCALayer::borderColor() const
539
return CACFLayerGetBorderColor(m_layer.get());
542
void PlatformCALayer::setBorderColor(const Color& value)
544
CGFloat components[4];
545
value.getRGBA(components[0], components[1], components[2], components[3]);
547
RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
548
RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
550
CACFLayerSetBorderColor(m_layer.get(), color.get());
554
float PlatformCALayer::opacity() const
556
return CACFLayerGetOpacity(m_layer.get());
559
void PlatformCALayer::setOpacity(float value)
561
CACFLayerSetOpacity(m_layer.get(), value);
565
#if ENABLE(CSS_FILTERS)
567
void PlatformCALayer::setFilters(const FilterOperations&)
571
void PlatformCALayer::copyFiltersFrom(const PlatformCALayer*)
575
bool PlatformCALayer::filtersCanBeComposited(const FilterOperations&)
580
#endif // ENABLE(CSS_FILTERS)
582
String PlatformCALayer::name() const
584
return CACFLayerGetName(m_layer.get());
587
void PlatformCALayer::setName(const String& value)
589
CACFLayerSetName(m_layer.get(), value.createCFString().get());
593
FloatRect PlatformCALayer::frame() const
595
return CACFLayerGetFrame(m_layer.get());
598
void PlatformCALayer::setFrame(const FloatRect& value)
600
intern(this)->setFrame(value);
604
float PlatformCALayer::speed() const
606
return CACFLayerGetSpeed(m_layer.get());
609
void PlatformCALayer::setSpeed(float value)
611
CACFLayerSetSpeed(m_layer.get(), value);
615
CFTimeInterval PlatformCALayer::timeOffset() const
617
return CACFLayerGetTimeOffset(m_layer.get());
620
void PlatformCALayer::setTimeOffset(CFTimeInterval value)
622
CACFLayerSetTimeOffset(m_layer.get(), value);
626
float PlatformCALayer::contentsScale() const
631
void PlatformCALayer::setContentsScale(float)
635
TiledBacking* PlatformCALayer::tiledBacking()
641
static void printIndent(int indent)
643
for ( ; indent > 0; --indent)
644
fprintf(stderr, " ");
647
static void printTransform(const CATransform3D& transform)
649
fprintf(stderr, "[%g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]",
650
transform.m11, transform.m12, transform.m13, transform.m14,
651
transform.m21, transform.m22, transform.m23, transform.m24,
652
transform.m31, transform.m32, transform.m33, transform.m34,
653
transform.m41, transform.m42, transform.m43, transform.m44);
656
static void printLayer(const PlatformCALayer* layer, int indent)
658
FloatPoint3D layerPosition = layer->position();
659
FloatPoint3D layerAnchorPoint = layer->anchorPoint();
660
FloatRect layerBounds = layer->bounds();
663
char* layerTypeName = 0;
664
switch (layer->layerType()) {
665
case PlatformCALayer::LayerTypeLayer: layerTypeName = "layer"; break;
666
case PlatformCALayer::LayerTypeWebLayer: layerTypeName = "web-layer"; break;
667
case PlatformCALayer::LayerTypeTransformLayer: layerTypeName = "transform-layer"; break;
668
case PlatformCALayer::LayerTypeWebTiledLayer: layerTypeName = "web-tiled-layer"; break;
669
case PlatformCALayer::LayerTypeRootLayer: layerTypeName = "root-layer"; break;
670
case PlatformCALayer::LayerTypeCustom: layerTypeName = "custom-layer"; break;
673
fprintf(stderr, "(%s [%g %g %g] [%g %g %g %g] [%g %g %g] superlayer=%p\n",
675
layerPosition.x(), layerPosition.y(), layerPosition.z(),
676
layerBounds.x(), layerBounds.y(), layerBounds.width(), layerBounds.height(),
677
layerAnchorPoint.x(), layerAnchorPoint.y(), layerAnchorPoint.z(), layer->superlayer());
679
// Print name if needed
680
String layerName = layer->name();
681
if (!layerName.isEmpty()) {
682
printIndent(indent + 1);
683
fprintf(stderr, "(name %s)\n", layerName.utf8().data());
686
// Print masksToBounds if needed
687
bool layerMasksToBounds = layer->masksToBounds();
688
if (layerMasksToBounds) {
689
printIndent(indent + 1);
690
fprintf(stderr, "(masksToBounds true)\n");
693
// Print opacity if needed
694
float layerOpacity = layer->opacity();
695
if (layerOpacity != 1) {
696
printIndent(indent + 1);
697
fprintf(stderr, "(opacity %hf)\n", layerOpacity);
700
// Print sublayerTransform if needed
701
TransformationMatrix layerTransform = layer->sublayerTransform();
702
if (!layerTransform.isIdentity()) {
703
printIndent(indent + 1);
704
fprintf(stderr, "(sublayerTransform ");
705
printTransform(layerTransform);
706
fprintf(stderr, ")\n");
709
// Print transform if needed
710
layerTransform = layer->transform();
711
if (!layerTransform.isIdentity()) {
712
printIndent(indent + 1);
713
fprintf(stderr, "(transform ");
714
printTransform(layerTransform);
715
fprintf(stderr, ")\n");
718
// Print contents if needed
719
CFTypeRef layerContents = layer->contents();
721
if (CFGetTypeID(layerContents) == CGImageGetTypeID()) {
722
CGImageRef imageContents = static_cast<CGImageRef>(const_cast<void*>(layerContents));
723
printIndent(indent + 1);
724
fprintf(stderr, "(contents (image [%d %d]))\n",
725
CGImageGetWidth(imageContents), CGImageGetHeight(imageContents));
729
// Print sublayers if needed
730
int n = layer->sublayerCount();
732
printIndent(indent + 1);
733
fprintf(stderr, "(sublayers\n");
735
PlatformCALayerList sublayers;
736
intern(layer)->getSublayers(sublayers);
737
ASSERT(n == sublayers.size());
738
for (int i = 0; i < n; ++i)
739
printLayer(sublayers[i].get(), indent + 2);
741
printIndent(indent + 1);
742
fprintf(stderr, ")\n");
746
fprintf(stderr, ")\n");
749
void PlatformCALayer::printTree() const
751
// Print heading info
752
CGRect rootBounds = bounds();
753
fprintf(stderr, "\n\n** Render tree at time %g (bounds %g, %g %gx%g) **\n\n",
754
currentTime(), rootBounds.origin.x, rootBounds.origin.y, rootBounds.size.width, rootBounds.size.height);
756
// Print layer tree from the root
759
#endif // #ifndef NDEBUG
761
#endif // USE(ACCELERATED_COMPOSITING)