1/*
2 * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
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 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.
24 */
25
26#include "config.h"
27#include "LayerPool.h"
28#include "PlatformCALayer.h"
29#include <wtf/StringExtras.h>
30
31#if USE(CA)
32
33namespace WebCore {
34
35static GraphicsLayer::PlatformLayerID generateLayerID()
36{
37    static GraphicsLayer::PlatformLayerID layerID;
38    return ++layerID;
39}
40
41#if COMPILER(MSVC)
42const float PlatformCALayer::webLayerWastedSpaceThreshold = 0.75f;
43#endif
44
45PlatformCALayer::PlatformCALayer(LayerType layerType, PlatformCALayerClient* owner)
46    : m_layerType(layerType)
47    , m_layerID(generateLayerID())
48    , m_owner(owner)
49{
50}
51
52PlatformCALayer::~PlatformCALayer()
53{
54    // Clear the owner, which also clears it in the delegate to prevent attempts
55    // to use the GraphicsLayerCA after it has been destroyed.
56    setOwner(nullptr);
57}
58
59void PlatformCALayer::drawRepaintIndicator(CGContextRef context, PlatformCALayer* platformCALayer, int repaintCount, CGColorRef customBackgroundColor)
60{
61    char text[16]; // that's a lot of repaints
62    snprintf(text, sizeof(text), "%d", repaintCount);
63
64    CGRect indicatorBox = platformCALayer->bounds();
65    indicatorBox.size.width = 12 + 10 * strlen(text);
66    indicatorBox.size.height = 27;
67    CGContextSaveGState(context);
68
69    CGContextSetAlpha(context, 0.5f);
70    CGContextBeginTransparencyLayerWithRect(context, indicatorBox, 0);
71
72    if (customBackgroundColor)
73        CGContextSetFillColorWithColor(context, customBackgroundColor);
74    else
75        CGContextSetRGBFillColor(context, 0, 0.5f, 0.25f, 1);
76
77    CGContextFillRect(context, indicatorBox);
78
79    if (platformCALayer->acceleratesDrawing())
80        CGContextSetRGBFillColor(context, 1, 0, 0, 1);
81    else
82        CGContextSetRGBFillColor(context, 1, 1, 1, 1);
83
84#pragma clang diagnostic push
85#pragma clang diagnostic ignored "-Wdeprecated-declarations"
86    CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1, -1));
87    CGContextSelectFont(context, "Helvetica", 22, kCGEncodingMacRoman);
88    CGContextShowTextAtPoint(context, indicatorBox.origin.x + 5, indicatorBox.origin.y + 22, text, strlen(text));
89#pragma clang diagnostic pop
90
91    CGContextEndTransparencyLayer(context);
92    CGContextRestoreGState(context);
93}
94
95PassRefPtr<PlatformCALayer> PlatformCALayer::createCompatibleLayerOrTakeFromPool(PlatformCALayer::LayerType layerType, PlatformCALayerClient* client, IntSize size)
96{
97    RefPtr<PlatformCALayer> layer;
98
99    if ((layer = layerPool().takeLayerWithSize(size))) {
100        layer->setOwner(client);
101        return layer.release();
102    }
103
104    layer = createCompatibleLayer(layerType, client);
105    layer->setBounds(FloatRect(FloatPoint(), size));
106
107    return layer.release();
108}
109
110void PlatformCALayer::moveToLayerPool()
111{
112    ASSERT(!superlayer());
113    layerPool().addLayer(this);
114}
115
116LayerPool& PlatformCALayer::layerPool()
117{
118    static LayerPool* sharedPool = new LayerPool;
119    return *sharedPool;
120}
121
122}
123
124#endif // USE(CA)
125