diff options
author | Fox Caminiti <fox@foxcam.net> | 2022-12-18 20:00:47 -0500 |
---|---|---|
committer | Fox Caminiti <fox@foxcam.net> | 2022-12-18 20:00:47 -0500 |
commit | 4854647d659f75ac6cf4575b61d1dcfd25865791 (patch) | |
tree | 3296bdfa30fa76688844755b37094753ea82d033 /src | |
parent | bedd6906eabdd513042d6a178d4dc56a3a41d1d3 (diff) |
lazy
Diffstat (limited to 'src')
-rw-r--r-- | src/createcalls.cpp | 34 | ||||
-rw-r--r-- | src/ffmpeg_backend.cpp | 41 | ||||
-rw-r--r-- | src/imgui_ui.cpp | 16 | ||||
-rw-r--r-- | src/imgui_ui_timeline.cpp | 28 | ||||
-rw-r--r-- | src/include/ffmpeg_backend.h | 2 | ||||
-rw-r--r-- | src/include/main.h | 8 | ||||
-rw-r--r-- | src/layer.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 90 | ||||
-rw-r--r-- | src/memory.cpp | 4 | ||||
-rw-r--r-- | src/sorted.cpp | 51 | ||||
-rw-r--r-- | src/undo.cpp | 4 |
11 files changed, 178 insertions, 102 deletions
diff --git a/src/createcalls.cpp b/src/createcalls.cpp index ee8888d..d3c7da4 100644 --- a/src/createcalls.cpp +++ b/src/createcalls.cpp @@ -63,7 +63,7 @@ IO_Save(project_data *File, project_state *State, memory *Memory, char *Filename void *CompressedLocation = Memory_PushScratch(Memory, FileSize); - uint64 CompressedSize = Data_Compress(Memory, File, FileSize, CompressedLocation, FileSize, 0); // Z_BEST_COMPRESSION); + uint64 CompressedSize = Data_Compress(Memory, File, FileSize, CompressedLocation, FileSize, Z_BEST_COMPRESSION); Memory_PopScratch(Memory, FileSize); @@ -117,7 +117,7 @@ Source_Generate_Blank(project_data *File, project_state *State, memory *Memory, static bool32 Source_IsFileSupported(char *Path, bool32 *IsVideo, bool32 *HasAudio) { AV_IsFileSupported(Path, IsVideo, HasAudio); - if (IsVideo || HasAudio) { + if (*IsVideo || *HasAudio) { return 1; } else { return stbi_info(Path, NULL, NULL, NULL); @@ -575,36 +575,6 @@ void File_DeselectAllKeyframes(project_data *File, project_state *State, memory } -void Layer_Evaluate_Display(project_state *State, memory *Memory, block_layer *Layer, - sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray, - sorted_layer_array *LayerArrayStart, sorted_comp_array *CompStart, sorted_layer_array *SortedLayerStart, - int i, real32 *Offset) -{ - int ExtraPad = 1; - sorted_property_array *InfoLocation = SortedPropertyStart + SortedLayerStart->SortedPropertyStart; - uint16 *ArrayLocation = SortedKeyframeArray + SortedLayerStart->SortedKeyframeStart; - int h = 0, c = 0, p = 0; - property_channel *Property = NULL; - block_effect *Effect = NULL; - while (Layer_LoopChannels(State, Memory, &InfoLocation, &ArrayLocation, Layer, &Property, &Effect, &h, &c, &p)) - { - if (Property->IsToggled) { - *Offset += 1 + ExtraPad; - ExtraPad = 0; - } - } - /* - if (Layer->Precomp_Toggled) { - Assert(Layer->IsPrecomp); - sorted_comp_array *Layer_SortedCompStart = &CompStart[Layer->Block_Source_Index]; - sorted_layer_array *Layer_SortedLayerStart = Sorted_GetLayerStart(LayerArrayStart, CompStart, Layer->Block_Source_Index); - sorted_layer_array *TopLayerEntry = &Layer_SortedLayerStart[0]; - sorted_layer_array *BottomLayerEntry = &Layer_SortedLayerStart[Layer_SortedCompStart->LayerCount - 1]; - *Offset += TopLayerEntry->SortedOffset - BottomLayerEntry->SortedOffset + 2; - } - */ -} - static void Project_Layer_Delete(project_data *File, project_state *State, memory *Memory) { diff --git a/src/ffmpeg_backend.cpp b/src/ffmpeg_backend.cpp index f4c4492..821afce 100644 --- a/src/ffmpeg_backend.cpp +++ b/src/ffmpeg_backend.cpp @@ -66,6 +66,9 @@ void AV_IsFileSupported(char *filename, bool32 *IsVideo, bool32 *HasAudio) AVFormatContext *temp = avformat_alloc_context(); err = avformat_open_input(&temp, filename, NULL, NULL);; + // if (*err == AVERROR_) { + // } + if (err < 0) { fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); avformat_free_context(temp); @@ -142,7 +145,7 @@ void AV_InitStream(av_stream_info *Stream) // The duration isn't always reported in AVStream, but seeking towards the end // and advancing until we hit EOF seems to be accurate. -void AV_GetDuration(av_info *AV, av_stream_info *Stream, uint64 *Duration, uint32 *FrameCount) +void AV_GetDuration(av_info *AV, av_stream_info *Stream, uint64 *Duration, real32 *SecondCount) { if (Stream->Stream->duration > 0) { *Duration = Stream->Stream->duration; @@ -163,12 +166,12 @@ void AV_GetDuration(av_info *AV, av_stream_info *Stream, uint64 *Duration, uint3 } *Duration = TestDuration; } + real32 FPS = (real32)AV->Video.Stream->r_frame_rate.num / AV->Video.Stream->r_frame_rate.den; if (Stream->Stream->nb_frames > 0) { - *FrameCount = Stream->Stream->nb_frames; + *SecondCount = Stream->Stream->nb_frames / FPS; } else if (AV->Video.CodecContext) { Assert(AV->FileFormatContext->duration > 0); - int TotalSeconds = AV->FileFormatContext->duration / 1000000LL; - *FrameCount = (int)(TotalSeconds * (real32)AV->Video.Stream->r_frame_rate.num / AV->Video.Stream->r_frame_rate.den); + *SecondCount = (real32)AV->FileFormatContext->duration / 1000000LL; } } @@ -239,15 +242,15 @@ void AV_Init(block_source *Source, av_info *AV, memory *Memory) Source->Width = AV->Video.CodecContext->width; Source->Height = AV->Video.CodecContext->height; Source->FPS = (real32)AV->Video.Stream->r_frame_rate.num / AV->Video.Stream->r_frame_rate.den; - AV_GetDuration(AV, &AV->Video, &AV->PTSDuration, &AV->FrameCount); + AV_GetDuration(AV, &AV->Video, &AV->PTSDuration, &AV->SecondCount); AV->LastFrameRendered = -1; av_seek_frame(AV->FileFormatContext, -1, 0, AVSEEK_FLAG_BACKWARD); - avcodec_flush_buffers(AV->Video.CodecContext); } else { - AV_GetDuration(AV, &AV->Audio, &AV->PTSDuration, &AV->FrameCount); + AV_GetDuration(AV, &AV->Audio, &AV->PTSDuration, &AV->SecondCount); av_seek_frame(AV->FileFormatContext, -1, 0, AVSEEK_FLAG_BACKWARD); - avcodec_flush_buffers(AV->Audio.CodecContext); } + avcodec_flush_buffers(AV->Video.CodecContext); + avcodec_flush_buffers(AV->Audio.CodecContext); }; uint32 AV_AudioTest(av_info *AV, void *Data, uint32 Size) @@ -301,15 +304,16 @@ uint32 AV_AudioTest(av_info *AV, void *Data, uint32 Size) return 0; } -void AV_SeekAudio(av_info *AV, uint32 FPS, int32 FrameToSeek) +void AV_SeekAudio(av_info *AV, real32 FPS, int32 FrameToSeek) { Assert(FrameToSeek > -1) int64 SeekSeconds = (int64)(FrameToSeek / (int32)(FPS + 0.5f) * AV_TIME_BASE); av_seek_frame(AV->FileFormatContext, -1, SeekSeconds, AVSEEK_FLAG_BACKWARD); - int64 SeekPTS = (int64)(((real64)FrameToSeek / AV->FrameCount) * AV->PTSDuration); - - //int64 AveragePTS = (AV->Video.CodecContext) ? AV->PTSDuration / AV->FrameCount : + /* + real32 TotalFrames = AV->SecondCount * FPS; + int64 SeekPTS = (int64)(((real64)FrameToSeek / TotalFrames) * AV->PTSDuration); + int64 AveragePTS = AV->PTSDuration / TotalFrames; int32 err = 0; bool32 EndOfFile = 0; @@ -319,16 +323,13 @@ void AV_SeekAudio(av_info *AV, uint32 FPS, int32 FrameToSeek) int a = 0; } } - AV_TryFrame(AV, AV->Video.CodecContext, &err, &EndOfFile); - - int64 AveragePTS = AV->PTSDuration / AV->FrameCount; while (err >= 0) { - if (AV_TryFrame(AV, AV->Video.CodecContext, &err, &EndOfFile, AV->Video.Index)) + if (AV_TryFrame(AV, AV->Audio.CodecContext, &err, &EndOfFile, AV->Audio.Index)) { // The first frame that gets loaded isn't always the actual // first frame, so we need to check until it's correct. - if (FrameToSeek == 0 && AV->Frame->pts < AV->Video.Stream->start_time) { + if (FrameToSeek == 0 && AV->Frame->pts < AV->Audio.Stream->start_time) { av_frame_unref(AV->Frame); // printf("NON-START: avg: %li, real pts: %li", SeekPTS, AV->VideoFrame->pts); continue; @@ -341,6 +342,7 @@ void AV_SeekAudio(av_info *AV, uint32 FPS, int32 FrameToSeek) } } } + */ } @@ -366,8 +368,9 @@ void AV_LoadVideoFrame(memory *Memory, block_source *Source, av_info *AV, int32 *LastFrameRendered = FrameToSeek; - int64 SeekPTS = (int64)(((real64)FrameToSeek / AV->FrameCount) * AV->PTSDuration); - int64 AveragePTS = AV->PTSDuration / AV->FrameCount; + real32 TotalFrames = AV->SecondCount * Source->FPS; + int64 SeekPTS = (int64)(((real64)FrameToSeek / TotalFrames) * AV->PTSDuration); + int64 AveragePTS = AV->PTSDuration / TotalFrames; bool32 EndOfFile = 0; while (err >= 0) { diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp index 612ee1a..5247716 100644 --- a/src/imgui_ui.cpp +++ b/src/imgui_ui.cpp @@ -489,6 +489,7 @@ ImGui_Viewport_TransformUI(project_data *File, project_state *State, memory *Mem State->Interact_Active = interact_type_none; State->Interact_Modifier = 0; State->UpdateFrame = true; + Memory->PurgeCache = true; } // Second condition so you don't have to reach for Enter. @@ -526,6 +527,7 @@ ImGui_Viewport_TransformUI(project_data *File, project_state *State, memory *Mem History_Entry_End(Memory); State->Interact_Active = interact_type_none; State->Interact_Modifier = 0; + State->UncommitedKeyframe = 1; State->UpdateFrame = true; } @@ -988,6 +990,10 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me State->Frame_Current = ((State->Frame_Current - 1) < 0) ? 0 : State->Frame_Current - 1; State->UpdateFrame = true; State->UpdateKeyframes = true; + if (State->UncommitedKeyframe) { + Memory->PurgeCache = true; + State->UncommitedKeyframe = false; + } } if (ImGui::IsKeyPressed(ImGuiKey_E)) { if (!io.KeyShift) { @@ -995,6 +1001,10 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me State->Frame_Current = ((State->Frame_Current + 1) >= MainComp->Frame_Count) ? 0 : State->Frame_Current + 1; State->UpdateFrame = true; State->UpdateKeyframes = true; + if (State->UncommitedKeyframe) { + Memory->PurgeCache = true; + State->UncommitedKeyframe = false; + } } else { State->Brush.EraseMode ^= 1; } @@ -1107,6 +1117,8 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me State->Interact_Active = interact_type_none; State->Interact_Modifier = 0; State->UpdateFrame = true; + State->UpdateKeyframes = true; + Memory->PurgeCache = true; } } if (ImGui::IsKeyPressed(ImGuiKey_Space) ) { @@ -1117,6 +1129,10 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me State->HotFramePerf = 1; State->PlayAudio = false; State->FramePlayingCount = 0; + if (State->UncommitedKeyframe) { + Memory->PurgeCache = true; + State->UncommitedKeyframe = false; + } switch (SDL_GetAudioStatus()) { case SDL_AUDIO_STOPPED: Assert(0); break; diff --git a/src/imgui_ui_timeline.cpp b/src/imgui_ui_timeline.cpp index 3a89641..42bb788 100644 --- a/src/imgui_ui_timeline.cpp +++ b/src/imgui_ui_timeline.cpp @@ -84,12 +84,15 @@ ImGui_Timeline_HorizontalIncrementDraw(project_state *State, ui *UI, ImDrawList int32 NewCurrent = (int32)(State->Interact_Offset[0] + (DragDelta.x / TimelineZoomSize.x * MainComp.Frame_Count) + 0.5); if (NewCurrent != State->Frame_Current) { State->Frame_Current = NewCurrent; + State->UpdateKeyframes = true; State->UpdateFrame = true; } } if (IsItemDeactivated) { State->Interact_Active = interact_type_none; State->Interact_Modifier = 0; + State->UpdateKeyframes = true; + State->UpdateFrame = true; } } @@ -417,7 +420,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem ImGui::PushID(CompIndex); - // NOTE(fox): Layer sorting pre-calculates UI positioning, so the order layers are drawn is arbitrary. + // NOTE(fox): Layer sorting pre-calculates UI positioning, so the order layers are drawn could be arbitrary. real32 DisplayOffset = 0; for (int i = SortedCompStart.LayerCount - 1; i >= 0; i--) { @@ -427,9 +430,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; - real32 Vertical_Offset = SortEntry.SortedOffset + DisplayOffset; - - Layer_Evaluate_Display(State, Memory, Layer, SortedPropertyStart, SortedKeyframeArray, SortedLayerArray, SortedCompArray, SortedLayerStart, i, &DisplayOffset); + real32 Vertical_Offset = SortEntry.SortedOffset + SortEntry.DisplayOffset; if (Layer->IsSelected) Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End); @@ -661,7 +662,12 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem } if (ImGui::IsItemDeactivated()) { - if (State->Interact_Active == interact_type_layer_move) { + if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + State->Interact_Active = interact_type_none; + State->Interact_Modifier = 0; + State->UpdateFrame = true; + Memory->PurgeCache = true; + } else if (State->Interact_Active == interact_type_layer_move) { History_Entry_Commit(Memory, "Move layers"); for (int i = 0; i < SortedCompStart.LayerCount; i++) { @@ -695,10 +701,10 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem { if (Property->IsToggled) { ImVec2 GraphMinPos = ImVec2(TimelineAbsolutePos.x, Layer_ScreenPos_Min.y + Layer_ScreenSize.y + (Layer_ScreenSize.y * Channel)); - ImVec2 GraphPos = GraphMinPos + ImVec2(0, Layer_ScreenSize.y); - ImVec2 GraphMinBounds = GraphMinPos + ImVec2(0, Layer_ScreenSize.y * 0.5); + ImVec2 GraphPos = GraphMinPos + ImVec2(0, Layer_ScreenSize.y / 2); + ImVec2 GraphMinBounds = GraphMinPos; ImVec2 GraphMaxBounds = GraphMinBounds + ImVec2(TimelineSizeWithBorder.x, Layer_ScreenSize.y); - uint32 col = (Channel % 2) ? IM_COL32(50, 50, 50, 255) : IM_COL32(50, 50, 50, 128); + uint32 col = (Channel % 2) ? IM_COL32(50, 50, 50, 255) : IM_COL32(70, 70, 70, 255); draw_list->AddRectFilled(GraphMinBounds, GraphMaxBounds, col); ImGui_Timeline_DrawKeySheet(File, State, Memory, UI, io, draw_list, Property, ArrayLocation, Increment, TimelineAbsolutePos, GraphPos, TimelineMoveSize, TimelineZoomSize, @@ -719,12 +725,8 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem sorted_comp_array Precomp_SortedCompStart = SortedCompArray[Layer->Block_Source_Index]; block_layer *Layer_Top = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Precomp_SortedLayerStart[Precomp_SortedCompStart.LayerCount - 1].Block_Layer_Index); - block_layer *Layer_Bottom = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Precomp_SortedLayerStart[0].Block_Layer_Index); real32 SmallestY = Layer_Top->Vertical_Offset; - real32 LargestY = Layer_Bottom->Vertical_Offset; - // Layer_Evaluate_Display(Layer_Top, SortedLayerArray, SortedCompArray, Precomp_SortedLayerStart, Precomp_SortedCompStart.LayerCount - 1, &SmallestY); - // Layer_Evaluate_Display(Layer_Bottom, SortedLayerArray, SortedCompArray, Precomp_SortedLayerStart, 0, &LargestY); - real32 PrecompHeight = LargestY - SmallestY + 2; + real32 PrecompHeight = Precomp_SortedCompStart.DisplaySize; ImVec2 MinClipPos = ImVec2(Layer_ScreenPos_Min.x, Layer_ScreenPos_Max.y); ImVec2 MaxClipPos = ImVec2(Layer_ScreenPos_Max.x, MinClipPos.y + (PrecompHeight * Increment.y * TimelineZoomSize.y)); diff --git a/src/include/ffmpeg_backend.h b/src/include/ffmpeg_backend.h index 717a33d..0c778f7 100644 --- a/src/include/ffmpeg_backend.h +++ b/src/include/ffmpeg_backend.h @@ -29,7 +29,7 @@ struct av_info { AVPacket *Packet; AVFrame *Frame; - uint32 FrameCount; + real32 SecondCount; uint64 PTSDuration; // likely not always 100% accurate SwsContext *RGBContext; diff --git a/src/include/main.h b/src/include/main.h index 3c7ff83..af92e31 100644 --- a/src/include/main.h +++ b/src/include/main.h @@ -157,12 +157,14 @@ struct sorted_comp_array { uint32 LayerCount; uint32 CurrentSortIndex; // Used intermediately in the sorting algorithm + real32 DisplaySize; }; struct sorted_layer_array { uint16 Block_Layer_Index; real32 SortedOffset; + real32 DisplayOffset; uint16 Sorted_Effect_Index[MAX_EFFECTS]; uint16 SortedPropertyStart; uint16 SortedKeyframeStart; @@ -384,6 +386,12 @@ struct project_state real32 Interact_Offset[12]; void *Interact_Address; + // NOTE(fox): We need to keep track of when the user changes the CurrentValue of a + // channel that has keyframes on it (i.e. CurrentValue will now evaluate to + // its previous value unless the user adds a new keyframe to the channel) + // so we can purge the cache if the user changes to a different frame. + int UncommitedKeyframe; + int32 Initializing = 3; int32 MsgTime; // currently in "frames" diff --git a/src/layer.cpp b/src/layer.cpp index f1ce0f4..41b52cc 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -166,7 +166,7 @@ Layer_ToggleChannel(project_data *File, memory *Memory, int32 a) while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected) + if (Layer->IsSelected == 1) Layer->Property[a].IsToggled ^= 1; } } diff --git a/src/main.cpp b/src/main.cpp index a3b3724..1b13405 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -270,11 +270,6 @@ AV_Retrieve(project_state *State, memory *Memory, uint32 SourceIndex) return AV; } -static void -File_RetrieveBitmap(project_data *File, project_state *State, memory *Memory, block_source *Source, int32 FrameToSeek, void *Bitmap, uint32 LayerIndex) -{ -} - 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, @@ -285,29 +280,57 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil void *CompBuffer = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry_Main->Block_StartIndex); uint64 Size = Comp->Width * Comp->Height * Comp->BytesPerPixel; - if (Entry_Main->IsCached) - return CompBuffer; - - Arbitrary_Zero((uint8 *)CompBuffer, Size); - - uint64 Comp_TimeStart = GetCPUTime(); - 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. + 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); - if (Layer->Frame_Start <= Frame_Current && - Layer->Frame_End > Frame_Current && Layer->IsVisible) + + int32 Frame_Start = Layer->Frame_Start; + int32 Frame_End = Layer->Frame_End; + if (Layer->IsSelected) + Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End); + int FrameToSeek = State->Frame_Current - Frame_Start; + + if (Frame_Start <= Frame_Current && + Frame_End > 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); } + } + } + + if (Entry_Main->IsCached) + return CompBuffer; + Arbitrary_Zero((uint8 *)CompBuffer, Size); + + uint64 Comp_TimeStart = GetCPUTime(); + + 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; + if (Layer->IsSelected) + Interact_Evaluate_Layer(Memory, State, Index_Physical, *SortedCompStart, SortedLayerStart, &Frame_Start, &Frame_End); + int FrameToSeek = State->Frame_Current - Frame_Start; + + if (Frame_Start <= Frame_Current && + Frame_End > Frame_Current && Layer->IsVisible) + { layer_bitmap_state *BitmapState = &State->Render.Bitmap[Index_Physical]; void *BitmapAddress = NULL; void *RenderAddress = NULL; // result of masking, effects, and intermediate paint stroke @@ -326,11 +349,12 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil State->AVCount++; } } - if (Source->HasAudio && !Source->HasVideo) { + if (Source->HasAudio) { Assert(Source->Type == source_type_file); if (State->AudioLayerIndex == -1) State->AudioLayerIndex = Index_Physical; - continue; + if (!Source->HasVideo) + continue; } // if ((State->PreviewSource != -1) && Layer->IsSelected) { // Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, State->PreviewSource); @@ -339,10 +363,9 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil if (Source->Type == source_type_principal || Source->Type == source_type_principal_temp) { BitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index, 0); } else { - cache_entry *CacheEntry = Memory_Cache_Search(State, Memory, cache_entry_type_source, Layer->Block_Source_Index, State->Frame_Current); + cache_entry *CacheEntry = Memory_Cache_Search(State, Memory, cache_entry_type_source, Layer->Block_Source_Index, FrameToSeek); BitmapAddress = Memory_Block_Bitmap_AddressAtIndex(Memory, CacheEntry->Block_StartIndex); if (!CacheEntry->IsCached) { - int FrameToSeek = State->Frame_Current - Layer->Frame_Start; AV_LoadVideoFrame(Memory, Source, AV, FrameToSeek, BitmapAddress); CacheEntry->IsCached = true; } @@ -411,6 +434,7 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, sorted_fil Memory_PopScratch(Memory, ScratchSize); } } + Entry_Main->CycleTime = GetCPUTime() - Comp_TimeStart; Entry_Main->IsCached = true; @@ -689,8 +713,13 @@ int main(int argc, char *argv[]) { // I'm loading the window positions from this convenient tool. ImGui by // default saves window position to an external .ini file, which can be // loaded from disk or memory. - // io.IniFilename = NULL; - // ImGui::LoadIniSettingsFromMemory(ImGuiPrefs); +#if DEBUG + io.IniFilename = NULL; + ImGui::LoadIniSettingsFromMemory(ImGuiPrefs); +#else + io.IniFilename = NULL; + ImGui::LoadIniSettingsFromMemory(ImGuiPrefs); +#endif // ImGui::SaveIniSettingsToDisk("imgui.ini"); ImGui::StyleColorsDark(); @@ -723,8 +752,9 @@ int main(int argc, char *argv[]) { sprintf(State->DummyName, "test"); File_Open(File, State, &Memory, State->DummyName); State->UpdateFrame = true; - State->MostRecentlySelectedLayer = 0; - uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/24.mp4"); + // State->MostRecentlySelectedLayer = 0; +#else + uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/yu.webm"); block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, SourceIndex); Source->IsSelected = true; Source_UICreateButton(File, State, &Memory); @@ -761,10 +791,7 @@ int main(int argc, char *argv[]) { // NextEffect->Index -= 1; // History_Entry_End(Memory); // } break; - case hotkey_newpaintlayer: - { - Project_PaintLayer_New(File, State, &Memory); - } break; + case hotkey_newpaintlayer: { Project_PaintLayer_New(File, State, &Memory); } break; case hotkey_newlayerfromsource: { Source_UICreateButton(File, State, &Memory); @@ -805,24 +832,23 @@ int main(int argc, char *argv[]) { State->UpdateKeyframes = true; } - if ((State->AudioLayerIndex != -1) && - (State->CachedFrameCount == (MainComp->Frame_End - MainComp->Frame_Start))) + bool32 FullyCached = (State->CachedFrameCount == (MainComp->Frame_End - MainComp->Frame_Start)); + if ((State->AudioLayerIndex != -1) && FullyCached) { block_layer *AudioLayer = (block_layer *)Memory_Block_AddressAtIndex(&Memory, F_Layers, State->AudioLayerIndex); - // block_source *AudioSource = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, SourceIndex); av_info *AV = AV_Retrieve(State, &Memory, AudioLayer->Block_Source_Index); int32 LayerPos = AudioLayer->Frame_Start; if (State->Frame_Current >= LayerPos) { if (State->Frame_Current == LayerPos) { SDL_ClearQueuedAudio(1); - AV_SeekAudio(AV, 60, 0); + AV_SeekAudio(AV, MainComp->FPS, 0); } if (State->HotFramePerf == 1) { SDL_ClearQueuedAudio(1); int32 FrameToSeek = State->Frame_Current - LayerPos; if (FrameToSeek > -1) - AV_SeekAudio(AV, 60, FrameToSeek); + AV_SeekAudio(AV, MainComp->FPS, FrameToSeek); } uint32 QueuedAudioSize = SDL_GetQueuedAudioSize(1); @@ -877,7 +903,7 @@ int main(int argc, char *argv[]) { Assert(Debug.ScratchState == 0); - if (State->IsPlaying && State->HotFramePerf > 1) { + if (State->IsPlaying && State->HotFramePerf > 1 && FullyCached) { uint64 RenderTime = SDL_GetPerformanceCounter() - State->HotFramePerf; real64 FrameMS = (1000.0f * (real64)RenderTime) / (real64)PerfFrequency; real64 TargetMS = (1000.0f / MainComp->FPS); diff --git a/src/memory.cpp b/src/memory.cpp index 05254cb..488f6bf 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -185,9 +185,9 @@ Memory_Cache_Purge(project_data *File, project_state *State, memory *Memory, int int c = 0; int count = Memory->EntryCount; while (count != 0) { - bool32 ExtraCheck = (SingleFrame == -1) ? 1 : EntryArray[c].TypeInfo == SingleFrame; + bool32 ExtraCheck = (SingleFrame == -1) ? 1 : EntryArray[c].TypeInfo_Sub == SingleFrame; if (EntryArray[c].Type == cache_entry_type_comp && - EntryArray[c].TypeInfo == File->PrincipalCompIndex && SingleFrame) { + EntryArray[c].TypeInfo == File->PrincipalCompIndex && ExtraCheck) { EntryArray[c].IsCached = 0; } c++; diff --git a/src/sorted.cpp b/src/sorted.cpp index 394c82f..9f2e135 100644 --- a/src/sorted.cpp +++ b/src/sorted.cpp @@ -73,6 +73,49 @@ void Property_SortAll(memory *Memory, project_state *State, property_channel *Pr } } +static real32 +Layer_Sort_DisplayOffset(project_state *State, memory *Memory, + sorted_property_array *SortedPropertyArray, uint16 *SortedKeyframeArray, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, + sorted_comp_array *SortedCompStart, sorted_layer_array *SortedLayerStart) +{ + int32 DisplayOffset = 0; + for (int i = SortedCompStart->LayerCount - 1; i >= 0; i--) + { + sorted_layer_array *SortEntry = &SortedLayerStart[i]; + SortEntry->DisplayOffset = DisplayOffset; + uint32 Index_Physical = SortEntry->Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + sorted_property_array *SortedPropertyStart = SortedPropertyArray + SortedLayerStart->SortedPropertyStart; + uint16 *SortedKeyframeStart = SortedKeyframeArray + SortedLayerStart->SortedKeyframeStart; + int h = 0, c = 0, p = 0; + property_channel *Property = NULL; + block_effect *Effect = NULL; + while (Layer_LoopChannels(State, Memory, &SortedPropertyStart, &SortedKeyframeStart, Layer, &Property, &Effect, &h, &c, &p)) + { + if (Property->IsToggled) { + DisplayOffset++; + } + } + if (Layer->Precomp_Toggled) { + Assert(Layer->IsPrecomp); + sorted_comp_array *InnerSortedCompStart = &SortedCompArray[Layer->Block_Source_Index]; + sorted_layer_array *InnerSortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, Layer->Block_Source_Index); + real32 InnerCompOffset = Layer_Sort_DisplayOffset(State, Memory, SortedPropertyArray, SortedKeyframeArray, SortedCompArray, SortedLayerArray, + InnerSortedCompStart, InnerSortedLayerStart); + InnerSortedCompStart->DisplaySize = InnerCompOffset; + DisplayOffset += InnerCompOffset; + } + } + if (SortedCompStart->LayerCount > 1) { + block_layer *Layer_Top = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayerStart[SortedCompStart->LayerCount - 1].Block_Layer_Index); + block_layer *Layer_Bottom = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayerStart[0].Block_Layer_Index); + real32 SmallestY = Layer_Top->Vertical_Offset; + real32 LargestY = Layer_Bottom->Vertical_Offset; + DisplayOffset = LargestY - SmallestY + 2 + DisplayOffset; + } + return DisplayOffset; +} static void Layer_Sort_CheckPrev(memory *Memory, int i, int Direction, sorted_layer_array *SortedLayerStart, sorted_comp_array SortedCompStart, int *EntriesPassed, sorted_layer_array *LayerEntry, bool32 AltMethod) @@ -324,6 +367,14 @@ File_Sort_Push(project_data *File, project_state *State, memory *Memory) Sorted.PropertyArray = (uint16 *)((uint8 *)Property_SortedArray + PropertyStartSize); LayerProperty_SortAll(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, Sorted.PropertyStart, Sorted.PropertyArray, File->Layer_Count, File->Comp_Count); + + sorted_comp_array *MainSortedCompStart = &Sorted.CompArray[File->PrincipalCompIndex]; + sorted_layer_array *MainSortedLayerStart = Sorted_GetLayerStart(Sorted.LayerArray, Sorted.CompArray, File->PrincipalCompIndex); + Layer_Sort_DisplayOffset(State, Memory, + Sorted.PropertyStart, Sorted.PropertyArray, + Sorted.CompArray, Sorted.LayerArray, + MainSortedCompStart, Sorted.LayerArray); + return Sorted; } diff --git a/src/undo.cpp b/src/undo.cpp index d55cedc..ec85530 100644 --- a/src/undo.cpp +++ b/src/undo.cpp @@ -75,7 +75,7 @@ void History_Action_DoSwapBitmap(memory *Memory, history_action *ActionPointer, Bitmap_SwapData((uint8 *)UncompressedTempBuffer, (uint8 *)Address_Data, FullSize, Action.Direction); // Then we recompress the old pixels and evaluate its size, and since the size can be different... - uint64 NewSize = Data_Compress(Memory, UncompressedTempBuffer, FullSize, CompressedTempBuffer, BytesForCompressedPart, 0); // Z_BEST_SPEED); + uint64 NewSize = Data_Compress(Memory, UncompressedTempBuffer, FullSize, CompressedTempBuffer, BytesForCompressedPart, Z_BEST_SPEED); // we have to shift the undo stack. if (NewSize != CompressedSize) { @@ -254,7 +254,7 @@ static void History_Action_Add(memory *Memory, history_action ActionData, void * // history tree as the destination. // ShiftAmount is also being used to save the uncompressed size. uint32 BytesForCompressedPart = (uint32)100 * 1024 * 1024; - Action->Size = Data_Compress(Memory, Address_Data, Action->ShiftAmount, Address_HistoryTree, BytesForCompressedPart, 0); // Z_BEST_SPEED); + Action->Size = Data_Compress(Memory, Address_Data, Action->ShiftAmount, Address_HistoryTree, BytesForCompressedPart, Z_BEST_SPEED); } else if (Action->Type == action_type_shift) { |