1 | /* |
2 | * Copyright (C) 2011 Apple Inc. All rights reserved. |
3 | * Copyright (C) 2011,2014 Igalia S.L. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * 2. Redistributions in binary form must reproduce the above copyright |
11 | * notice, this list of conditions and the following disclaimer in the |
12 | * documentation and/or other materials provided with the distribution. |
13 | * |
14 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
16 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
18 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
24 | * THE POSSIBILITY OF SUCH DAMAGE. |
25 | */ |
26 | |
27 | #include "config.h" |
28 | #include "BackingStore.h" |
29 | |
30 | #include "ShareableBitmap.h" |
31 | #include "UpdateInfo.h" |
32 | #include "WebPageProxy.h" |
33 | #include <WebCore/BackingStoreBackendCairoImpl.h> |
34 | #include <WebCore/CairoUtilities.h> |
35 | #include <WebCore/GraphicsContextImplCairo.h> |
36 | #include <WebCore/PlatformContextCairo.h> |
37 | #include <WebCore/RefPtrCairo.h> |
38 | #include <cairo.h> |
39 | |
40 | #if PLATFORM(GTK) && PLATFORM(X11) && defined(GDK_WINDOWING_X11) |
41 | #include <WebCore/BackingStoreBackendCairoX11.h> |
42 | #include <WebCore/PlatformDisplayX11.h> |
43 | #include <gdk/gdkx.h> |
44 | #endif |
45 | |
46 | namespace WebKit { |
47 | using namespace WebCore; |
48 | |
49 | std::unique_ptr<BackingStoreBackendCairo> BackingStore::createBackend() |
50 | { |
51 | #if PLATFORM(GTK) && PLATFORM(X11) && defined(GDK_WINDOWING_X11) |
52 | const auto& sharedDisplay = PlatformDisplay::sharedDisplay(); |
53 | if (is<PlatformDisplayX11>(sharedDisplay)) { |
54 | GdkVisual* visual = gtk_widget_get_visual(m_webPageProxy.viewWidget()); |
55 | GdkScreen* screen = gdk_visual_get_screen(visual); |
56 | ASSERT(downcast<PlatformDisplayX11>(sharedDisplay).native() == GDK_SCREEN_XDISPLAY(screen)); |
57 | return std::make_unique<BackingStoreBackendCairoX11>(GDK_WINDOW_XID(gdk_screen_get_root_window(screen)), |
58 | GDK_VISUAL_XVISUAL(visual), gdk_visual_get_depth(visual), m_size, m_deviceScaleFactor); |
59 | } |
60 | #endif |
61 | |
62 | return std::make_unique<BackingStoreBackendCairoImpl>(m_size, m_deviceScaleFactor); |
63 | } |
64 | |
65 | void BackingStore::paint(cairo_t* context, const IntRect& rect) |
66 | { |
67 | ASSERT(m_backend); |
68 | |
69 | cairo_save(context); |
70 | cairo_set_operator(context, CAIRO_OPERATOR_SOURCE); |
71 | cairo_set_source_surface(context, m_backend->surface(), 0, 0); |
72 | cairo_rectangle(context, rect.x(), rect.y(), rect.width(), rect.height()); |
73 | cairo_fill(context); |
74 | cairo_restore(context); |
75 | } |
76 | |
77 | void BackingStore::incorporateUpdate(ShareableBitmap* bitmap, const UpdateInfo& updateInfo) |
78 | { |
79 | if (!m_backend) |
80 | m_backend = createBackend(); |
81 | |
82 | scroll(updateInfo.scrollRect, updateInfo.scrollOffset); |
83 | |
84 | // Paint all update rects. |
85 | IntPoint updateRectLocation = updateInfo.updateRectBounds.location(); |
86 | RefPtr<cairo_t> cairoContext = adoptRef(cairo_create(m_backend->surface())); |
87 | GraphicsContext graphicsContext(GraphicsContextImplCairo::createFactory(cairoContext.get())); |
88 | |
89 | // When m_webPageProxy.drawsBackground() is false, bitmap contains transparent parts as a background of the webpage. |
90 | // For such case, bitmap must be drawn using CompositeCopy to overwrite the existing surface. |
91 | graphicsContext.setCompositeOperation(WebCore::CompositeCopy); |
92 | |
93 | for (const auto& updateRect : updateInfo.updateRects) { |
94 | IntRect srcRect = updateRect; |
95 | srcRect.move(-updateRectLocation.x(), -updateRectLocation.y()); |
96 | bitmap->paint(graphicsContext, deviceScaleFactor(), updateRect.location(), srcRect); |
97 | } |
98 | } |
99 | |
100 | void BackingStore::scroll(const IntRect& scrollRect, const IntSize& scrollOffset) |
101 | { |
102 | if (scrollOffset.isZero()) |
103 | return; |
104 | |
105 | ASSERT(m_backend); |
106 | m_backend->scroll(scrollRect, scrollOffset); |
107 | } |
108 | |
109 | } // namespace WebKit |
110 | |