Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 69 additions & 1 deletion packages/skia/cpp/api/JsiSkAnimatedImage.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#pragma once

#include <algorithm>
#include <cmath>
#include <limits>
#include <memory>
#include <string>
#include <utility>
Expand Down Expand Up @@ -63,7 +66,72 @@ class JsiSkAnimatedImage
: JsiSkWrappingSkPtrHostObject<SkAnimatedImage>(std::move(context),
std::move(image)) {}

size_t getMemoryPressure() const override { return 8192; }
size_t getMemoryPressure() const override {
auto animation = getObject();
if (!animation) {
return 0;
}

const auto safeMul = [](size_t a, size_t b) {
if (a == 0 || b == 0) {
return static_cast<size_t>(0);
}
if (std::numeric_limits<size_t>::max() / a < b) {
return std::numeric_limits<size_t>::max();
}
return a * b;
};

const auto safeAdd = [](size_t a, size_t b) {
if (std::numeric_limits<size_t>::max() - a < b) {
return std::numeric_limits<size_t>::max();
}
return a + b;
};

SkRect bounds = animation->getBounds();
auto width = std::max<SkScalar>(0, bounds.width());
auto height = std::max<SkScalar>(0, bounds.height());
size_t frameWidth =
static_cast<size_t>(std::ceil(static_cast<double>(width)));
size_t frameHeight =
static_cast<size_t>(std::ceil(static_cast<double>(height)));

size_t frameBytes = safeMul(safeMul(frameWidth, frameHeight),
static_cast<size_t>(4)); // RGBA bytes
if (frameBytes == 0) {
if (auto frame = animation->getCurrentFrame()) {
auto frameInfo = frame->imageInfo();
size_t bytesPerPixel = static_cast<size_t>(frameInfo.bytesPerPixel());
if (bytesPerPixel == 0) {
bytesPerPixel = 4;
}
frameBytes =
safeMul(safeMul(static_cast<size_t>(frame->width()),
static_cast<size_t>(frame->height())),
bytesPerPixel);
}
}

if (frameBytes == 0) {
return 0;
}

int frameCount = animation->getFrameCount();
if (frameCount <= 0) {
frameCount = 1;
}

// Animated images keep display, decoding, and restore frames resident.
size_t cachedFrames =
static_cast<size_t>(std::min(frameCount, 3)); // triple buffering
size_t estimated = safeMul(frameBytes, cachedFrames);

// Include codec/metadata overhead.
estimated = safeAdd(estimated, 256 * 1024);

return estimated;
}

std::string getObjectType() const override { return "JsiSkAnimatedImage"; }
};
Expand Down
2 changes: 1 addition & 1 deletion packages/skia/cpp/api/JsiSkImageFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class JsiSkImageFilter : public JsiSkWrappingSkPtrHostObject<SkImageFilter> {
: JsiSkWrappingSkPtrHostObject<SkImageFilter>(std::move(context),
std::move(imageFilter)) {}

size_t getMemoryPressure() const override { return 4096; }
size_t getMemoryPressure() const override { return 1024 * 1024; }

std::string getObjectType() const override { return "JsiSkImageFilter"; }

Expand Down
2 changes: 1 addition & 1 deletion packages/skia/cpp/api/JsiSkParagraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class JsiSkParagraph
JSI_EXPORT_FUNC(JsiSkParagraph, getLineMetrics),
JSI_EXPORT_FUNC(JsiSkParagraph, dispose))

size_t getMemoryPressure() const override { return 8192; }
size_t getMemoryPressure() const override { return 1024 * 1024; }

std::string getObjectType() const override { return "JsiSkParagraph"; }

Expand Down
2 changes: 1 addition & 1 deletion packages/skia/cpp/api/JsiSkParagraphBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class JsiSkParagraphBuilder : public JsiSkHostObject {
JSI_EXPORT_FUNC(JsiSkParagraphBuilder, pushStyle),
JSI_EXPORT_FUNC(JsiSkParagraphBuilder, pop))

size_t getMemoryPressure() const override { return 4096; }
size_t getMemoryPressure() const override { return 1024 * 1024; }

std::string getObjectType() const override { return "JsiSkParagraphBuilder"; }

