1 #include "core/framebuffer.hpp"
2 #include "core/instance.hpp"
3 #include "core/misc.hpp"
4 #include "lua/internal.hpp"
5 #include "lua/bitmap.hpp"
11 lua_renderqueue(lua::state
& L
, uint32_t width
, uint32_t height
) throw();
12 static size_t overcommit(uint32_t width
, uint32_t height
) { return 0; }
13 ~lua_renderqueue() throw() {}
14 lua::render_context
* get() { return &lctx
; }
17 size_t s
= rqueue
.get_object_count();
18 return (stringfmt() << s
<< " " << ((s
!= 1) ? "objects" : "object")).str();
20 static int create(lua::state
& L
, lua::parameters
& P
);
21 static int setnull(lua::state
& L
, lua::parameters
& P
);
22 int run(lua::state
& L
, lua::parameters
& P
)
25 if(!core
.lua2
->render_ctx
) return 0;
27 lua::render_context
* ptr
= get();
28 if(ptr
->top_gap
!= std::numeric_limits
<uint32_t>::max())
29 core
.lua2
->render_ctx
->top_gap
= ptr
->top_gap
;
30 if(ptr
->right_gap
!= std::numeric_limits
<uint32_t>::max())
31 core
.lua2
->render_ctx
->right_gap
= ptr
->right_gap
;
32 if(ptr
->bottom_gap
!= std::numeric_limits
<uint32_t>::max())
33 core
.lua2
->render_ctx
->bottom_gap
= ptr
->bottom_gap
;
34 if(ptr
->left_gap
!= std::numeric_limits
<uint32_t>::max())
35 core
.lua2
->render_ctx
->left_gap
= ptr
->left_gap
;
36 core
.lua2
->render_ctx
->queue
->copy_from(*ptr
->queue
);
39 int synchronous_repaint(lua::state
& L
, lua::parameters
& P
)
42 lua::objpin
<lua_renderqueue
> q
;
46 core
.lua2
->synchronous_paint_ctx
= &*q
;
47 core
.fbuf
->redraw_framebuffer();
48 core
.lua2
->synchronous_paint_ctx
= NULL
;
51 int clear(lua::state
& L
, lua::parameters
& P
)
53 lua::render_context
* ptr
= get();
54 ptr
->top_gap
= std::numeric_limits
<uint32_t>::max();
55 ptr
->right_gap
= std::numeric_limits
<uint32_t>::max();
56 ptr
->bottom_gap
= std::numeric_limits
<uint32_t>::max();
57 ptr
->left_gap
= std::numeric_limits
<uint32_t>::max();
61 int set(lua::state
& L
, lua::parameters
& P
)
64 lua::objpin
<lua_renderqueue
> q
;
68 lua::render_context
* ptr
= q
->get();
69 if(!core
.lua2
->renderq_redirect
|| core
.lua2
->renderq_last
!= core
.lua2
->render_ctx
)
70 core
.lua2
->renderq_saved
= core
.lua2
->render_ctx
;
71 core
.lua2
->render_ctx
= core
.lua2
->renderq_last
= ptr
;
72 core
.lua2
->renderq_redirect
= true;
75 int render(lua::state
& L
, lua::parameters
& P
)
77 uint32_t rwidth
= lctx
.width
+ rdgap(lctx
.left_gap
) + rdgap(lctx
.right_gap
);
78 uint32_t rheight
= lctx
.height
+ rdgap(lctx
.top_gap
) + rdgap(lctx
.bottom_gap
);
79 uint32_t xoff
= rdgap(lctx
.left_gap
);
80 uint32_t yoff
= rdgap(lctx
.top_gap
);
81 framebuffer::fb
<false> fb
;
82 fb
.reallocate(rwidth
, rheight
);
83 fb
.set_origin(xoff
, yoff
);
85 lua_dbitmap
* b
= lua::_class
<lua_dbitmap
>::create(L
, rwidth
, rheight
);
86 for(auto y
= 0U; y
< rheight
; y
++) {
87 const uint32_t* rowp
= fb
.rowptr(y
);
88 auto rowt
= &b
->pixels
[y
* rwidth
];
89 for(auto x
= 0U; x
< rwidth
; x
++) {
93 c
= ((256 - (v
>> 24) - (v
>> 31)) << 24) + (v
& 0xFFFFFF);
100 uint32_t rdgap(uint32_t v
)
102 return (v
+ 1) ? v
: 0;
104 framebuffer::queue rqueue
;
105 lua::render_context lctx
;
108 lua_renderqueue::lua_renderqueue(lua::state
& L
, uint32_t width
, uint32_t height
) throw()
110 lctx
.left_gap
= std::numeric_limits
<uint32_t>::max();
111 lctx
.right_gap
= std::numeric_limits
<uint32_t>::max();
112 lctx
.bottom_gap
= std::numeric_limits
<uint32_t>::max();
113 lctx
.top_gap
= std::numeric_limits
<uint32_t>::max();
114 lctx
.queue
= &rqueue
;
116 lctx
.height
= height
;
119 int lua_renderqueue::create(lua::state
& L
, lua::parameters
& P
)
125 lua::_class
<lua_renderqueue
>::create(L
, x
, y
);
129 int lua_renderqueue::setnull(lua::state
& L
, lua::parameters
& P
)
132 if(core
.lua2
->renderq_redirect
&& core
.lua2
->renderq_last
== core
.lua2
->render_ctx
)
133 //If there is valid redirect, undo it.
134 core
.lua2
->render_ctx
= core
.lua2
->renderq_saved
;
135 core
.lua2
->renderq_redirect
= false;
136 core
.lua2
->renderq_last
= NULL
;
137 core
.lua2
->renderq_saved
= NULL
;
141 lua::_class
<lua_renderqueue
> LUA_class_lua_renderqueue(lua_class_gui
, "RENDERCTX", {
142 {"new", lua_renderqueue::create
},
143 {"setnull", lua_renderqueue::setnull
},
145 {"run", &lua_renderqueue::run
},
146 {"synchronous_repaint", &lua_renderqueue::synchronous_repaint
},
147 {"clear", &lua_renderqueue::clear
},
148 {"set", &lua_renderqueue::set
},
149 {"render", &lua_renderqueue::render
},
150 }, &lua_renderqueue::print
);
153 void lua_renderq_run(lua::render_context
* ctx
, void* _sctx
)
155 lua_renderqueue
* sctx
= (lua_renderqueue
*)_sctx
;
156 lua::render_context
* ptr
= sctx
->get();
157 if(ptr
->top_gap
!= std::numeric_limits
<uint32_t>::max())
158 ctx
->top_gap
= ptr
->top_gap
;
159 if(ptr
->right_gap
!= std::numeric_limits
<uint32_t>::max())
160 ctx
->right_gap
= ptr
->right_gap
;
161 if(ptr
->bottom_gap
!= std::numeric_limits
<uint32_t>::max())
162 ctx
->bottom_gap
= ptr
->bottom_gap
;
163 if(ptr
->left_gap
!= std::numeric_limits
<uint32_t>::max())
164 ctx
->left_gap
= ptr
->left_gap
;
165 ctx
->queue
->copy_from(*ptr
->queue
);