diff --git a/components/display/core/gds.c b/components/display/core/gds.c index c80f18d8..6cec45d2 100644 --- a/components/display/core/gds.c +++ b/components/display/core/gds.c @@ -61,9 +61,22 @@ void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2, // driver can provide onw optimized clear window if (Device->ClearWindow) { Device->ClearWindow( Device, x1, y1, x2, y2, Color ); - // cheap optimization on boundaries - if (x1 == 0 && x2 == Device->Width - 1 && y1 % 8 == 0 && (y2 + 1) % 8 == 0) { - memset( Device->Framebuffer + (y1 / 8) * Device->Width, 0, (y2 - y1 + 1) / 8 * Device->Width ); + } else if (Device->Depth == 1) { + // single shot if we erase all screen + if (x2 - x1 == Device->Width - 1 && y2 - y1 == Device->Height - 1) { + memset( Device->Framebuffer, Color, Device->FramebufferSize ); + } else { + uint8_t _Color = Color == GDS_COLOR_BLACK ? 0: 0xff; + uint8_t Width = Device->Width; + // try to do byte processing as much as possible + for (int c = x1; c <= x2; c++) { + int r = y1; + while (r & 0x07 && r <= y2) GDS_DrawPixelFast( Device, c, r++, Color); + for (; (r >> 3) < (y2 >> 3); r++) Device->Framebuffer[(r >> 3) * Width + c] = _Color; + // memset(Device->Framebuffer + (r >> 3) * Width, _Color, (y2 >> 3) - (r >> 3)); + while (r <= y2) GDS_DrawPixelFast( Device, c, r++, Color); + } + } } else { for (int y = y1; y <= y2; y++) { for (int x = x1; x <= x2; x++) { diff --git a/components/display/core/gds.h b/components/display/core/gds.h index 88156279..2c3a9e26 100644 --- a/components/display/core/gds.h +++ b/components/display/core/gds.h @@ -4,6 +4,15 @@ #include #include +/* NOTE for drivers: + The build-in DrawPixel(Fast), DrawCBR and ClearWindow are optimized for 1 bit + and 4 bits screen depth. For any other type of screen, DrawCBR and ClearWindow + default to use DrawPixel, which is very sub-optimal. For such other depth, you + must supply the DrawPixelFast. The built-in 1 bit depth function are only for + screen with vertical framing (1 byte = 8 lines). For example SSD1326 in + monochrome mode is not such type of screen, SH1106 and SSD1306 are +*/ + enum { GDS_COLOR_L0 = 0, GDS_COLOR_L1, GDS_COLOR_L2, GDS_COLOR_L3, GDS_COLOR_L4, GDS_COLOR_L5, GDS_COLOR_L6, GDS_COLOR_L7, GDS_COLOR_L8, GDS_COLOR_L9, GDS_COLOR_L10, GDS_COLOR_L11, GDS_COLOR_L12, GDS_COLOR_L13, GDS_COLOR_L14, GDS_COLOR_L15, }; diff --git a/components/display/core/gds_private.h b/components/display/core/gds_private.h index 806f5a90..3e2676ff 100644 --- a/components/display/core/gds_private.h +++ b/components/display/core/gds_private.h @@ -93,7 +93,7 @@ struct GDS_Device { bool FontForceMonospace; // various driver-specific method - // must provide + // must always provide bool (*Init)( struct GDS_Device* Device); void (*SetContrast)( struct GDS_Device* Device, uint8_t Contrast ); void (*DisplayOn)( struct GDS_Device* Device ); @@ -101,8 +101,9 @@ struct GDS_Device { void (*SetHFlip)( struct GDS_Device* Device, bool On ); void (*SetVFlip)( struct GDS_Device* Device, bool On ); void (*Update)( struct GDS_Device* Device ); - // may provide for optimization + // must provide for depth other than 1 (vertical) and 4 (may provide for optimization) void (*DrawPixelFast)( struct GDS_Device* Device, int X, int Y, int Color ); + // may provide for optimization void (*DrawRGB16)( struct GDS_Device* Device, int x, int y, int Width, int Height, int RGB_Mode, uint16_t **Image ); void (*ClearWindow)( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int Color );