From 635576972024319c15141645d3304db8cd1d1e19 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Mon, 8 Aug 2022 13:50:34 -0400 Subject: basic bezier path system added --- bitmap_calls.cpp | 103 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 18 deletions(-) (limited to 'bitmap_calls.cpp') diff --git a/bitmap_calls.cpp b/bitmap_calls.cpp index 09d1cb1..2031459 100644 --- a/bitmap_calls.cpp +++ b/bitmap_calls.cpp @@ -117,46 +117,113 @@ Bitmap_Clear(void *Buffer, uint16 Width, uint16 Height, uint16 BytesPerPixel) bytes += ByteOffset; } } -#if 0 -// 0 - original -> effect -// 1 - effect -> original + static void -CopyToBuffer(pixel_buffer *Raster, uint16 Which) +Bitmap_CalcPackedDimensions(uint16 Width, uint16 Height, uint16 *WidthP, uint16 *HeightP) { + uint16 ExtraWidth = 4 - (Width % 4); + if (ExtraWidth == 4) + ExtraWidth = 0; + uint16 ExtraHeight = 4 - (Height % 4); + if (ExtraHeight == 4) + ExtraHeight = 0; + *WidthP = Width + ExtraWidth; + *HeightP = Height + ExtraHeight; +} + +static uint16 +Bitmap_CalcByteOffset(uint16 BytesPerPixel) { + uint16 ByteOffset = BytesPerPixel; + if (InstructionMode == instruction_mode_avx) + ByteOffset = 8*BytesPerPixel; + if (InstructionMode == instruction_mode_sse) + ByteOffset = 4*BytesPerPixel; + return ByteOffset; +} + +static uint64 +Bitmap_CalcUnpackedBytes(uint16 Width, uint16 Height, uint16 BytesPerPixel) { + uint64 TotalBytes = (uint64)Width*Height*BytesPerPixel; + return TotalBytes; +} + +static uint64 +Bitmap_CalcTotalBytes(uint16 Width, uint16 Height, uint16 BytesPerPixel) { + uint16 WidthP, HeightP; + Bitmap_CalcPackedDimensions(Width, Height, &WidthP, &HeightP); + uint64 TotalBytes = (uint64)WidthP*HeightP*BytesPerPixel; + return TotalBytes; +} + +// TODO(fox): Maybe turn this into a generic memory copy; we don't need to care +// about pixels for any particular reason here. +static void +Bitmap_CopyToPointer(void *Input, void *Output, uint16 BytesPerPixel, uint64 TotalBytes) { - uint8 *Row, *Row2; - if (Which == 0) { - Row = ((uint8 *)Raster->OriginalBuffer); - Row2 = ((uint8 *)Raster->EffectBuffer); - } else { - Row = ((uint8 *)Raster->EffectBuffer); - Row2 = ((uint8 *)Raster->OriginalBuffer); - } + uint8 *Row = (uint8 *)Input; + uint8 *Row2 = (uint8 *)Output; uint64 bytes = 0; - uint16 ByteOffset = Bitmap_CalculateByteOffset(BytesPerPixel); - uint64 TotalBytes = Bitmap_CalculateTotalBytes(Width, Height, BytesPerPixel); + uint16 ByteOffset = Bitmap_CalcByteOffset(BytesPerPixel); uint64 RemainderBytes = TotalBytes % ByteOffset; while (bytes <= TotalBytes - RemainderBytes) { uint8 *Pixel = (uint8 *)Row + bytes; uint8 *Pixel2 = (uint8 *)Row2 + bytes; - if (InstructionMode == instruction_mode_sse || InstructionMode == instruction_mode_avx) { + if (InstructionMode == instruction_mode_avx) { + __m256i OutputPixel = _mm256_loadu_si256((__m256i *)Pixel); + _mm256_storeu_si256((__m256i *)Pixel2, OutputPixel); + } else if (InstructionMode == instruction_mode_sse) { __m128i OutputPixel = _mm_loadu_si128((__m128i *)Pixel); _mm_storeu_si128((__m128i *)Pixel2, OutputPixel); - bytes += 4*Raster->BytesPerPixel; } else { *(uint32 *)Pixel2 = *(uint32 *)Pixel; - bytes += Raster->BytesPerPixel; } + bytes += ByteOffset; } while (bytes <= TotalBytes) { uint8 *Pixel = (uint8 *)Row + bytes; uint8 *Pixel2 = (uint8 *)Row2 + bytes; *(uint32 *)Pixel2 = *(uint32 *)Pixel; - bytes += Raster->BytesPerPixel; + bytes += BytesPerPixel; + } +} + +// This would be an easy SIMD if only AVX had a scatter call... +// NOTE(fox): Only works with unpacked bitmaps for now. +static void +Bitmap_CalcHistogram(void *Data, void *Input, uint16 BytesPerPixel, uint64 TotalBytes) +{ + uint32 *Slot = (uint32 *)Data; + uint8 *Row = (uint8 *)Input; + uint64 bytes = 0; + uint16 ByteOffset = Bitmap_CalcByteOffset(BytesPerPixel); + uint64 RemainderBytes = TotalBytes % ByteOffset; + + for (int i = 0; i < 256*5; i++) { + *(real32 *)((uint8 *)Slot + i*sizeof(real32)) = 0; + } + + while (bytes <= TotalBytes) { + uint8 *Pixel = (uint8 *)Row + bytes; + + uint8 A = (*(uint32 *)Pixel >> 24); + uint8 R = (*(uint32 *)Pixel >> 16); + uint8 G = (*(uint32 *)Pixel >> 8); + uint8 B = (*(uint32 *)Pixel >> 0); + + uint8 Avg = (uint8)((real32)(R + G + B) / 3.0f); + + *(real32 *)((uint8 *)Slot + Avg*sizeof(real32)) += 1; + *(real32 *)((uint8 *)Slot + (256 + R)*sizeof(real32)) += 1; + *(real32 *)((uint8 *)Slot + (256*2 + G)*sizeof(real32)) += 1; + *(real32 *)((uint8 *)Slot + (256*3 + B)*sizeof(real32)) += 1; + *(real32 *)((uint8 *)Slot + (256*4 + A)*sizeof(real32)) += 1; + + bytes += BytesPerPixel; } } +#if 0 static void BitmapPackRGB(pixel_buffer *Buffer) { Assert(Buffer->Pitch); -- cgit v1.2.3