1/* 2 Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) 3 Copyright (C) 2012 Company 100, Inc. 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public License 16 along with this library; see the file COPYING.LIB. If not, write to 17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 21#include "config.h" 22#include "UpdateAtlas.h" 23 24#if USE(COORDINATED_GRAPHICS) 25 26#include "CoordinatedGraphicsState.h" 27#include "GraphicsContext.h" 28#include "IntRect.h" 29#include <wtf/MathExtras.h> 30 31namespace WebCore { 32 33class UpdateAtlasSurfaceClient : public CoordinatedSurface::Client { 34public: 35 UpdateAtlasSurfaceClient(CoordinatedSurface::Client* client, const IntSize& size, bool supportsAlpha) 36 : m_client(client) 37 , m_size(size) 38 , m_supportsAlpha(supportsAlpha) 39 { 40 } 41 42 virtual void paintToSurfaceContext(GraphicsContext* context) override 43 { 44 if (m_supportsAlpha) { 45 context->setCompositeOperation(CompositeCopy); 46 context->fillRect(IntRect(IntPoint::zero(), m_size), Color::transparent, ColorSpaceDeviceRGB); 47 context->setCompositeOperation(CompositeSourceOver); 48 } 49 50 m_client->paintToSurfaceContext(context); 51 } 52 53private: 54 CoordinatedSurface::Client* m_client; 55 IntSize m_size; 56 bool m_supportsAlpha; 57}; 58 59UpdateAtlas::UpdateAtlas(Client* client, int dimension, CoordinatedSurface::Flags flags) 60 : m_client(client) 61 , m_inactivityInSeconds(0) 62{ 63 static uint32_t nextID = 0; 64 m_ID = ++nextID; 65 IntSize size = nextPowerOfTwo(IntSize(dimension, dimension)); 66 m_surface = CoordinatedSurface::create(size, flags); 67 68 m_client->createUpdateAtlas(m_ID, m_surface); 69} 70 71UpdateAtlas::~UpdateAtlas() 72{ 73 if (m_surface) 74 m_client->removeUpdateAtlas(m_ID); 75} 76 77void UpdateAtlas::buildLayoutIfNeeded() 78{ 79 if (!m_areaAllocator) { 80 m_areaAllocator = std::make_unique<GeneralAreaAllocator>(size()); 81 m_areaAllocator->setMinimumAllocation(IntSize(32, 32)); 82 } 83} 84 85void UpdateAtlas::didSwapBuffers() 86{ 87 m_areaAllocator = nullptr; 88} 89 90 91bool UpdateAtlas::paintOnAvailableBuffer(const IntSize& size, uint32_t& atlasID, IntPoint& offset, CoordinatedSurface::Client* client) 92{ 93 m_inactivityInSeconds = 0; 94 buildLayoutIfNeeded(); 95 IntRect rect = m_areaAllocator->allocate(size); 96 97 // No available buffer was found. 98 if (rect.isEmpty()) 99 return false; 100 101 if (!m_surface) 102 return false; 103 104 atlasID = m_ID; 105 106 // FIXME: Use tri-state buffers, to allow faster updates. 107 offset = rect.location(); 108 109 UpdateAtlasSurfaceClient surfaceClient(client, size, supportsAlpha()); 110 m_surface->paintToSurface(rect, &surfaceClient); 111 112 return true; 113} 114 115} // namespace WebCore 116#endif // USE(COORDINATED_GRAPHICS) 117