2 * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
27 #import "BackingStore.h"
29 #import "CGUtilities.h"
30 #import "ShareableBitmap.h"
31 #import "UpdateInfo.h"
32 #import "WebPageProxy.h"
33 #import <WebCore/GraphicsContext.h>
35 using namespace WebCore;
39 void BackingStore::paint(PlatformGraphicsContext context, const IntRect& rect)
42 CGContextSaveGState(context);
43 CGContextClipToRect(context, rect);
45 CGContextScaleCTM(context, 1, -1);
46 CGContextDrawLayerAtPoint(context, CGPointMake(0, -m_size.height()), m_cgLayer.get());
48 CGContextRestoreGState(context);
52 ASSERT(m_bitmapContext);
53 paintBitmapContext(context, m_bitmapContext.get(), rect.location(), rect);
56 CGContextRef BackingStore::backingStoreContext()
59 return CGLayerGetContext(m_cgLayer.get());
61 // Try to create a layer.
62 if (CGContextRef containingWindowContext = m_webPageProxy->containingWindowGraphicsContext()) {
63 m_cgLayer.adoptCF(CGLayerCreateWithContext(containingWindowContext, NSSizeToCGSize(m_size), 0));
64 CGContextRef layerContext = CGLayerGetContext(m_cgLayer.get());
66 CGContextSetBlendMode(layerContext, kCGBlendModeCopy);
68 // We want the origin to be in the top left corner so flip the backing store context.
69 CGContextTranslateCTM(layerContext, 0, m_size.height());
70 CGContextScaleCTM(layerContext, 1, -1);
72 if (m_bitmapContext) {
73 // Paint the contents of the bitmap into the layer context.
74 paintBitmapContext(layerContext, m_bitmapContext.get(), CGPointZero, CGRectMake(0, 0, m_size.width(), m_size.height()));
75 m_bitmapContext = nullptr;
81 if (!m_bitmapContext) {
82 RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
84 m_bitmapContext.adoptCF(CGBitmapContextCreate(0, m_size.width(), m_size.height(), 8, m_size.width() * 4, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
86 CGContextSetBlendMode(m_bitmapContext.get(), kCGBlendModeCopy);
88 // We want the origin to be in the top left corner so flip the backing store context.
89 CGContextTranslateCTM(m_bitmapContext.get(), 0, m_size.height());
90 CGContextScaleCTM(m_bitmapContext.get(), 1, -1);
93 return m_bitmapContext.get();
96 void BackingStore::incorporateUpdate(ShareableBitmap* bitmap, const UpdateInfo& updateInfo)
98 CGContextRef context = backingStoreContext();
100 scroll(updateInfo.scrollRect, updateInfo.scrollOffset);
102 IntPoint updateRectLocation = updateInfo.updateRectBounds.location();
104 GraphicsContext graphicsContext(context);
106 // Paint all update rects.
107 for (size_t i = 0; i < updateInfo.updateRects.size(); ++i) {
108 IntRect updateRect = updateInfo.updateRects[i];
109 IntRect srcRect = updateRect;
110 srcRect.move(-updateRectLocation.x(), -updateRectLocation.y());
112 bitmap->paint(graphicsContext, updateInfo.deviceScaleFactor, updateRect.location(), srcRect);
116 void BackingStore::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
118 if (scrollOffset.isZero())
122 CGContextRef layerContext = CGLayerGetContext(m_cgLayer.get());
124 // Scroll the layer by painting it into itself with the given offset.
125 CGContextSaveGState(layerContext);
126 CGContextClipToRect(layerContext, scrollRect);
127 CGContextScaleCTM(layerContext, 1, -1);
128 CGContextDrawLayerAtPoint(layerContext, CGPointMake(scrollOffset.width(), -m_size.height() - scrollOffset.height()), m_cgLayer.get());
129 CGContextRestoreGState(layerContext);
134 ASSERT(m_bitmapContext);
136 CGContextSaveGState(m_bitmapContext.get());
137 CGContextClipToRect(m_bitmapContext.get(), scrollRect);
138 CGPoint destination = CGPointMake(scrollRect.x() + scrollOffset.width(), scrollRect.y() + scrollOffset.height());
139 paintBitmapContext(m_bitmapContext.get(), m_bitmapContext.get(), destination, scrollRect);
140 CGContextRestoreGState(m_bitmapContext.get());
143 } // namespace WebKit