summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2022-08-03 16:57:07 -0400
committerFox Caminiti <fox@foxcam.net>2022-08-03 16:57:07 -0400
commit8875d0226f0d38a1e5ef946e56cd15810627f5ac (patch)
treeef7a8fa7b19f41faade33bdf5eaa24902c3b9f37
parentb26f27d9e3fd44ec5775accdc3666a339684be4c (diff)
caching introduced
-rw-r--r--createcalls.cpp90
-rw-r--r--defines.h3
-rw-r--r--effects.cpp33
-rw-r--r--ffmpeg_backend.cpp169
-rw-r--r--ffmpeg_backend.h25
-rw-r--r--functions.h6
-rw-r--r--main.cpp23
-rw-r--r--main.h76
-rw-r--r--memory.cpp19
-rw-r--r--my_imgui_internal_widgets.cpp222
-rw-r--r--my_imgui_widgets.cpp136
-rw-r--r--prenderer.cpp2
12 files changed, 407 insertions, 397 deletions
diff --git a/createcalls.cpp b/createcalls.cpp
index 42ab9b1..892be0a 100644
--- a/createcalls.cpp
+++ b/createcalls.cpp
@@ -55,7 +55,6 @@ Source_Generate(project_data *File, memory *Memory, char *Path)
if (!Found && AV_IsFileSupported(Path)) {
Source->SourceType = source_type_video;
- AV_CodecInfo_Init(Path, Source, Memory);
Found = true;
}
@@ -178,27 +177,96 @@ project_layer * Layer_Init(project_data *File, memory *Memory)
return File->Layer[a];
}
+static cached_bitmap *
+Cache_CheckBitmap(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, int32 TimelineFrame)
+{
+ memory_table *Table = &Memory->Slot[B_LoadedBitmaps];
+ int32 FrameToSeek = TimelineFrame - BitmapInfo->FrameOffset;
+ if (FrameToSeek < 0) { FrameToSeek = 0; };
+ for (int i = 0; i < Table->NumberOfPointers; i++) {
+ cached_bitmap *Bitmap = &Memory->Bitmap[i];
+ if (Bitmap->Frame == FrameToSeek && Bitmap->SourceOwner == Source) {
+ return Bitmap;
+ }
+ }
+ return 0;
+}
+
static void
-Layer_UpdateBitmap(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, int32 CurrentFrame) {
- AV_LoadVideoFrame(Source, BitmapInfo, Memory, CurrentFrame);
- // UpdateEffects(Layer, Memory);
+Layer_UpdateBitmap(project_layer *Layer, memory *Memory, int32 CurrentFrame) {
+ source *Source = Layer->Source;
+ layer_bitmap_info *BitmapInfo = &Layer->BitmapInfo;
+ cached_bitmap *Bitmap = Cache_CheckBitmap(Source, BitmapInfo, Memory, CurrentFrame);
+ if (Bitmap) {
+ uint16 Width = Source->Info.Width;
+ uint16 Height = Source->Info.Height;
+ uint16 BytesPerPixel = Source->Info.BytesPerPixel;
+ void *DestBuffer = BitmapInfo->BitmapBuffer;
+ Bitmap_ConvertPacking(Bitmap->Data, DestBuffer, Width, Height, BytesPerPixel, 0);
+ } else {
+ AV_LoadVideoFrame(Source, BitmapInfo, Memory, CurrentFrame);
+ }
+ for (int i = 0; i < Layer->NumberOfEffects; i++)
+ {
+ if (Layer->Effect[i]->IsActive)
+ Layer->Effect[i]->func(Source, BitmapInfo, Memory, Layer->Effect[i]->Property);
+ }
}
static void
-LoadTestFootage(project_data *File, project_state *State, memory *Memory)
+Layer_InitSource(project_layer *Layer, source *Source, memory *Memory)
{
- if (!Source_Generate(File, Memory, "../asset/24.mp4"))
- PostMsg(State, "File open fail...");
- source *Source = &File->Source[0];
- project_layer *Layer = Layer_Init(File, Memory);
Layer->Source = Source;
- AV_PacketInfo_Init(&Layer->BitmapInfo, Memory);
uint16 Height = Source->Info.Height;
uint16 Width = Source->Info.Width;
uint16 BytesPerPixel = Source->Info.BytesPerPixel;
- Layer_AllocateBitmap(Memory, Width, Height, BytesPerPixel);
+ Layer->BitmapInfo.BitmapBuffer = Layer_AllocateBitmap(Memory, Width, Height, BytesPerPixel);
+}
+static void
+Layer_PositionCenter(project_layer *Layer, uint16 Width, uint16 Height) {
+ Layer->x.CurrentValue.f = Width/2;
+ Layer->y.CurrentValue.f = Height/2;
+}
+
+static void
+Layer_CreateFromSource(project_data *File, project_state *State, memory *Memory, source *Source)
+{
+ project_layer *Layer = Layer_Init(File, Memory);
+ AV_Init(Source, &Layer->BitmapInfo, Memory);
+ Layer_InitSource(Layer, Source, Memory);
+ Layer_PositionCenter(Layer, File->Width, File->Height);
+ State->UpdateFrame = true;
+}
+
+static void
+LoadTestFootage(project_data *File, project_state *State, memory *Memory)
+{
+ if (!Source_Generate(File, Memory, "../asset/24.mp4"))
+ PostMsg(State, "File open fail...");
+ source *Source = &File->Source[0];
+ Layer_CreateFromSource(File, State, Memory, Source);
SelectLayer(File->Layer[0], State, 0);
+ AddEffect(File->Layer[0], Memory, 2);
+ property_channel *Property = &File->Layer[0]->x;
+ ManualKeyframeInsertF(Property, Memory, 1, 500);
+ ManualKeyframeInsertF(Property, Memory, 30, 800);
+ ManualKeyframeInsertF(Property, Memory, 15, 400);
+ ManualKeyframeInsertF(Property, Memory, 20, 100);
+ Property->IsToggled = true;
+ Property->IsGraphToggled = true;
+ Property->GraphLength = 150;
+ Property->GraphYOffset = (Property->GraphWindowHeight - Property->GraphLength)/2;
+
+ // Layer_CreateFromSource(File, State, Memory, Source);
+
+ if (!Source_Generate(File, Memory, "../asset/p.mp4"))
+ PostMsg(State, "File open fail...");
+ source *Source2 = &File->Source[1];
+ project_layer *Layer2 = Layer_Init(File, Memory);
+ AV_Init(Source2, &Layer2->BitmapInfo, Memory);
+ Layer_InitSource(Layer2, Source2, Memory);
+
// AddEffect(File->Layer[0], Memory, 2);
// 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));
diff --git a/defines.h b/defines.h
index ccca81c..d4a8788 100644
--- a/defines.h
+++ b/defines.h
@@ -32,9 +32,10 @@ typedef double real64;
#define MAX_EFFECTS 32
#define MAX_SOURCES 1024
#define MAX_PROPERTIES_PER_EFFECT 16
+// max keyframes on a single channel is 2048
#define MAX_KEYFRAME_BLOCKS 64
#define MAX_KEYFRAMES_PER_BLOCK 32
-#define STRING_SIZE 256
+#define STRING_SIZE 1024
#define MAX_SELECTED_PROPERTIES 16
diff --git a/effects.cpp b/effects.cpp
index d427778..6d27df1 100644
--- a/effects.cpp
+++ b/effects.cpp
@@ -1,5 +1,5 @@
static void
-DrawColor(pixel_buffer *Buffer, memory *Memory, property_channel Property[])
+DrawColor(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
{
v4 FloatColor = Property[0].CurrentValue.col;
blend_mode BlendMode = Property[1].CurrentValue.blendmode;
@@ -32,14 +32,14 @@ DrawColor(pixel_buffer *Buffer, memory *Memory, property_channel Property[])
__m256 B_Colx2 = _mm256_mul_ps(B_Col, Two);
__m256 B_ColInv = _mm256_set1_ps(1.0f - FloatColor.E[2]);
- for (int16 Y = 0; Y < Buffer->Height; Y += 2)
+ for (int16 Y = 0; Y < Source->Info.Height; Y += 2)
{
- for (int16 X = 0; X < Buffer->Width; X += 4)
+ for (int16 X = 0; X < Source->Info.Width; X += 4)
{
uint32 XLookup = (X >> 2)*16 + (X % 4);
- uint32 YLookup = (Y >> 2)*(Buffer->Width*4) + (Y % 4)*4;
+ uint32 YLookup = (Y >> 2)*(Source->Info.Width*4) + (Y % 4)*4;
uint32 PixelToSeek = XLookup + YLookup;
- uint8 *Pixel = (uint8 *)Buffer->EffectBuffer + PixelToSeek*Buffer->BytesPerPixel;
+ uint8 *Pixel = (uint8 *)BitmapInfo->BitmapBuffer + PixelToSeek*Source->Info.BytesPerPixel;
__m256i DestPixel = _mm256_loadu_si256((const __m256i *)Pixel);
// normalized values
@@ -178,14 +178,14 @@ DrawColor(pixel_buffer *Buffer, memory *Memory, property_channel Property[])
}
static void
-DrawGradient(pixel_buffer *Buffer, memory *Memory, property_channel Property[])
+DrawGradient(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
{
v4 StartColor = Property[0].CurrentValue.col;
v4 EndColor = Property[1].CurrentValue.col;
}
static void
-Levels(pixel_buffer *Buffer, memory *Memory, property_channel Property[])
+Levels(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[])
{
}
@@ -303,25 +303,6 @@ AddEffect(project_layer *Layer, memory *Memory, uint16 EffectListIndex)
Layer->NumberOfEffects++;
}
-static void
-CopyToBuffer(pixel_buffer *, uint16 asda = 0);
-
-static void
-UpdateEffects(project_layer *Layer, memory *Memory)
-{
- source_image *Source = (source_image *)Layer->RenderInfo;
- if (!Source->Raster.EffectBuffer) {
- Source->Raster.EffectBuffer = AllocateMemory(Memory, Source->Raster.Width * Source->Raster.Height * Source->Raster.BytesPerPixel,
- B_Scratch);
- }
- CopyToBuffer(&Source->Raster);
- for (int i = 0; i < Layer->NumberOfEffects; i++)
- {
- if (Layer->Effect[i]->IsActive)
- Layer->Effect[i]->func(&Source->Raster, Memory, Layer->Effect[i]->Property);
- }
-}
-
#if 0
static void
diff --git a/ffmpeg_backend.cpp b/ffmpeg_backend.cpp
index e97b4da..dfc1241 100644
--- a/ffmpeg_backend.cpp
+++ b/ffmpeg_backend.cpp
@@ -19,20 +19,20 @@ av_always_inline std::string av_err2string(int errnum) {
#include "ffmpeg_backend.h"
-bool32 AV_TryFrame(av_codec_info *AV, av_packet_info *AVLayer, int32 *err)
+bool32 AV_TryFrame(av_info *AV, int32 *err)
{
- *err = av_read_frame(AV->FileFormatContext, AVLayer->VideoPacket);
- if (*err >= 0 && AVLayer->VideoPacket->stream_index != AV->VideoStream->index) {
- av_packet_unref(AVLayer->VideoPacket);
+ *err = av_read_frame(AV->FileFormatContext, AV->VideoPacket);
+ if (*err >= 0 && AV->VideoPacket->stream_index != AV->VideoStream->index) {
+ av_packet_unref(AV->VideoPacket);
return 0;
}
if (*err < 0)
- *err = avcodec_send_packet(AV->VideoCodecContext, AVLayer->VideoPacket);
+ *err = avcodec_send_packet(AV->VideoCodecContext, AV->VideoPacket);
else {
- *err = avcodec_send_packet(AV->VideoCodecContext, AVLayer->VideoPacket);
+ *err = avcodec_send_packet(AV->VideoCodecContext, AV->VideoPacket);
}
- av_packet_unref(AVLayer->VideoPacket);
+ av_packet_unref(AV->VideoPacket);
if (*err < 0)
{
@@ -41,7 +41,7 @@ bool32 AV_TryFrame(av_codec_info *AV, av_packet_info *AVLayer, int32 *err)
}
while (*err >= 0) {
- *err = avcodec_receive_frame(AV->VideoCodecContext, AVLayer->VideoFrame);
+ *err = avcodec_receive_frame(AV->VideoCodecContext, AV->VideoFrame);
if (*err == AVERROR_EOF) {
} else if (*err == AVERROR(EAGAIN)) {
*err = 0;
@@ -54,6 +54,8 @@ bool32 AV_TryFrame(av_codec_info *AV, av_packet_info *AVLayer, int32 *err)
return 0;
}
+// TODO(fox): Could be combined into AV_Init once we have dealloc functions for
+// the AVInfo allocation.
bool32 AV_IsFileSupported(char *filename)
{
int32 err = 0;
@@ -84,10 +86,10 @@ bool32 AV_IsFileSupported(char *filename)
return 1;
}
-void AV_CodecInfo_Init(char *filename, source *Source, memory *Memory)
+void AV_Init(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory)
{
- Source->Info.AVCodecInfo = AllocateMemory(Memory, sizeof(av_codec_info), P_AVInfo);
- av_codec_info *AV = (av_codec_info *)Source->Info.AVCodecInfo;
+ BitmapInfo->AVInfo = AllocateMemory(Memory, sizeof(av_info), P_AVInfo);
+ av_info *AV = (av_info *)BitmapInfo->AVInfo;
*AV = {};
int32 err = 0;
@@ -96,17 +98,20 @@ void AV_CodecInfo_Init(char *filename, source *Source, memory *Memory)
// while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE)
// printf("%s\n", av_hwdevice_get_type_name(type));
- AV->FileFormatContext = avformat_alloc_context();
- err = avformat_open_input(&AV->FileFormatContext, filename, NULL, NULL);;
+ // The two calls below theoretically shouldn't fail since we already tested them in IsFileSupported.
+ AV->FileFormatContext = avformat_alloc_context();
+ err = avformat_open_input(&AV->FileFormatContext, Source->Path, NULL, NULL);;
if (err < 0) {
fprintf(stderr, "Libav error: (%s)\n", av_err2str(err));
+ Assert(0);
}
err = avformat_find_stream_info(AV->FileFormatContext, NULL);
if (err < 0) {
fprintf(stderr, "Libav error: (%s)\n", av_err2str(err));
+ Assert(0);
}
for (int i = 0; i < AV->FileFormatContext->nb_streams; i++)
@@ -154,12 +159,20 @@ void AV_CodecInfo_Init(char *filename, source *Source, memory *Memory)
if (err < 0) {
fprintf(stderr, "Libav error: (%s)\n", av_err2str(err));
}
-
avcodec_open2(AV->VideoCodecContext, AV->VideoCodec, NULL);
if (err < 0) {
fprintf(stderr, "Libav error: (%s)\n", av_err2str(err));
}
+ AV->VideoPacket = av_packet_alloc();
+ if (err < 0) {
+ fprintf(stderr, "Libav error: (%s)\n", av_err2str(err));
+ }
+ AV->VideoFrame = av_frame_alloc();
+ if (err < 0) {
+ fprintf(stderr, "Libav error: (%s)\n", av_err2str(err));
+ }
+
Source->Info.FPS = (real32)AV->VideoStream->r_frame_rate.num / AV->VideoStream->r_frame_rate.den;
Source->Info.Width = AV->VideoCodecContext->width;
Source->Info.Height = AV->VideoCodecContext->height;
@@ -167,7 +180,7 @@ void AV_CodecInfo_Init(char *filename, source *Source, memory *Memory)
-void AV_GetPTSAverage(av_codec_info *AV, av_packet_info *AVLayer, int32 *err)
+void AV_GetPTSAverage(source *Source, av_info *AV, int32 *err)
{
// TODO(fox): This PTS average isn't exact and causes an occasional
// frame skip. See libav remarks in forum for more details.
@@ -180,62 +193,34 @@ void AV_GetPTSAverage(av_codec_info *AV, av_packet_info *AVLayer, int32 *err)
int16 i = 0;
real32 AvgPTSPerSecond = 0;
for (;;) {
- if (AV_TryFrame(AV, AVLayer, err)) {
+ if (AV_TryFrame(AV, err)) {
if (i >= FPS * TestAmount) {
- AvgPTSPerSecond = (real32)AVLayer->VideoFrame->pts / TestAmount;
- printf("frame: %i, pts: %li\n", i, AVLayer->VideoFrame->pts);
+ AvgPTSPerSecond = (real32)AV->VideoFrame->pts / TestAmount;
+ printf("frame: %i, pts: %li\n", i, AV->VideoFrame->pts);
break;
}
i++;
- av_frame_unref(AVLayer->VideoFrame);
+ av_frame_unref(AV->VideoFrame);
}
}
- AV->AvgPTSPerFrame = (real32)AvgPTSPerSecond / (int32)(FPS + 0.5f);
- printf("Avg PTS per sec: %.06f, Avg PTS per frame: %.06f\n", AvgPTSPerSecond, AV->AvgPTSPerFrame);
+ Source->Info.AvgPTSPerFrame = (real32)AvgPTSPerSecond / (int32)(FPS + 0.5f);
+ printf("Avg PTS per sec: %.06f, Avg PTS per frame: %.06f\n", AvgPTSPerSecond, Source->Info.AvgPTSPerFrame);
av_seek_frame(AV->FileFormatContext, -1, 0, AVSEEK_FLAG_BACKWARD);
}
-
-void AV_PacketInfo_Init(layer_bitmap_info *BitmapInfo, memory *Memory)
-{
- BitmapInfo->AVPacketInfo = AllocateMemory(Memory, sizeof(av_packet_info), P_AVInfo);
- av_packet_info *AV = (av_packet_info *)BitmapInfo->AVPacketInfo;
- *AV = {};
- printf("%li", AV->PreviousPTS);
-
- int32 err = 0;
-
- AV->VideoPacket = av_packet_alloc();
- if (err < 0) {
- fprintf(stderr, "Libav error: (%s)\n", av_err2str(err));
- }
- AV->VideoFrame = av_frame_alloc();
- if (err < 0) {
- fprintf(stderr, "Libav error: (%s)\n", av_err2str(err));
- }
-}
-
-
-static void
-Convert4x4Chunk(pixel_buffer *Raster, uint8);
-static void
-ClearBuffer(pixel_buffer *Raster, void *);
-
bool32 AV_LoadVideoFrame(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, int32 TimelineFrame)
{
- av_codec_info *AV = (av_codec_info *)Source->Info.AVCodecInfo;
- av_packet_info *AVLayer = (av_packet_info *)BitmapInfo->AVPacketInfo;
-
+ av_info *AV = (av_info *)BitmapInfo->AVInfo;
int32 *CurrentlyRenderedFrame = &BitmapInfo->CurrentFrame;
int32 err = 0;
- if (!AV->AvgPTSPerFrame) {
- AV_GetPTSAverage(AV, AVLayer, &err);
+ if (!Source->Info.AvgPTSPerFrame) {
+ AV_GetPTSAverage(Source, AV, &err);
}
- Assert(AV->AvgPTSPerFrame);
+ Assert(Source->Info.AvgPTSPerFrame);
int p = 0;
int i = 0;
@@ -258,28 +243,28 @@ bool32 AV_LoadVideoFrame(source *Source, layer_bitmap_info *BitmapInfo, memory *
*CurrentlyRenderedFrame = FrameToSeek;
- int64 SeekPTS = (int64)(AV->AvgPTSPerFrame*FrameToSeek + 0.5f);
+ int64 SeekPTS = (int64)(Source->Info.AvgPTSPerFrame*FrameToSeek + 0.5f);
while (err >= 0) {
- if (AV_TryFrame(AV, AVLayer, &err)) {
+ if (AV_TryFrame(AV, &err)) {
// 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 && AVLayer->VideoFrame->pts != AV->VideoStream->start_time) {
- av_frame_unref(AVLayer->VideoFrame);
- printf("NON-START: avg: %li, real pts: %li", SeekPTS, AVLayer->VideoFrame->pts);
+ if (FrameToSeek == 0 && AV->VideoFrame->pts != AV->VideoStream->start_time) {
+ av_frame_unref(AV->VideoFrame);
+ printf("NON-START: avg: %li, real pts: %li", SeekPTS, AV->VideoFrame->pts);
continue;
}
- int64 Difference = AVLayer->VideoFrame->pts - SeekPTS;
- if (abs(Difference) < AV->AvgPTSPerFrame)
+ int64 Difference = AV->VideoFrame->pts - SeekPTS;
+ if (abs(Difference) < Source->Info.AvgPTSPerFrame)
{
- if (AVLayer->PreviousPTS == -1) {
- AVLayer->PreviousPTS = AVLayer->VideoFrame->pts;
- printf("avg: %li, real pts: %li, difference: %li\n", SeekPTS, AVLayer->VideoFrame->pts, Difference);
+ if (AV->PreviousPTS == -1) {
+ AV->PreviousPTS = AV->VideoFrame->pts;
+ printf("avg: %li, real pts: %li, difference: %li\n", SeekPTS, AV->VideoFrame->pts, Difference);
} else {
- printf("avg: %li, real pts: %li, difference: %li difference from last pts: %li\n", SeekPTS, AVLayer->VideoFrame->pts, AVLayer->VideoFrame->pts - SeekPTS, AVLayer->VideoFrame->pts - AVLayer->PreviousPTS);
- AVLayer->PreviousPTS = AVLayer->VideoFrame->pts;
+ printf("avg: %li, real pts: %li, difference: %li difference from last pts: %li\n", SeekPTS, AV->VideoFrame->pts, AV->VideoFrame->pts - SeekPTS, AV->VideoFrame->pts - AV->PreviousPTS);
+ AV->PreviousPTS = AV->VideoFrame->pts;
}
uint16 Width = Source->Info.Width;
@@ -287,31 +272,63 @@ bool32 AV_LoadVideoFrame(source *Source, layer_bitmap_info *BitmapInfo, memory *
uint16 BytesPerPixel = Source->Info.BytesPerPixel;
int32 Pitch = Width*BytesPerPixel;
- void *Buffer = AllocateMemory(Memory, Bitmap_CalcTotalBytes(Width, Height, BytesPerPixel), B_LoadedBitmaps);
+ // probably should rename this
+ memory_table *Table = &Memory->Slot[B_LoadedBitmaps];
+ uint64 Size = Bitmap_CalcTotalBytes(Width, Height, BytesPerPixel);
+ if (Table->CurrentPosition + Size > Table->Size) {
+ Table->CurrentPosition = 0;
+ Table->PointerIndex = 0;
+ }
+ cached_bitmap *Bitmap = &Memory->Bitmap[Table->PointerIndex];
+ if (Table->PointerIndex < Table->NumberOfPointers) {
+ bool32 Avail = false;
+ void *DataStart = Memory->Bitmap[Table->PointerIndex].Data;
+ while(!Avail) {
+ void *Data2 = Memory->Bitmap[Table->PointerIndex+1].Data;
+ uint64 BytesBetween = (uint8 *)Data2 - (uint8 *)DataStart;
+ if (BytesBetween < Size) {
+ Memory->Bitmap[Table->PointerIndex+1].SourceOwner = NULL;
+ Table->PointerIndex++;
+ } else {
+ Avail = true;
+ }
+ Table->NumberOfPointers--;
+ }
+ }
+ Table->NumberOfPointers++;
+ Bitmap->Data = AllocateMemory(Memory, Size, B_LoadedBitmaps);
+ if (!Bitmap->Data) {
+ Assert(0);
+ }
+ Bitmap->SourceOwner = Source;
+ Bitmap->Frame = FrameToSeek;
+ Bitmap->Index = Table->PointerIndex;
+ Table->PointerIndex++;
+ void *Buffer = Bitmap->Data;
int out_linesize[4] = { Pitch, Pitch, Pitch, Pitch };
uint8 *dst_data[4] = { (uint8 *)Buffer, (uint8 *)Buffer + Width*Height*BytesPerPixel,
(uint8 *)Buffer + Width*Height*BytesPerPixel*2, (uint8 *)Buffer + Width*Height*BytesPerPixel*3 };
// NOTE(fox): This function will be replaced in the future.
- AVLayer->RGBContext = sws_getContext(AVLayer->VideoFrame->width, AVLayer->VideoFrame->height, (AVPixelFormat)AVLayer->VideoFrame->format,
- AVLayer->VideoFrame->width, AVLayer->VideoFrame->height, AV_PIX_FMT_RGBA, SWS_BILINEAR,
+ AV->RGBContext = sws_getContext(AV->VideoFrame->width, AV->VideoFrame->height, (AVPixelFormat)AV->VideoFrame->format,
+ AV->VideoFrame->width, AV->VideoFrame->height, AV_PIX_FMT_RGBA, SWS_BILINEAR,
NULL, NULL, NULL);
- if(!AVLayer->RGBContext) {
+ if(!AV->RGBContext) {
printf("Libav error: SwsContext creation failed.");
}
- sws_scale(AVLayer->RGBContext, AVLayer->VideoFrame->data, AVLayer->VideoFrame->linesize, 0, AVLayer->VideoFrame->height,
+ sws_scale(AV->RGBContext, AV->VideoFrame->data, AV->VideoFrame->linesize, 0, AV->VideoFrame->height,
dst_data, out_linesize);
- av_frame_unref(AVLayer->VideoFrame);
+ av_frame_unref(AV->VideoFrame);
- if (!BitmapInfo->BitmapBuffer) {
- BitmapInfo->BitmapBuffer = AllocateMemory(Memory, Bitmap_CalcTotalBytes(Width, Height, BytesPerPixel), B_LayerBitmaps);
- }
+ Assert(BitmapInfo->BitmapBuffer);
void *DestBuffer = BitmapInfo->BitmapBuffer;
Bitmap_ConvertPacking(Buffer, DestBuffer, Width, Height, BytesPerPixel, 0);
+ // void *Buffer2 = AllocateMemory(Memory, Bitmap_CalcTotalBytes(Width, Height, BytesPerPixel), B_LoadedBitmaps);
+ // uint64 test = &Buffer2 - &Buffer;
// CopyToBuffer(Buffer, 1);
// Bitmap_Clear(Buffer, Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel);
@@ -320,9 +337,9 @@ bool32 AV_LoadVideoFrame(source *Source, layer_bitmap_info *BitmapInfo, memory *
else
{
// If this gets printed when not seeking, a frame has been skipped!
- printf("FRAME SKIP: avg: %li, real pts: %li, difference: %li\n", SeekPTS, AVLayer->VideoFrame->pts, Difference);
+ printf("FRAME SKIP: avg: %li, real pts: %li, difference: %li\n", SeekPTS, AV->VideoFrame->pts, Difference);
}
- av_frame_unref(AVLayer->VideoFrame);
+ av_frame_unref(AV->VideoFrame);
}
}
/*
diff --git a/ffmpeg_backend.h b/ffmpeg_backend.h
index d6a6a66..de73ff4 100644
--- a/ffmpeg_backend.h
+++ b/ffmpeg_backend.h
@@ -1,22 +1,23 @@
-struct av_codec_info {
- real32 AvgPTSPerFrame;
+// NOTE(fox): Even though each layer has its own completely isolated AV
+// instance, it appears two layers with the same file still share something.
+// When the layers aren't at the same position in time, the playhead of one
+// layer gets misaligned every few frames and causes a manual seek back to the
+// position. Different files don't exhibit this behavior.
- AVFormatContext *FileFormatContext;
- AVCodecParameters *VideoCodecParameters;
+struct av_info {
+ uint64 PreviousPTS = -1; // PTS value of the previous frame, used to check timings.
+
+ AVCodecParameters *VideoCodecParameters; // Used to supply info about the decoder.
const AVCodec* VideoCodec;
- const AVCodecHWConfig* VideoHWConfig;
+ // const AVCodecHWConfig* VideoHWConfig; // Haven't done enough research to know if HW decoding is already done by default or if we need these.
// AVPixelFormat HWPixFormat;
+ AVStream *VideoStream; // Which stream, or channel, the video is in. Holds FPS info and is used to verify that the decoded packet belongs to this stream.
+ AVFormatContext *FileFormatContext; // Umbrella for everything else, seems to contain the playhead state
AVCodecContext *VideoCodecContext;
- AVStream *VideoStream;
-};
-
-struct av_packet_info {
- uint64 PreviousPTS = -1; // PTS value of the previous frame, used to check timings.
-
AVPacket *VideoPacket;
AVFrame *VideoFrame;
SwsContext *RGBContext;
};
-static bool32 AV_TryFrame(av_codec_info *AV, av_packet_info *AVPacket, int32 *err); // Internal attempt to decode a frame. Typically run in a while loop until it returns true.
+static bool32 AV_TryFrame(av_info *AVPacket, int32 *err); // Internal attempt to decode a frame. Typically run in a while loop until it returns true.
diff --git a/functions.h b/functions.h
index af4f109..64c8dc9 100644
--- a/functions.h
+++ b/functions.h
@@ -1,7 +1,7 @@
// Buffer management
-static void * Layer_AllocateBuffer(memory *Memory, uint16 Width, uint16 Height, uint16 BytesPerPixel); //
+static void * Layer_AllocateBitmap(memory *Memory, uint16 Width, uint16 Height, uint16 BytesPerPixel); //
static project_layer * Layer_Init(project_data *File, memory *Memory); // Initializes a layer's name and properties. Add a source manually.
@@ -10,9 +10,11 @@ static uint16 Bitmap_CalcByteOffset(uint16 BytesPerPixel); // Returns the amount
static uint64 Bitmap_CalcTotalBytes(uint16 Width, uint16 Height, uint16 BytesPerPixel); // Returns the total amount of bytes a bitmap takes up.
static void Bitmap_ConvertPacking(void *Buffer, void *DestBuffer, uint16 Width, uint16 Height, uint16 BytesPerPixel, uint16 Which);
+static bool32 Source_Generate(project_data *File, memory *Memory, char *Path); // Fills out source info if the source is a supported file.
+
// Libav (ffmpeg) backend for decoding video
static bool32 AV_IsFileSupported(char *filename); // Tests whether a decoder is available for a given file.
-static void AV_CodecInfo_Init(char *filename, source *Source, memory *Memory); // Initializes all internal structs and calculates average PTS.
+static void AV_Init(char *filename, source *Source, memory *Memory); // Initializes all internal structs and calculates average PTS.
static bool32 AV_LoadVideoFrame(source *Source, memory *Memory, int32 TimelineFrame); // Loads video frame at TimelineFrame.
diff --git a/main.cpp b/main.cpp
index c6e129b..dc16f30 100644
--- a/main.cpp
+++ b/main.cpp
@@ -55,7 +55,7 @@ SDL_Thread *thread[8];
SDL_sem *Semaphore;
#include "memory.cpp"
-// #include "effects.cpp"
+#include "effects.cpp"
#include "keyframes.cpp"
#include "layer.cpp"
#include "strings.cpp"
@@ -88,8 +88,7 @@ MainFunction(main_sdl *Main, memory *Memory,
CalculateKeyframesLinearly(File->CurrentFrame, &Layer->Property[r]);
}
}
-
- Layer_UpdateBitmap(Layer->Source, &Layer->BitmapInfo, Memory, File->CurrentFrame);
+ Layer_UpdateBitmap(Layer, Memory, File->CurrentFrame);
}
State->UpdateKeyframes = false;
QueueCurrentFrame(File, CompBuffer, State);
@@ -215,17 +214,18 @@ int main(int argc, char *argv[]) {
memory Memory = {};
- InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, P_UIState, "UI state");
// TODO(fox): Make clean-up functions when these get deleted!
+
InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, P_AVInfo, "Image/video headers");
+ InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, P_SourceBitmapTable, "Source bitmap tables");
- InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_ProjectSettings, "Project settings");
- InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Layers, "Layers");
+ InitMemoryTable(&GlobalMemory, &Memory, 15 * 1024 * 1024, F_Layers, "Layers");
InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Effects, "Effects");
InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Keyframes, "Keyframe blocks");
InitMemoryTable(&GlobalMemory, &Memory, 10 * 1024 * 1024, F_Strings, "Strings");
- InitMemoryTable(&GlobalMemory, &Memory, (uint64)16 * 1024 * 1024, B_LayerBitmaps, "Layer buffer");
- InitMemoryTable(&GlobalMemory, &Memory, (uint64)1 * 1024 * 1024 * 1024, B_LoadedBitmaps, "Loaded bitmap buffer");
+
+ InitMemoryTable(&GlobalMemory, &Memory, (uint64)200 * 1024 * 1024, B_LayerBitmaps, "Layer buffer");
+ InitMemoryTable(&GlobalMemory, &Memory, (uint64)200 * 1024 * 1024, B_LoadedBitmaps, "Loaded bitmap buffer");
project_state State = {};
@@ -251,8 +251,9 @@ int main(int argc, char *argv[]) {
layer_bitmap_info BitmapInfo;
BitmapInfo.ToUpdate = 0;
BitmapInfo.FrameOffset = 2;
- av_packet_info BS = {};
+ av_info BS = {};
BS.PreviousPTS = 0;
+ effect as = {};
#endif
LoadTestFootage(&File, &State, &Memory);
@@ -432,8 +433,10 @@ int main(int argc, char *argv[]) {
ImGui_Timeline(&File, &State, &Memory, &UI, io);
#if DEBUG
- if (Debug.ToggleWindow)
+ if (Debug.ToggleWindow) {
ImGui::ShowDemoWindow();
+ ImGui_DebugMemoryViewer(&File, &Memory);
+ }
#endif
if (UI.TemporaryUpdateOverride) {
diff --git a/main.h b/main.h
index 691d915..0067c26 100644
--- a/main.h
+++ b/main.h
@@ -28,16 +28,14 @@ enum memory_table_list {
// P = persistent data, but not file-based
// B = cached data, often cleared
- F_ProjectSettings,
- // The majority bloat from these two are the properties.
+ P_AVInfo,
+ P_SourceBitmapTable,
+
F_Layers,
F_Effects,
F_Keyframes,
F_Strings,
- P_UIState,
- P_AVInfo,
-
B_LayerBitmaps,
B_LoadedBitmaps,
};
@@ -47,6 +45,8 @@ struct memory_table {
void *Address;
uint64 CurrentPosition;
uint64 Size;
+ uint32 NumberOfPointers;
+ uint32 PointerIndex;
};
struct global_memory {
@@ -55,12 +55,18 @@ struct global_memory {
uint64 Size;
};
-struct cached_bitmap_block;
+struct source;
+
+struct cached_bitmap {
+ source *SourceOwner; // Which source it belongs to. Currently used to dereference the bitmap.
+ void *Data; // Unpacked data loaded from the source file.
+ uint32 Frame; // What frame it is.
+ uint32 Index; // Index in memory.
+};
struct memory {
memory_table Slot[16];
- cached_bitmap_block *CacheBlock[256];
- uint16 NumberOfCachedBlocks;
+ cached_bitmap Bitmap[4096];
};
struct property_channel;
@@ -144,7 +150,7 @@ struct keyframe_block {
struct property_channel {
char *Name;
keyframe_block *KeyframeBlock[MAX_KEYFRAME_BLOCKS];
- uint16 SortedIndex[MAX_KEYFRAMES_PER_BLOCK * MAX_KEYFRAME_BLOCKS];
+ uint16 SortedIndex[MAX_KEYFRAME_BLOCKS * MAX_KEYFRAMES_PER_BLOCK];
uint16 NumberOfKeyframeBlocks;
uint16 NumberOfSelectedKeyframes;
uint16 NumberOfTotalKeyframes;
@@ -175,27 +181,6 @@ struct property_header
val MaxVal;
};
-struct pixel_buffer {};
-
-struct effect_header
-{
- char *Name;
- void (*func)(pixel_buffer *, memory *, property_channel []);
- uint16 NumberOfProperties;
- display_type DisplayType;
- property_header PropertyHeader[MAX_PROPERTIES_PER_EFFECT];
-};
-
-struct effect {
- char *Name;
- void (*func)(pixel_buffer *, memory *, property_channel []);
- uint16 NumberOfProperties;
- display_type DisplayType;
- property_channel Property[MAX_PROPERTIES_PER_EFFECT];
- bool32 UIIsCollapsed = 0;
- bool32 IsActive = 1;
-};
-
// Information about a particular file.
@@ -216,7 +201,7 @@ struct source_info {
// Video only
real32 FPS;
- void* AVCodecInfo; // Internal data for the video decoder library.
+ real32 AvgPTSPerFrame; // set by Libav
};
struct source {
@@ -227,12 +212,6 @@ struct source {
// Bitmaps from files are loaded into these temporary cache blocks.
-struct cached_bitmap_block {
- source *SourceOwner; // Which source the data belongs to.
- void *Data; // Unpacked data loaded from the source file.
- uint32 StartFrame;
- uint32 NumberOfCachedFrames;
-};
struct layer_bitmap_info {
// Image and video
@@ -242,7 +221,7 @@ struct layer_bitmap_info {
// Video only
int32 FrameOffset; // the "true" position of video layers, separate from StartFrame
int32 CurrentFrame = -1; // The last frame number rendered to the bitmap.
- void *AVPacketInfo; // Internal data containing current frame info
+ void *AVInfo; // Internal data containing current frame info
};
struct comp_buffer {
@@ -253,6 +232,26 @@ struct comp_buffer {
void *UnpackedBuffer;
};
+struct effect_header
+{
+ char *Name;
+ void (*func)(source *, layer_bitmap_info *, memory *, property_channel []);
+ uint16 NumberOfProperties;
+ display_type DisplayType;
+ property_header PropertyHeader[MAX_PROPERTIES_PER_EFFECT];
+};
+
+struct effect {
+ char *Name;
+ void (*func)(source *, layer_bitmap_info *, memory *, property_channel []);
+ uint16 NumberOfProperties;
+ display_type DisplayType;
+ property_channel Property[MAX_PROPERTIES_PER_EFFECT];
+ bool32 UIIsCollapsed = 0;
+ bool32 IsActive = 1;
+};
+
+
struct transform_info {
real32 XAxisPX;
@@ -366,7 +365,6 @@ enum transforms_hotkey_interact {
struct main_sdl
{
- // pixel_buffer Buffer;
SDL_Texture *Texture;
SDL_Event Event;
SDL_Window *Window;
diff --git a/memory.cpp b/memory.cpp
index 6aebdc3..fcd7627 100644
--- a/memory.cpp
+++ b/memory.cpp
@@ -2,7 +2,7 @@ static void
InitMemoryTable(global_memory *GlobalMemory, memory *Memory, uint64 Size, memory_table_list TableName, char *Name) {
memory_table *Table = &Memory->Slot[TableName];
Table->Name = Name;
- Table->Address = (uint64 *)GlobalMemory->Address + GlobalMemory->CurrentPosition;
+ Table->Address = (uint64 *)((uint8 *)GlobalMemory->Address + GlobalMemory->CurrentPosition);
Table->Size = Size;
GlobalMemory->CurrentPosition += Size;
}
@@ -11,8 +11,21 @@ static void*
AllocateMemory(memory *Memory, uint64 Size, memory_table_list TableName) {
void *Address;
memory_table *Table = &Memory->Slot[TableName];
- Assert(Table->CurrentPosition + Size < Table->Size);
- Address = (uint64 *)Table->Address + Table->CurrentPosition;
+ if (Table->CurrentPosition + Size > Table->Size) {
+ return NULL;
+ }
+ Address = (uint64 *)((uint8 *)Table->Address + Table->CurrentPosition);
Table->CurrentPosition += Size;
return Address;
}
+
+// Returns 0-1 range wherever Pointer is in relation to StartingPointer to Size*Amount.
+static real32
+Memory_NormalizedPosition(void *StartingPointer, uint32 Amount, uint32 Size, void *Pointer)
+{
+ real32 Result = 0;
+ uint64 TotalSize = Amount*Size;
+ uint64 PointerLocationSize = (uint8 *)Pointer - (uint8 *)StartingPointer;
+ Result = (real32)PointerLocationSize / (real32)TotalSize;
+ return Result;
+}
diff --git a/my_imgui_internal_widgets.cpp b/my_imgui_internal_widgets.cpp
index 5ff01ee..d8934d8 100644
--- a/my_imgui_internal_widgets.cpp
+++ b/my_imgui_internal_widgets.cpp
@@ -7,57 +7,14 @@
#include "imgui_internal.h"
// A modded version of ScalarSlider allowing for the minimum and maximum parts
-// of the slider to be draggable by two other buttons. p_data is from range -1
+// of the slider to be draggable by two other buttons. p_mid is from range -1
// to 1, and s_min and max are from 0-1.
-#if 0
-// bool ImGui::SliderLevels(const char* label, ImGuiDataType data_type, void* v, int components, const void* v_min, const void* v_max, const char* format, ImGuiSliderFlags flags)
-bool ImGui::SliderLevels(const char* label, void* p_data, const void* s_min, const void* s_max)
+bool ImGui::SliderLevels(const char* label, void* p_mid, void* p_left, void* p_right)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
- const float MidMin = -1;
- const float MidMax = 1;
- const void* mid_min = &SliderMin;
- const void* mid_max = &SliderMax;
- ImGuiDataType data_type = ImGuiDataType_Float;
- const char *format = "%f";
-
- ImVec2 picker_pos = window->DC.CursorPos;
-
- ImGuiContext& g = *GImGui;
- bool value_changed = false;
- BeginGroup();
- PushID(label);
- value_changed |= SliderScalar("", data_type, p_data, mid_min, mid_max, format, ImGuiSliderFlags_Logarithmic);
- SetCursorScreenPos(ImVec2(picker_pos.x + 20.0f, picker_pos.y));
- // PushItemWidth();
- value_changed |= SliderScalar("", data_type, p_data, p_min, p_max, format, ImGuiSliderFlags_Logarithmic);
- // PushMultiItemsWidths(components, CalcItemWidth());
- // size_t type_size = GDataTypeInfo[data_type].Size;
- // for (int i = 0; i < components; i++)
- // {
- // PushID(i);
- // if (i > 0)
- // SameLine(0, g.Style.ItemInnerSpacing.x);
- // value_changed |= SliderScalar("", data_type, v, v_min, v_max, format, flags);
- // PopID();
- // PopItemWidth();
- // v = (void*)((char*)v + type_size);
- // }
- PopID();
-
- EndGroup();
- return value_changed;
-}
-bool ImGui::SliderLevels(const char* label, void* p_data, void* s_left, void* s_right)
-{
- ImGuiSliderFlags flags = ImGuiSliderFlags_NoInput;
- ImGuiWindow* window = GetCurrentWindow();
- if (window->SkipItems)
- return false;
-
const float SliderMin = -1;
const float SliderMax = 1;
const float OtherMin = 0;
@@ -69,154 +26,53 @@ bool ImGui::SliderLevels(const char* label, void* p_data, void* s_left, void* s_
ImGuiDataType data_type = ImGuiDataType_Float;
const char *format = "%f";
+ ImGuiSliderFlags flags = ImGuiSliderFlags_NoInput;
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
+
+ // I'm not well-versed in exactly what ImGui's id system does, but I'm
+ // pretty sure it's one clickable object equals one ImGui ID.
const ImGuiID id = window->GetID(label);
- const ImGuiID id_mid = window->GetID("asdasbdsgd");
- const ImGuiID id_L = window->GetID("ppasd");
+ PushID(label);
+ PushID(1);
+ const ImGuiID id_L = window->GetID("");
+ PopID();
+ PopID();
const ImGuiID id_R = window->GetID("adsafb");
+ const ImGuiID id_mid = window->GetID("asdasbdsgd");
const float w = CalcItemWidth();
const ImVec2 label_size = CalcTextSize(label, NULL, true);
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
- // const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0;
- // ItemSize(total_bb, style.FramePadding.y);
- // if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0))
- // return false;
-
- const bool hovered = ItemHoverable(frame_bb, id_L);
-
- // NOTE(fox): Making bogus calls here to get these positions so we can only activate the one we want - replace with the lower-level call.
- // const ImGuiID id_bogus = window->GetID("ppp");
- // ImRect test_left;
- // SliderBehavior(frame_bb, id_bogus, data_type, s_left, o_min, o_max, format, ImGuiSliderFlags_NoInput, &test_left);
- // ImRect test_right;
- // SliderBehavior(frame_bb, id_bogus, data_type, s_right, o_min, o_max, format, ImGuiSliderFlags_NoInput, &test_right);
-
- const bool input_requested_by_tabbing = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
- const bool clicked = (hovered && g.IO.MouseClicked[0]);
- const bool make_active = (input_requested_by_tabbing || clicked || g.NavActivateId == id_L || g.NavActivateInputId == id_L);
- if (make_active)
- {
- SetActiveID(id_L, window);
- SetFocusID(id_L, window);
- FocusWindow(window);
- g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
- }
- /*
- else if (make_active && g.IO.MousePos.x > test_right.Min.x) {
- SetActiveID(id_R, window);
- SetFocusID(id_R, window);
- FocusWindow(window);
- g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
- } else if (make_active) {
- SetActiveID(id_mid, window);
- SetFocusID(id_mid, window);
- FocusWindow(window);
- g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
- }
- */
-
- // Draw frame
- const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
- RenderNavHighlight(frame_bb, id);
- RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
+ ItemSize(total_bb, style.FramePadding.y);
+ if (!ItemAdd(total_bb, id_L, &frame_bb, 0))
+ return false;
+ if (!ItemAdd(total_bb, id_R, &frame_bb, 0))
+ return false;
+ if (!ItemAdd(total_bb, id_mid, &frame_bb, 0))
+ return false;
// Slider behavior
- ImRect L_grab_bb;
- const bool value_changed = SliderBehavior(frame_bb, id_L, data_type, s_left, o_min, o_max, format, ImGuiSliderFlags_NoInput, &L_grab_bb);
+ ImRect grab_bb;
+ const bool value_changed = SliderBehavior(frame_bb, id_L, data_type, p_left, o_min, o_max, format, flags, &grab_bb);
if (value_changed)
MarkItemEdited(id_L);
- // Render grab
- if (L_grab_bb.Max.x > L_grab_bb.Min.x)
- window->DrawList->AddRectFilled(L_grab_bb.Min, L_grab_bb.Max, GetColorU32(g.ActiveId == id_L ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
-
-#if 0
- // Slider behavior
- ImRect R_grab_bb;
- const bool value_changed2 = SliderBehavior(frame_bb, id_R, data_type, s_right, o_min, o_max, format, ImGuiSliderFlags_NoInput, &R_grab_bb);
+ ImRect grab_bb2;
+ const bool value_changed2 = SliderBehavior(frame_bb, id_R, data_type, p_right, o_min, o_max, format, flags, &grab_bb2);
if (value_changed2)
MarkItemEdited(id_R);
- // Render grab
- if (R_grab_bb.Max.x > R_grab_bb.Min.x)
- window->DrawList->AddRectFilled(R_grab_bb.Min, R_grab_bb.Max, GetColorU32(g.ActiveId == id_R ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
-
- const ImRect range_bb(ImVec2(L_grab_bb.Min.x, frame_bb.Min.y), ImVec2(R_grab_bb.Min.x, frame_bb.Max.y));
+ const ImRect mid_bb(ImVec2(grab_bb.Max.x, frame_bb.Min.y), ImVec2(grab_bb2.Min.x, frame_bb.Max.y));
// Slider behavior
- ImRect grab_bb_mid;
- const bool value_changed_mid = SliderBehavior(range_bb, id_mid, data_type, p_data, p_min, p_max, format, flags | ImGuiSliderFlags_Logarithmic, &grab_bb_mid);
- // if (value_changed2)
- // MarkItemEdited(id_bogus);
-
- ImVec2 asda = ImVec2(0, 5);
- // // Render grab
- if (grab_bb_mid.Max.x > grab_bb_mid.Min.x)
- window->DrawList->AddRectFilled(grab_bb_mid.Min + asda, grab_bb_mid.Max + asda, GetColorU32(g.ActiveId == id_bogus ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
-#endif
- // Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
- char value_buf[64];
- const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
- if (g.LogEnabled)
- LogSetNextTextDecoration("{", "}");
- RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
-
- if (label_size.x > 0.0f)
- RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
-
- IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
- return value_changed;
-}
-#else
-bool ImGui::SliderLevels(const char* label, void* p_mid, void* p_left, void* p_right)
-{
- ImGuiWindow* window = GetCurrentWindow();
- if (window->SkipItems)
- return false;
-
- const float SliderMin = -1;
- const float SliderMax = 1;
- const float OtherMin = 0;
- const float OtherMax = 1;
- const void* p_min = &SliderMin;
- const void* p_max = &SliderMax;
- const void* o_min = &OtherMin;
- const void* o_max = &OtherMax;
- ImGuiDataType data_type = ImGuiDataType_Float;
- const char *format = "%f";
-
- ImGuiSliderFlags flags = ImGuiSliderFlags_NoInput;
- ImGuiContext& g = *GImGui;
- const ImGuiStyle& style = g.Style;
- const ImGuiID id = window->GetID(label);
- const ImGuiID idnull = window->GetID("asdas");
- const ImGuiID id_mid = window->GetID("asdasbdsgd");
- const ImGuiID id_L = window->GetID("ppasd");
- const ImGuiID id_R = window->GetID("adsafb");
- const float w = CalcItemWidth();
-
- const ImVec2 label_size = CalcTextSize(label, NULL, true);
- const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
- const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
-
- ImRect test_L_bb;
- SliderBehavior(frame_bb, idnull, data_type, p_left, o_min, o_max, format, flags, &test_L_bb);
- ImRect test_R_bb;
- SliderBehavior(frame_bb, idnull, data_type, p_right, o_min, o_max, format, flags, &test_R_bb);
-
- ItemSize(total_bb, style.FramePadding.y);
-
- if (!ItemAdd(total_bb, id_L, &frame_bb, 0))
- return false;
- if (!ItemAdd(total_bb, id_R, &frame_bb, 0))
- return false;
- if (!ItemAdd(total_bb, id_mid, &frame_bb, 0))
- return false;
+ ImRect grab_bb3;
+ const bool value_changed3 = SliderBehavior(mid_bb, id_mid, data_type, p_mid, p_min, p_max, format, flags, &grab_bb3);
+ if (value_changed3)
+ MarkItemEdited(id_mid);
const bool hovered = ItemHoverable(frame_bb, id);
@@ -226,10 +82,10 @@ bool ImGui::SliderLevels(const char* label, void* p_mid, void* p_left, void* p_r
if (make_active)
{
- if (g.IO.MousePos.x < test_L_bb.Max.x) {
+ if (g.IO.MousePos.x < grab_bb.Max.x) {
SetActiveID(id_L, window);
SetFocusID(id_L, window);
- } else if (g.IO.MousePos.x > test_R_bb.Min.x) {
+ } else if (g.IO.MousePos.x > grab_bb2.Min.x) {
SetActiveID(id_R, window);
SetFocusID(id_R, window);
} else {
@@ -246,33 +102,16 @@ bool ImGui::SliderLevels(const char* label, void* p_mid, void* p_left, void* p_r
RenderNavHighlight(frame_bb, id_L);
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
- // Slider behavior
- ImRect grab_bb;
- const bool value_changed = SliderBehavior(frame_bb, id_L, data_type, p_left, o_min, o_max, format, flags, &grab_bb);
- if (value_changed)
- MarkItemEdited(id_L);
// Render grab
if (grab_bb.Max.x > grab_bb.Min.x)
window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id_L ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
- // Slider behavior
- ImRect grab_bb2;
- const bool value_changed2 = SliderBehavior(frame_bb, id_R, data_type, p_right, o_min, o_max, format, flags, &grab_bb2);
- if (value_changed2)
- MarkItemEdited(id_R);
// Render grab
if (grab_bb2.Max.x > grab_bb2.Min.x)
window->DrawList->AddRectFilled(grab_bb2.Min, grab_bb2.Max, GetColorU32(g.ActiveId == id_R ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
- const ImRect mid_bb(ImVec2(grab_bb.Max.x, frame_bb.Min.y), ImVec2(grab_bb2.Min.x, frame_bb.Max.y));
-
- // Slider behavior
- ImRect grab_bb3;
- const bool value_changed3 = SliderBehavior(mid_bb, id_mid, data_type, p_mid, p_min, p_max, format, flags, &grab_bb3);
- if (value_changed3)
- MarkItemEdited(id_mid);
// Render grab
if (grab_bb3.Max.x > grab_bb3.Min.x)
@@ -291,4 +130,3 @@ bool ImGui::SliderLevels(const char* label, void* p_mid, void* p_left, void* p_r
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
return value_changed;
}
-#endif
diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp
index 1ee82e9..f93866a 100644
--- a/my_imgui_widgets.cpp
+++ b/my_imgui_widgets.cpp
@@ -71,6 +71,87 @@ ImGui_KeyframeDragging(project_data *File, project_state *State, ui *UI, propert
}
static void
+ImGui_DebugMemoryViewer(project_data *File, memory *Memory)
+{
+ ImGui::SetNextWindowSize(ImVec2(800, 200));
+ ImGui::Begin("memoryviewer");
+ ImVec2 ViewportMin = ImGui::GetCursorScreenPos();
+ ImVec2 ViewportScale = ImGui::GetContentRegionAvail();
+ ImVec2 ViewportMax = ImVec2(ViewportMin.x + ViewportScale.x, ViewportMin.y + ViewportScale.y);
+
+ memory_table *Table = &Memory->Slot[B_LoadedBitmaps];
+
+ real32 TotalMB = Table->Size/1024/1024;
+ real32 LineAmount = 50;
+ real32 IncrementMB = TotalMB / LineAmount;
+ real32 ScreenIncrement = ViewportScale.x / LineAmount;
+
+ real32 CubeHeight = ImGui::GetFontSize();
+ real32 TotalHeight = CubeHeight*4;
+
+ ImDrawList* draw_list = ImGui::GetWindowDrawList();
+ draw_list->AddRectFilled(ViewportMin, ViewportMax, IM_COL32(50, 50, 50, 255));
+
+ for (float x = 0; x < LineAmount; x++) {
+ uint32 LineColor = IM_COL32(200, 200, 200, 40);
+ ImVec2 Min = ImVec2(ViewportMin.x + ScreenIncrement * x, ViewportMin.y);
+ ImVec2 Max = ImVec2(Min.x + 2, ViewportMax.y);
+ draw_list->AddLine(Min, Max, LineColor);
+ }
+
+ for (uint32 i = 0; i < Table->NumberOfPointers; i++) {
+ if (Memory->Bitmap[i].SourceOwner) {
+ void *DataStart = Memory->Bitmap[i].Data;
+ void *NextDataStart;
+ int pp = 1;
+ for (;;) {
+ if (Memory->Bitmap[i+pp].SourceOwner) {
+ NextDataStart = Memory->Bitmap[i+pp].Data;
+ break;
+ }
+ pp++;
+ }
+ uint64 BytesBetween = (uint8 *)NextDataStart - (uint8 *)DataStart;
+ source *Source = Memory->Bitmap[i].SourceOwner;
+ real32 Pos = Memory_NormalizedPosition(&File->Source[0], File->NumberOfSources, sizeof(source), Source);
+
+ ImVec4 col = ImColor::HSV(Pos, 0.3, 0.6, 1.0f);
+ uint64 BitmapSize = Bitmap_CalcTotalBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel);
+ if (BitmapSize > BytesBetween) {
+ col = ImColor::HSV(Pos, 1.0, 1.0, 1.0f);
+ }
+
+ uint64 DataStart2 = (uint8 *)DataStart - (uint8 *)Table->Address;
+ real32 StartReal = ((real32)DataStart2/1024/1024);
+ ImVec2 Min = ImVec2(ViewportMin.x + (StartReal/IncrementMB * ScreenIncrement), ViewportMin.y + (ViewportScale.y / 2) - (TotalHeight / 2) + TotalHeight*Pos);
+ real32 SizeReal = ((real32)BitmapSize/1024/1024);
+ ImVec2 Size = ImVec2(SizeReal/IncrementMB * ScreenIncrement, CubeHeight);
+ ImGui::SetCursorScreenPos(Min);
+ ImGui::PushID(i);
+ ImGui::PushStyleColor(ImGuiCol_Button, col);
+ char buf2[256];
+ sprintf(buf2, "%i##mempos", Memory->Bitmap[i].Frame);
+ ImGui::Button(buf2, Size);
+ ImGui::PopStyleColor();
+ if (ImGui::IsItemHovered()) {
+ char buf[1024];
+ sprintf(buf, "Source owner: %s\nSize: %.02f MB\n Frame number: %i", Memory->Bitmap[i].SourceOwner->Path, SizeReal, Memory->Bitmap[i].Frame);
+ ImGui::BeginTooltip();
+ ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
+ ImGui::TextUnformatted(buf);
+ ImGui::PopTextWrapPos();
+ ImGui::EndTooltip();
+ }
+ ImGui::PopID();
+ ImVec2 Max = ImVec2(ViewportMax.x, Min.y + CubeHeight);
+ // draw_list->AddRectFilled(Min, Max, IM_COL32(200, 200, 200, 255));
+ }
+ }
+
+ ImGui::End();
+}
+
+static void
ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory)
{
if (State->MostRecentlySelectedLayer > -1) {
@@ -130,20 +211,10 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
ImGui::PopID();
}
} else if (Effect->DisplayType == levels) {
- ImGui::Button("asda");
- // bool ImGui::SliderScalarasda(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags)
- // static int8 p = 0;
- // static int8 m = 10;
- // static int8 c = 2;
- // ImGui::SliderScalarasda("slider s8 full", ImGuiDataType_S8, &c, &p, &m, "%d", ImGuiSliderFlags_None);
- static real32 p = 0;
- static real32 m = 1;
- static real32 c = 2;
- ImGui::SliderScalar("f2", ImGuiDataType_Float, &c, &p, &m, "%f", ImGuiSliderFlags_Logarithmic);
- static real32 Max = 0.8;
- static real32 Min = 0.25;
- static real32 Mid = 0; // NOTE(fox): "Neutral" is zero, negative one is full black, one is full white.
- ImGui::SliderLevels("f", &Mid, &Min, &Max);
+ real32 *Min = &Effect->Property[0].CurrentValue.f;
+ real32 *Mid = &Effect->Property[1].CurrentValue.f;
+ real32 *Max = &Effect->Property[2].CurrentValue.f;
+ ImGui::SliderLevels("f", Mid, Min, Max);
}
}
} else {
@@ -297,10 +368,7 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ui *UI, ImG
{
ImGui::Begin("Files");
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
- // if (ImGui::Button("Add source")) {
- // }
if (State->DemoButton) {
- ImGui::SameLine();
if (ImGui::Button("Generate demo scene")) {
// CreateDemoScene(File, Memory);
State->UpdateKeyframes = true;
@@ -317,12 +385,23 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ui *UI, ImG
State->GridButton = false;
}
}
- static char Input[1024];
- ImGui::InputText("##sourceinput", Input, STRING_SIZE);
- ImGui::SameLine();
- if (ImGui::Button("Create Layer")) {
- // AddSource(File, State, Memory, Input);
+ ImGui::Text("Sources:");
+ for (int i = 0; i < File->NumberOfSources; i++) {
+ ImGui::Text(File->Source[i].Path);
+ ImGui::OpenPopupOnItemClick("sourcecontext", ImGuiPopupFlags_MouseButtonRight);
+ if (ImGui::BeginPopup("sourcecontext")) {
+ if (ImGui::MenuItem("Create layer from source")) {
+ Layer_CreateFromSource(File, State, Memory, &File->Source[i]);
+ }
+ ImGui::EndPopup();
+ }
}
+ // static char Input[1024];
+ // ImGui::InputText("##sourceinput", Input, STRING_SIZE);
+ // ImGui::SameLine();
+ // if (ImGui::Button("Create Layer")) {
+ // // AddSource(File, State, Memory, Input);
+ // }
#if DEBUG
for (int i = 0; i < Debug.WatchedProperties; i++) {
if (Debug.DebugPropertyType[i] == d_float) {
@@ -340,7 +419,6 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ui *UI, ImG
static void
ImGui_EffectsPanel(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io)
{
-#if 0
ImGui::Begin("Effects list", NULL);
if (State->RerouteEffects) {
ImGui::SetKeyboardFocusHere();
@@ -390,7 +468,6 @@ ImGui_EffectsPanel(project_data *File, project_state *State, memory *Memory, ui
}
}
ImGui::End();
-#endif
}
@@ -467,9 +544,12 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
ImGui::BeginChild("Topbar", TopbarSize, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar);
+ ImGui::Text
+ /*
ImGui::Button("V", TopbarButtonSize); ImGui::SameLine();
ImGui::Button("V", TopbarButtonSize); ImGui::SameLine();
ImGui::Button("V", TopbarButtonSize); ImGui::SameLine();
+ */
ImGui::SetCursorScreenPos(PlayheadPos);
ImGui::Button("P", ButtonSize);
@@ -688,6 +768,14 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
}
ImGui_SlidingLayer(Layer, &UI->DraggingKeyframeThreshold, io.MouseDelta.x, UI->TimelineZoom, 2);
+ for (int a = Layer->StartFrame; a < Layer->EndFrame; a++) {
+ cached_bitmap *Bitmap = Cache_CheckBitmap(Layer->Source, &Layer->BitmapInfo, Memory, a);
+ if (Bitmap) {
+ ImVec2 MinPos = ImVec2(TimelineStartingPos.x + UI->TimelineZoom * a, ImGui::GetCursorScreenPos().y);
+ draw_list->AddRect(MinPos, ImVec2(MinPos.x + UI->TimelineZoom, MinPos.y + 2.0f), ImColor(0, 255, 0, 255));
+ }
+ }
+
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ItemSpacing.y * UI->KeyframeSpacing));
ImGui::SetCursorPosY(ImGui::GetCursorPos().y + (ItemSpacing.y * UI->KeyframeSpacing / 2));
diff --git a/prenderer.cpp b/prenderer.cpp
index 7ce738a..24b271c 100644
--- a/prenderer.cpp
+++ b/prenderer.cpp
@@ -3,7 +3,7 @@ static void
PushRect(rectangle RenderRegion);
static void
-RenderLayerNeon(project_layer *Layer, pixel_buffer *Buffer, rectangle RenderRegion);
+RenderLayerNeon(project_layer *Layer, comp_buffer *Buffer, rectangle RenderRegion);
static void
AVX2_RenderLayer(transform_info TransformInfo, comp_buffer *Buffer, rectangle RenderRegion);
static void