-
Notifications
You must be signed in to change notification settings - Fork 491
/
Copy pathRNSkDomView.cpp
145 lines (117 loc) · 3.98 KB
/
RNSkDomView.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "RNSkDomView.h"
#include "DrawingContext.h"
#include <chrono>
#include <utility>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdocumentation"
#include "include/core/SkFont.h"
#pragma clang diagnostic pop
namespace RNSkia {
RNSkDomRenderer::RNSkDomRenderer(std::function<void()> requestRedraw,
std::shared_ptr<RNSkPlatformContext> context)
: RNSkRenderer(requestRedraw), _platformContext(std::move(context)),
_renderLock(std::make_shared<std::timed_mutex>()),
_renderTimingInfo("SKIA/RENDER") {
auto style = SkFontStyle::Normal();
auto fontMgr = _platformContext->createFontMgr();
auto _typeface = fontMgr->matchFamilyStyle("Arial", style);
_font = SkFont(_typeface, 14);
}
RNSkDomRenderer::~RNSkDomRenderer() {
if (_root != nullptr) {
_root->dispose(true);
_root = nullptr;
}
}
bool RNSkDomRenderer::tryRender(
std::shared_ptr<RNSkCanvasProvider> canvasProvider) {
// We render on the main thread
if (_renderLock->try_lock()) {
bool result = false;
// If we have a Dom Node we can render directly on the main thread
if (_root != nullptr) {
result = canvasProvider->renderToCanvas(std::bind(
&RNSkDomRenderer::renderCanvas, this, std::placeholders::_1,
canvasProvider->getScaledWidth(), canvasProvider->getScaledHeight()));
}
_renderLock->unlock();
return result;
} else {
return false;
}
}
void RNSkDomRenderer::renderImmediate(
std::shared_ptr<RNSkCanvasProvider> canvasProvider) {
auto prevDebugOverlay = getShowDebugOverlays();
setShowDebugOverlays(false);
canvasProvider->renderToCanvas(std::bind(
&RNSkDomRenderer::renderCanvas, this, std::placeholders::_1,
canvasProvider->getScaledWidth(), canvasProvider->getScaledHeight()));
setShowDebugOverlays(prevDebugOverlay);
}
void RNSkDomRenderer::setRoot(std::shared_ptr<JsiDomRenderNode> node) {
std::lock_guard<std::mutex> lock(_rootLock);
if (_root != nullptr) {
_root->dispose(true);
_root = nullptr;
}
_root = node;
}
void RNSkDomRenderer::renderCanvas(SkCanvas *canvas, float scaledWidth,
float scaledHeight) {
_renderTimingInfo.beginTiming();
auto pd = _platformContext->getPixelDensity();
canvas->clear(SK_ColorTRANSPARENT);
canvas->save();
canvas->scale(pd, pd);
if (_drawingContext == nullptr) {
_drawingContext = std::make_shared<DrawingContext>();
_drawingContext->setRequestRedraw([weakSelf = weak_from_this()]() {
auto self = weakSelf.lock();
if (self) {
self->_requestRedraw();
}
});
}
_drawingContext->setScaledWidth(scaledWidth);
_drawingContext->setScaledHeight(scaledHeight);
// Update canvas before drawing
_drawingContext->setCanvas(canvas);
try {
// Ask the root node to render to the provided canvas
std::lock_guard<std::mutex> lock(_rootLock);
if (_root != nullptr) {
_root->commitPendingChanges();
_root->render(_drawingContext.get());
_root->resetPendingChanges();
}
} catch (std::runtime_error err) {
_platformContext->raiseError(err);
} catch (jsi::JSError err) {
_platformContext->raiseError(err);
} catch (...) {
_platformContext->raiseError(
std::runtime_error("Error rendering the Skia view."));
}
renderDebugOverlays(canvas);
canvas->restore();
_renderTimingInfo.stopTiming();
}
void RNSkDomRenderer::renderDebugOverlays(SkCanvas *canvas) {
if (!getShowDebugOverlays()) {
return;
}
auto renderAvg = _renderTimingInfo.getAverage();
auto fps = _renderTimingInfo.getFps();
// Build string
std::ostringstream stream;
stream << "render: " << renderAvg << "ms"
<< " fps: " << fps;
std::string debugString = stream.str();
// Set up debug font/paints
auto paint = SkPaint();
paint.setColor(SkColors::kRed);
canvas->drawSimpleText(debugString.c_str(), debugString.size(),
SkTextEncoding::kUTF8, 8, 18, _font, paint);
}
} // namespace RNSkia