|
Carlos Lopez |
a09598 |
/* === S Y N F I G ========================================================= */
|
|
Carlos Lopez |
a09598 |
/*! \file target_scanline.cpp
|
|
Carlos Lopez |
a09598 |
** \brief Template File
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** $Id$
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** \legal
|
|
Carlos Lopez |
a09598 |
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
|
|
Carlos Lopez |
a09598 |
** Copyright (c) 2008 Chris Moore
|
|
Carlos Lopez |
e83454 |
** Copyright (c) 2012-2013 Carlos Lรณpez
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** This package is free software; you can redistribute it and/or
|
|
Carlos Lopez |
a09598 |
** modify it under the terms of the GNU General Public License as
|
|
Carlos Lopez |
a09598 |
** published by the Free Software Foundation; either version 2 of
|
|
Carlos Lopez |
a09598 |
** the License, or (at your option) any later version.
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** This package is distributed in the hope that it will be useful,
|
|
Carlos Lopez |
a09598 |
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Carlos Lopez |
a09598 |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Carlos Lopez |
a09598 |
** General Public License for more details.
|
|
Carlos Lopez |
a09598 |
** \endlegal
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
/* ========================================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === H E A D E R S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifdef USING_PCH
|
|
Carlos Lopez |
a09598 |
# include "pch.h"
|
|
Carlos Lopez |
a09598 |
#else
|
|
Carlos Lopez |
a09598 |
#ifdef HAVE_CONFIG_H
|
|
Carlos Lopez |
a09598 |
# include <config.h></config.h>
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include "target_scanline.h"
|
|
bw |
94d8a6 |
|
|
bw |
94d8a6 |
#include "general.h"
|
|
bw |
94d8a6 |
#include <synfig localization.h=""></synfig>
|
|
bw |
94d8a6 |
|
|
Carlos Lopez |
a09598 |
#include "canvas.h"
|
|
Carlos Lopez |
a09598 |
#include "context.h"
|
|
bw |
94d8a6 |
#include "render.h"
|
|
bw |
94d8a6 |
#include "string.h"
|
|
bw |
94d8a6 |
#include "surface.h"
|
|
|
371bd9 |
#include "rendering/renderer.h"
|
|
|
5e2754 |
#include "rendering/surface.h"
|
|
|
5e2754 |
#include "rendering/software/surfacesw.h"
|
|
|
5e2754 |
#include "rendering/common/task/tasktransformation.h"
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === U S I N G =========================================================== */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
using namespace std;
|
|
Carlos Lopez |
a09598 |
using namespace etl;
|
|
Carlos Lopez |
a09598 |
using namespace synfig;
|
|
|
371bd9 |
using namespace rendering;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === M A C R O S ========================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define PIXEL_RENDERING_LIMIT 1500000
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define USE_PIXELRENDERING_LIMIT 1
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === G L O B A L S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === P R O C E D U R E S ================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === M E T H O D S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Target_Scanline::Target_Scanline():
|
|
Carlos Lopez |
a09598 |
threads_(2)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
curr_frame_=0;
|
|
|
371bd9 |
if (const char *s = getenv("SYNFIG_TARGET_DEFAULT_ENGINE"))
|
|
|
371bd9 |
set_engine(s);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
int
|
|
Carlos Lopez |
a09598 |
Target_Scanline::next_frame(Time& time)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
4a0029 |
return Target::next_frame(time);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
4fdecc |
|
|
Carlos Lopez |
a09598 |
bool
|
|
|
a4bbdd |
synfig::Target_Scanline::call_renderer(
|
|
|
a4bbdd |
const etl::handle<rendering::surfaceresource> &surface,</rendering::surfaceresource>
|
|
|
a4bbdd |
Canvas &canvas,
|
|
|
a4bbdd |
const ContextParams &context_params,
|
|
|
a4bbdd |
const RendDesc &renddesc )
|
|
|
371bd9 |
{
|
|
|
5e2754 |
surface->create(renddesc.get_w(), renddesc.get_h());
|
|
|
a4bbdd |
rendering::Task::Handle task = canvas.build_rendering_task(context_params);
|
|
|
9b5397 |
|
|
|
b006b4 |
if (task)
|
|
|
371bd9 |
{
|
|
|
b006b4 |
rendering::Renderer::Handle renderer = rendering::Renderer::get_renderer(get_engine());
|
|
|
b006b4 |
if (!renderer)
|
|
|
b006b4 |
throw "Renderer '" + get_engine() + "' not found";
|
|
|
371bd9 |
|
|
|
5e2754 |
Vector p0 = renddesc.get_tl();
|
|
|
5e2754 |
Vector p1 = renddesc.get_br();
|
|
|
5e2754 |
if (p0[0] > p1[0] || p0[1] > p1[1]) {
|
|
|
093a8b |
Matrix m;
|
|
|
5e2754 |
if (p0[0] > p1[0]) { m.m00 = -1.0; m.m20 = p0[0] + p1[0]; std::swap(p0[0], p1[0]); }
|
|
|
5e2754 |
if (p0[1] > p1[1]) { m.m11 = -1.0; m.m21 = p0[1] + p1[1]; std::swap(p0[1], p1[1]); }
|
|
|
5e2754 |
TaskTransformationAffine::Handle t = new TaskTransformationAffine();
|
|
|
5e2754 |
t->transformation->matrix = m;
|
|
|
5e2754 |
t->sub_task() = task;
|
|
|
5e2754 |
task = t;
|
|
|
5e2754 |
}
|
|
|
5e2754 |
|
|
|
5e2754 |
task->target_surface = surface;
|
|
|
5e2754 |
task->target_rect = RectInt( VectorInt(), surface->get_size() );
|
|
|
5e2754 |
task->source_rect = Rect(p0, p1);
|
|
|
371bd9 |
|
|
|
b006b4 |
rendering::Task::List list;
|
|
|
b006b4 |
list.push_back(task);
|
|
|
b006b4 |
renderer->run(list);
|
|
|
371bd9 |
}
|
|
|
371bd9 |
return true;
|
|
|
371bd9 |
}
|
|
|
371bd9 |
|
|
|
371bd9 |
bool
|
|
Carlos Lopez |
a09598 |
synfig::Target_Scanline::render(ProgressCallback *cb)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
SuperCallback super_cb;
|
|
Carlos Lopez |
a09598 |
int
|
|
Carlos Lopez |
4fdecc |
frames=0,
|
|
Carlos Lopez |
a09598 |
total_frames,
|
|
Carlos Lopez |
a09598 |
frame_start,
|
|
Carlos Lopez |
a09598 |
frame_end;
|
|
Carlos Lopez |
a09598 |
Time
|
|
Carlos Lopez |
4fdecc |
t=0;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
assert(canvas);
|
|
Carlos Lopez |
a09598 |
curr_frame_=0;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if( !init() ){
|
|
Carlos Lopez |
a09598 |
if(cb) cb->error(_("Target initialization failure"));
|
|
Carlos Lopez |
a09598 |
return false;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
frame_start=desc.get_frame_start();
|
|
Carlos Lopez |
a09598 |
frame_end=desc.get_frame_end();
|
|
Carlos Lopez |
a09598 |
|
|
|
c74593 |
ContextParams context_params(desc.get_render_excluded_contexts());
|
|
|
c74593 |
|
|
Carlos Lopez |
a09598 |
// Calculate the number of frames
|
|
Carlos Lopez |
4fdecc |
total_frames=frame_end-frame_start+1;
|
|
Carlos Lopez |
4fdecc |
if(total_frames<=0)total_frames=1;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
try {
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
//synfig::info("1time_set_to %s",t.get_string().c_str());
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
4fdecc |
if(total_frames>=1)
|
|
Carlos Lopez |
ddc8e7 |
{
|
|
Carlos Lopez |
ddc8e7 |
do{
|
|
Carlos Lopez |
ddc8e7 |
// Grab the time
|
|
Carlos Lopez |
ddc8e7 |
frames=next_frame(t);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
ddc8e7 |
// If we have a callback, and it returns
|
|
Carlos Lopez |
ddc8e7 |
// false, go ahead and bail. (it may be a user cancel)
|
|
Carlos Lopez |
ddc8e7 |
if(cb && !cb->amount_complete(total_frames-frames,total_frames))
|
|
Carlos Lopez |
ddc8e7 |
return false;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
ddc8e7 |
// Set the time that we wish to render
|
|
|
c3039f |
if(!get_avoid_time_sync() || canvas->get_time()!=t) {
|
|
|
2ffd0a |
canvas->set_time(t);
|
|
|
c3039f |
canvas->load_resources(t);
|
|
|
c3039f |
}
|
|
|
9cd69d |
canvas->set_outline_grow(desc.get_outline_grow());
|
|
Carlos Lopez |
a09598 |
|
|
|
b006b4 |
// If quality is set otherwise, then we use the accelerated renderer
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
ddc8e7 |
#if USE_PIXELRENDERING_LIMIT
|
|
Carlos Lopez |
ddc8e7 |
if(desc.get_w()*desc.get_h() > PIXEL_RENDERING_LIMIT)
|
|
Carlos Lopez |
a09598 |
{
|
|
|
5e2754 |
SurfaceResource::Handle surface = new SurfaceResource();
|
|
|
371bd9 |
|
|
Carlos Lopez |
ddc8e7 |
int rowheight = PIXEL_RENDERING_LIMIT/desc.get_w();
|
|
Carlos Lopez |
ddc8e7 |
if (!rowheight) rowheight = 1; // TODO: render partial lines to stay within the limit?
|
|
Carlos Lopez |
ddc8e7 |
int rows = desc.get_h()/rowheight;
|
|
Carlos Lopez |
ddc8e7 |
int lastrowheight = desc.get_h() - rows*rowheight;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
ddc8e7 |
rows++;
|
|
Carlos Lopez |
a09598 |
|
|
|
d1262f |
synfig::info("Render split to %d block%s %d pixels tall, and a final block %d pixels tall",
|
|
Carlos Lopez |
ddc8e7 |
rows-1, rows==2?"":"s", rowheight, lastrowheight);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
ddc8e7 |
// loop through all the full rows
|
|
Carlos Lopez |
ddc8e7 |
if(!start_frame())
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
ddc8e7 |
throw(string("add_frame(): target panic on start_frame()"));
|
|
Carlos Lopez |
a09598 |
return false;
|
|
Carlos Lopez |
ddc8e7 |
}
|
|
Carlos Lopez |
ddc8e7 |
|
|
Carlos Lopez |
ddc8e7 |
for(int i=0; i < rows; ++i)
|
|
Carlos Lopez |
a09598 |
{
|
|
|
d1262f |
surface->reset();
|
|
|
d1262f |
RendDesc blockrd = desc;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
ddc8e7 |
//render the strip at the normal size unless it's the last one...
|
|
Carlos Lopez |
ddc8e7 |
if(i == rows-1)
|
|
Carlos Lopez |
ddc8e7 |
{
|
|
Carlos Lopez |
ddc8e7 |
if(!lastrowheight) break;
|
|
Carlos Lopez |
ddc8e7 |
blockrd.set_subwindow(0,i*rowheight,desc.get_w(),lastrowheight);
|
|
Carlos Lopez |
ddc8e7 |
}
|
|
Carlos Lopez |
ddc8e7 |
else
|
|
Carlos Lopez |
ddc8e7 |
{
|
|
Carlos Lopez |
ddc8e7 |
blockrd.set_subwindow(0,i*rowheight,desc.get_w(),rowheight);
|
|
Carlos Lopez |
ddc8e7 |
}
|
|
Carlos Lopez |
a09598 |
|
|
|
59badb |
//synfig::info( " -- block %d/%d left, top, width, height: %d, %d, %d, %d",
|
|
|
59badb |
// i+1, rows, 0, i*rowheight, blockrd.get_w(), blockrd.get_h() );
|
|
|
d1262f |
|
|
|
a4bbdd |
if (!call_renderer(surface, *canvas, context_params, blockrd))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
ddc8e7 |
if(cb)cb->error(_("Accelerated Renderer Failure"));
|
|
Carlos Lopez |
ddc8e7 |
return false;
|
|
|
5e2754 |
} else {
|
|
|
5e2754 |
SurfaceResource::LockRead<surfacesw> lock(surface);</surfacesw>
|
|
|
5e2754 |
if (!lock) {
|
|
|
d1262f |
if(cb)cb->error(_("Accelerated Renderer Failure: cannot read surface"));
|
|
|
5e2754 |
return false;
|
|
|
5e2754 |
}
|
|
|
5e2754 |
|
|
|
5e2754 |
const synfig::Surface &s = lock->get_surface();
|
|
|
5e2754 |
|
|
Carlos Lopez |
ddc8e7 |
int y;
|
|
|
5e2754 |
int rowspan=sizeof(Color)*s.get_w();
|
|
|
5e2754 |
Surface::const_pen pen = s.begin();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
ddc8e7 |
int yoff = i*rowheight;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
ddc8e7 |
for(y = 0; y < blockrd.get_h(); y++, pen.inc_y())
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
ddc8e7 |
Color *colordata= start_scanline(y + yoff);
|
|
Carlos Lopez |
ddc8e7 |
if(!colordata)
|
|
Carlos Lopez |
ddc8e7 |
{
|
|
Carlos Lopez |
ddc8e7 |
throw(string("add_frame(): call to start_scanline(y) returned NULL"));
|
|
Carlos Lopez |
ddc8e7 |
return false;
|
|
Carlos Lopez |
ddc8e7 |
}
|
|
Carlos Lopez |
ddc8e7 |
|
|
|
dc451c |
switch(get_alpha_mode())
|
|
Carlos Lopez |
ddc8e7 |
{
|
|
|
dc451c |
case TARGET_ALPHA_MODE_FILL:
|
|
|
5e2754 |
for(int i = 0; i < s.get_w(); i++)
|
|
|
5e2754 |
colordata[i] = Color::blend(s[y][i], desc.get_bg_color(), 1.0f);
|
|
|
dc451c |
break;
|
|
|
dc451c |
case TARGET_ALPHA_MODE_EXTRACT:
|
|
|
5e2754 |
for(int i = 0; i < s.get_w(); i++)
|
|
|
dc451c |
{
|
|
|
5e2754 |
float a=s[y][i].get_a();
|
|
|
dc451c |
colordata[i] = Color(a,a,a,a);
|
|
|
dc451c |
}
|
|
|
dc451c |
break;
|
|
|
dc451c |
case TARGET_ALPHA_MODE_REDUCE:
|
|
|
5e2754 |
for(int i = 0; i < s.get_w(); i++)
|
|
|
5e2754 |
colordata[i] = Color(s[y][i].get_r(), s[y][i].get_g(), s[y][i].get_b(), 1.f);
|
|
|
dc451c |
break;
|
|
|
dc451c |
case TARGET_ALPHA_MODE_KEEP:
|
|
|
5e2754 |
memcpy(colordata, s[y], rowspan);
|
|
|
dc451c |
break;
|
|
|
d18194 |
}
|
|
Carlos Lopez |
ddc8e7 |
|
|
Carlos Lopez |
ddc8e7 |
if(!end_scanline())
|
|
Carlos Lopez |
ddc8e7 |
{
|
|
Carlos Lopez |
ddc8e7 |
throw(string("add_frame(): target panic on end_scanline()"));
|
|
Carlos Lopez |
ddc8e7 |
return false;
|
|
Carlos Lopez |
ddc8e7 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
|
d1262f |
surface->reset();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
ddc8e7 |
end_frame();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
ddc8e7 |
}else //use normal rendering...
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
ddc8e7 |
#endif
|
|
|
5e2754 |
SurfaceResource::Handle surface = new SurfaceResource();
|
|
Carlos Lopez |
7902ad |
|
|
|
a4bbdd |
if (!call_renderer(surface, *canvas, context_params, desc))
|
|
Carlos Lopez |
ddc8e7 |
{
|
|
Carlos Lopez |
7902ad |
// For some reason, the accelerated renderer failed.
|
|
Carlos Lopez |
7902ad |
if(cb)cb->error(_("Accelerated Renderer Failure"));
|
|
Carlos Lopez |
7902ad |
return false;
|
|
Carlos Lopez |
dcc781 |
}
|
|
|
371bd9 |
|
|
|
5e2754 |
SurfaceResource::LockRead<surfacesw> lock(surface);</surfacesw>
|
|
|
5e2754 |
if(!lock)
|
|
|
5e2754 |
{
|
|
|
5e2754 |
if(cb)cb->error(_("Bad surface"));
|
|
|
5e2754 |
return false;
|
|
|
5e2754 |
}
|
|
|
5e2754 |
|
|
|
371bd9 |
// Put the surface we renderer
|
|
|
371bd9 |
// onto the target.
|
|
|
5e2754 |
if(!add_frame(&lock->get_surface()))
|
|
Carlos Lopez |
dcc781 |
{
|
|
|
371bd9 |
if(cb)cb->error(_("Unable to put surface on target"));
|
|
|
371bd9 |
return false;
|
|
Carlos Lopez |
ddc8e7 |
}
|
|
Carlos Lopez |
ddc8e7 |
#if USE_PIXELRENDERING_LIMIT
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
ddc8e7 |
#endif
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
ddc8e7 |
}while(frames);
|
|
Carlos Lopez |
ddc8e7 |
}
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
// Set the time that we wish to render
|
|
|
c3039f |
if(!get_avoid_time_sync() || canvas->get_time()!=t) {
|
|
|
2ffd0a |
canvas->set_time(t);
|
|
|
c3039f |
canvas->load_resources(t);
|
|
|
c3039f |
}
|
|
|
9cd69d |
canvas->set_outline_grow(desc.get_outline_grow());
|
|
Carlos Lopez |
a09598 |
|
|
|
b006b4 |
// If quality is set otherwise, then we use the accelerated renderer
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
#if USE_PIXELRENDERING_LIMIT
|
|
Carlos Lopez |
a09598 |
if(desc.get_w()*desc.get_h() > PIXEL_RENDERING_LIMIT)
|
|
Carlos Lopez |
a09598 |
{
|
|
|
5e2754 |
SurfaceResource::Handle surface(new SurfaceResource());
|
|
|
371bd9 |
|
|
Carlos Lopez |
a09598 |
int totalheight = desc.get_h();
|
|
Carlos Lopez |
a09598 |
int rowheight = PIXEL_RENDERING_LIMIT/desc.get_w();
|
|
Carlos Lopez |
a09598 |
if (!rowheight) rowheight = 1; // TODO: render partial lines to stay within the limit?
|
|
Carlos Lopez |
a09598 |
int rows = desc.get_h()/rowheight;
|
|
Carlos Lopez |
a09598 |
int lastrowheight = desc.get_h() - rows*rowheight;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
rows++;
|
|
Carlos Lopez |
a09598 |
|
|
|
d1262f |
synfig::info("Render split to %d block%s %d pixels tall, and a final block %d pixels tall",
|
|
Carlos Lopez |
a09598 |
rows-1, rows==2?"":"s", rowheight, lastrowheight);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// loop through all the full rows
|
|
Carlos Lopez |
a09598 |
if(!start_frame())
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
throw(string("add_frame(): target panic on start_frame()"));
|
|
Carlos Lopez |
a09598 |
return false;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
for(int i=0; i < rows; ++i)
|
|
Carlos Lopez |
a09598 |
{
|
|
|
d1262f |
surface->reset();
|
|
|
d1262f |
RendDesc blockrd = desc;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
//render the strip at the normal size unless it's the last one...
|
|
Carlos Lopez |
a09598 |
if(i == rows-1)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if(!lastrowheight) break;
|
|
Carlos Lopez |
a09598 |
blockrd.set_subwindow(0,i*rowheight,desc.get_w(),lastrowheight);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
blockrd.set_subwindow(0,i*rowheight,desc.get_w(),rowheight);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
|
59badb |
//synfig::info( " -- block %d/%d left, top, width, height: %d, %d, %d, %d",
|
|
|
59badb |
// i+1, rows, 0, i*rowheight, blockrd.get_w(), blockrd.get_h() );
|
|
|
d1262f |
|
|
|
a4bbdd |
if (!call_renderer(surface, *canvas, context_params, blockrd))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if(cb)cb->error(_("Accelerated Renderer Failure"));
|
|
Carlos Lopez |
a09598 |
return false;
|
|
|
371bd9 |
}
|
|
Carlos Lopez |
a09598 |
|
|
|
5e2754 |
SurfaceResource::LockRead<surfacesw> lock(surface);</surfacesw>
|
|
|
5e2754 |
|
|
|
5e2754 |
if(!lock)
|
|
|
5e2754 |
{
|
|
|
5e2754 |
if(cb)cb->error(_("Bad surface"));
|
|
|
5e2754 |
return false;
|
|
|
5e2754 |
}
|
|
|
5e2754 |
|
|
|
5e2754 |
const synfig::Surface &s = lock->get_surface();
|
|
|
5e2754 |
|
|
|
371bd9 |
int y;
|
|
|
5e2754 |
int rowspan=sizeof(Color)*s.get_w();
|
|
|
5e2754 |
Surface::const_pen pen = s.begin();
|
|
Carlos Lopez |
a09598 |
|
|
|
371bd9 |
int yoff = i*rowheight;
|
|
|
371bd9 |
|
|
|
371bd9 |
for(y = 0; y < blockrd.get_h(); y++, pen.inc_y())
|
|
|
371bd9 |
{
|
|
|
371bd9 |
Color *colordata= start_scanline(y + yoff);
|
|
|
371bd9 |
if(!colordata)
|
|
Carlos Lopez |
a09598 |
{
|
|
|
371bd9 |
throw(string("add_frame(): call to start_scanline(y) returned NULL"));
|
|
|
371bd9 |
return false;
|
|
|
371bd9 |
}
|
|
Carlos Lopez |
a09598 |
|
|
|
371bd9 |
switch(get_alpha_mode())
|
|
|
371bd9 |
{
|
|
|
371bd9 |
case TARGET_ALPHA_MODE_FILL:
|
|
|
5e2754 |
for(int i = 0; i < s.get_w(); i++)
|
|
|
5e2754 |
colordata[i] = Color::blend(s[y][i], desc.get_bg_color(), 1.0f);
|
|
|
371bd9 |
break;
|
|
|
371bd9 |
case TARGET_ALPHA_MODE_EXTRACT:
|
|
|
5e2754 |
for(int i = 0; i < s.get_w(); i++)
|
|
|
371bd9 |
{
|
|
|
5e2754 |
float a=s[y][i].get_a();
|
|
|
371bd9 |
colordata[i] = Color(a,a,a,a);
|
|
|
371bd9 |
}
|
|
|
371bd9 |
break;
|
|
|
371bd9 |
case TARGET_ALPHA_MODE_REDUCE:
|
|
|
5e2754 |
for(int i = 0; i < s.get_w(); i++)
|
|
|
5e2754 |
colordata[i] = Color(s[y][i].get_r(), s[y][i].get_g(), s[y][i].get_b(), 1.0f);
|
|
|
371bd9 |
break;
|
|
|
371bd9 |
case TARGET_ALPHA_MODE_KEEP:
|
|
|
5e2754 |
memcpy(colordata,s[y], rowspan);
|
|
|
371bd9 |
break;
|
|
|
371bd9 |
}
|
|
|
371bd9 |
|
|
|
371bd9 |
if(!end_scanline())
|
|
|
371bd9 |
{
|
|
|
371bd9 |
throw(string("add_frame(): target panic on end_scanline()"));
|
|
|
371bd9 |
return false;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
//I'm done with this part
|
|
|
a4bbdd |
if (cb) cb->amount_complete((i+1)*rowheight, totalheight);
|
|
Carlos Lopez |
a09598 |
}
|
|
|
d1262f |
surface->reset();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
end_frame();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
}else
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
#endif
|
|
|
5e2754 |
SurfaceResource::Handle surface = new SurfaceResource();
|
|
Carlos Lopez |
7902ad |
|
|
|
a4bbdd |
if (!call_renderer(surface, *canvas, context_params, desc))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
7902ad |
if(cb)cb->error(_("Accelerated Renderer Failure"));
|
|
Carlos Lopez |
7902ad |
return false;
|
|
Carlos Lopez |
dcc781 |
}
|
|
|
371bd9 |
|
|
|
5e2754 |
SurfaceResource::LockRead<surfacesw> lock(surface);</surfacesw>
|
|
|
5e2754 |
|
|
|
5e2754 |
if(!lock)
|
|
|
5e2754 |
{
|
|
|
5e2754 |
if(cb)cb->error(_("Bad surface"));
|
|
|
5e2754 |
return false;
|
|
|
5e2754 |
}
|
|
|
5e2754 |
|
|
|
371bd9 |
// Put the surface we renderer
|
|
|
371bd9 |
// onto the target.
|
|
|
5e2754 |
if(!add_frame(&lock->get_surface()))
|
|
Carlos Lopez |
dcc781 |
{
|
|
|
371bd9 |
if(cb)cb->error(_("Unable to put surface on target"));
|
|
|
371bd9 |
return false;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
#if USE_PIXELRENDERING_LIMIT
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
}
|
|
|
b1afd8 |
catch(const String& str)
|
|
Carlos Lopez |
a09598 |
{
|
|
Firas Hanife |
b4b6a7 |
if (cb) cb->error(_("Caught string: ")+str);
|
|
Carlos Lopez |
a09598 |
return false;
|
|
Carlos Lopez |
a09598 |
}
|
|
|
b1afd8 |
catch (std::bad_alloc&)
|
|
Carlos Lopez |
a09598 |
{
|
|
|
b1afd8 |
if (cb) cb->error(_("Ran out of memory (Probably a bug)"));
|
|
Carlos Lopez |
a09598 |
return false;
|
|
Carlos Lopez |
a09598 |
}
|
|
|
b1afd8 |
catch (...)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if(cb)cb->error(_("Caught unknown error, rethrowing..."));
|
|
Carlos Lopez |
a09598 |
throw;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
return true;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
bool
|
|
Carlos Lopez |
a09598 |
Target_Scanline::add_frame(const Surface *surface)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
assert(surface);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
int y;
|
|
Carlos Lopez |
a09598 |
int rowspan=sizeof(Color)*surface->get_w();
|
|
Carlos Lopez |
a09598 |
Surface::const_pen pen=surface->begin();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(!start_frame())
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
throw(string("add_frame(): target panic on start_frame()"));
|
|
Carlos Lopez |
a09598 |
return false;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
for(y=0;y<surface->get_h();y++,pen.inc_y())</surface->
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Color *colordata= start_scanline(y);
|
|
Carlos Lopez |
a09598 |
if(!colordata)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
throw(string("add_frame(): call to start_scanline(y) returned NULL"));
|
|
Carlos Lopez |
a09598 |
return false;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
|
dc451c |
switch(get_alpha_mode())
|
|
Carlos Lopez |
a09598 |
{
|
|
|
dc451c |
case TARGET_ALPHA_MODE_FILL:
|
|
|
dc451c |
for(int i=0;i<surface->get_w();i++)</surface->
|
|
|
dc451c |
colordata[i]=Color::blend((*surface)[y][i],desc.get_bg_color(),1.0f);
|
|
|
dc451c |
break;
|
|
|
dc451c |
case TARGET_ALPHA_MODE_EXTRACT:
|
|
|
dc451c |
for(int i=0;i<surface->get_w();i++)</surface->
|
|
|
dc451c |
{
|
|
|
dc451c |
float a=(*surface)[y][i].get_a();
|
|
|
dc451c |
colordata[i] = Color(a,a,a,a);
|
|
|
dc451c |
}
|
|
|
dc451c |
break;
|
|
|
dc451c |
case TARGET_ALPHA_MODE_REDUCE:
|
|
|
dc451c |
for(int i = 0; i < surface->get_w(); i++)
|
|
|
dc451c |
colordata[i] = Color((*surface)[y][i].get_r(),(*surface)[y][i].get_g(),(*surface)[y][i].get_b(),1.0f);
|
|
|
dc451c |
break;
|
|
|
dc451c |
case TARGET_ALPHA_MODE_KEEP:
|
|
|
dc451c |
memcpy(colordata,(*surface)[y],rowspan);
|
|
|
dc451c |
break;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(!end_scanline())
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
throw(string("add_frame(): target panic on end_scanline()"));
|
|
Carlos Lopez |
a09598 |
return false;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
end_frame();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return true;
|
|
Carlos Lopez |
a09598 |
}
|