2 * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file RenderBuffer.cpp
18 * @author Yunchan Cho (yunchan.cho@samsung.com)
23 #include <Ecore_Evas.h>
25 #include <provider_buffer.h>
26 #include <Core/Util/Log.h>
27 #include <Core/Util/Util.h>
28 #include "IRenderBuffer.h"
29 #include "RenderBuffer.h"
31 RenderBuffer::RenderBuffer()
38 RenderBuffer::~RenderBuffer()
43 bool RenderBuffer::allocate()
52 ecore_evas_buffer_allocfunc_new(
53 getWidth(), getHeight(),
54 allocateCallback, freeCallback,
56 LogD("Using %s engine!", ecore_evas_engine_name_get(ee));
59 LogD("invalid ecore evas object");
63 LogD("evas ecore setting");
65 // alpha_set function access the canvas buffer directly,
66 // without pre/post render callback.
67 provider_buffer_pre_render(m_bufferInfo);
68 ecore_evas_alpha_set(ee, EINA_TRUE);
69 provider_buffer_post_render(m_bufferInfo);
70 ecore_evas_manual_render_set(ee, EINA_FALSE);
72 // resize function will invoke the freeCallback and allocateCallback again. (internally)
73 ecore_evas_resize(ee, getWidth(), getHeight());
75 ecore_evas_activate(ee);
77 LogD("Using %s engine!", ecore_evas_engine_name_get(ee));
79 Evas* e = ecore_evas_get(ee);
80 evas_image_cache_flush(e);
81 Evas_Object *eo = evas_object_rectangle_add(e);
82 evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
83 evas_object_color_set(eo, 0, 0, 0, 1);
84 evas_object_resize(eo, getWidth(), getHeight());
93 bool RenderBuffer::reallocate(int width, int height)
98 // TODO This function should be implemented due to box resize operation
102 Ecore_Evas* ee = ecore_evas_ecore_evas_get(m_canvas);
103 // resize function will invoke the freeCallback and allocateCallback again. (internally)
104 ecore_evas_resize(ee, getWidth(), getHeight());
105 evas_object_resize(m_win, getWidth(), getHeight());
110 bool RenderBuffer::free()
117 ecore_evas_free(ecore_evas_ecore_evas_get(m_canvas));
124 void RenderBuffer::startCanvasUpdate()
127 evas_event_callback_del(
129 EVAS_CALLBACK_RENDER_PRE,
132 evas_event_callback_del(
134 EVAS_CALLBACK_RENDER_POST,
137 evas_event_callback_add(
139 EVAS_CALLBACK_RENDER_PRE,
140 preRenderCallback, this);
142 evas_event_callback_add(
144 EVAS_CALLBACK_RENDER_POST,
145 postRenderCallback, this);
149 void RenderBuffer::stopCanvasUpdate()
152 evas_event_callback_del(
154 EVAS_CALLBACK_RENDER_PRE,
157 evas_event_callback_del(
159 EVAS_CALLBACK_RENDER_POST,
163 Evas_Object* RenderBuffer::getWindow()
168 void RenderBuffer::preRenderCallback(void* data, Evas* canvas, void *eventInfo)
171 UNUSED_PARAM(eventInfo);
173 RenderBuffer *buffer = static_cast<RenderBuffer*>(data);
174 if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
175 LogD("not hw backend");
179 provider_buffer_pre_render(buffer->m_bufferInfo);
180 evas_damage_rectangle_add(canvas, 0, 0, buffer->getWidth(), buffer->getHeight());
183 void RenderBuffer::postRenderCallback(void* data, Evas* canvas, void* eventInfo)
187 UNUSED_PARAM(canvas);
188 UNUSED_PARAM(eventInfo);
190 RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
192 evas_data_argb_unpremul(static_cast<unsigned int*>(buffer->m_bufferAddr), buffer->getWidth() * buffer->getHeight());
193 #ifdef RENDER_BUFFER_VERIFY_SHOT
198 snprintf(filename, sizeof(filename) - 1, "/tmp/render%d-%dx%d.raw", idx++, buffer->getWidth(), buffer->getHeight());
199 fp = fopen(filename, "w+");
201 LogD("RenderShot: %s(%d)\n", filename, buffer->getWidth() * buffer->getHeight() * sizeof(int));
202 fwrite(buffer->m_bufferAddr, buffer->getWidth() * buffer->getHeight() * sizeof(int), 1, fp);
205 LogD("Failed to open a file: %s", filename);
209 LogD("/tmp/render-%dx%d.raw", buffer->getWidth(), buffer->getHeight());
211 if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
212 provider_buffer_sync(buffer->m_bufferInfo);
213 buffer->updateBuffer();
215 provider_buffer_post_render(buffer->m_bufferInfo);
216 buffer->updateBuffer();
220 void RenderBuffer::paintColor(unsigned int color)
224 if (!provider_buffer_pixmap_is_support_hw(m_bufferInfo)) {
225 memset(m_bufferAddr, color, getWidth() * getHeight() * 4);
226 provider_buffer_sync(m_bufferInfo);
229 preRenderCallback(this, m_canvas, NULL);
230 memset(m_bufferAddr, color, getWidth() * getHeight() * 4);
231 postRenderCallback(this, m_canvas, NULL);
235 Evas* RenderBuffer::getCanvas()
240 void* RenderBuffer::allocateCallback(void* data, int size)
245 RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
247 if (buffer->m_bufferInfo) {
248 freeCallback(data, NULL);
251 buffer->m_bufferInfo = buffer->acquireBuffer();
252 if (!buffer->m_bufferInfo) {
256 // set buffer address
257 if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
258 LogD("s/w evas backend");
259 buffer->m_bufferAddr = provider_buffer_ref(buffer->m_bufferInfo);
261 LogD("h/w evas backend");
262 int ret = provider_buffer_pixmap_create_hw(buffer->m_bufferInfo);
264 LogD("can't create hw pixmap");
266 buffer->m_bufferAddr = provider_buffer_pixmap_hw_addr(buffer->m_bufferInfo);
269 LogD("success to allocate buffer");
270 return buffer->m_bufferAddr;
273 void RenderBuffer::freeCallback(void* data, void *pix)
278 RenderBuffer* buffer = static_cast<RenderBuffer*>(data);
281 if (!provider_buffer_pixmap_is_support_hw(buffer->m_bufferInfo)) {
282 provider_buffer_unref(buffer->m_bufferAddr);
284 provider_buffer_pixmap_destroy_hw(buffer->m_bufferInfo);
287 provider_buffer_release(buffer->m_bufferInfo);
289 buffer->m_bufferInfo = NULL;
290 buffer->m_bufferAddr = NULL;
292 LogD("success to free buffer");
296 Evas_Object *RenderBuffer::getSnapshot(void)
299 Evas_Object *snapshot;
302 snapshot = evas_object_image_add(m_canvas);
305 evas_object_image_data_set(snapshot, NULL);
306 evas_object_image_colorspace_set(snapshot, EVAS_COLORSPACE_ARGB8888);
307 evas_object_image_alpha_set(snapshot, EINA_TRUE);
308 evas_object_image_size_set(snapshot, getWidth(), getHeight());
310 tmpBuffer = malloc(getWidth() * getHeight() * sizeof(int));
312 memcpy(tmpBuffer, m_bufferAddr, getWidth() * getHeight() * sizeof(int));
313 evas_data_argb_premul(
314 static_cast<unsigned int*>(tmpBuffer),
315 getWidth() * getHeight());
316 evas_object_image_data_set(snapshot, tmpBuffer);
318 LogD("Failed to allocate heap");
321 evas_object_image_data_update_add(snapshot, 0, 0, getWidth(), getHeight());
322 evas_object_image_fill_set(snapshot, 0, 0, getWidth(), getHeight());
323 evas_object_resize(snapshot, getWidth(), getHeight());