1/* 2 * Copyright (C) 2010 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#import "WebRenderLayer.h" 27 28#import "WebFrameInternal.h" 29#import <WebCore/Frame.h> 30#import <WebCore/FrameLoader.h> 31#import <WebCore/FrameLoaderClient.h> 32#import <WebCore/RenderLayer.h> 33#import <WebCore/RenderLayerBacking.h> 34#import <WebCore/RenderView.h> 35#import <WebCore/StyledElement.h> 36#import <wtf/text/StringBuilder.h> 37#import <wtf/text/WTFString.h> 38 39using namespace WebCore; 40 41@interface WebRenderLayer(Private) 42 43- (id)initWithRenderLayer:(RenderLayer *)layer; 44- (void)buildDescendantLayers:(RenderLayer*)rootLayer; 45 46@end 47 48@implementation WebRenderLayer 49 50+ (NSString *)nameForLayer:(RenderLayer*)layer 51{ 52 const RenderObject& renderer = layer->renderer(); 53 NSString *name = [NSString stringWithUTF8String:renderer.renderName()]; 54 55 if (Element* element = renderer.node() && renderer.node()->isElementNode() ? toElement(renderer.node()) : 0) { 56 name = [name stringByAppendingFormat:@" %@", (NSString *)element->tagName()]; 57 if (element->hasID()) 58 name = [name stringByAppendingFormat:@" id=\"%@\"", (NSString *)element->getIdAttribute()]; 59 60 if (element->hasClass()) { 61 StringBuilder classes; 62 for (size_t i = 0; i < element->classNames().size(); ++i) { 63 if (i > 0) 64 classes.append(' '); 65 classes.append(element->classNames()[i]); 66 } 67 name = [name stringByAppendingFormat:@" class=\"%@\"", (NSString *)classes.toString()]; 68 } 69 } 70 71 if (layer->isReflection()) 72 name = [name stringByAppendingString:@" (reflection)"]; 73 74 return name; 75} 76 77+ (NSString *)compositingInfoForLayer:(RenderLayer*)layer 78{ 79 if (!layer->isComposited()) 80 return @""; 81 82 NSString *layerType = @""; 83 RenderLayerBacking* backing = layer->backing(); 84 switch (backing->compositingLayerType()) { 85 case NormalCompositingLayer: 86 layerType = @"composited"; 87 break; 88 case TiledCompositingLayer: 89 layerType = @"composited: tiled layer"; 90 break; 91 case MediaCompositingLayer: 92 layerType = @"composited for plug-in, video or WebGL"; 93 break; 94 case ContainerCompositingLayer: 95 layerType = @"composited: container layer"; 96 break; 97 } 98 99 if (backing->hasClippingLayer()) 100 layerType = [layerType stringByAppendingString:@" (clipping)"]; 101 102 if (backing->hasAncestorClippingLayer()) 103 layerType = [layerType stringByAppendingString:@" (clipped)"]; 104 105 return layerType; 106} 107 108- (id)initWithRenderLayer:(RenderLayer*)layer 109{ 110 if ((self = [super init])) { 111 name = [[WebRenderLayer nameForLayer:layer] retain]; 112 bounds = layer->absoluteBoundingBox(); 113 composited = layer->isComposited(); 114 compositingInfo = [[WebRenderLayer compositingInfoForLayer:layer] retain]; 115 } 116 117 return self; 118} 119 120- (id)initWithName:(NSString*)layerName 121{ 122 if ((self = [super init])) { 123 name = [layerName copy]; 124 separator = YES; 125 } 126 127 return self; 128} 129 130// Only called on the root. 131- (id)initWithWebFrame:(WebFrame *)webFrame 132{ 133 self = [super init]; 134 135 Frame* frame = core(webFrame); 136 if (!frame->loader().client().hasHTMLView()) { 137 [self release]; 138 return nil; 139 } 140 141 RenderObject* renderer = frame->contentRenderer(); 142 if (!renderer) { 143 [self release]; 144 return nil; 145 } 146 147 if (renderer->hasLayer()) { 148 RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); 149 150 name = [[WebRenderLayer nameForLayer:layer] retain]; 151 bounds = layer->absoluteBoundingBox(); 152 composited = layer->isComposited(); 153 compositingInfo = [[WebRenderLayer compositingInfoForLayer:layer] retain]; 154 155 [self buildDescendantLayers:layer]; 156 } 157 158 return self; 159} 160 161- (void)dealloc 162{ 163 [children release]; 164 [name release]; 165 [compositingInfo release]; 166 [super dealloc]; 167} 168 169- (void)buildDescendantLayers:(RenderLayer*)layer 170{ 171 NSMutableArray *childWebLayers = [[NSMutableArray alloc] init]; 172 173 // Build children in back to front order. 174 175 if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) { 176 size_t listSize = negZOrderList->size(); 177 178 if (listSize) { 179 WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithName:@"-ve z-order list"]; 180 [childWebLayers addObject:newLayer]; 181 [newLayer release]; 182 } 183 184 for (size_t i = 0; i < listSize; ++i) { 185 RenderLayer* curLayer = negZOrderList->at(i); 186 187 WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithRenderLayer:curLayer]; 188 [newLayer buildDescendantLayers:curLayer]; 189 190 [childWebLayers addObject:newLayer]; 191 [newLayer release]; 192 } 193 } 194 195 if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) { 196 size_t listSize = normalFlowList->size(); 197 198 if (listSize) { 199 WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithName:@"normal flow list"]; 200 [childWebLayers addObject:newLayer]; 201 [newLayer release]; 202 } 203 204 for (size_t i = 0; i < listSize; ++i) { 205 RenderLayer* curLayer = normalFlowList->at(i); 206 207 WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithRenderLayer:curLayer]; 208 [newLayer buildDescendantLayers:curLayer]; 209 210 [childWebLayers addObject:newLayer]; 211 [newLayer release]; 212 } 213 } 214 215 if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) { 216 size_t listSize = posZOrderList->size(); 217 218 if (listSize) { 219 WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithName:@"+ve z-order list"]; 220 [childWebLayers addObject:newLayer]; 221 [newLayer release]; 222 } 223 224 for (size_t i = 0; i < listSize; ++i) { 225 RenderLayer* curLayer = posZOrderList->at(i); 226 227 WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithRenderLayer:curLayer]; 228 [newLayer buildDescendantLayers:curLayer]; 229 230 [childWebLayers addObject:newLayer]; 231 [newLayer release]; 232 } 233 } 234 235 children = childWebLayers; 236} 237 238- (NSArray *)children 239{ 240 return children; 241} 242 243- (NSString *)name 244{ 245 return name; 246} 247 248- (NSString *)positionString 249{ 250 return [NSString stringWithFormat:@"(%.0f, %.0f)", bounds.origin.x, bounds.origin.y]; 251} 252 253- (NSString *)widthString 254{ 255 return [NSString stringWithFormat:@"%.0f", bounds.size.width]; 256} 257 258- (NSString *)heightString 259{ 260 return [NSString stringWithFormat:@"%.0f", bounds.size.height]; 261} 262 263- (NSString *)compositingInfo 264{ 265 return compositingInfo; 266} 267 268- (BOOL)isComposited 269{ 270 return composited; 271} 272 273- (BOOL)isSeparator 274{ 275 return separator; 276} 277 278@end 279