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 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#import "WebTiledLayer.h"
28
29#import "GraphicsContext.h"
30#import "GraphicsLayerCA.h"
31#import "PlatformCALayer.h"
32
33#if PLATFORM(IOS)
34#import "WebCoreThread.h"
35#import "WebCoreThreadRun.h"
36#endif
37
38using namespace WebCore;
39
40@implementation WebTiledLayer
41
42// Set a zero duration for the fade in of tiles
43+ (CFTimeInterval)fadeDuration
44{
45    return 0;
46}
47
48// Make sure that tiles are drawn on the main thread
49+ (BOOL)shouldDrawOnMainThread
50{
51#if PLATFORM(IOS)
52    // FIXME: WebKit2 always wants to draw on the main thread, but there is
53    // probably a better way to check for WebKit2 than using the existance of
54    // the web thread as a proxy.
55    return !WebThreadIsEnabled();
56#else
57    return YES;
58#endif
59}
60
61+ (unsigned int)prefetchedTiles
62{
63    return 2;
64}
65
66// Disable default animations
67- (id<CAAction>)actionForKey:(NSString *)key
68{
69    UNUSED_PARAM(key);
70    return nil;
71}
72
73- (void)setNeedsDisplay
74{
75    PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
76    if (layer && layer->owner() && layer->owner()->platformCALayerDrawsContent())
77        [super setNeedsDisplay];
78}
79
80- (void)setNeedsDisplayInRect:(CGRect)dirtyRect
81{
82    PlatformCALayer* platformLayer = PlatformCALayer::platformCALayer(self);
83    if (!platformLayer) {
84        [super setNeedsDisplayInRect:dirtyRect];
85        return;
86    }
87
88    if (PlatformCALayerClient* layerOwner = platformLayer->owner()) {
89        if (layerOwner->platformCALayerDrawsContent()) {
90            if (layerOwner->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp)
91                dirtyRect.origin.y = [self bounds].size.height - dirtyRect.origin.y - dirtyRect.size.height;
92
93            [super setNeedsDisplayInRect:dirtyRect];
94
95            if (layerOwner->platformCALayerShowRepaintCounter(platformLayer)) {
96                CGRect bounds = [self bounds];
97                CGRect indicatorRect = CGRectMake(bounds.origin.x, bounds.origin.y, 52, 27);
98                if (layerOwner->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp)
99                    indicatorRect.origin.y = [self bounds].size.height - indicatorRect.origin.y - indicatorRect.size.height;
100
101                [super setNeedsDisplayInRect:indicatorRect];
102            }
103        }
104    }
105}
106
107- (void)display
108{
109    [super display];
110#if PLATFORM(IOS)
111    // CATiledLayer never calls display on a background thread, so it's safe
112    // to assume we're either on the main thread or on the web thread.
113    if (pthread_main_np())
114        WebThreadLock();
115    ASSERT(WebThreadIsLockedOrDisabled());
116#endif
117    PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
118    if (layer && layer->owner())
119        layer->owner()->platformCALayerLayerDidDisplay(self);
120}
121
122- (void)drawInContext:(CGContextRef)context
123{
124#if PLATFORM(IOS)
125    void (^draw)() = ^{
126#endif
127    PlatformCALayer* layer = PlatformCALayer::platformCALayer(self);
128    if (layer)
129        drawLayerContents(context, layer);
130#if PLATFORM(IOS)
131    };
132    if (pthread_main_np()) {
133        WebThreadLock();
134        draw();
135    } else
136        WebThreadRunSync(draw);
137#endif
138}
139
140@end // implementation WebTiledLayer
141