Expand Down
2 changes: 1 addition & 1 deletion packages/skia/cpp/api/JsiSkParagraphBuilderFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class JsiSkParagraphBuilderFactory : public JsiSkHostObject {

JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkParagraphBuilderFactory, Make))

size_t getMemoryPressure() const override { return 3072; }
size_t getMemoryPressure() const override { return 1024 * 1024; }

std::string getObjectType() const override {
return "JsiSkParagraphBuilderFactory";
Expand Down
4 changes: 1 addition & 3 deletions packages/skia/cpp/api/JsiSkPictureRecorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ class JsiSkPictureRecorder
finishRecordingAsPicture),
JSI_EXPORT_FUNC(JsiSkPictureRecorder, dispose))

size_t getMemoryPressure() const override {
return sizeof(SkPictureRecorder);
}
size_t getMemoryPressure() const override { return 1024 * 1024; }

std::string getObjectType() const override { return "JsiSkPictureRecorder"; }

Expand Down
2 changes: 1 addition & 1 deletion packages/skia/cpp/api/JsiSkShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class JsiSkShader : public JsiSkWrappingSkPtrHostObject<SkShader> {
: JsiSkWrappingSkPtrHostObject<SkShader>(std::move(context),
std::move(shader)) {}

size_t getMemoryPressure() const override { return 4096; }
size_t getMemoryPressure() const override { return 1024 * 1024; }

std::string getObjectType() const override { return "JsiSkShader"; }

Expand Down
55 changes: 48 additions & 7 deletions packages/skia/cpp/api/JsiSkSurface.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <algorithm>
#include <limits>
#include <memory>
#include <utility>

Expand Down Expand Up @@ -116,15 +118,54 @@ class JsiSkSurface : public JsiSkWrappingSkPtrHostObject<SkSurface> {

size_t getMemoryPressure() const override {
auto surface = getObject();
if (!surface)
if (!surface) {
return 0;
}

const auto safeAdd = [](size_t a, size_t b) {
if (std::numeric_limits<size_t>::max() - a < b) {
return std::numeric_limits<size_t>::max();
}
return a + b;
};

SkImageInfo info = surface->imageInfo();
size_t pixelBytes = info.computeMinByteSize();
if (pixelBytes == 0) {
auto width = std::max(info.width(), surface->width());
auto height = std::max(info.height(), surface->height());
int bytesPerPixel = info.bytesPerPixel();
if (bytesPerPixel <= 0) {
bytesPerPixel = 4;
}
if (width > 0 && height > 0) {
pixelBytes = static_cast<size_t>(width) * static_cast<size_t>(height) *
static_cast<size_t>(bytesPerPixel);
}
}

if (pixelBytes == 0) {
return 0;
}

size_t estimated = pixelBytes;

auto canvas = surface->getCanvas();
const bool isGpuBacked =
surface->recordingContext() != nullptr || surface->recorder() != nullptr ||
(canvas && (canvas->recordingContext() != nullptr ||
canvas->recorder() != nullptr));

if (isGpuBacked) {
// Account for a resolved texture and depth/stencil attachments.
estimated = safeAdd(estimated, pixelBytes); // resolve/texture copy
estimated = safeAdd(estimated, pixelBytes / 2); // depth-stencil buffers
}

// Add a small overhead buffer for bookkeeping allocations.
estimated = safeAdd(estimated, 128 * 1024);

// Surface memory is primarily the pixel buffer: width × height × bytes per
// pixel
int width = surface->width();
int height = surface->height();
// Assume 4 bytes per pixel (RGBA) for most surfaces
return width * height * 4;
return estimated;
}

std::string getObjectType() const override { return "JsiSkSurface"; }
Expand Down
2 changes: 1 addition & 1 deletion packages/skia/cpp/api/JsiSkiaContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class JsiSkiaContext : public JsiSkWrappingSharedPtrHostObject<WindowContext> {
std::shared_ptr<WindowContext> ctx)
: JsiSkWrappingSharedPtrHostObject(std::move(context), std::move(ctx)) {}

size_t getMemoryPressure() const override { return 8192; }
size_t getMemoryPressure() const override { return 10 * 1024 * 1024; }

std::string getObjectType() const override { return "JsiSkiaContext"; }

Expand Down
Loading