diff options
-rw-r--r-- | bitmap_calls.cpp | 5 | ||||
-rwxr-xr-x | build.sh | 2 | ||||
-rw-r--r-- | createcalls.cpp | 31 | ||||
-rw-r--r-- | main.cpp | 105 | ||||
-rw-r--r-- | main.h | 1 | ||||
-rw-r--r-- | my_imgui_widgets.cpp | 27 | ||||
-rw-r--r-- | prenderer.cpp | 56 | ||||
-rw-r--r-- | threading.cpp | 20 |
8 files changed, 90 insertions, 157 deletions
diff --git a/bitmap_calls.cpp b/bitmap_calls.cpp index 2cdb463..132aec5 100644 --- a/bitmap_calls.cpp +++ b/bitmap_calls.cpp @@ -177,10 +177,7 @@ BitmapPackRGB(pixel_buffer *Buffer) { internal void OutputToViewport(pixel_buffer *CompBuffer, project_state *State, GLuint textureID) { - if (D) - Convert4x4Chunk(CompBuffer, 1); - else - CopyToBuffer(CompBuffer, 0); + Convert4x4Chunk(CompBuffer, 1); EndRenderState(State); glBindTexture(GL_TEXTURE_2D, textureID); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, CompBuffer->Width, CompBuffer->Height, GL_RGBA, GL_UNSIGNED_BYTE, @@ -8,7 +8,7 @@ WARNING_FLAGS=" -Wno-missing-field-initializers -Wno-sign-compare -Wno-write-strings -Wno-unused-but-set-parameter \ -Wno-missing-braces -Wno-format-security -fno-exceptions -Wno-strict-aliasing \ - -DDEBUG=1 -DARM=0 -DTHREADED=0 \ + -DDEBUG=1 -DARM=0 -DTHREADED=1 \ " if [[ "$WINDOWS" == 1 ]]; then diff --git a/createcalls.cpp b/createcalls.cpp index 0dbf75c..1c20b1a 100644 --- a/createcalls.cpp +++ b/createcalls.cpp @@ -311,6 +311,18 @@ CreateDebugLayer(project_data *File, memory *Memory, uint16 Width, uint16 Height } internal void +LoadTestFootage(project_data *File, project_state *State, memory *Memory) +{ + CreateLayerFromSource(File, State, Memory, "../asset/24.mp4"); + // project_layer *Layer1 = CreateDebugLayer(&File, &Memory, 9, 14); + // project_layer *Layer1 = CreateSolidLayer(&File, &Memory, 9, 13, V4(1.0, 1.0, 1.0, 1.0)); + // Layer1->x.CurrentValue.f = 7; + // Layer1->y.CurrentValue.f = 4; + // Layer1->StartFrame = 0; + // Layer1->EndFrame = File.EndFrame; +} + +internal void CreateDemoScene(project_data *File, memory *Memory) { project_layer *Layer1 = CreateSolidLayer(File, Memory, 720, 1280, V4(0.0, 0.0, 0.0, 1.0)); @@ -339,3 +351,22 @@ CreateDemoScene(project_data *File, memory *Memory) Layer3->x.IsToggled = true; Layer3->y.IsToggled = true; } + +internal void +CreateGrid(project_data *File, memory *Memory) { + uint16 Amount = 8; + real32 XInc = File->Width / Amount; + real32 YInc = File->Height / Amount; + for (int16 j = 0; j < 8; j++) { + for (int16 i = 0; i < 8; i++) { + project_layer *Layer = CreateSolidLayer(File, Memory, 200, 200, V4(0.6, 0.3, 0.4, 1.0)); + Layer->x.CurrentValue.f = (XInc*i); + Layer->y.CurrentValue.f = (XInc*j); + Layer->opacity.CurrentValue.f = 0.25; + Layer->StartFrame = 0; + Layer->EndFrame = File->EndFrame; + ManualKeyframeInsertF(&Layer->rotation, Memory, i, 0); + ManualKeyframeInsertF(&Layer->rotation, Memory, 40+i, 360); + } + } +} @@ -5,15 +5,6 @@ #include <sys/mman.h> #endif -// TODO(fox): Switch all thread code to SDL! -#if WINDOWS -#else -#if THREADED -#include <pthread.h> -#else -#endif -#endif - #if ARM #include <arm_neon.h> #else @@ -101,11 +92,10 @@ typedef double real64; #include "main.h" #include "debug.h" -global_variable uint32 volatile CompletedJobs; -global_variable uint32 volatile NextEntryToDo; -global_variable uint32 volatile EntryCount; +SDL_atomic_t CurrentEntry; +SDL_atomic_t QueuedEntries; +SDL_atomic_t CompletedEntries; global_variable bool32 IsRendering = false; -global_variable bool32 D = true; global_variable instruction_mode InstructionMode = scalar_only; @@ -314,11 +304,9 @@ int main(int argc, char *argv[]) { InstructionMode = avx_enabled; } - InstructionMode = scalar_only; - project_data File = {}; - File.Width = 1280; - File.Height = 720; + File.Width = 1283; + File.Height = 723; File.NumberOfFrames = 65; File.FPS = 30; File.CurrentFrame = 1; @@ -337,14 +325,6 @@ int main(int argc, char *argv[]) { ui UI = {}; - // File.NumberOfSources = 2; - // File.Source[0] = (char *)AllocateMemory(&Memory, STRING_SIZE, F_Strings); - // File.Source[1] = (char *)AllocateMemory(&Memory, STRING_SIZE, F_Strings); - // sprintf(File.Source[0], "../asset/b.jpg"); - // sprintf(File.Source[1], "../asset/24.mp4"); - // CreateLayerFromSource(&File, &State, &Memory, File.Source[0]); - // CreateLayerFromSource(&File, &State, &Memory, File.Source[1]); - // shm_unlink("/testl"); // int fd = shm_open("/testl", O_CREAT | O_EXCL | O_RDWR, // S_IRUSR | S_IWUSR); @@ -367,68 +347,6 @@ int main(int argc, char *argv[]) { // if (sem_init(&shmp->sem2, 1, 0) == -1) // Assert(0); - // CreateLayerFromSource(&File, &State, &Memory, "../asset/24.mp4"); - // project_layer *Layer1 = CreateDebugLayer(&File, &Memory, 9, 14); - // project_layer *Layer1 = CreateSolidLayer(&File, &Memory, 9, 13, V4(1.0, 1.0, 1.0, 1.0)); - // Layer1->x.CurrentValue.f = 7; - // Layer1->y.CurrentValue.f = 4; - // Layer1->StartFrame = 0; - // Layer1->EndFrame = File.EndFrame; - - // CreateDebugLayer(&File, &Memory, 12, 8); - // File.Layer[0]->Name = "debug"; - // File.Layer[0]->StartFrame = 0; - // File.Layer[0]->EndFrame = 65; - - // CreateLayer(&File, &Memory); - - // CreateRenderInfo(File.Layer[0], &Memory, File, image, "./asset/r.jpg"); - - // File.Layer[0]->Name = "Robot"; - // File.Layer[0]->x.CurrentValue.f = 200; - // File.Layer[0]->y.CurrentValue.f = 250; - // File.Layer[0]->scale.CurrentValue.f = 1.1; - // File.Layer[0]->opacity.CurrentValue.f = 1.0; - // File.Layer[0]->StartFrame = 0; - // File.Layer[0]->EndFrame = 65; - - // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 2, 100); - // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 60, 500); - - - // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 3, 300); - // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 8, 800); - // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 5, 500); - // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 6, 600); - // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, 7, 700); - - // File.Layer[0]->x.KeyframeBlock[0]->Keyframe[2].IsSelected = true; - // File.Layer[0]->x.KeyframeBlock[0]->Keyframe[3].IsSelected = true; - // File.Layer[0]->x.KeyframeBlock[0]->Keyframe[4].IsSelected = true; - // File.Layer[0]->x.KeyframeBlock[0]->Keyframe[6].IsSelected = true; - - // DeleteSelectedKeyframes(&File, &Memory); - - // for (int16 i = 0; i < 10; i++) { - // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, i*6 + 3, i*100); - // } - - // int16 kef = 2; - // for (int16 i = 0; i < kef; i++) { - // int16 p = kef - i; - // ManualKeyframeInsertF(&File.Layer[0]->x, &Memory, p*4, p*100); - // } - // &File.Layer[1]->x.KeyframeBlock[0]->Keyframe[2]; - // KeyframeDelete(&File.Layer[1]->x, &Memory, 2); - - // AddEffect(File.Layer[0], &Memory, 0); - // AddEffect(File.Layer[0], &Memory, 0); - - // for (int i = 0; i < 3; i++) - // CreateLayer(&File, &Memory); - - // DebugPrintMemoryUsage(Memory); - SDL_Init(SDL_INIT_VIDEO); Semaphore = SDL_CreateSemaphore(0); @@ -583,18 +501,24 @@ int main(int argc, char *argv[]) { // File.CurrentFrame = shmp->shared_framenumber; // } + // Right now IsRendering does nothing. I have it here if we want to + // completely detatch the rendering updater onto its own thread so the + // UI never lags. + if (State.UpdateFrame && !IsRendering) { MainFunction(0, &Memory, &State, &File, &Cache, &CompBuffer); State.UpdateFrame = 0; - OutputToViewport(&CompBuffer, &State, textureID); } #if THREADED + uint32 C = SDL_AtomicGet(&CompletedEntries); if (IsRendering) { - while (CompletedJobs != 16) { + while (C != 16) { + C = SDL_AtomicGet(&CompletedEntries); CheckQueue(RenderInfo, 8); } - if (CompletedJobs == 16) { + C = SDL_AtomicGet(&CompletedEntries); + if (C == 16) { Convert4x4Chunk(&CompBuffer, 1); EndRenderState(&State); glBindTexture(GL_TEXTURE_2D, textureID); @@ -608,6 +532,7 @@ int main(int argc, char *argv[]) { } } #else + OutputToViewport(&CompBuffer, &State, textureID); #endif ImGui::Render(); @@ -386,6 +386,7 @@ struct project_state bool32 IsRunning = 1; bool32 IsPlaying; bool32 DemoButton = 1; + bool32 GridButton = 1; uint16 NumberOfSelectedLayers; int16 MostRecentlySelectedLayer = -1; // convenience for the properties panel diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index 1190430..440694b 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -200,7 +200,7 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, pixel_buffer Com // { // Debug.ToggleRenders = true; // } - ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); + ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonMiddle); if (ImGui::BeginPopup("context")) { if (ImGui::MenuItem("Scalar", NULL, false, InstructionMode != scalar_only)) { InstructionMode = scalar_only; } if (ImGui::MenuItem("SSE", NULL, false, InstructionMode != sse_enabled)) { InstructionMode = sse_enabled; } @@ -295,6 +295,15 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ui *UI, ImG State->DemoButton = false; } } + if (State->GridButton) { + ImGui::SameLine(); + if (ImGui::Button("Generate square grid")) { + CreateGrid(File, Memory); + State->UpdateKeyframes = true; + State->UpdateFrame = true; + State->GridButton = false; + } + } for (int16 i = 0; i < File->NumberOfSources; i++) { ImGui::PushID(i); ImGui::InputText("##source", File->Source[i], STRING_SIZE); @@ -932,14 +941,16 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if (IsRectTouching(WindowMinAbs, WindowMaxAbs, io.MousePos, io.MousePos + 1)) { if (io.KeyCtrl && io.MouseWheel) { - real32 ZoomAmount = io.MouseWheel*8; + real32 ZoomAmount = io.MouseWheel*16; real32 LocalMousePos = ImGui::GetMousePos().x - TimelineStartingPos.x; real32 ZoomRatio = LocalMousePos / UI->TimelineZoom; UI->TimelineZoom += ZoomAmount; UI->ScrollXOffset -= ZoomAmount*ZoomRatio; + } else if (io.KeyShift && io.MouseWheel) { + UI->ScrollXOffset += io.MouseWheel*16; } else { - UI->ScrollXOffset += io.MouseWheelH*8; - UI->ScrollYOffset += io.MouseWheel*8; + UI->ScrollXOffset += io.MouseWheelH*16; + UI->ScrollYOffset += io.MouseWheel*16; } } @@ -987,6 +998,9 @@ ImGui_ProcessInputs(project_data *File, project_state *State, pixel_buffer *Comp if (ImGui::IsKeyPressed(ImGuiKey_A) && State->NumberOfSelectedLayers) TransformsInteract(File, State, UI, sliding_anchorpoint); + if (ImGui::IsKeyPressed(ImGuiKey_1)) + LoadTestFootage(File, State, Memory); + if (ImGui::IsKeyPressed(ImGuiKey_Delete)) { switch (State->RecentSelectionType) @@ -1010,11 +1024,6 @@ ImGui_ProcessInputs(project_data *File, project_state *State, pixel_buffer *Comp } #if DEBUG - if (ImGui::IsKeyPressed(ImGuiKey_Z)) - { - // SwitchBool(D); - // State->UpdateFrame = true; - } if (ImGui::IsKeyPressed(ImGuiKey_M)) { Debug.Markers[Debug.MarkerIndex] = File->CurrentFrame; diff --git a/prenderer.cpp b/prenderer.cpp index 356ecd7..72c2893 100644 --- a/prenderer.cpp +++ b/prenderer.cpp @@ -97,13 +97,6 @@ internal void EndRenderState(project_state *State) { IsRendering = false; - DEBUG_CycleCountEnd(3); - //TODO(fox): proper pixel accounting - // Debug.ExecutionAmount[4] += 1280*720; - - // printf("%lu %lu, avg %lu\n", Debug.EndCycleCount[3], Debug.ExecutionAmount[4], - // Debug.EndCycleCount[3] / Debug.ExecutionAmount[4]); - // Debug = {}; for (int16 i = 0; i < State->NumberOfLayersToRender; i++) { @@ -112,9 +105,9 @@ EndRenderState(project_state *State) State->NumberOfLayersToRender = 0; #if THREADED - __atomic_store_n(&EntryCount, 0, __ATOMIC_SEQ_CST); - __atomic_store_n(&NextEntryToDo, 0, __ATOMIC_SEQ_CST); - __atomic_store_n(&CompletedJobs, 0, __ATOMIC_SEQ_CST); + SDL_AtomicSet(&CurrentEntry, 0); + SDL_AtomicSet(&QueuedEntries, 0); + SDL_AtomicSet(&CompletedEntries, 0); #endif } @@ -138,9 +131,6 @@ QueueCurrentFrame(project_data *File, pixel_buffer *CompBuffer, project_state *S IsRendering = true; render_queue RenderInfo = {File, State, CompBuffer}; - uint16 TileWidth = (CompBuffer->Width - (CompBuffer->Width & 3)) / 4; - uint16 TileHeight = (CompBuffer->Height - (CompBuffer->Height & 3)) / 4; - for (int16 i = 0; i < File->NumberOfLayers; i++) { if (File->Layer[i]->StartFrame <= File->CurrentFrame && @@ -153,54 +143,30 @@ QueueCurrentFrame(project_data *File, pixel_buffer *CompBuffer, project_state *S } #if THREADED + + uint16 TileWidth = CompBuffer->Width / 4; + uint16 TileHeight = CompBuffer->Height / 4; + DEBUG_CycleCountStart(3); for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { // if (x == y) { rectangle RenderRegion = {TileWidth*x, TileHeight*y, TileWidth + TileWidth*x, TileHeight + TileHeight*y}; + if (RenderRegion.Max.x > CompBuffer->Width) + RenderRegion.Max.x = CompBuffer->Width; + if (RenderRegion.Max.y > CompBuffer->Height) + RenderRegion.Max.y = CompBuffer->Height; PushRect(RenderRegion); // } } } - // while (CompletedJobs != 16) { - // // CheckQueue(RenderInfo, 8); - // } - // DEBUG_CycleCountEnd(3); - // // //TODO(fox): proper pixel accounting - // Debug.ExecutionAmount[4] += 1280*720; - - // for (int16 i = 0; i < State->NumberOfLayersToRender; i++) - // { - // State->LayersToRender[i] = 0; - // } - - // State->NumberOfLayersToRender = 0; - #else - // DEBUG_CycleCountStart(3); rectangle RenderRegion = {0, 0, (int32)CompBuffer->Width, (int32)CompBuffer->Height}; RenderLayers(&RenderInfo, RenderRegion); - // DEBUG_CycleCountEnd(3); - // Debug.ExecutionAmount[4] += 1280*720; - - for (int16 i = 0; i < State->NumberOfLayersToRender; i++) - { - State->LayersToRender[i] = 0; - } - - State->NumberOfLayersToRender = 0; - #endif - - // printf("Completed jobs: %i\n", CompletedJobs); - // printf("Next: %i\n", NextEntryToDo); - // Assert(CompletedJobs == 4*4); - // __atomic_store_n(&EntryCount, 0, __ATOMIC_SEQ_CST); - // __atomic_store_n(&NextEntryToDo, 0, __ATOMIC_SEQ_CST); - // __atomic_store_n(&CompletedJobs, 0, __ATOMIC_SEQ_CST); } diff --git a/threading.cpp b/threading.cpp index 39e7b75..1b89136 100644 --- a/threading.cpp +++ b/threading.cpp @@ -1,26 +1,30 @@ internal void PushRect(rectangle RenderRegion) { - render_entry *Entry = Entries + EntryCount; + uint32 Q = SDL_AtomicGet(&QueuedEntries); + render_entry *Entry = Entries + Q; Entry->RenderRegion = RenderRegion; - __atomic_add_fetch(&EntryCount, 1, __ATOMIC_ACQ_REL); + SDL_AtomicAdd(&QueuedEntries, 1); SDL_SemPost(Semaphore); } +internal void +RenderLayers(render_queue *RenderInfo, rectangle RenderRegion); internal bool32 CheckQueue(render_queue RenderInfo, uint16 Index) { bool32 Result = 0; - uint32 OriginalEntry = NextEntryToDo; - if (NextEntryToDo < EntryCount) + uint32 Q = SDL_AtomicGet(&QueuedEntries); + uint32 C = SDL_AtomicGet(&CurrentEntry); + if (Q > C) { - if (__atomic_compare_exchange_n(&NextEntryToDo, &OriginalEntry, NextEntryToDo + 1, true, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE)) { - render_entry *Entry = Entries + OriginalEntry; + if (SDL_AtomicCAS(&CurrentEntry, C, C + 1)) { + render_entry *Entry = Entries + C; Assert(Entry->RenderRegion.Max.x != 0); - RenderLayers(RenderInfo, Entry->RenderRegion); + RenderLayers(&RenderInfo, Entry->RenderRegion); // printf("(FINISHED) Thread %i, region X%i Y%i\n", Index, Entry->RenderRegion.Min.x/240, Entry->RenderRegion.Min.y/135); - __atomic_add_fetch(&CompletedJobs, 1, __ATOMIC_ACQ_REL); + SDL_AtomicAdd(&CompletedEntries, 1); Result = 1; } } |