summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2022-12-18 20:00:47 -0500
committerFox Caminiti <fox@foxcam.net>2022-12-18 20:00:47 -0500
commit4854647d659f75ac6cf4575b61d1dcfd25865791 (patch)
tree3296bdfa30fa76688844755b37094753ea82d033 /src
parentbedd6906eabdd513042d6a178d4dc56a3a41d1d3 (diff)
lazy
Diffstat (limited to 'src')
-rw-r--r--src/createcalls.cpp34
-rw-r--r--src/ffmpeg_backend.cpp41
-rw-r--r--src/imgui_ui.cpp16
-rw-r--r--src/imgui_ui_timeline.cpp28
-rw-r--r--src/include/ffmpeg_backend.h2
-rw-r--r--src/include/main.h8
-rw-r--r--src/layer.cpp2
-rw-r--r--src/main.cpp90
-rw-r--r--src/memory.cpp4
-rw-r--r--src/sorted.cpp51
-rw-r--r--src/undo.cpp4
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)
{