2 * Copyright (C) 2009 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)
32 #import "GraphicsContext.h"
33 #import "GraphicsLayerCA.h"
34 #import "PlatformCALayer.h"
35 #import <objc/objc-runtime.h>
36 #import <QuartzCore/QuartzCore.h>
37 #import <wtf/UnusedParam.h>
39 using namespace WebCore;
41 @implementation WebLayer
43 void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCALayer* platformLayer)
45 WebCore::PlatformCALayerClient* layerContents = platformLayer->owner();
49 CGContextSaveGState(context);
51 CGRect layerBounds = [layer bounds];
52 if (layerContents->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp) {
53 CGContextScaleCTM(context, 1, -1);
54 CGContextTranslateCTM(context, 0, -layerBounds.size.height);
57 [NSGraphicsContext saveGraphicsState];
59 // Set up an NSGraphicsContext for the context, so that parts of AppKit that rely on
60 // the current NSGraphicsContext (e.g. NSCell drawing) get the right one.
61 NSGraphicsContext* layerContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:YES];
62 [NSGraphicsContext setCurrentContext:layerContext];
64 GraphicsContext graphicsContext(context);
65 graphicsContext.setIsCALayerContext(true);
66 graphicsContext.setIsAcceleratedContext(platformLayer->acceleratesDrawing());
68 if (!layerContents->platformCALayerContentsOpaque()) {
69 // Turn off font smoothing to improve the appearance of text rendered onto a transparent background.
70 graphicsContext.setShouldSmoothFonts(false);
73 // It's important to get the clip from the context, because it may be significantly
74 // smaller than the layer bounds (e.g. tiled layers)
75 CGRect clipBounds = CGContextGetClipBoundingBox(context);
76 IntRect clip(enclosingIntRect(clipBounds));
77 layerContents->platformCALayerPaintContents(graphicsContext, clip);
79 [NSGraphicsContext restoreGraphicsState];
81 // Re-fetch the layer owner, since <rdar://problem/9125151> indicates that it might have been destroyed during painting.
82 layerContents = platformLayer->owner();
83 ASSERT(layerContents);
84 if (layerContents && layerContents->platformCALayerShowRepaintCounter()) {
85 bool isTiledLayer = [layer isKindOfClass:[CATiledLayer class]];
87 char text[16]; // that's a lot of repaints
88 snprintf(text, sizeof(text), "%d", layerContents->platformCALayerIncrementRepaintCount());
90 CGContextSaveGState(context);
92 CGContextSetRGBFillColor(context, 0.0f, 1.0f, 0.0f, 0.8f);
94 CGContextSetRGBFillColor(context, 1.0f, 0.0f, 0.0f, 0.8f);
96 CGRect aBounds = layerBounds;
98 aBounds.size.width = 10 + 12 * strlen(text);
99 aBounds.size.height = 25;
100 CGContextFillRect(context, aBounds);
102 CGContextSetRGBFillColor(context, 0.0f, 0.0f, 0.0f, 1.0f);
104 CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0f, -1.0f));
105 CGContextSelectFont(context, "Helvetica", 25, kCGEncodingMacRoman);
106 CGContextShowTextAtPoint(context, aBounds.origin.x + 3.0f, aBounds.origin.y + 20.0f, text, strlen(text));
108 CGContextRestoreGState(context);
111 CGContextRestoreGState(context);
114 void setLayerNeedsDisplayInRect(CALayer *layer, WebCore::PlatformCALayerClient* layerContents, CGRect rect)
116 if (layerContents && layerContents->platformCALayerDrawsContent()) {
117 struct objc_super layerSuper = { layer, class_getSuperclass(object_getClass(layer)) };
118 #if defined(BUILDING_ON_LEOPARD)
119 rect = CGRectApplyAffineTransform(rect, [layer contentsTransform]);
121 if (layerContents->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp)
122 rect.origin.y = [layer bounds].size.height - rect.origin.y - rect.size.height;
124 objc_msgSendSuper(&layerSuper, @selector(setNeedsDisplayInRect:), rect);
127 if (layerContents->platformCALayerShowRepaintCounter()) {
128 CGRect bounds = [layer bounds];
129 CGRect indicatorRect = CGRectMake(bounds.origin.x, bounds.origin.y, 46, 25);
130 #if defined(BUILDING_ON_LEOPARD)
131 indicatorRect = CGRectApplyAffineTransform(indicatorRect, [layer contentsTransform]);
133 if (layerContents->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp)
134 indicatorRect.origin.y = [layer bounds].size.height - indicatorRect.origin.y - indicatorRect.size.height;
136 objc_msgSendSuper(&layerSuper, @selector(setNeedsDisplayInRect:), indicatorRect);
142 // Disable default animations
143 - (id<CAAction>)actionForKey:(NSString *)key
149 - (void)setNeedsDisplay
151 PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
152 if (layer && layer->owner() && layer->owner()->platformCALayerDrawsContent())
153 [super setNeedsDisplay];
156 - (void)setNeedsDisplayInRect:(CGRect)dirtyRect
158 PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
160 setLayerNeedsDisplayInRect(self, layer->owner(), dirtyRect);
166 PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
167 if (layer && layer->owner())
168 layer->owner()->platformCALayerLayerDidDisplay(self);
171 - (void)drawInContext:(CGContextRef)context
173 PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
175 drawLayerContents(context, self, layer);
178 @end // implementation WebLayer
184 @implementation CALayer(ExtendedDescription)
186 - (NSString*)_descriptionWithPrefix:(NSString*)inPrefix
188 CGRect aBounds = [self bounds];
189 CGPoint aPos = [self position];
191 NSString* selfString = [NSString stringWithFormat:@"%@<%@ 0x%08x> \"%@\" bounds(%.1f, %.1f, %.1f, %.1f) pos(%.1f, %.1f), sublayers=%d masking=%d",
196 aBounds.origin.x, aBounds.origin.y, aBounds.size.width, aBounds.size.height,
198 [[self sublayers] count],
199 [self masksToBounds]];
201 NSMutableString* curDesc = [NSMutableString stringWithString:selfString];
203 if ([[self sublayers] count] > 0)
204 [curDesc appendString:@"\n"];
206 NSString* sublayerPrefix = [inPrefix stringByAppendingString:@"\t"];
208 NSEnumerator* sublayersEnum = [[self sublayers] objectEnumerator];
210 while ((curLayer = [sublayersEnum nextObject]))
211 [curDesc appendString:[curLayer _descriptionWithPrefix:sublayerPrefix]];
213 if ([[self sublayers] count] == 0)
214 [curDesc appendString:@"\n"];
219 - (NSString*)extendedDescription
221 return [self _descriptionWithPrefix:@""];
224 @end // implementation WebLayer(ExtendedDescription)
228 #endif // USE(ACCELERATED_COMPOSITING)