Update tile partially
[framework/web/webkit-efl.git] / Source / WebKit2 / WebProcess / WebPage / efl / tizen / TiledBackingStoreRemoteTileTizen.cpp
1 /*
2 *   Copyright (C) 2011 Samsung Electronics
3 *
4 *   This library is free software; you can redistribute it and/or
5 *   modify it under the terms of the GNU Library General Public
6 *   License as published by the Free Software Foundation; either
7 *   version 2 of the License, or (at your option) any later version.
8 *
9 *   This library is distributed in the hope that it will be useful,
10 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 *   Library General Public License for more details.
13 *
14 *   You should have received a copy of the GNU Library General Public License
15 *   along with this library; see the file COPYING.LIB.  If not, write to
16 *   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 *   Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "TiledBackingStoreRemoteTileTizen.h"
22
23 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
24 #include "WebProcess.h"
25 #include <WebCore/CairoUtilities.h>
26 #include <WebCore/PlatformContextCairo.h>
27 #include <wtf/RefPtr.h>
28 #if ENABLE(TIZEN_WEBKIT2_DEBUG_BORDERS)
29 #include <stdio.h>
30 #endif
31
32 using namespace WebCore;
33
34 namespace WebKit {
35
36 TiledBackingStoreRemoteTileBackendTizen::TiledBackingStoreRemoteTileBackendTizen(TiledBackingStoreRemoteTileClient* client)
37     : m_client(client)
38 {
39 }
40
41 PassRefPtr<WebCore::Tile> TiledBackingStoreRemoteTileBackendTizen::createTile(WebCore::TiledBackingStore* tiledBackingStore, const WebCore::Tile::Coordinate& tileCoordinate)
42 {
43     return TiledBackingStoreRemoteTileTizen::create(m_client, tiledBackingStore, tileCoordinate);
44 }
45
46 TiledBackingStoreRemoteTileTizen::TiledBackingStoreRemoteTileTizen(TiledBackingStoreRemoteTileClient* client, TiledBackingStore* tiledBackingStore, const Coordinate& tileCoordinate)
47     : TiledBackingStoreRemoteTile(client, tiledBackingStore, tileCoordinate)
48     , m_tiledBackingStoreRemoteTileBufferTizen(adoptPtr(new TiledBackingStoreRemoteTileBufferTizen(client, tiledBackingStore, m_rect)))
49 {
50 }
51
52 static inline bool needUpdateBackBufferPartially(const IntRect& entireRect, const IntRect& dirtyRect)
53 {
54     if (entireRect.size() != dirtyRect.size())
55         return true;
56     return false;
57 }
58
59 Vector<IntRect> TiledBackingStoreRemoteTileTizen::updateBackBuffer()
60 {
61     if (!isDirty())
62         return Vector<IntRect>();
63
64     SurfaceUpdateInfo updateInfo;
65
66     static int id = 0;
67     bool needToCreateTile = false;
68     if (!m_ID) {
69         m_ID = ++id;
70         needToCreateTile = true;
71     }
72
73     if (!m_tiledBackingStoreRemoteTileBufferTizen->drawPlatformSurface(m_tiledBackingStore->tileSize(), m_dirtyRect, m_ID))
74         return Vector<IntRect>();
75
76     updateInfo.updateRect = m_rect;
77     updateInfo.scaleFactor = m_tiledBackingStore->contentsScale();
78     updateInfo.platformSurfaceID = m_tiledBackingStoreRemoteTileBufferTizen->platformSurfaceID();
79     updateInfo.platformSurfaceSize = m_tiledBackingStoreRemoteTileBufferTizen->platformSurfaceSize();
80
81     if (needToCreateTile)
82         m_client->createTile(m_ID, updateInfo, m_rect);
83     else
84         m_client->updateTile(m_ID, updateInfo, m_rect);
85
86     m_dirtyRect = IntRect();
87
88     Vector<IntRect> paintedRects;
89     paintedRects.append(m_rect);
90     return paintedRects;
91 }
92
93 void TiledBackingStoreRemoteTileTizen::resize(const IntSize& newSize)
94 {
95     m_rect = IntRect(m_rect.location(), newSize);
96     m_dirtyRect = m_rect;
97
98     m_tiledBackingStoreRemoteTileBufferTizen->resize(m_rect.size());
99 }
100
101 void TiledBackingStoreRemoteTileTizen::review()
102 {
103     if (!m_ID)
104         return;
105
106     SurfaceUpdateInfo updateInfo;
107     updateInfo.updateRect = m_rect;
108     updateInfo.platformSurfaceID = m_tiledBackingStoreRemoteTileBufferTizen->platformSurfaceID();
109     updateInfo.platformSurfaceSize = m_tiledBackingStoreRemoteTileBufferTizen->platformSurfaceSize();
110     updateInfo.scaleFactor = m_tiledBackingStore->contentsScale();
111
112     m_client->createTile(m_ID, updateInfo, m_rect);
113 }
114
115 bool TiledBackingStoreRemoteTileBufferTizen::copyPreviousFrame(void* dst, int platformSurfaceID, const IntRect& wholeRect, const IntRect& clipRect)
116 {
117     SharedPlatformSurfaceTizen* backupSurface;
118     unsigned int offset;
119     void* src;
120
121     PlatformSurfacePoolTizen* platformSurfacePool = WebProcess::shared().platformSurfacePool();
122     if(!platformSurfacePool)
123         return false;
124
125     backupSurface = platformSurfacePool->acquirePlatformSurfaceByID(platformSurfaceID);
126     if (!backupSurface)
127         return false;
128
129     if (!backupSurface->lockSurface())
130         return false;
131
132     if (!backupSurface->querySurface((int*)&src)) {
133         backupSurface->unlockSurface();
134         return false;
135     }
136
137     // upper side
138     if (clipRect.y() -wholeRect.y() > 0)
139         memcpy(dst, src, 4 * wholeRect.width() * (clipRect.y() -wholeRect.y()));
140
141     if (wholeRect.width() - clipRect.width() > 0) {
142         offset = 4 * (clipRect.y() - wholeRect.y()) * wholeRect.width();
143         for (int i = 0; i < clipRect.height(); i++) {
144             // left side
145             if (clipRect.x() - wholeRect.x() > 0)
146                 memcpy(dst + offset, src + offset, 4 * (clipRect.x() - wholeRect.x()));
147
148             // right side
149             if (wholeRect.x() + wholeRect.width() - clipRect.x() - clipRect.width() > 0)
150                 memcpy(dst + offset + 4 * (clipRect.x() + clipRect.width() - wholeRect.x()),
151                     src + offset + 4 * (clipRect.x() + clipRect.width() - wholeRect.x()),
152                     4 * (wholeRect.x() + wholeRect.width() - clipRect.x() - clipRect.width()));
153             offset += 4 * wholeRect.width();
154         }
155     }
156     // lower side
157     if (wholeRect.y() + wholeRect.height() - clipRect.y() - clipRect.height() > 0) {
158         offset = 4 * wholeRect.width() * (clipRect.y() + clipRect.height() - wholeRect.y());
159         memcpy(dst + offset, src + offset,
160             4 * wholeRect.width() * (wholeRect.y() + wholeRect.height() - clipRect.y() - clipRect.height()));
161     }
162     backupSurface->unlockSurface();
163     return true;
164 }
165
166 bool TiledBackingStoreRemoteTileBufferTizen::drawPlatformSurface(const IntSize& size, const IntRect& dirtyRect, int tileID)
167 {
168     PlatformSurfacePoolTizen* platformSurfacePool = WebProcess::shared().platformSurfacePool();
169     if(!platformSurfacePool)
170         return false;
171
172     SharedPlatformSurfaceTizen* sharedPlatformSurface = platformSurfacePool->acquirePlatformSurface(size, tileID);
173     if (!sharedPlatformSurface)
174         return false;
175
176     if (!sharedPlatformSurface->lockSurface()) {
177         platformSurfacePool->freePlatformSurface(sharedPlatformSurface->id());
178         return false;
179     }
180     if (!sharedPlatformSurface->querySurface((int*)&m_eglImgData)) {
181         sharedPlatformSurface->unlockSurface();
182         platformSurfacePool->freePlatformSurface(sharedPlatformSurface->id());
183         return false;
184     }
185     RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(static_cast<unsigned char*>(m_eglImgData), CAIRO_FORMAT_ARGB32,
186         sharedPlatformSurface->size().width(), sharedPlatformSurface->size().height(), 4 * sharedPlatformSurface->size().width()));
187     RefPtr<cairo_t> bitmapContext = adoptRef(cairo_create(surface.get()));
188
189     OwnPtr<WebCore::GraphicsContext> graphicsContext = adoptPtr(new GraphicsContext(bitmapContext.get()));
190 #if ENABLE(TIZEN_WEBKIT2_DEBUG_BORDERS)
191     double startTime = 0;
192     double endTime = 0;
193     if (m_tiledBackingStore->client()->drawTileInfo()) {
194         graphicsContext->save();
195         startTime = currentTime();
196     }
197 #endif
198     graphicsContext->clearRect(WebCore::FloatRect(WebCore::FloatPoint(0, 0), sharedPlatformSurface->size()));
199
200     IntRect paintRect = m_rect;
201     if (needUpdateBackBufferPartially(m_rect, dirtyRect) && m_platformSurfaceID > 0) {
202         if (copyPreviousFrame(m_eglImgData, m_platformSurfaceID, IntRect(m_rect.location(), sharedPlatformSurface->size()), dirtyRect))
203             paintRect = dirtyRect;
204     }
205
206 #if ENABLE(TIZEN_RECORDING_SURFACE_SET)
207     if (m_tiledBackingStore->client()->recordingSurfaceSetEnableGet()) {
208         m_tiledBackingStore->client()->tiledBackingStorePaint(graphicsContext.get(), m_rect);
209     } else
210 #endif
211     {
212         graphicsContext->translate(-m_rect.x(), -m_rect.y());
213         graphicsContext->scale(FloatSize(m_tiledBackingStore->contentsScale(), m_tiledBackingStore->contentsScale()));
214         m_tiledBackingStore->client()->tiledBackingStorePaint(graphicsContext.get(), m_tiledBackingStore->mapToContents(paintRect));
215     }
216
217     m_platformSurfaceID = sharedPlatformSurface->id();
218     m_platformSurfaceSize = sharedPlatformSurface->size();
219
220 #if ENABLE(TIZEN_WEBKIT2_DEBUG_BORDERS)
221     if (m_tiledBackingStore->client()->drawTileInfo()) {
222         endTime = currentTime();
223         graphicsContext->restore();
224
225         char tileInfo[256];
226         int fontSize = 15;
227         snprintf(tileInfo, 256, "[%d] %.1fms (%d,%d / %dX%d)", m_platformSurfaceID, (endTime - startTime) * 1000, m_rect.x(), m_rect.y(), m_platformSurfaceSize.width(), m_platformSurfaceSize.height());
228         cairo_set_source_rgb(bitmapContext.get(), 0.0, 0.0, 1.0);
229         cairo_select_font_face(bitmapContext.get(), "", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
230         cairo_set_font_size(bitmapContext.get(), fontSize);
231         cairo_move_to(bitmapContext.get(), 0, fontSize);
232         cairo_show_text(bitmapContext.get(), tileInfo);
233     }
234 #endif
235      if (!sharedPlatformSurface->unlockSurface())
236         return false;
237     return true;
238 }
239 } // namespace WebKit
240
241 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)