1/* 2 * Copyright (C) 2010 codeaurora.org All rights reserved. 3 * Copyright (C) 2011 Collabora Ltd. 4 * Copyright (C) 2011 Samsung Electronics 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include "config.h" 29#include "TileCairo.h" 30 31#if USE(TILED_BACKING_STORE) && USE(CAIRO) 32#include "CairoUtilities.h" 33#include "GraphicsContext.h" 34#include "PlatformContextCairo.h" 35#include "TiledBackingStore.h" 36#include "TiledBackingStoreClient.h" 37#include <RefPtrCairo.h> 38 39namespace WebCore { 40 41TileCairo::TileCairo(TiledBackingStore* backingStore, const Coordinate& tileCoordinate) 42 : m_backingStore(backingStore) 43 , m_coordinate(tileCoordinate) 44 , m_rect(m_backingStore->tileRectForCoordinate(tileCoordinate)) 45{ 46 cairo_rectangle_int_t rect = m_rect; 47 m_dirtyRegion = adoptRef(cairo_region_create_rectangle(&rect)); 48} 49 50TileCairo::~TileCairo() 51{ 52} 53 54bool TileCairo::isDirty() const 55{ 56 return !cairo_region_is_empty(m_dirtyRegion.get()); 57} 58 59bool TileCairo::isReadyToPaint() const 60{ 61 return m_buffer; 62} 63 64void TileCairo::invalidate(const IntRect& dirtyRect) 65{ 66 IntRect tileDirtyRect = intersection(dirtyRect, m_rect); 67 if (tileDirtyRect.isEmpty()) 68 return; 69 70 cairo_rectangle_int_t rect = tileDirtyRect; 71 cairo_region_union_rectangle(m_dirtyRegion.get(), &rect); 72} 73 74Vector<IntRect> TileCairo::updateBackBuffer() 75{ 76 if (m_buffer && !isDirty()) 77 return Vector<IntRect>(); 78 79 if (!m_buffer) 80 m_buffer = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 81 m_backingStore->tileSize().width(), 82 m_backingStore->tileSize().height())); 83 84 RefPtr<cairo_t> cr = adoptRef(cairo_create(m_buffer.get())); 85 GraphicsContext context(cr.get()); 86 context.translate(-m_rect.x(), -m_rect.y()); 87 88 Vector<IntRect> updateRects; 89 cairo_rectangle_int_t rect; 90 91 int rectCount = cairo_region_num_rectangles(m_dirtyRegion.get()); 92 for (int i = 0; i < rectCount; ++i) { 93 cairo_region_get_rectangle(m_dirtyRegion.get(), i, &rect); 94 updateRects.append(IntRect(rect)); 95 96 context.save(); 97 context.clip(FloatRect(rect)); 98 context.scale(FloatSize(m_backingStore->contentsScale(), m_backingStore->contentsScale())); 99 m_backingStore->client()->tiledBackingStorePaint(&context, m_backingStore->mapToContents(rect)); 100 context.restore(); 101 } 102 103 m_dirtyRegion.clear(); 104 m_dirtyRegion = adoptRef(cairo_region_create()); 105 106 return updateRects; 107} 108 109void TileCairo::swapBackBufferToFront() 110{ 111} 112 113void TileCairo::paint(GraphicsContext* context, const IntRect& rect) 114{ 115 if (!m_buffer) 116 return; 117 118 IntRect target = intersection(rect, m_rect); 119 120 cairo_t* cr = context->platformContext()->cr(); 121 cairo_set_source_surface(cr, m_buffer.get(), m_rect.x(), m_rect.y()); 122 cairo_rectangle(cr, target.x(), target.y(), target.width(), target.height()); 123 cairo_fill(cr); 124} 125 126void TileCairo::resize(const WebCore::IntSize& newSize) 127{ 128 IntRect oldRect = m_rect; 129 m_rect = IntRect(m_rect.location(), newSize); 130 if (m_rect.maxX() > oldRect.maxX()) 131 invalidate(IntRect(oldRect.maxX(), oldRect.y(), m_rect.maxX() - oldRect.maxX(), m_rect.height())); 132 if (m_rect.maxY() > oldRect.maxY()) 133 invalidate(IntRect(oldRect.x(), oldRect.maxY(), m_rect.width(), m_rect.maxY() - oldRect.maxY())); 134} 135 136} 137 138#endif 139