tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebCore / platform / graphics / efl / LayerWebGLContents.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
22 #if ENABLE(TIZEN_ACCELERATED_COMPOSITING)
23 #if USE(ACCELERATED_COMPOSITING)
24
25 #include "LayerWebGLContents.h"
26
27 #include "GraphicsContext3D.h"
28 #include "LayerTextureManager.h"
29 #include "Logging.h"
30 #include "OwnArrayPtr.h"
31 #include "RefPtrCairo.h"
32
33 namespace WebCore {
34
35 PassRefPtr<LayerContents> LayerWebGLContents::create(EflLayer* owner)
36 {
37     return adoptRef(new LayerWebGLContents(owner));
38 }
39
40 LayerWebGLContents::LayerWebGLContents(EflLayer* owner)
41     : LayerContents(owner)
42     , m_needToUpdateTexture(false)
43     , m_zoomFactor(1.0)
44 {
45 }
46
47 LayerWebGLContents::~LayerWebGLContents()
48 {
49 }
50
51 void LayerWebGLContents::releaseResources(LayerTextureManager* manager)
52 {
53     // A ownership of WebGL Contents texture is belong to GraphicsContext3D
54     // The texture used by LayerTextureManager for WebGL is borrowed from GraphicsContext3D.
55     // So do not release it here
56
57     m_textureId = 0;
58     m_textureSize = IntSize();
59
60     m_readyToRender = false;
61 }
62
63 void LayerWebGLContents::drawContents(const FloatRect& contentRect, const FloatRect& dirtyRect, float zoomFactor)
64 {
65     m_updateRect = IntRect(dirtyRect);
66
67     bool needToRescale = false;
68     IntSize fbSize = m_context->getInternalFramebufferSize();
69     if (m_fbSize != fbSize) {
70         needToRescale = true;
71         m_fbSize = fbSize;
72     }
73     if (m_zoomFactor != zoomFactor) {
74         needToRescale = true;
75         m_zoomFactor = zoomFactor;
76     }
77     if (needToRescale) {
78         m_scaledDrawRect = IntSize(static_cast<int>(m_fbSize.width() * m_zoomFactor)
79             , static_cast<int>(m_fbSize.height() * m_zoomFactor));
80     }
81
82     m_needToUpdateTexture = true;
83 }
84
85 void LayerWebGLContents::updateTexture(LayerTextureManager* manager)
86 {
87     if (!m_needToUpdateTexture)
88         return;
89
90     m_context->prepareTexture();
91
92     if (!m_textureId) {
93         m_textureId = m_context->platformTexture();
94         manager->useTexture(m_textureId);
95     }
96
97     m_readyToRender = true;
98     m_needToUpdateTexture = false;
99     m_updateRect = IntRect();
100 }
101
102 void LayerWebGLContents::saveImage(int frame, int tileIndex, const String& dir)
103 {
104 #if USE(CAIRO)
105     if (m_needToUpdateTexture) {
106         IntRect r = m_owner->screenRect();
107         String fileName = dir + String::format("/%d_%p_%d_html_%d_%d_%d_%d.png", frame, m_owner, tileIndex, r.x(), r.y(), r.width(), r.height());
108
109         unsigned int rowBytes = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_fbSize.width());
110         unsigned int totalBytes = rowBytes * m_fbSize.height();
111         OwnArrayPtr<unsigned char> pixels = adoptArrayPtr(new unsigned char[totalBytes]);
112         if (!pixels)
113             return;
114
115         m_context->readRenderingResults(pixels.get(), totalBytes);
116
117         RefPtr<cairo_surface_t> fbCairoSurface = adoptRef(cairo_image_surface_create_for_data(pixels.get()
118                 , CAIRO_FORMAT_ARGB32
119                 , m_fbSize.width(), m_fbSize.height()
120                 , rowBytes));
121         cairo_status_t cairoStatus = cairo_surface_status(fbCairoSurface.get());
122         if (cairoStatus != CAIRO_STATUS_SUCCESS) {
123             LOG(AcceleratedCompositing, "---> RETURN : failed to create cairo_surface_t\n");
124             return;
125         }
126
127         RefPtr<cairo_surface_t> cairoSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32
128                 , m_scaledDrawRect.width(), m_scaledDrawRect.height()));
129         cairoStatus = cairo_surface_status(cairoSurface.get());
130         if (cairoStatus != CAIRO_STATUS_SUCCESS) {
131             LOG(AcceleratedCompositing, "---> RETURN : failed to create cairo_surface_t\n");
132             return;
133         }
134
135         RefPtr<cairo_t> cairoContext = adoptRef(cairo_create(cairoSurface.get()));
136         cairoStatus = cairo_status(cairoContext.get());
137         if (cairoStatus != CAIRO_STATUS_SUCCESS) {
138             LOG(AcceleratedCompositing, "---> RETURN : failed to create cairo_t\n");
139             return;
140         }
141
142         cairo_matrix_t resultMat;
143         cairo_matrix_t t1, t2;
144         cairo_matrix_t s;
145         cairo_matrix_t flip;
146
147         cairo_matrix_init_identity(&resultMat);
148         cairo_matrix_init_translate(&t1, m_scaledDrawRect.width() * 0.5, m_scaledDrawRect.height() * 0.5);
149         cairo_matrix_init_scale(&s, m_zoomFactor, m_zoomFactor);
150         cairo_matrix_init(&flip, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
151         cairo_matrix_init_translate(&t2, -m_fbSize.width() * 0.5, -m_fbSize.height() * 0.5);
152
153         cairo_matrix_multiply(&resultMat, &resultMat, &t2);
154         cairo_matrix_multiply(&resultMat, &resultMat, &flip);
155         cairo_matrix_multiply(&resultMat, &resultMat, &s);
156         cairo_matrix_multiply(&resultMat, &resultMat, &t1);
157
158         cairo_set_matrix(cairoContext.get(), &resultMat);
159         cairo_set_source_surface(cairoContext.get(), fbCairoSurface.get(), 0, 0);
160         cairo_set_operator (cairoContext.get(), CAIRO_OPERATOR_SOURCE);
161         cairo_paint(cairoContext.get());
162
163         cairo_surface_write_to_png(cairoSurface.get(), fileName.utf8().data());
164     }
165 #endif
166 }
167
168 } // namespace WebCore
169
170 #endif
171 #endif