@geastack/core 0.1.38 → 0.1.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include "canvas.h"
4
4
  #include "display.h"
5
+ #include "image.h"
5
6
 
6
7
  #include <algorithm>
7
8
  #include <array>
@@ -284,6 +285,13 @@ inline void addCommandBounds(const Command &command, Rect *rects, int *count, in
284
285
  addRect(rects, count, capacity, commandBounds(command, width, height), width, height);
285
286
  }
286
287
 
288
+ // An app-registered buffer (native surface, ImageData565, video frame) is
289
+ // rewritten in place, so equal pointers say nothing about equal pixels.
290
+ inline bool imagePixelsStable(const Command &command)
291
+ {
292
+ return !gea::framework::graphics::ImageStore::instance().pixelsMayChange(command.pixels);
293
+ }
294
+
287
295
  inline bool commandsEqual(const Command &a, const Command &b)
288
296
  {
289
297
  if (a.type != b.type || a.alpha != b.alpha) return false;
@@ -321,15 +329,15 @@ inline bool commandsEqual(const Command &a, const Command &b)
321
329
  sizeof(gea::framework::graphics::TriangleEntry)) == 0;
322
330
  }
323
331
  case Type::DrawImage:
324
- return a.pixels == b.pixels && a.alphaPixels == b.alphaPixels &&
332
+ return a.pixels == b.pixels && a.alphaPixels == b.alphaPixels && imagePixelsStable(a) &&
325
333
  a.srcWidth == b.srcWidth && a.srcHeight == b.srcHeight && a.x == b.x && a.y == b.y;
326
334
  case Type::DrawImageScaled:
327
335
  case Type::DrawImageRotated90CW:
328
- return a.pixels == b.pixels && a.alphaPixels == b.alphaPixels &&
336
+ return a.pixels == b.pixels && a.alphaPixels == b.alphaPixels && imagePixelsStable(a) &&
329
337
  a.srcWidth == b.srcWidth && a.srcHeight == b.srcHeight &&
330
338
  a.x == b.x && a.y == b.y && a.w == b.w && a.h == b.h;
331
339
  case Type::DrawImageTiledX:
332
- return a.pixels == b.pixels && a.alphaPixels == b.alphaPixels &&
340
+ return a.pixels == b.pixels && a.alphaPixels == b.alphaPixels && imagePixelsStable(a) &&
333
341
  a.srcWidth == b.srcWidth && a.srcHeight == b.srcHeight &&
334
342
  a.x == b.x && a.y == b.y && a.w == b.w;
335
343
  case Type::FillText:
@@ -574,8 +582,17 @@ inline bool frameHasOpaqueBase(const Frame &frame, int width, int height)
574
582
  const Command &first = frame.commands.front();
575
583
  using Type = gea::platform::display::DisplayPresentCommandType;
576
584
  if (first.type == Type::Clear) return true;
577
- if (first.type != Type::FillRectRgb565 || first.alpha != 255) return false;
578
- const Rect bounds = rectFromBox(first.x, first.y, first.w, first.h);
585
+ if (first.alpha != 255) return false;
586
+ Rect bounds;
587
+ if (first.type == Type::FillRectRgb565) {
588
+ bounds = rectFromBox(first.x, first.y, first.w, first.h);
589
+ } else if (first.type == Type::DrawImage && first.alphaPixels == nullptr) {
590
+ // A full-panel opaque image (putImageData of a whole-screen buffer)
591
+ // paints every pixel, the same as a full-panel fill.
592
+ bounds = rectFromBox(first.x, first.y, first.srcWidth, first.srcHeight);
593
+ } else {
594
+ return false;
595
+ }
579
596
  return bounds.x0 <= 0 && bounds.y0 <= 0 && bounds.x1 >= width - 1 && bounds.y1 >= height - 1;
580
597
  }
581
598
 
package/include/image.h CHANGED
@@ -61,6 +61,9 @@ struct ImageSlot {
61
61
  pixel::native_t *pixels = nullptr;
62
62
  std::uint8_t *alpha = nullptr;
63
63
  bool ownsPixels = false;
64
+ // Registered by the app (registerBuffer): the app writes these pixels in
65
+ // place between frames, so the same pointer does not mean the same image.
66
+ bool mutablePixels = false;
64
67
 
65
68
  void *gifDecoder = nullptr;
66
69
  std::uint8_t *gifData = nullptr;
@@ -98,6 +101,11 @@ public:
98
101
  // camera capture, which hands over a freshly-allocated RGBA8888 still.
99
102
  int registerBuffer(pixel::native_t *pixels, int width, int height, int preferredSlot = -1, bool takeOwnership = false);
100
103
 
104
+ // True when `pixels` point into a registerBuffer() image, whose content the
105
+ // app rewrites in place. The present diff never treats such an image as
106
+ // unchanged from the previous frame.
107
+ bool pixelsMayChange(const pixel::native_t *pixels) const;
108
+
101
109
  int width(int id) const;
102
110
  int height(int id) const;
103
111
  int frameCount(int id) const;
package/index.d.ts CHANGED
@@ -1023,6 +1023,16 @@ export interface CanvasRenderingContext2D {
1023
1023
  createImageData565(width: number, height: number): ImageData565
1024
1024
  /** Draw an `ImageData565` with its top-left corner at (dx, dy): one blit. */
1025
1025
  putImageData(image: ImageData565, dx: number, dy: number): void
1026
+ /** Draw only the dirty rectangle of an `ImageData565`, at (dx + dirtyX, dy + dirtyY). */
1027
+ putImageData(
1028
+ image: ImageData565,
1029
+ dx: number,
1030
+ dy: number,
1031
+ dirtyX: number,
1032
+ dirtyY: number,
1033
+ dirtyWidth: number,
1034
+ dirtyHeight: number,
1035
+ ): void
1026
1036
  flush(): void
1027
1037
  beginBatch(): void
1028
1038
  endBatch(): void
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geastack/core",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "GeaStack app API, reactivity headers, runtime sources, and type declarations.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -65,8 +65,8 @@
65
65
  "@babel/types": "^7.23.0",
66
66
  "@geajs/core": "1.5.1",
67
67
  "@geajs/vite-plugin": "1.5.0",
68
- "@geastack/compiler": "^1.0.23",
69
- "@geastack/geatsc-plugin-gea": "^0.1.20",
68
+ "@geastack/compiler": "^1.0.25",
69
+ "@geastack/geatsc-plugin-gea": "^0.1.21",
70
70
  "opentype.js": "^2.0.0",
71
71
  "vite": "^8.0.0"
72
72
  }