diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 338 |
1 files changed, 250 insertions, 88 deletions
diff --git a/src/main.cpp b/src/main.cpp index e9cbf32..82f0153 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,66 +1,4 @@ -#include <glad.h> - -#include <stdio.h> -#if WINDOWS -#include <windows.h> -#else -#include <sys/mman.h> -#include <unistd.h> -#endif - -#if ARM -#include <arm_neon.h> -#include <arm_sve.h> -#else -#include <smmintrin.h> -#endif - -#include "imgui.h" -#include "imgui_impl_sdl.h" -#include "imgui_impl_opengl3.h" -#include <SDL.h> -#if defined(IMGUI_IMPL_OPENGL_ES2) -#include <SDL_opengles2.h> -#else -#include <SDL_opengl.h> -#endif - -#define STB_IMAGE_IMPLEMENTATION -#define STBI_FAILURE_USERMSG -#include "stb_image.h" - -#define STB_IMAGE_WRITE_IMPLEMENTATION -#include "stb_image_write.h" - -// TODO(fox): Used for thumbnails. The renderer could be expanded to do this -// much more efficiently. -#define STB_IMAGE_RESIZE_IMPLEMENTATION -#include "stb_image_resize.h" - -extern "C" { -#include <libavcodec/avcodec.h> -#include <libavformat/avformat.h> -#include <libavformat/avio.h> -#include <libavutil/avutil.h> -#include <libswscale/swscale.h> -#include <libswresample/swresample.h> -} - - -#include "defines.h" -#include "my_math.h" -#include "structs.h" -#if STABLE -#include "stable_diffusion.h" -#endif -#include "memory.h" -#include "nanovg.h" #include "main.h" -#include "ffmpeg_backend.h" - -#include "layer.h" -#include "debug.h" -#include "functions.h" SDL_Thread *Thread[8]; SDL_sem *Semaphore; @@ -82,6 +20,8 @@ uint32 BitmapFill = 0x00000001; #include <curl/curl.h> #endif +#if SPECIAL +#else #include "memory.cpp" #include "undo.cpp" #include "io.cpp" @@ -95,13 +35,26 @@ uint32 BitmapFill = 0x00000001; #include "stable_diffusion.cpp" #endif #include "ffmpeg_backend.cpp" + +#include "imgui_helper.cpp" +#include "imgui_ui_properties.cpp" +#include "imgui_ui_timeline.cpp" +#include "imgui_ui_viewport.cpp" +#if DEBUG +#include "imgui_ui_debug.cpp" +#endif +#if STABLE +#include "imgui_ui_stable_diffusion.cpp" +#endif #include "imgui_ui.cpp" + #include "prenderer.cpp" #include "gl_calls.cpp" #include "bezier.cpp" #include "effects_gl_shader.cpp" #include "effects.cpp" #include "effects_constructors.cpp" +#endif static void Main_RenderUI(ImGuiIO io, ImVec4 clear_color, SDL_Window *window) @@ -173,12 +126,17 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_ } #endif - ImGui_Viewport(File, State, UI, Memory, io, textureID, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyArray); + ImGui_Viewport(File, State, UI, Memory, io, textureID, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); ImGui_Timeline(File, State, Memory, UI, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); + + if (File->UI.Mode == 0) { + ImGui_EffectsPanel(File, State, Memory, UI, io); + } else { + } ImGui_PropertiesPanel(File, State, UI, Memory, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray); ImGui_ColorPanel(File, State, UI, Memory, io); - ImGui_EffectsPanel(File, State, Memory, UI, io); + #if STABLE if (UI->StableEnabled) { ImGui_SD_Prompt(File, State, UI, Memory, io, Sorted.CompArray, Sorted.LayerArray); @@ -207,7 +165,7 @@ Render_Main(project_data *File, project_state *State, memory *Memory, sorted_fil bool32 IsRendering = true; Renderer_Start(Data, OutputBuffer, RenderType, RenderRegion); while (IsRendering) { - Main_InputTest(File, State, Memory, Sorted, UI, window, textureID); + // Main_InputTest(File, State, Memory, Sorted, UI, window, textureID); // ImGuiIO& io = ImGui::GetIO(); // Main_RenderUI(io, ImVec4(0.45f, 0.55f, 0.60f, 1.00f), window); Renderer_Check(&IsRendering, RenderType); @@ -282,11 +240,137 @@ AV_Retrieve(project_state *State, memory *Memory, uint32 SourceIndex) return AV; } -static void * -Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_file Sorted, ui *UI, SDL_Window *window, GLuint textureID, ImGuiIO io, +static void +Render_SortKeyframes(project_data *File, project_state *State, memory *Memory, + sorted_comp_array *SortedCompStart, sorted_layer_array *SortedLayerStart, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, - sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray, uint32 CompIndex, int32 Frame_Current) + sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray, int Frame_Current) +{ + for (int i = 0; i < SortedCompStart->LayerCount; i++) { + sorted_layer_array SortEntry = SortedLayerStart[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + + int32 Frame_Start = Layer->Frame_Start; + int32 Frame_End = Layer->Frame_End; + int32 Frame_Offset = Layer->Frame_Offset; + if (Layer->IsSelected) + Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End, &Frame_Offset); + int32 Frame_Start_Abs = Frame_Start + Frame_Offset; + int32 Frame_End_Abs = Frame_End + Frame_Offset; + int FrameToSeek = State->Frame_Current - Frame_Start_Abs; + + if (Frame_Start_Abs <= Frame_Current && + Frame_End_Abs > Frame_Current && Layer->IsVisible) + { + if (State->UpdateKeyframes) { + sorted_property_array *SortedLayerProperties = SortedPropertyStart + SortEntry.SortedPropertyStart; + uint16 *SortedLayerKeyframes = SortedKeyframeArray + SortEntry.SortedKeyframeStart; + Layer_UpdateAllKeyframes(File, State, Memory, Layer, Index_Physical, SortedLayerProperties, SortedLayerKeyframes, Frame_Current); + } + } + } +} + +/* +struct render_entry_data +{ + int LayerCount; + int Width; + int Height; + int BytesPerPixel; + blend_mode BlendMode; +}; + +struct render_layer_data { + layer_transforms T; + int Width; + int Height; + // AV-specific + int BytesPerPixel; + void *Buffer; + // shape-specific + void *Stroke_Data; + uint32 Stroke_Count; + v4 Stroke_Col; + void *Fill_Data; + uint32 Fill_Count; + v4 Fill_Col; +}; +*/ + +struct gl_data +{ + void *StrokeData; + uint32 StrokeCount; + v4 StrokeCol; + void *FillData; + uint32 FillCount; + v4 FillCol; + layer_transforms T; + real32 Width; + real32 Height; + int RenderMode; +}; + +struct gl_viewport_data +{ + ImVec2 ViewportSize; + int Width; + int Height; + int BytesPerPixel; + ImVec2 UIPos; + ImVec2 UIZoom; + real32 UIScale; + gl_data *LayerEntry[MAX_LAYERS]; + int LayerCount; +}; + +static void +GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd) +{ + gl_viewport_data *RenderData = (gl_viewport_data *)cmd->UserCallbackData; + gl_effect_layer MSBuffer = {}; + + int A[4] = {}; + glGetIntegerv(GL_VIEWPORT, A); + + GL_UpdateTexture(&MSBuffer, NULL, A[2], A[3], RenderData->BytesPerPixel, 1); + glBindFramebuffer(GL_FRAMEBUFFER, MSBuffer.FramebufferObject); + glBindTexture(GL_TEXTURE_2D, 0); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glUseProgram(DefaultShaderProgram); + + // for (int i = 0; i < 1; i++) { + for (int i = 0; i < RenderData->LayerCount; i++) { + gl_data *Data = RenderData->LayerEntry[i]; + GL_RasterizeShape2(&MSBuffer, Data->StrokeData, Data->FillData, Data->StrokeCount, Data->FillCount, + Data->T, RenderData->Width, RenderData->Height, RenderData->BytesPerPixel, + Data->Width, Data->Height, Data->StrokeCol, Data->FillCol, Data->RenderMode, 0, + RenderData->ViewportSize, RenderData->UIPos, RenderData->UIZoom); + } + + glBindFramebuffer(GL_READ_FRAMEBUFFER, MSBuffer.FramebufferObject); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + // The multisample framebuffer allows us to conveniently clip to the comp bounds. + ImVec2 MinPos(RenderData->UIPos.x, A[3] - RenderData->UIPos.y - RenderData->UIZoom.y); + ImVec2 MaxPos = MinPos + RenderData->UIZoom; + glBlitFramebuffer(MinPos.x, MinPos.y, MaxPos.x, MaxPos.y, + MinPos.x, MinPos.y, MaxPos.x, MaxPos.y, + GL_COLOR_BUFFER_BIT, GL_LINEAR); + + GL_DeleteHWBuffer(&MSBuffer); +} + +static void +Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, + sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray, uint32 CompIndex, int32 Frame_Current) +{ + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); cache_entry *Entry_Main = Memory_Cache_Search(State, Memory, cache_entry_type_comp, CompIndex, Frame_Current); void *CompBuffer = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry_Main->Block_StartIndex); @@ -295,16 +379,27 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil sorted_comp_array *SortedCompStart = &SortedCompArray[CompIndex]; sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, CompIndex); - // NOTE(fox): We have to re-evalute keyframes even when the frame is - // cached, since we aren't caching the values and the UI needs to have - // them. Make sure that the cache is always purged if keyframes are - // updated. + Render_SortKeyframes(File, State, Memory, SortedCompStart, SortedLayerStart, SortedCompArray, SortedLayerArray, SortedPropertyStart, SortedKeyframeArray, Frame_Current); - for (int i = 0; i < SortedCompStart->LayerCount; i++) { + uint8 *StartAddress = (uint8 *)Memory->Slot[B_PointData].Address; + Arbitrary_Zero(StartAddress, Memory->Slot[B_PointData].Size); + + + gl_viewport_data *RenderData = (gl_viewport_data *)StartAddress; + StartAddress += sizeof(gl_viewport_data); + *RenderData = { ImGui::GetMainViewport()->Size, + Comp->Width, Comp->Height, Comp->BytesPerPixel, + UI->CompPos, UI->CompZoom, UI->CompZoom.x / Comp->Width, {} }; + + int LayerCount = SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount; + for (int i = 0; i < LayerCount; i++) + { sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - + if (!Layer->IsShapeLayer) { + continue; + } int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; int32 Frame_Offset = Layer->Frame_Offset; @@ -317,14 +412,76 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil if (Frame_Start_Abs <= Frame_Current && Frame_End_Abs > Frame_Current && Layer->IsVisible) { - if (State->UpdateKeyframes) { - sorted_property_array *SortedLayerProperties = SortedPropertyStart + SortEntry.SortedPropertyStart; - uint16 *SortedLayerKeyframes = SortedKeyframeArray + SortEntry.SortedKeyframeStart; - Layer_UpdateAllKeyframes(File, State, Memory, Layer, Index_Physical, SortedLayerProperties, SortedLayerKeyframes, Frame_Current); + shape_layer *Shape = &Layer->Shape; + void *Data = StartAddress; + + layer_transforms T = Layer_GetTransforms(Layer); + if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected == 1) { + Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &T.x, &T.y, &T.rotation, &T.scale); + } + if (State->Interact_Active == interact_type_viewport_slide && Layer->IsSelected == 1) { + // Transform_ApplySlide((v2 *)&State->Interact_Offset[0], &T); + } + if (State->Interact_Active == interact_type_viewport_duplicate && SortEntry.IsFake) { + Assert(Layer->IsSelected); + T.x += State->Interact_Offset[0]; + T.y += State->Interact_Offset[1]; } + + v2 Min = {}, Max = {}; + uint32 NumberOfVerts = NVG_FlattenPath(Memory, Shape, (nvg_point *)Data, + State, T, Shape->Width, Shape->Height, Comp->Width, Comp->Height, 1, &Min, &Max); + StartAddress += NumberOfVerts * sizeof(nvg_point); + void *Data_Stroke = StartAddress; + uint32 StrokeCount = NVG_ExpandStroke(Memory, NumberOfVerts, Shape->Opt.StrokeWidth, Shape->Opt.LineCapType, Shape->Opt.LineJoinType, Shape->IsClosed, (nvg_point *)Data, (real32 *)Data_Stroke); + StartAddress += StrokeCount * sizeof(real32) * 4; + void *Data_Fill = StartAddress; + NVG_ExpandFill(Memory, NumberOfVerts, (nvg_point *)Data, (real32 *)Data_Fill); + StartAddress += NumberOfVerts * sizeof(real32) * 4; + + // zero to set the framebuffer to main + gl_effect_layer TestL = {}; + void *EffectBitmapAddress = NULL; + + gl_data *GL_Data = RenderData->LayerEntry[RenderData->LayerCount] = (gl_data *)StartAddress; + RenderData->LayerCount++; + StartAddress += sizeof(gl_data); + + int Visibility = (Shape->Opt.StrokeWidth > 0.0f) ? Shape->Opt.Visibility : 1; + *GL_Data = { Data_Stroke, StrokeCount, Shape->Opt.StrokeCol, + Data_Fill, NumberOfVerts, Shape->Opt.FillCol, + T, Shape->Width, Shape->Height, Visibility }; } } + Assert((StartAddress - (uint8 *)Memory->Slot[B_PointData].Address) < Memory->Slot[B_PointData].Size); + + ImDrawCallback CustomRenderer = GL_Test; + draw_list->AddCallback(CustomRenderer, (void *)RenderData); + + draw_list->AddCallback(ImDrawCallback_ResetRenderState, NULL); +} + +static void * +Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_file Sorted, ui *UI, SDL_Window *window, GLuint textureID, ImGuiIO io, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, + sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray, uint32 CompIndex, int32 Frame_Current) +{ + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); + cache_entry *Entry_Main = Memory_Cache_Search(State, Memory, cache_entry_type_comp, CompIndex, Frame_Current); + void *CompBuffer = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry_Main->Block_StartIndex); + uint64 Size = Comp->Width * Comp->Height * Comp->BytesPerPixel; + + sorted_comp_array *SortedCompStart = &SortedCompArray[CompIndex]; + sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, CompIndex); + + // NOTE(fox): We have to re-evalute keyframes even when the frame is + // cached, since we aren't caching the values and the UI needs to have + // them. Make sure that the cache is always purged if keyframes are + // updated. + + Render_SortKeyframes(File, State, Memory, SortedCompStart, SortedLayerStart, SortedCompArray, SortedLayerArray, SortedPropertyStart, SortedKeyframeArray, Frame_Current); + if (Entry_Main->IsCached) return CompBuffer; @@ -533,7 +690,6 @@ Main_Renderer(project_data *File, project_state *State, memory *Memory, sorted_f int ByteFlag2 = (MainComp->BytesPerPixel == 4) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; if (State->FirstFrame) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MainComp->Width, MainComp->Height, 0, GL_RGBA, ByteFlag2, MainCompBuffer); - State->FirstFrame = false; } glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, MainComp->Width, MainComp->Height, GL_RGBA, ByteFlag2, MainCompBuffer); @@ -543,8 +699,6 @@ Main_Renderer(project_data *File, project_state *State, memory *Memory, sorted_f State->UpdateKeyframes = false; } -static int pp = -2; - int main(int argc, char *argv[]) { global_memory GlobalMemory = {}; @@ -557,10 +711,10 @@ int main(int argc, char *argv[]) { MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); #else GlobalMemory.Address = mmap(0, GlobalMemory.Size, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, - -1, - 0); + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, + 0); #endif // 1 meg per block @@ -569,7 +723,7 @@ int main(int argc, char *argv[]) { memory Memory = {}; Memory_InitTable(&GlobalMemory, &Memory, 1 * 1024 * 1024, P_AVInfo, "FFmpeg state", sizeof(av_info)); - Memory_InitTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, P_UndoBuffer, "Undo buffer"); + Memory_InitTable(&GlobalMemory, &Memory, 1 * 1024 * 1024, P_UndoBuffer, "Undo buffer"); Memory_InitTable(&GlobalMemory, &Memory, 40 * 1024 * 1024, P_MiscCache, "Misc persistent"); Memory_InitTable(&GlobalMemory, &Memory, sizeof(project_data), F_File, "File", sizeof(project_data)); @@ -583,10 +737,13 @@ int main(int argc, char *argv[]) { Memory_InitTable(&GlobalMemory, &Memory, (uint64)100 * 1024 * 1024, F_PrincipalBitmaps, "Principal bitmap data", BitmapBlockSize); Memory_InitTable(&GlobalMemory, &Memory, (uint64)5 * 1024 * 1024, B_Thumbnails, "Thumbnails"); - Memory_InitTable(&GlobalMemory, &Memory, (uint64)64 * 1024 * 1024, B_ScratchSpace, "Scratch"); + Memory_InitTable(&GlobalMemory, &Memory, (uint64)5 * 1024 * 1024, B_PointData, "Point data"); + Memory_InitTable(&GlobalMemory, &Memory, (uint64)128 * 1024 * 1024, B_ScratchSpace, "Scratch"); // Memory_InitTable(&GlobalMemory, &Memory, (uint64)1 * 1024 * 1024, B_CacheEntries, "Cache entries", sizeof(cache_entry)); Memory_InitTable(&GlobalMemory, &Memory, (uint64)700 * 1024 * 1024, B_CachedBitmaps, "Cached bitmap buffer"); + uint8 *Test = (uint8 *)Memory.Slot[B_ScratchSpace].Address + Memory.Slot[B_ScratchSpace].Size + 2; + *Test = 30; #if ARM InstructionMode = instruction_mode_neon; @@ -967,6 +1124,7 @@ int main(int argc, char *argv[]) { } } +#if 0 if (State->UpdateFrame) { // Default queue item type simply calls the renderer on the current // frame, so no additional info is needed @@ -980,7 +1138,7 @@ int main(int argc, char *argv[]) { Memory_Cache_Purge(File, State, &Memory, State->Frame_Current); } // Assert(pp != State->Frame_Current); - pp = State->Frame_Current; + // pp = State->Frame_Current; Main_Renderer(File, State, &Memory, Sorted, &File->UI, window, textureID, io); } else if (Item.Type == 1) { Assert(State->Interact_Active == interact_type_brush); @@ -995,6 +1153,7 @@ int main(int argc, char *argv[]) { State->Queue.CurrentIdx = 0; State->Queue.Playhead = 0; Arbitrary_Zero((uint8 *)State->Queue.Item, sizeof(State->Queue.Item)); +#endif File_Sort_Pop(&Memory, Sorted.Layer_SortSize, Sorted.Property_SortSize, Sorted.Source_SortSize); @@ -1019,6 +1178,9 @@ int main(int argc, char *argv[]) { if (State->Initializing) State->Initializing--; + if (State->FirstFrame) + State->FirstFrame = false; + uint64 PerfEnd = SDL_GetPerformanceCounter(); uint64 PerfTime = PerfEnd - PerfStart; real64 FrameMS = (1000.0f * (real64)PerfTime) / (real64)PerfFrequency; |