Font antialiasing (smoothing) changes when elements are rendered into compositing...
[WebKit-https.git] / Source / WebCore / platform / graphics / ca / PlatformCALayer.cpp
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 "PlatformCALayer.h"
28
29 #include "LayerPool.h"
30 #include "PlatformCALayerClient.h"
31 #include "TextStream.h"
32 #include <wtf/StringExtras.h>
33
34 #if USE(CA)
35
36 namespace WebCore {
37
38 static GraphicsLayer::PlatformLayerID generateLayerID()
39 {
40     static GraphicsLayer::PlatformLayerID layerID;
41     return ++layerID;
42 }
43
44 #if COMPILER(MSVC)
45 const float PlatformCALayer::webLayerWastedSpaceThreshold = 0.75f;
46 #endif
47
48 PlatformCALayer::PlatformCALayer(LayerType layerType, PlatformCALayerClient* owner)
49     : m_layerType(layerType)
50     , m_layerID(generateLayerID())
51     , m_owner(owner)
52 {
53 }
54
55 PlatformCALayer::~PlatformCALayer()
56 {
57     // Clear the owner, which also clears it in the delegate to prevent attempts
58     // to use the GraphicsLayerCA after it has been destroyed.
59     setOwner(nullptr);
60 }
61
62 void PlatformCALayer::drawRepaintIndicator(CGContextRef context, PlatformCALayer* platformCALayer, int repaintCount, CGColorRef customBackgroundColor)
63 {
64     char text[16]; // that's a lot of repaints
65     snprintf(text, sizeof(text), "%d", repaintCount);
66     
67     CGRect indicatorBox = platformCALayer->bounds();
68
69     CGContextSaveGState(context);
70
71     indicatorBox.size.width = 12 + 10 * strlen(text);
72     indicatorBox.size.height = 27;
73     
74     CGContextSetAlpha(context, 0.5f);
75     CGContextBeginTransparencyLayerWithRect(context, indicatorBox, 0);
76     
77     if (customBackgroundColor)
78         CGContextSetFillColorWithColor(context, customBackgroundColor);
79     else
80         CGContextSetRGBFillColor(context, 0, 0.5f, 0.25f, 1);
81     
82     CGContextFillRect(context, indicatorBox);
83
84     if (platformCALayer->owner()->isUsingDisplayListDrawing(platformCALayer)) {
85         CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.65);
86         CGContextSetLineWidth(context, 2);
87         CGContextStrokeRect(context, indicatorBox);
88     }
89     
90     if (!platformCALayer->isOpaque() && (platformCALayer->contentsFormat() & SmoothedFonts)) {
91         CGContextSetRGBFillColor(context, 1, 1, 1, 0.4);
92         platformCALayer->drawTextAtPoint(context, indicatorBox.origin.x + 7, indicatorBox.origin.y + 24, CGSizeMake(1, -1), 22, text, strlen(text));
93     }
94
95     if (platformCALayer->acceleratesDrawing())
96         CGContextSetRGBFillColor(context, 1, 0, 0, 1);
97     else
98         CGContextSetRGBFillColor(context, 1, 1, 1, 1);
99     
100     platformCALayer->drawTextAtPoint(context, indicatorBox.origin.x + 5, indicatorBox.origin.y + 22, CGSizeMake(1, -1), 22, text, strlen(text));
101     
102     CGContextEndTransparencyLayer(context);
103     CGContextRestoreGState(context);
104 }
105
106 void PlatformCALayer::flipContext(CGContextRef context, CGFloat height)
107 {
108     CGContextScaleCTM(context, 1, -1);
109     CGContextTranslateCTM(context, 0, -height);
110 }
111
112 // This function is needed to work around a bug in Windows CG <rdar://problem/22703470>
113 void PlatformCALayer::drawTextAtPoint(CGContextRef context, CGFloat x, CGFloat y, CGSize scale, CGFloat fontSize, const char* text, size_t length) const
114 {
115 #pragma clang diagnostic push
116 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
117     CGContextSetTextMatrix(context, CGAffineTransformMakeScale(scale.width, scale.height));
118     CGContextSelectFont(context, "Helvetica", fontSize, kCGEncodingMacRoman);
119     CGContextShowTextAtPoint(context, x, y, text, length);
120 #pragma clang diagnostic pop
121 }
122
123 PassRefPtr<PlatformCALayer> PlatformCALayer::createCompatibleLayerOrTakeFromPool(PlatformCALayer::LayerType layerType, PlatformCALayerClient* client, IntSize size)
124 {
125     RefPtr<PlatformCALayer> layer;
126
127     if ((layer = layerPool().takeLayerWithSize(size))) {
128         layer->setOwner(client);
129         return layer.release();
130     }
131
132     layer = createCompatibleLayer(layerType, client);
133     layer->setBounds(FloatRect(FloatPoint(), size));
134     
135     return layer.release();
136 }
137
138 void PlatformCALayer::moveToLayerPool()
139 {
140     ASSERT(!superlayer());
141     layerPool().addLayer(this);
142 }
143
144 LayerPool& PlatformCALayer::layerPool()
145 {
146     static LayerPool* sharedPool = new LayerPool;
147     return *sharedPool;
148 }
149
150 TextStream& operator<<(TextStream& ts, PlatformCALayer::LayerType layerType)
151 {
152     switch (layerType) {
153     case PlatformCALayer::LayerTypeLayer:
154     case PlatformCALayer::LayerTypeWebLayer:
155     case PlatformCALayer::LayerTypeSimpleLayer:
156         ts << "layer";
157         break;
158     case PlatformCALayer::LayerTypeTransformLayer:
159         ts << "transform-layer";
160         break;
161     case PlatformCALayer::LayerTypeWebTiledLayer:
162         ts << "tiled-layer";
163         break;
164     case PlatformCALayer::LayerTypeTiledBackingLayer:
165         ts << "tiled-backing-layer";
166         break;
167     case PlatformCALayer::LayerTypePageTiledBackingLayer:
168         ts << "page-tiled-backing-layer";
169         break;
170     case PlatformCALayer::LayerTypeTiledBackingTileLayer:
171         ts << "tiled-backing-tile";
172         break;
173     case PlatformCALayer::LayerTypeRootLayer:
174         ts << "root-layer";
175         break;
176     case PlatformCALayer::LayerTypeBackdropLayer:
177         ts << "backdrop-layer";
178         break;
179     case PlatformCALayer::LayerTypeAVPlayerLayer:
180         ts << "av-player-layer";
181         break;
182     case PlatformCALayer::LayerTypeWebGLLayer:
183         ts << "web-gl-layer";
184         break;
185     case PlatformCALayer::LayerTypeShapeLayer:
186         ts << "shape-layer";
187         break;
188     case PlatformCALayer::LayerTypeScrollingLayer:
189         ts << "scrolling-layer";
190         break;
191     case PlatformCALayer::LayerTypeCustom:
192         ts << "custom-layer";
193         break;
194     case PlatformCALayer::LayerTypeLightSystemBackdropLayer:
195         ts << "light-system-backdrop-layer";
196         break;
197     case PlatformCALayer::LayerTypeDarkSystemBackdropLayer:
198         ts << "dark-system-backdrop-layer";
199         break;
200     }
201     return ts;
202 }
203
204 TextStream& operator<<(TextStream& ts, PlatformCALayer::FilterType filterType)
205 {
206     switch (filterType) {
207     case PlatformCALayer::Linear:
208         ts << "linear";
209         break;
210     case PlatformCALayer::Nearest:
211         ts << "nearest";
212         break;
213     case PlatformCALayer::Trilinear:
214         ts << "trilinear";
215         break;
216     default:
217         ASSERT_NOT_REACHED();
218         break;
219     }
220     return ts;
221 }
222
223 }
224
225 #endif // USE(CA)