summaryrefslogtreecommitdiff
path: root/createcalls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'createcalls.cpp')
-rw-r--r--createcalls.cpp338
1 files changed, 239 insertions, 99 deletions
diff --git a/createcalls.cpp b/createcalls.cpp
index 912917f..4be6b45 100644
--- a/createcalls.cpp
+++ b/createcalls.cpp
@@ -102,14 +102,15 @@ Source_Generate_Blank(project_data *File, project_state *State, memory *Memory,
Assert(File->Source_Count < MAX_SOURCES);
uint16 Index = Memory_Block_AllocateNew(Memory, F_Sources);
block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Index, 0);
+ History_Action_Block_Swap(Memory, F_Sources, Source);
Source->Occupied = 1;
Source->Width = Width;
Source->Height = Height;
- Source->BytesPerPixel= BytesPerPixel;
+ Source->BytesPerPixel = BytesPerPixel;
Source->Type = source_type_principal;
Source->Bitmap_Index = Memory_Block_PrincipalBitmap_AllocateNew(File, State, Memory);
Source->Path_String_Index = String_AddToFile(Memory, "test");
- // History_Action_Swap(Memory, F_File, sizeof(File->Source_Count), &File->Source_Count);
+ History_Action_Swap(Memory, F_File, sizeof(File->Source_Count), &File->Source_Count);
File->Source_Count++;
return Index;
}
@@ -204,15 +205,15 @@ Bezier_EvaluateValue(project_state *State, bezier_point *PointAddress, v2 *Pos,
}
}
-
+// TODO(fox): Test multiple keyframe blocks!
static void
Bezier_Add(memory *Memory, memory_table_list TableName, property_channel *Property, bezier_point PointData, uint16 *ArrayLocation)
{
if (!Property->Block_Bezier_Count) {
+ Assert(Property->Keyframe_Count < MAX_KEYFRAMES_PER_BLOCK);
Property->Block_Bezier_Index[0] = Memory_Block_AllocateNew(Memory, F_Bezier);
block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0], 0);
Bezier->Occupied = true;
- // NOTE(fox): Effects will change this!
History_Action_Swap(Memory, TableName, sizeof(Property->Block_Bezier_Count), &Property->Block_Bezier_Count);
Property->Block_Bezier_Count++;
}
@@ -320,6 +321,8 @@ Effect_Init(project_state *State, memory *Memory, uint32 EffectEntryIndex, int E
{
uint16 EffectAddressIndex = Memory_Block_AllocateNew(Memory, F_Effects);
block_effect *Effect = (block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, EffectAddressIndex, 0);
+ History_Action_Block_Swap(Memory, F_Effects, Effect);
+ *Effect = {};
Effect->Occupied = true;
header_effect *EffectHeader = &State->Effect[EffectEntryIndex];
String_Copy(Effect->ID, EffectHeader->ID, 8);
@@ -328,6 +331,7 @@ Effect_Init(project_state *State, memory *Memory, uint32 EffectEntryIndex, int E
for (int e = 0; e < EffectHeader->Property_Count; e++) {
Effect->Block_Property_Index[e] = Memory_Block_AllocateNew(Memory, F_Properties);
property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[e], 0);
+ History_Action_Block_Swap(Memory, F_Properties, Property);
Property->Occupied = true;
header_property PropertyHeader = State->Property[EffectHeader->PropertyStartIndex + e];
Property->Identifier = -1;
@@ -341,15 +345,21 @@ Effect_Init(project_state *State, memory *Memory, uint32 EffectEntryIndex, int E
static void
Effect_Add(project_data *File, project_state *State, memory *Memory, uint32 EffectEntryIndex)
{
+ History_Entry_Commit(Memory, "Add effect");
int h = 0, c = 0, i = 0;
+ int Selected = 0;
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) {
Layer->Block_Effect_Index[Layer->Block_Effect_Count] = Effect_Init(State, Memory, EffectEntryIndex, Layer->Block_Effect_Count);
+ History_Action_Swap(Memory, F_File, sizeof(Layer->Block_Effect_Count), &Layer->Block_Effect_Count);
Layer->Block_Effect_Count++;
+ Selected++;
}
}
+ History_Entry_End(Memory);
+ Assert(Selected);
}
static void
@@ -793,13 +803,13 @@ Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory,
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, State->Brush.LayerToPaint_Index);
layer_transforms T = Layer_GetTransforms(Layer);
Layer_GetDimensions(Memory, Layer, &InnerWidth, &InnerHeight);
- PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, State->TempZoomRatio);
+ PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, PrincipalCompUV);
} else {
for (int i = 1; i <= Recursions; i++) {
block_layer *InnerLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, RecursionIdx[i]);
layer_transforms T = Layer_GetTransforms(InnerLayer);
Layer_GetDimensions(Memory, InnerLayer, &InnerWidth, &InnerHeight);
- PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, State->TempZoomRatio);
+ PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, PrincipalCompUV);
OuterWidth = InnerWidth;
OuterHeight = InnerHeight;
}
@@ -971,10 +981,6 @@ void Property_SortAll(memory *Memory, project_state *State, property_channel *Pr
v2 PointPos[3];
bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, i);
- if (PointAddress->IsSelected) {
- PropertyInfo->IsGraphSelected = true;
- }
-
Bezier_EvaluateValue(State, PointAddress, PointPos);
if (MinY > PointAddress->Pos[0].y) {
@@ -1316,17 +1322,73 @@ void File_Sort_Pop(memory *Memory, uint64 Layer_SortSize, uint64 Property_SortSi
Memory_PopScratch(Memory, Layer_SortSize);
}
-
+// lots of cleanup...
static void
-Layer_Delete(project_data *File, memory *Memory, uint32 Index)
+Layer_Delete(project_data *File, project_state *State, memory *Memory, uint32 Index)
{
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index);
History_Action_Block_Swap(Memory, F_Layers, Layer);
Layer->Occupied = 0;
+
+ block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index, 0);
+ History_Action_Block_Swap(Memory, F_Strings, String);
+ String->Occupied = 0;
+
+ for (int i = 0; i < Layer->Block_Effect_Count; i++) {
+ block_effect *Effect = (block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, Layer->Block_Effect_Index[i]);
+ header_effect *EffectHeader = Effect_EntryFromID(State, Effect->ID);
+ for (int h = 0; h < EffectHeader->Property_Count; h++) {
+ header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + h];
+ property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[h]);
+ if (Property->Block_Bezier_Count) {
+ block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[i], 0);
+ History_Action_Block_Swap(Memory, F_Bezier, Bezier);
+ Bezier->Occupied = 0;
+ }
+ History_Action_Block_Swap(Memory, F_Properties, Property);
+ Property->Occupied = 0;
+ }
+ History_Action_Block_Swap(Memory, F_Effects, Effect);
+ Effect->Occupied = 0;
+ }
History_Action_Swap(Memory, F_File, sizeof(File->Layer_Count), &File->Layer_Count);
File->Layer_Count--;
}
+static void
+Project_Layer_Delete(project_data *File, project_state *State, memory *Memory)
+{
+ bool32 CommitAction = 0;
+ int h = 0, c = 0, i = 0;
+ int LayerCount = File->Layer_Count;
+ while (Block_Loop(Memory, F_Layers, LayerCount, &h, &c, &i)) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (Layer->IsSelected) {
+ if (!CommitAction) {
+ History_Entry_Commit(Memory, "Delete layer");
+ CommitAction = 1;
+ }
+ Layer_Delete(File, State, Memory, i);
+ }
+ }
+ if (CommitAction) {
+ History_Entry_End(Memory);
+ State->UpdateFrame = true;
+ State->MostRecentlySelectedLayer = -1;
+ }
+}
+
+static bool32
+Property_IsGraphSelected(memory *Memory, property_channel *Property, uint16 *ArrayLocation)
+{
+ for (int p = 0; p < Property->Keyframe_Count; p++) {
+ int k = ArrayLocation[p];
+ bezier_point *Point = Bezier_LookupAddress(Memory, Property, k);
+ if (Point->IsSelected)
+ return 1;
+ }
+ return 0;
+}
block_layer * Layer_Init(project_data *File, memory *Memory)
{
@@ -1342,6 +1404,7 @@ block_layer * Layer_Init(project_data *File, memory *Memory)
Layer->Block_String_Index = Memory_Block_AllocateNew(Memory, F_Strings);
block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index, 0);
sprintf(String->Char, "Layer %i", File->Layer_Count + 1); // CSbros...
+ History_Action_Swap(Memory, F_File, sizeof(String->Occupied), &String->Occupied);
String->Occupied = 1;
Layer->x = Property_InitFloat(0.0f, 1.0f);
@@ -1361,19 +1424,52 @@ block_layer * Layer_Init(project_data *File, memory *Memory)
return Layer;
}
-void Source_UICreateButton(project_data *File, project_state *State, memory *Memory,
- sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
+static int
+Layer_GetTopOffset(project_data *File, memory *Memory)
{
- block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
- sorted_comp_info *SortedCompInfo = &SortedCompArray[File->PrincipalCompIndex];
- int32 TopOffset;
- if (!File->Layer_Count) {
- TopOffset = 11;
+ int TopOffset = 9999;
+ int h = 0, c = 0, i = 0;
+ 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->Block_Composition_Index == File->PrincipalCompIndex) {
+ TopOffset = (Layer->Vertical_Offset < TopOffset) ? Layer->Vertical_Offset : TopOffset;
+ }
+ }
+ return TopOffset;
+}
+
+static void
+Project_PaintLayer_New(project_data *File, project_state *State, memory *Memory)
+{
+ int TopOffset = Layer_GetTopOffset(File, Memory);
+ block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
+ Arbitrary_Zero((uint8 *)State->Brush.TransientBitmap, 2048*2048*4);
+ State->Interact_Active = interact_type_brush;
+ Layer_DeselectAll(File, State, Memory);
+ History_Entry_Commit(Memory, "Paint new layer");
+ uint16 i = Source_Generate_Blank(File, State, Memory, MainComp->Width, MainComp->Height, MainComp->BytesPerPixel);
+ block_layer *Layer = Layer_Init(File, Memory);
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ State->Brush.LayerToPaint_Index = Memory_Block_LazyIndexAtAddress(Memory, F_Layers, (void *)Layer);
+ Layer->Block_Source_Index = i;
+ Layer->x.CurrentValue = MainComp->Width / 2;
+ Layer->y.CurrentValue = MainComp->Height / 2;
+ if (File->Layer_Count == 1) {
+ Layer->Vertical_Offset = 11 - 1;
} else {
- sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex);
- block_layer *TopLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayerInfo[SortedCompInfo->LayerCount - 1].Block_Layer_Index);
- TopOffset = TopLayer->Vertical_Offset;
+ Layer->Vertical_Offset = TopOffset - 1;
}
+ Layer->Frame_Start = MainComp->Frame_Start;
+ Layer->Frame_End = MainComp->Frame_End;
+ Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, Layer));
+ History_Entry_End(Memory);
+ State->UpdateFrame = true;
+}
+
+void Source_UICreateButton(project_data *File, project_state *State, memory *Memory)
+{
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
+ int TopOffset = Layer_GetTopOffset(File, Memory);
bool32 CommitAction = 0;
int h = 0, c = 0, i = 0;
while (Block_Loop(Memory, F_Sources, File->Source_Count, &h, &c, &i)) {
@@ -1434,6 +1530,20 @@ void Precomp_UIDuplicate(project_data *File, project_state *State, memory *Memor
}
}
+void Precomp_UIDelete(project_data *File, project_state *State, memory *Memory, uint16 CompIndex,
+ sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo)
+{
+ block_layer *Layer = NULL;
+ for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--)
+ {
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+ if (Layer->IsSelected) {
+ }
+ }
+}
+
void Precomp_UICreateButton(project_data *File, project_state *State, memory *Memory, uint16 CompIndex,
sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo)
{
@@ -1542,14 +1652,63 @@ Brush_CalcBitmapAlphaFromSize(memory *Memory, brush_state *Brush, uint32 BytesPe
real32 L = sqrt(LengthSq(Pos));
real32 Gradient = Ceil(L, MaxLength) / MaxLength;
Gradient = pow(Gradient, Brush->Hardness);
+ // Gradient = (Gradient >= 0.04045) ? pow((Gradient + 0.055) / (1 + 0.055), 2.4) : Gradient / 12.92;
+ // Gradient = (Gradient >= 0.0031308) ? (1.055) * pow(Gradient, (1.0/2.4)) - 0.055 : 12.92 * Gradient;
*R_DestAddress = (*R_DestAddress & ~Byte.MaskPixel) | Byte.Bits; // brush preview is red
*A_DestAddress = (*A_DestAddress & ~Byte.MaskPixel) | (uint32)((1.0f - Gradient)*Byte.Bits);
}
}
}
+// Imported bitmaps are stored in linear, and all ops are also done in linear.
+static void
+Bitmap_SRGBToLinear(void *Buffer, uint16 Width, uint16 Height, uint16 BytesPerPixel, bool32 ToLinear)
+{
+ uint8 *Row = (uint8 *)Buffer;
+ uint64 TotalBytes = Width * Height * BytesPerPixel;
+
+ render_byte_info LayerBits = Bitmap_ByteInfo(BytesPerPixel);
+
+ uint64 bytes = 0;
+ while (bytes < TotalBytes) {
+ uint8 *LayerPixel = Row + bytes;
+ uint32 *R_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 0);
+ uint32 *G_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 1);
+ uint32 *B_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 2);
+ uint32 *A_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 3);
+
+ real32 TexR = (real32)(*R_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized;
+ real32 TexG = (real32)(*G_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized;
+ real32 TexB = (real32)(*B_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized;
+ real32 TexA = (real32)(*A_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized;
+
+ if (ToLinear) {
+ TexR = (TexR >= 0.04045) ? pow((TexR + 0.055) / (1 + 0.055), 2.4) : TexR / 12.92;
+ TexG = (TexG >= 0.04045) ? pow((TexG + 0.055) / (1 + 0.055), 2.4) : TexG / 12.92;
+ TexB = (TexB >= 0.04045) ? pow((TexB + 0.055) / (1 + 0.055), 2.4) : TexB / 12.92;
+ TexA = (TexA >= 0.04045) ? pow((TexA + 0.055) / (1 + 0.055), 2.4) : TexA / 12.92;
+ } else {
+ TexR = (TexR >= 0.0031308) ? (1.055) * pow(TexR, (1.0/2.4)) - 0.055 : 12.92 * TexR;
+ TexG = (TexG >= 0.0031308) ? (1.055) * pow(TexG, (1.0/2.4)) - 0.055 : 12.92 * TexG;
+ TexB = (TexB >= 0.0031308) ? (1.055) * pow(TexB, (1.0/2.4)) - 0.055 : 12.92 * TexB;
+ TexA = (TexA >= 0.0031308) ? (1.055) * pow(TexA, (1.0/2.4)) - 0.055 : 12.92 * TexA;
+ }
+
+ uint32 R_Out = (uint32)(Normalize(TexR) * LayerBits.Bits);
+ uint32 G_Out = (uint32)(Normalize(TexG) * LayerBits.Bits);
+ uint32 B_Out = (uint32)(Normalize(TexB) * LayerBits.Bits);
+ uint32 A_Out = (uint32)(Normalize(TexA) * LayerBits.Bits);
+
+ *R_DestAddress = (*R_DestAddress & ~LayerBits.MaskPixel) | R_Out;
+ *G_DestAddress = (*G_DestAddress & ~LayerBits.MaskPixel) | G_Out;
+ *B_DestAddress = (*B_DestAddress & ~LayerBits.MaskPixel) | B_Out;
+ *A_DestAddress = (*A_DestAddress & ~LayerBits.MaskPixel) | A_Out;
+ bytes += BytesPerPixel;
+ }
+}
+
static void
-Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, v2 LayerPos, v4 Color)
+Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, void *SourceBuffer, v2 LayerPos, v4 Color)
{
B->BrushLength = (uint32)Brush->Size;
if (B->BrushLength > 128) {
@@ -1573,9 +1732,12 @@ Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, v2 LayerPos,
if (BrushPos.Max.y > Brush->CacheBounds.Max.y)
Brush->CacheBounds.Max.y = BrushPos.Max.y;
+ Assert(Source->Type == source_type_principal);
+
B->BytesPerPixel = 4;
B->SourceWidth = Source->Width;
B->SourceBytesPerPixel = Source->BytesPerPixel;
+ B->SourceBuffer = SourceBuffer;
Assert(Source->BytesPerPixel == 4);
@@ -1597,15 +1759,10 @@ Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, v2 LayerPos,
B->BrushBuffer = Brush->PaintBuffer;
B->EraseMode = Brush->EraseMode;
- // ImGui's color picker works in sRGB, so we need to convert to linear.
- // real32 R_Brush = (Color.r >= 0.04045) ? pow((Color.r + 0.055) / (1 + 0.055), 2.4) : Color.r / 12.92;
- // real32 G_Brush = (Color.g >= 0.04045) ? pow((Color.g + 0.055) / (1 + 0.055), 2.4) : Color.g / 12.92;
- // real32 B_Brush = (Color.b >= 0.04045) ? pow((Color.b + 0.055) / (1 + 0.055), 2.4) : Color.b / 12.92;
- // real32 A_Brush = (Color.a >= 0.04045) ? pow((Color.a + 0.055) / (1 + 0.055), 2.4) : Color.a / 12.92;
- B->R_Brush = Color.r;
- B->G_Brush = Color.g;
- B->B_Brush = Color.b;
- B->A_Brush = Color.a;
+ B->R_Brush = (Color.r >= 0.04045) ? pow((Color.r + 0.055) / (1 + 0.055), 2.4) : Color.r / 12.92;
+ B->G_Brush = (Color.g >= 0.04045) ? pow((Color.g + 0.055) / (1 + 0.055), 2.4) : Color.g / 12.92;
+ B->B_Brush = (Color.b >= 0.04045) ? pow((Color.b + 0.055) / (1 + 0.055), 2.4) : Color.b / 12.92;
+ B->A_Brush = (Color.a >= 0.04045) ? pow((Color.a + 0.055) / (1 + 0.055), 2.4) : Color.a / 12.92;
B->BrushRow = (uint8 *)B->BrushBuffer;
}
@@ -1615,68 +1772,29 @@ void Bitmap_SwapData(uint8 *Address_0, uint8 *Address_1, uint64 Size, uint16 Byt
uint64 i = 0;
uint16 ByteOffset = Bitmap_ByteInfo(BytesPerPixel).ByteOffset;
uint64 RemainderBytes = Size % ByteOffset;
- Assert(BytesPerPixel == 8);
-
-#if ARM
- Assert(InstructionMode != instruction_mode_neon);
-#else
- if (BytesPerPixel == 4) {
- uint32 Temp = 0;
- while (i < Size) {
- uint32 *Pixel_0 = (uint32 *)(Address_0 + i);
- uint32 *Pixel_1 = (uint32 *)(Address_1 + i);
- if (*Pixel_0 != 0x00000000) {
- Temp = *Pixel_1;
- *Pixel_1 = *Pixel_0;
- *Pixel_0 = Temp;
- }
- i += sizeof(uint32);
+ Assert(BytesPerPixel == 4);
+
+ while (i < Size) {
+ uint32 *Pixel_0 = (uint32 *)(Address_0 + i);
+ uint32 *Pixel_1 = (uint32 *)(Address_1 + i);
+ if (*Pixel_0 != 0x00000000) {
+ uint32 Temp = *Pixel_1;
+ *Pixel_1 = *Pixel_0;
+ *Pixel_0 = Temp;
}
- } else if (BytesPerPixel == 8) {
- uint64 Temp = 0;
- __m256i Zero = _mm256_set1_epi64x(0);
- __m256i Max32 = _mm256_set1_epi32(0xFFFFFFFF);
- if (InstructionMode == instruction_mode_avx) {
- while (i < Size - RemainderBytes) {
- uint8 *Pixel_0_Address = (Address_0 + i);
- __m256i Pixel_0 = _mm256_loadu_si256((__m256i *)Pixel_0_Address);
- __m256i AlphaMask = _mm256_cmpeq_epi64(Pixel_0, Zero);
- if (_mm256_movemask_epi8(AlphaMask) != 0xFFFFFFFF) {
- uint8 *Pixel_1_Address = (Address_1 + i);
- __m256i Pixel_1 = _mm256_loadu_si256((__m256i *)Pixel_1_Address);
- AlphaMask = _mm256_andnot_si256(AlphaMask, Max32);
- _mm256_maskstore_epi64((long long *)Pixel_1_Address, AlphaMask, Pixel_0);
- _mm256_maskstore_epi64((long long *)Pixel_0_Address, AlphaMask, Pixel_1);
- }
- i += sizeof(uint64)*4;
- }
- }
- while (i < Size) {
- uint64 *Pixel_0 = (uint64 *)(Address_0 + i);
- uint64 *Pixel_1 = (uint64 *)(Address_1 + i);
- if (*Pixel_0 != 0x0000000000000000) {
- Temp = *Pixel_1;
- *Pixel_1 = *Pixel_0;
- *Pixel_0 = Temp;
- }
- i += sizeof(uint64);
- }
- } else {
- Assert(0);
+ i += sizeof(uint32);
}
-#endif
-
}
static void
-PaintTest(brush_info B, void *Buffer, rectangle RenderRegion)
+PaintTest(brush_info B, void *CacheBuffer, rectangle RenderRegion)
{
for (int32 Y = RenderRegion.Min.y; Y < RenderRegion.Max.y; Y++) {
for (int32 X = RenderRegion.Min.x; X < RenderRegion.Max.x; X++) {
uint32 Offset = Y*B.LayerPitch + X*B.SourceBytesPerPixel;
- uint8 *LayerPixel = (uint8 *)Buffer + Offset;
+ uint8 *LayerPixel = (uint8 *)CacheBuffer + Offset;
uint32 *R_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 0);
uint32 *G_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 1);
@@ -1691,6 +1809,12 @@ PaintTest(brush_info B, void *Buffer, rectangle RenderRegion)
int32 TrueX = (X - B.LayerBounds.Min.x) - B.ExtraX;
int32 TrueY = (Y - B.LayerBounds.Min.y) - B.ExtraY;
+ uint8 *SourcePixel = (uint8 *)B.SourceBuffer + Offset;
+ Assert(B.SourceBytesPerPixel == 4);
+ bool32 IsEmpty = (*(uint32 *)SourcePixel == 0x00000000);
+ if (IsEmpty)
+ *(uint32 *)SourcePixel = 0x00010101;
+
// Assert(TrueX >= 0 && TrueX < BrushLength);
// Assert(TrueY >= 0 && TrueY < BrushLength);
@@ -1698,7 +1822,10 @@ PaintTest(brush_info B, void *Buffer, rectangle RenderRegion)
real32 Brush_BitmapAlpha = (real32)((*(uint32 *)(BrushPixel + B.BrushBits.ByteOffset*3)) & B.BrushBits.MaskPixel) * B.BrushBits.Normalized;
- real32 BrushAlpha = Brush_BitmapAlpha * B.A_Brush;
+ if (!Brush_BitmapAlpha)
+ continue;
+
+ real32 BrushAlpha = Brush_BitmapAlpha;
real32 LayerAlpha = A_Layer;
real32 A_Blend = 0;
@@ -1707,13 +1834,22 @@ PaintTest(brush_info B, void *Buffer, rectangle RenderRegion)
real32 B_Blend = 0;
if (!B.EraseMode) {
- A_Blend = LayerAlpha + BrushAlpha;
- // R_Blend = (R_Layer * (1.0f - BrushAlpha)) + (B.R_Brush * BrushAlpha);
- // G_Blend = (G_Layer * (1.0f - BrushAlpha)) + (B.G_Brush * BrushAlpha);
- // B_Blend = (B_Layer * (1.0f - BrushAlpha)) + (B.B_Brush * BrushAlpha);
- R_Blend = B.R_Brush;
- G_Blend = B.G_Brush;
- B_Blend = B.B_Brush;
+ if (IsEmpty) {
+ R_Blend = B.R_Brush;
+ G_Blend = B.G_Brush;
+ B_Blend = B.B_Brush;
+ A_Blend = LayerAlpha + BrushAlpha;
+ } else {
+ R_Blend = B.R_Brush;
+ G_Blend = B.G_Brush;
+ B_Blend = B.B_Brush;
+ A_Blend = LayerAlpha + ((1.0f - LayerAlpha) * BrushAlpha);
+ real32 Blend = BrushAlpha;
+ // R_Blend = (R_Layer * (1.0f - Blend)) + (B.R_Brush * Blend);
+ // G_Blend = (G_Layer * (1.0f - Blend)) + (B.G_Brush * Blend);
+ // B_Blend = (B_Layer * (1.0f - Blend)) + (B.B_Brush * Blend);
+ }
+ // A_Blend = BrushAlpha;
} else {
A_Blend = A_Layer * (1.0f - BrushAlpha);
R_Blend = R_Layer;
@@ -1815,13 +1951,17 @@ PaintTest_AVX2(brush_info B, void *Buffer, rectangle RenderRegion)
#endif
static void
-Brush_Render(project_state *State, ui *UI, layer_transforms T_Layer, block_composition *MainComp, block_source *Source, void *BitmapAddress, ImVec2 ViewportMin, v2 LayerPos)
+RenderQueue_AddBrush(project_state *State, v2 LayerPos)
{
- brush_info B;
- Brush_Info(&B, &State->Brush, Source, LayerPos, UI->Color);
- if (State->Brush.Size >= 128) {
- Render_Main((void *)&B, BitmapAddress, render_type_brush, B.LayerBounds);
- } else {
- PaintTest(B, BitmapAddress, B.LayerBounds);
- }
+ State->Queue.Item[State->Queue.CurrentIdx].Pos = LayerPos;
+ State->Queue.Item[State->Queue.CurrentIdx].Type = 1;
+ State->Queue.CurrentIdx++;
+ State->Brush.PrevPos = LayerPos;
+}
+
+static void
+RenderQueue_AddBlit(project_state *State)
+{
+ State->Queue.Item[State->Queue.CurrentIdx].Type = 2;
+ State->Queue.CurrentIdx++;
}