1/* 2 * Copyright (C) 2009 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 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. 24 */ 25 26#include "config.h" 27 28#if USE(ACCELERATED_COMPOSITING) 29 30#import "WebLayer.h" 31 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> 38 39using namespace WebCore; 40 41@implementation WebLayer 42 43void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCALayer* platformLayer) 44{ 45 WebCore::PlatformCALayerClient* layerContents = platformLayer->owner(); 46 if (!layerContents) 47 return; 48 49 CGContextSaveGState(context); 50 51 CGRect layerBounds = [layer bounds]; 52 if (layerContents->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp) { 53 CGContextScaleCTM(context, 1, -1); 54 CGContextTranslateCTM(context, 0, -layerBounds.size.height); 55 } 56 57 [NSGraphicsContext saveGraphicsState]; 58 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]; 63 64 GraphicsContext graphicsContext(context); 65 graphicsContext.setIsCALayerContext(true); 66 graphicsContext.setIsAcceleratedContext(platformLayer->acceleratesDrawing()); 67 68 if (!layerContents->platformCALayerContentsOpaque()) { 69 // Turn off font smoothing to improve the appearance of text rendered onto a transparent background. 70 graphicsContext.setShouldSmoothFonts(false); 71 } 72 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); 78 79 [NSGraphicsContext restoreGraphicsState]; 80 81 if (layerContents->platformCALayerShowRepaintCounter()) { 82 bool isTiledLayer = [layer isKindOfClass:[CATiledLayer class]]; 83 84 char text[16]; // that's a lot of repaints 85 snprintf(text, sizeof(text), "%d", layerContents->platformCALayerIncrementRepaintCount()); 86 87 CGContextSaveGState(context); 88 if (isTiledLayer) 89 CGContextSetRGBFillColor(context, 0.0f, 1.0f, 0.0f, 0.8f); 90 else 91 CGContextSetRGBFillColor(context, 1.0f, 0.0f, 0.0f, 0.8f); 92 93 CGRect aBounds = layerBounds; 94 95 aBounds.size.width = 10 + 12 * strlen(text); 96 aBounds.size.height = 25; 97 CGContextFillRect(context, aBounds); 98 99 CGContextSetRGBFillColor(context, 0.0f, 0.0f, 0.0f, 1.0f); 100 101 CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0f, -1.0f)); 102 CGContextSelectFont(context, "Helvetica", 25, kCGEncodingMacRoman); 103 CGContextShowTextAtPoint(context, aBounds.origin.x + 3.0f, aBounds.origin.y + 20.0f, text, strlen(text)); 104 105 CGContextRestoreGState(context); 106 } 107 108 CGContextRestoreGState(context); 109} 110 111void setLayerNeedsDisplayInRect(CALayer *layer, WebCore::PlatformCALayerClient* layerContents, CGRect rect) 112{ 113 if (layerContents && layerContents->platformCALayerDrawsContent()) { 114 struct objc_super layerSuper = { layer, class_getSuperclass(object_getClass(layer)) }; 115#if defined(BUILDING_ON_LEOPARD) 116 rect = CGRectApplyAffineTransform(rect, [layer contentsTransform]); 117#else 118 if (layerContents->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp) 119 rect.origin.y = [layer bounds].size.height - rect.origin.y - rect.size.height; 120#endif 121 objc_msgSendSuper(&layerSuper, @selector(setNeedsDisplayInRect:), rect); 122 123#ifndef NDEBUG 124 if (layerContents->platformCALayerShowRepaintCounter()) { 125 CGRect bounds = [layer bounds]; 126 CGRect indicatorRect = CGRectMake(bounds.origin.x, bounds.origin.y, 46, 25); 127#if defined(BUILDING_ON_LEOPARD) 128 indicatorRect = CGRectApplyAffineTransform(indicatorRect, [layer contentsTransform]); 129#else 130 if (layerContents->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp) 131 indicatorRect.origin.y = [layer bounds].size.height - indicatorRect.origin.y - indicatorRect.size.height; 132#endif 133 objc_msgSendSuper(&layerSuper, @selector(setNeedsDisplayInRect:), indicatorRect); 134 } 135#endif 136 } 137} 138 139// Disable default animations 140- (id<CAAction>)actionForKey:(NSString *)key 141{ 142 UNUSED_PARAM(key); 143 return nil; 144} 145 146- (void)setNeedsDisplay 147{ 148 PlatformCALayer* layer = PlatformCALayer::platformCALayer(self); 149 if (layer && layer->owner() && layer->owner()->platformCALayerDrawsContent()) 150 [super setNeedsDisplay]; 151} 152 153- (void)setNeedsDisplayInRect:(CGRect)dirtyRect 154{ 155 PlatformCALayer* layer = PlatformCALayer::platformCALayer(self); 156 if (layer) 157 setLayerNeedsDisplayInRect(self, layer->owner(), dirtyRect); 158} 159 160- (void)display 161{ 162 [super display]; 163 PlatformCALayer* layer = PlatformCALayer::platformCALayer(self); 164 if (layer && layer->owner()) 165 layer->owner()->platformCALayerLayerDidDisplay(self); 166} 167 168- (void)drawInContext:(CGContextRef)context 169{ 170 PlatformCALayer* layer = PlatformCALayer::platformCALayer(self); 171 if (layer) 172 drawLayerContents(context, self, layer); 173} 174 175@end // implementation WebLayer 176 177// MARK: - 178 179#ifndef NDEBUG 180 181@implementation CALayer(ExtendedDescription) 182 183- (NSString*)_descriptionWithPrefix:(NSString*)inPrefix 184{ 185 CGRect aBounds = [self bounds]; 186 CGPoint aPos = [self position]; 187 188 NSString* selfString = [NSString stringWithFormat:@"%@<%@ 0x%08x> \"%@\" bounds(%.1f, %.1f, %.1f, %.1f) pos(%.1f, %.1f), sublayers=%d masking=%d", 189 inPrefix, 190 [self class], 191 self, 192 [self name], 193 aBounds.origin.x, aBounds.origin.y, aBounds.size.width, aBounds.size.height, 194 aPos.x, aPos.y, 195 [[self sublayers] count], 196 [self masksToBounds]]; 197 198 NSMutableString* curDesc = [NSMutableString stringWithString:selfString]; 199 200 if ([[self sublayers] count] > 0) 201 [curDesc appendString:@"\n"]; 202 203 NSString* sublayerPrefix = [inPrefix stringByAppendingString:@"\t"]; 204 205 NSEnumerator* sublayersEnum = [[self sublayers] objectEnumerator]; 206 CALayer* curLayer; 207 while ((curLayer = [sublayersEnum nextObject])) 208 [curDesc appendString:[curLayer _descriptionWithPrefix:sublayerPrefix]]; 209 210 if ([[self sublayers] count] == 0) 211 [curDesc appendString:@"\n"]; 212 213 return curDesc; 214} 215 216- (NSString*)extendedDescription 217{ 218 return [self _descriptionWithPrefix:@""]; 219} 220 221@end // implementation WebLayer(ExtendedDescription) 222 223#endif // NDEBUG 224 225#endif // USE(ACCELERATED_COMPOSITING) 226