/* * Mr. 4th Dimention - Allen Webster * * 10.11.2017 * * Render target function implementations. * */ // TOP #define Render_Begin_Push_Sig(n,t,p,s) void* (n)(Render_Target *t, void *p, i32 s) #define Render_End_Push_Sig(n,t,h) void (n)(Render_Target *t, void *h) #define Render_Change_Clip_Sig(n,t,c) void (n)(Render_Target *t, i32_Rect c) #define Render_Push_Clip_Sig(n,t,c) void (n)(Render_Target *t, i32_Rect c) #define Render_Pop_Clip_Sig(n,t) i32_Rect (n)(Render_Target *t) //////////////////////////////// internal Render_Begin_Push_Sig(render_internal_begin_push, t, ptr, size){ void *out = push_array(&t->buffer, u8, size); if (out != 0){ memcpy(out, ptr, size); } // TODO(allen): Application side logging. #if 0 else{ LOG("Render command buffer out of memory!\n"); } #endif return(out); } internal Render_End_Push_Sig(render_internal_end_push, t, h){ if (h != 0){ u8 *end_ptr = (u8*)push_align(&t->buffer, 8); Render_Command_Header *header = (Render_Command_Header*)h; header->size = (i32)(end_ptr - (u8*)h); } // TODO(allen): else { LOG } } internal void render_internal_push_clip(Render_Target *t, i32_Rect clip_box){ t->clip_all = (clip_box.x0 >= clip_box.x1 || clip_box.y0 >= clip_box.y1); if (t->clip_all){ return; } // TODO(allen): If the previous command was also a push clip should // undo that one and just do this one. (OPTIMIZATION). Render_Command_Change_Clip cmd = {0}; cmd.header.size = sizeof(cmd); cmd.header.type = RenCom_ChangeClip; cmd.box = clip_box; void *h = render_internal_begin_push(t, &cmd, cmd.header.size); render_internal_end_push(t, h); } //////////////////////////////// internal Render_Begin_Push_Sig(render_begin_push, t, ptr, size){ void *out = 0; if (!t->clip_all){ out = render_internal_begin_push(t, ptr, size); } return(out); } internal Render_End_Push_Sig(render_end_push, t, h){ render_internal_end_push(t, h); } internal Render_Change_Clip_Sig(render_change_clip, t, clip_box){ Assert(t->clip_top > -1); t->clip_boxes[t->clip_top] = clip_box; render_internal_push_clip(t, clip_box); } internal Render_Push_Clip_Sig(render_push_clip, t, clip_box){ Assert(t->clip_top == -1 || fits_inside(clip_box, t->clip_boxes[t->clip_top])); Assert(t->clip_top + 1 < ArrayCount(t->clip_boxes)); t->clip_boxes[++t->clip_top] = clip_box; render_internal_push_clip(t, clip_box); } internal Render_Pop_Clip_Sig(render_pop_clip, t){ Assert(t->clip_top > 0); i32_Rect result = t->clip_boxes[t->clip_top]; --t->clip_top; i32_Rect clip_box = t->clip_boxes[t->clip_top]; render_internal_push_clip(t, clip_box); return(result); } // BOTTOM