1/*
2 * Copyright (C) 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19#include "config.h"
20#include "CanvasLayerWebKitThread.h"
21
22#include "LayerCompositingThread.h"
23
24#if USE(ACCELERATED_COMPOSITING) && ENABLE(ACCELERATED_2D_CANVAS)
25
26#include <BlackBerryPlatformGLES2Program.h>
27
28using BlackBerry::Platform::Graphics::GLES2Program;
29
30namespace WebCore {
31
32void CanvasLayerWebKitThread::deleteTextures()
33{
34}
35
36class CanvasLayerCompositingThreadClient : public LayerCompositingThreadClient {
37public:
38    CanvasLayerCompositingThreadClient(BlackBerry::Platform::Graphics::Buffer*, const IntSize&);
39
40    void layerCompositingThreadDestroyed(LayerCompositingThread*) { }
41    void layerVisibilityChanged(LayerCompositingThread*, bool) { }
42    void uploadTexturesIfNeeded(LayerCompositingThread*) { }
43
44    void drawTextures(LayerCompositingThread*, const GLES2Program&, double scale, const FloatRect& clipRect);
45    void deleteTextures(LayerCompositingThread*);
46
47    void commitPendingTextureUploads(LayerCompositingThread*);
48
49    void clearBuffer() { m_buffer = 0; }
50
51private:
52    BlackBerry::Platform::Graphics::Buffer* m_buffer;
53    IntSize m_size;
54};
55
56CanvasLayerCompositingThreadClient::CanvasLayerCompositingThreadClient(BlackBerry::Platform::Graphics::Buffer* buffer, const IntSize& size)
57    : m_buffer(buffer)
58    , m_size(size)
59{
60}
61
62void CanvasLayerCompositingThreadClient::drawTextures(LayerCompositingThread* layer, const GLES2Program&, double, const FloatRect& /*clipRect*/)
63{
64    if (!m_buffer)
65        return;
66
67    TransformationMatrix dt = layer->drawTransform();
68    dt.translate(-layer->bounds().width() / 2.0, -layer->bounds().height() / 2.0);
69    dt.scaleNonUniform(static_cast<double>(layer->bounds().width()) / m_size.width(), static_cast<double>(layer->bounds().height()) / m_size.height());
70    blitToBuffer(0, m_buffer, reinterpret_cast<BlackBerry::Platform::TransformationMatrix&>(dt),
71        BlackBerry::Platform::Graphics::SourceOver, static_cast<unsigned char>(layer->drawOpacity() * 255));
72}
73
74void CanvasLayerCompositingThreadClient::deleteTextures(LayerCompositingThread*)
75{
76    // Nothing to do here, the buffer is not owned by us.
77}
78
79void CanvasLayerCompositingThreadClient::commitPendingTextureUploads(LayerCompositingThread*)
80{
81    if (!m_buffer)
82        return;
83
84    // This method is called during a synchronization point between WebKit and compositing thread.
85    // This is our only chance to transfer the back display list to the front display list without
86    // race conditions.
87    // 1. Flush back display list to front
88    BlackBerry::Platform::Graphics::releaseBufferDrawable(m_buffer);
89    // 2. Draw front display list to FBO
90    BlackBerry::Platform::Graphics::updateBufferBackingSurface(m_buffer);
91}
92
93
94CanvasLayerWebKitThread::CanvasLayerWebKitThread(BlackBerry::Platform::Graphics::Buffer* buffer, const IntSize& size)
95    : LayerWebKitThread(CanvasLayer, 0)
96{
97    m_compositingThreadClient = new CanvasLayerCompositingThreadClient(buffer, size);
98    layerCompositingThread()->setClient(m_compositingThreadClient);
99}
100
101CanvasLayerWebKitThread::~CanvasLayerWebKitThread()
102{
103    layerCompositingThread()->setClient(0);
104    delete m_compositingThreadClient;
105}
106
107void CanvasLayerWebKitThread::clearBuffer(CanvasLayerWebKitThread* layer)
108{
109    layer->m_compositingThreadClient->clearBuffer();
110}
111
112}
113
114#endif // USE(ACCELERATED_COMPOSITING) && ENABLE(ACCELERATED_2D_CANVAS)
115