Last active
February 28, 2024 01:31
-
-
Save rsms/2b53bee10921bc9905db866a759ba537 to your computer and use it in GitHub Desktop.
Demonstrates a method for remote rendering with Skia. First run build-skia-macos.sh, then make and finally ./remote-render
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
cd "$(dirname "$0")" | |
if [ ! -d depot_tools ]; then | |
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git | |
fi | |
export PATH="$PWD/depot_tools:$PATH" | |
if [ ! -d skia ]; then | |
git clone https://skia.googlesource.com/skia.git | |
fi | |
_begin() { | |
echo | |
echo ">> $@" | |
} | |
cd skia | |
python2 tools/git-sync-deps | |
_begin "bin/gn gen out/Release" | |
rm -rf out/Release | |
bin/gn gen out/Release --args="\ | |
is_official_build=true \ | |
skia_use_libjpeg_turbo_decode=false \ | |
skia_use_libjpeg_turbo_encode=false \ | |
skia_use_system_libpng=false \ | |
skia_use_system_zlib=false \ | |
skia_use_system_harfbuzz=false \ | |
skia_use_system_icu=false \ | |
skia_use_libwebp_decode=false \ | |
skia_use_libwebp_encode=false \ | |
skia_use_metal=true" | |
_begin "ninja -C out/Release" | |
ninja -C out/Release |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SRCROOT := $(shell pwd) | |
SYSTEM := $(shell uname -s) | |
OBJDIR := .build | |
SKIA_DIR := skia | |
SOURCES := remote-render.cc | |
# skia-compatible config sourced from skia/out/Release/obj/remote_demo.ninja | |
# via temporarily configuring Skia with skia_enable_tools=true | |
CFLAGS := -g -ffile-prefix-map=$(SRCROOT)/= -MMD \ | |
-fstrict-aliasing \ | |
-fPIC \ | |
-fvisibility=hidden \ | |
-DDEBUG | |
CXXFLAGS := \ | |
-std=c++17 \ | |
-fvisibility-inlines-hidden \ | |
-fno-exceptions \ | |
-fno-rtti | |
LDFLAGS := -Wl,-rpath,@loader_path/. -Wl,-w -dead_strip | |
SKIA_LIB_CFLAGS := -I$(SKIA_DIR) \ | |
-DSK_ASSUME_GL=1 \ | |
-DSK_CODEC_DECODES_PNG \ | |
-DSK_ENABLE_API_AVAILABLE \ | |
-DSK_ENCODE_PNG \ | |
-DSK_GAMMA_APPLY_TO_A8 \ | |
-DSK_GL \ | |
-DSK_SUPPORT_PDF \ | |
-DSK_USE_LIBGIFCODEC \ | |
-DSK_XML | |
SKIA_LIB_LDFLAGS := $(SKIA_DIR)/out/Release/libskia.a -ldl -lexpat | |
ifeq ($(SYSTEM),Darwin) | |
SKIA_LIB_CFLAGS += -DSK_METAL | |
SKIA_LIB_LDFLAGS += \ | |
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk \ | |
-framework ApplicationServices \ | |
-framework OpenGL \ | |
-framework AppKit \ | |
-framework Quartz \ | |
-framework Metal \ | |
-framework Foundation | |
endif | |
CFLAGS += $(SKIA_LIB_CFLAGS) | |
OBJS := $(patsubst %,$(OBJDIR)/%.o,$(subst $(SKIA_DIR)/,skia/,$(SOURCES))) | |
DEPS := ${OBJS:.o=.d} | |
-include $(DEPS) | |
all: remote-render | |
remote-render: $(OBJS) | |
@echo "link $@ ($(foreach fn,$^,$(notdir ${fn:.o=})))" | |
$(CXX) $(LDFLAGS) $(SKIA_LIB_LDFLAGS) -o $@ $^ | |
$(OBJDIR)/%.cc.o: %.cc | |
@echo "cc $<" | |
@mkdir -p $(dir $@) | |
$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ -c $< | |
clean: | |
rm -rfv $(OBJDIR) remote-render | |
.PHONY: all clean |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "include/core/SkCanvas.h" | |
#include "include/core/SkSurface.h" | |
#include "include/core/SkPicture.h" | |
#include "include/core/SkPictureRecorder.h" | |
void save_png_file(sk_sp<SkSurface> surface, const char* filename) { | |
sk_sp<SkData> imageData = | |
surface->makeImageSnapshot()->encodeToData(SkEncodedImageFormat::kPNG, /*quality*/100); | |
FILE* fp = fopen(filename, "w"); | |
fwrite(imageData->data(), imageData->size(), 1, fp); | |
fclose(fp); | |
} | |
void draw(SkCanvas* canvas) { | |
canvas->save(); | |
canvas->clear(SK_ColorWHITE); | |
SkPaint paint; | |
paint.setAntiAlias(true); | |
paint.setColor(SK_ColorRED); | |
canvas->drawCircle(200, 200, 64, paint); | |
canvas->restore(); | |
} | |
sk_sp<SkData> simulate_client(int w, int h) { | |
SkPictureRecorder recorder; | |
SkCanvas* canvas = recorder.beginRecording(SkRect::MakeWH(w, h), /*bbh*/nullptr); | |
draw(canvas); | |
sk_sp<SkPicture> pic = recorder.finishRecordingAsPicture(); | |
return pic->serialize(); | |
} | |
void simulate_renderer(sk_sp<SkData> data) { | |
sk_sp<SkPicture> pic = SkPicture::MakeFromData(data.get()); | |
SkRect bounds = pic->cullRect(); | |
// setup a render surface, play back the draw commands from SkPicture and write to PNG | |
sk_sp<SkColorSpace> colorSpace; | |
SkAlphaType alphaType = SkAlphaType::kPremul_SkAlphaType; | |
SkColorType colorType = SkColorType::kRGBA_8888_SkColorType; | |
SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), colorType, alphaType, colorSpace); | |
sk_sp<SkSurface> surface = SkSurface::MakeRaster(info); | |
SkCanvas* canvas = surface->getCanvas(); | |
pic->playback(canvas, /*callback*/nullptr); | |
save_png_file(surface, "recorder1.png"); | |
} | |
int main(int argc, const char* argv[argc]) { | |
sk_sp<SkData> data = simulate_client(400, 400); | |
// in a real implementation, data would be transmitted over a socket or something here | |
simulate_renderer(data); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment