{
}
+static inline bool needUpdateBackBufferPartially(const IntRect& entireRect, const IntRect& dirtyRect)
+{
+ if (entireRect.size() != dirtyRect.size())
+ return true;
+ return false;
+}
+
Vector<IntRect> TiledBackingStoreRemoteTileTizen::updateBackBuffer()
{
if (!isDirty())
needToCreateTile = true;
}
- if (!m_tiledBackingStoreRemoteTileBufferTizen->drawPlatformSurface(m_tiledBackingStore->tileSize(), m_rect, m_ID))
+ if (!m_tiledBackingStoreRemoteTileBufferTizen->drawPlatformSurface(m_tiledBackingStore->tileSize(), m_dirtyRect, m_ID))
return Vector<IntRect>();
updateInfo.updateRect = m_rect;
m_client->createTile(m_ID, updateInfo, m_rect);
}
-bool TiledBackingStoreRemoteTileBufferTizen::drawPlatformSurface(const IntSize& size, const IntRect& dirty, int tileID)
+void TiledBackingStoreRemoteTileBufferTizen::copyDirtyRect(unsigned char* dst, unsigned char* src, const IntRect& wholeRect, const IntRect& dirtyRect)
+{
+ unsigned int offset = 4 * wholeRect.width() * (dirtyRect.y() - wholeRect.y()) + 4 * (dirtyRect.x() - wholeRect.x());
+
+ //FIXME : Now, handling row datas directly performs better than using Cairo APIs.
+ //This will be replaced to Cairo APIs if using Cairo APIs perform better.
+
+ for (int i = 0; i < dirtyRect.height(); i++) {
+ memcpy(dst + offset, src + (4 * i * dirtyRect.width()), 4 * dirtyRect.width());
+ offset += 4* wholeRect.width();
+ }
+}
+
+bool TiledBackingStoreRemoteTileBufferTizen::copyPreviousFrame(unsigned char* dst, int platformSurfaceID, const IntRect& wholeRect, const IntRect& clipRect)
+{
+ SharedPlatformSurfaceTizen* backupSurface;
+ unsigned int offset;
+ unsigned char* src;
+
+ PlatformSurfacePoolTizen* platformSurfacePool = WebProcess::shared().platformSurfacePool();
+ if(!platformSurfacePool)
+ return false;
+
+ backupSurface = platformSurfacePool->acquirePlatformSurfaceByID(platformSurfaceID);
+ if (!backupSurface)
+ return false;
+
+ if (!backupSurface->lockSurface())
+ return false;
+
+ if (!backupSurface->querySurface((int*)&src)) {
+ backupSurface->unlockSurface();
+ return false;
+ }
+
+ //FIXME : Now, handling row datas directly performs better than using Cairo APIs.
+ //This will be replaced to Cairo APIs if using Cairo APIs perform better.
+
+ // upper side
+ if (clipRect.y() -wholeRect.y() > 0)
+ memcpy(dst, src, 4 * wholeRect.width() * (clipRect.y() -wholeRect.y()));
+
+ if (wholeRect.width() - clipRect.width() > 0) {
+ offset = 4 * (clipRect.y() - wholeRect.y()) * wholeRect.width();
+ for (int i = 0; i < clipRect.height(); i++) {
+ // left side
+ if (clipRect.x() - wholeRect.x() > 0)
+ memcpy(dst + offset, src + offset, 4 * (clipRect.x() - wholeRect.x()));
+
+ // right side
+ if (wholeRect.maxX() - clipRect.maxX() > 0)
+ memcpy(dst + offset + 4 * (clipRect.maxX() - wholeRect.x()),
+ src + offset + 4 * (clipRect.maxX() - wholeRect.x()), 4 * (wholeRect.maxX() - clipRect.maxX()));
+ offset += 4 * wholeRect.width();
+ }
+ }
+ // lower side
+ if (wholeRect.maxY() - clipRect.maxY() > 0) {
+ offset = 4 * wholeRect.width() * (clipRect.maxY() - wholeRect.y());
+ memcpy(dst + offset, src + offset, 4 * wholeRect.width() * (wholeRect.maxY() - clipRect.maxY()));
+ }
+ backupSurface->unlockSurface();
+ return true;
+}
+
+bool TiledBackingStoreRemoteTileBufferTizen::drawPlatformSurface(const IntSize& size, const IntRect& dirtyRect, int tileID)
{
PlatformSurfacePoolTizen* platformSurfacePool = WebProcess::shared().platformSurfacePool();
if(!platformSurfacePool)
platformSurfacePool->freePlatformSurface(sharedPlatformSurface->id());
return false;
}
- if (!sharedPlatformSurface->querySurface((int*)&m_eglImgData)) {
+
+ unsigned char* dstBuffer;
+ unsigned char* dirtyBuffer;
+ RefPtr<cairo_surface_t> dstSurface, dirtySurface;
+ RefPtr<cairo_t> dstBitmapContext, dirtyBitmapContext;
+ OwnPtr<WebCore::GraphicsContext> graphicsContext;
+ IntRect paintRect = m_rect;
+ bool canPartiallyUpdate = false;
+
+ if (!sharedPlatformSurface->querySurface((int*)&dstBuffer)) {
sharedPlatformSurface->unlockSurface();
platformSurfacePool->freePlatformSurface(sharedPlatformSurface->id());
return false;
}
- RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(static_cast<unsigned char*>(m_eglImgData), CAIRO_FORMAT_ARGB32,
+
+ dstSurface = adoptRef(cairo_image_surface_create_for_data(dstBuffer, CAIRO_FORMAT_ARGB32,
sharedPlatformSurface->size().width(), sharedPlatformSurface->size().height(), 4 * sharedPlatformSurface->size().width()));
- RefPtr<cairo_t> bitmapContext = adoptRef(cairo_create(surface.get()));
- OwnPtr<WebCore::GraphicsContext> graphicsContext = adoptPtr(new GraphicsContext(bitmapContext.get()));
+ if (m_platformSurfaceID > 0 && needUpdateBackBufferPartially(m_rect, dirtyRect)
+ && copyPreviousFrame(dstBuffer, m_platformSurfaceID, IntRect(m_rect.location(), sharedPlatformSurface->size()), dirtyRect)) {
+ paintRect = dirtyRect;
+ canPartiallyUpdate = true;
+ }
+
+ if (canPartiallyUpdate) {
+ dirtyBuffer = (unsigned char*) malloc(4 * dirtyRect.width() * dirtyRect.height());
+ dirtySurface = adoptRef(cairo_image_surface_create_for_data(dirtyBuffer, CAIRO_FORMAT_ARGB32, dirtyRect.width(), dirtyRect.height(), 4 * dirtyRect.width()));
+ dirtyBitmapContext = adoptRef(cairo_create(dirtySurface.get()));
+ graphicsContext = adoptPtr(new GraphicsContext(dirtyBitmapContext.get()));
+ graphicsContext->clearRect(WebCore::FloatRect(WebCore::FloatPoint(0, 0), dirtyRect.size()));
+ } else {
+ dstBitmapContext = adoptRef(cairo_create(dstSurface.get()));
+ graphicsContext = adoptPtr(new GraphicsContext(dstBitmapContext.get()));
+ graphicsContext->clearRect(WebCore::FloatRect(WebCore::FloatPoint(0, 0), sharedPlatformSurface->size()));
+ }
+
#if ENABLE(TIZEN_WEBKIT2_DEBUG_BORDERS)
double startTime = 0;
double endTime = 0;
startTime = currentTime();
}
#endif
- graphicsContext->clearRect(WebCore::FloatRect(WebCore::FloatPoint(0, 0), sharedPlatformSurface->size()));
#if ENABLE(TIZEN_RECORDING_SURFACE_SET)
if (m_tiledBackingStore->client()->recordingSurfaceSetEnableGet()) {
} else
#endif
{
- graphicsContext->translate(-m_rect.x(), -m_rect.y());
+ graphicsContext->translate(-paintRect.x(), -paintRect.y());
graphicsContext->scale(FloatSize(m_tiledBackingStore->contentsScale(), m_tiledBackingStore->contentsScale()));
- m_tiledBackingStore->client()->tiledBackingStorePaint(graphicsContext.get(), m_tiledBackingStore->mapToContents(dirty));
+ m_tiledBackingStore->client()->tiledBackingStorePaint(graphicsContext.get(), m_tiledBackingStore->mapToContents(paintRect));
+ }
+
+ if (canPartiallyUpdate) {
+ copyDirtyRect(dstBuffer, dirtyBuffer, IntRect(m_rect.location(), sharedPlatformSurface->size()), dirtyRect);
+ dstBitmapContext = adoptRef(cairo_create(dstSurface.get()));
+ free(dirtyBuffer);
+ dirtySurface.release();
+ dirtyBitmapContext.release();
}
m_platformSurfaceID = sharedPlatformSurface->id();
char tileInfo[256];
int fontSize = 15;
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());
- cairo_set_source_rgb(bitmapContext.get(), 0.0, 0.0, 1.0);
- cairo_select_font_face(bitmapContext.get(), "", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
- cairo_set_font_size(bitmapContext.get(), fontSize);
- cairo_move_to(bitmapContext.get(), 0, fontSize);
- cairo_show_text(bitmapContext.get(), tileInfo);
+ cairo_set_source_rgb(dstBitmapContext.get(), 0.0, 0.0, 1.0);
+ cairo_select_font_face(dstBitmapContext.get(), "", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+ cairo_set_font_size(dstBitmapContext.get(), fontSize);
+ cairo_move_to(dstBitmapContext.get(), 0, fontSize);
+ cairo_show_text(dstBitmapContext.get(), tileInfo);
}
#endif
- if (!sharedPlatformSurface->unlockSurface())
+ dstBitmapContext.release();
+ graphicsContext.release();
+
+ if (!sharedPlatformSurface->unlockSurface())
return false;
return true;
}