From bb865881cdce02af9266f7995c94d257434ac6b2 Mon Sep 17 00:00:00 2001 From: seven332 Date: Fri, 15 Dec 2023 19:35:56 +0800 Subject: [PATCH] feat: query sksl uniforms --- packages/extension/src/index.ts | 9 ++- packages/extension/src/runner-data.ts | 1 + packages/extension/src/server.ts | 9 ++- packages/lsp/package.json | 2 +- packages/lsp/src/index.ts | 2 + packages/lsp/src/runner-data.ts | 25 ++++++++ packages/lsp/src/sksl-server.ts | 9 +++ packages/wasm/c++/src/CMakeLists.txt | 22 ++++++- packages/wasm/c++/src/data.h | 10 +++ packages/wasm/c++/src/main.cpp | 16 +++++ packages/wasm/c++/src/runner/query.cpp | 61 +++++++++++++++++++ packages/wasm/c++/src/runner/query.h | 31 ++++++++++ .../wasm/c++/third_party/skia/CMakeLists.txt | 6 +- packages/wasm/src/sksl-wasm.d.ts | 1 + 14 files changed, 198 insertions(+), 6 deletions(-) create mode 100644 packages/extension/src/runner-data.ts create mode 100644 packages/lsp/src/index.ts create mode 100644 packages/lsp/src/runner-data.ts create mode 100644 packages/wasm/c++/src/runner/query.cpp create mode 100644 packages/wasm/c++/src/runner/query.h diff --git a/packages/extension/src/index.ts b/packages/extension/src/index.ts index e5aa4ee..c2bd5b4 100644 --- a/packages/extension/src/index.ts +++ b/packages/extension/src/index.ts @@ -2,6 +2,8 @@ import * as path from 'path' import * as vscode from 'vscode' import { LanguageClient, TransportKind } from 'vscode-languageclient/node' import * as fs from 'fs' +import { kQueryUrl } from './runner-data' +import { QueryResult } from '@workspace/lsp' let client: LanguageClient | undefined @@ -67,6 +69,11 @@ function showRunner(context: vscode.ExtensionContext, uri: vscode.Uri | undefine ) } -function selectSkSL(panel: vscode.WebviewPanel, uri: vscode.Uri) { +async function selectSkSL(panel: vscode.WebviewPanel, uri: vscode.Uri) { panel.webview.postMessage(uri.toString()) + const buffer = fs.readFileSync(uri.fsPath) + const result: QueryResult | undefined = await client?.sendRequest(kQueryUrl, { + source: buffer.toString(), + }) + console.log(result) } diff --git a/packages/extension/src/runner-data.ts b/packages/extension/src/runner-data.ts new file mode 100644 index 0000000..a183dad --- /dev/null +++ b/packages/extension/src/runner-data.ts @@ -0,0 +1 @@ +export const kQueryUrl = 'sksl/query' diff --git a/packages/extension/src/server.ts b/packages/extension/src/server.ts index 1767f42..559f0c3 100644 --- a/packages/extension/src/server.ts +++ b/packages/extension/src/server.ts @@ -1,6 +1,7 @@ import * as ls from 'vscode-languageserver/node' import * as lstd from 'vscode-languageserver-textdocument' -import { SkSLServer } from '@workspace/lsp' +import { QueryParams, SkSLServer } from '@workspace/lsp' +import { kQueryUrl } from './runner-data' const connection = ls.createConnection(ls.ProposedFeatures.all) const documents = new ls.TextDocuments(lstd.TextDocument) @@ -88,5 +89,11 @@ connection.onCompletion((params) => { return server?.completion(params.textDocument.uri, params.position) }) +// Runner + +connection.onRequest(kQueryUrl, (params: QueryParams) => { + return server?.query(params) +}) + documents.listen(connection) connection.listen() diff --git a/packages/lsp/package.json b/packages/lsp/package.json index e5182bb..11f87c4 100644 --- a/packages/lsp/package.json +++ b/packages/lsp/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "author": "seven332", "license": "MIT", - "main": "src/sksl-server.ts", + "main": "src/index.ts", "dependencies": { "@workspace/util": "workspace:*", "@workspace/wasm": "workspace:*", diff --git a/packages/lsp/src/index.ts b/packages/lsp/src/index.ts new file mode 100644 index 0000000..fec897b --- /dev/null +++ b/packages/lsp/src/index.ts @@ -0,0 +1,2 @@ +export * from './runner-data' +export * from './sksl-server' diff --git a/packages/lsp/src/runner-data.ts b/packages/lsp/src/runner-data.ts new file mode 100644 index 0000000..eb0a5db --- /dev/null +++ b/packages/lsp/src/runner-data.ts @@ -0,0 +1,25 @@ +export interface QueryParams { + source: string +} + +export interface SkSLUniform { + type: string + name: string +} + +export const dummySkSLUniform: SkSLUniform = { + type: '', + name: '', +} + +export interface QueryResult { + succeed: boolean + kind: string + uniforms: SkSLUniform[] +} + +export const dummyQueryResult: QueryResult = { + succeed: false, + kind: '', + uniforms: [dummySkSLUniform], +} diff --git a/packages/lsp/src/sksl-server.ts b/packages/lsp/src/sksl-server.ts index 7f3164b..e401a00 100644 --- a/packages/lsp/src/sksl-server.ts +++ b/packages/lsp/src/sksl-server.ts @@ -4,6 +4,7 @@ import * as ls from 'vscode-languageserver/node' import { FilePosition } from './file-position' import { UTFOffset, dummyUTFOffset } from './utf-offset-converter' import { decode, encode } from '@workspace/util' +import { QueryParams, QueryResult, dummyQueryResult } from './runner-data' export const kTokenTypes = [ 'class', @@ -257,6 +258,14 @@ export class SkSLServer { return result.items } + // Runner + + public query(params: QueryParams): QueryResult { + this.setParams(params) + this.wasm._Query() + return this.getResult(dummyQueryResult) + } + private files = new Map>() private documents = new Map() diff --git a/packages/wasm/c++/src/CMakeLists.txt b/packages/wasm/c++/src/CMakeLists.txt index 7b28d71..c853167 100644 --- a/packages/wasm/c++/src/CMakeLists.txt +++ b/packages/wasm/c++/src/CMakeLists.txt @@ -15,10 +15,30 @@ add_library(sksl-wasm-lib STATIC action/hover.cpp action/definition.cpp action/completion.cpp + runner/query.cpp ) target_include_directories(sksl-wasm-lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(sksl-wasm-lib PUBLIC skia_sksl) +set(EXPORTED_FUNCTIONS + _ToUTFOffsets + _SetParamsSize + _GetParamsPtr + _GetResultPtr + _GetResultSize + _Update + _Close + _GetSymbol + _Format + _GetToken + _GetTokenRange + _Hover + _Definition + _Completion + _Query +) +list(JOIN EXPORTED_FUNCTIONS "," EXPORTED_FUNCTIONS_JOINED) + add_executable(sksl-wasm main.cpp) target_link_libraries(sksl-wasm PRIVATE sksl-wasm-lib) target_link_options(sksl-wasm PRIVATE @@ -26,7 +46,7 @@ target_link_options(sksl-wasm PRIVATE -sENVIRONMENT=node -sMODULARIZE -sEXPORTED_RUNTIME_METHODS=ccall - -sEXPORTED_FUNCTIONS=_ToUTFOffsets,_SetParamsSize,_GetParamsPtr,_GetResultPtr,_GetResultSize,_Update,_Close,_GetSymbol,_Format,_GetToken,_GetTokenRange,_Hover,_Definition,_Completion + -sEXPORTED_FUNCTIONS=${EXPORTED_FUNCTIONS_JOINED} -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=32MB -sDISABLE_EXCEPTION_CATCHING=1 diff --git a/packages/wasm/c++/src/data.h b/packages/wasm/c++/src/data.h index 5918823..019d3c4 100644 --- a/packages/wasm/c++/src/data.h +++ b/packages/wasm/c++/src/data.h @@ -130,3 +130,13 @@ struct SkSLCompletion { Write(bytes, static_cast(value.kind)); } }; + +struct SkSLUniform { + std::string type; + std::string name; + + friend void Write(std::vector* bytes, const SkSLUniform& value) { + Write(bytes, value.type); + Write(bytes, value.name); + } +}; diff --git a/packages/wasm/c++/src/main.cpp b/packages/wasm/c++/src/main.cpp index 6dfce31..2cdefc4 100644 --- a/packages/wasm/c++/src/main.cpp +++ b/packages/wasm/c++/src/main.cpp @@ -14,6 +14,7 @@ #include "action/hover.h" #include "action/update.h" #include "module.h" +#include "runner/query.h" #include "utf_offset.h" static Modules modules; @@ -71,4 +72,19 @@ ACTION(Definition, "definition") ACTION(Completion, "completion") #undef ACTION + +#define RUNNER(Type, Name) \ + void Type() { \ + Type##Params params; \ + Read(params_bytes, 0, ¶ms); \ + std::cout << Name " start" << '\n'; \ + auto result = Type(std::move(params)); \ + std::cout << Name " end" << '\n'; \ + result_bytes.clear(); \ + Write(&result_bytes, result); \ + } + +RUNNER(Query, "query") + +#undef RUNNER } diff --git a/packages/wasm/c++/src/runner/query.cpp b/packages/wasm/c++/src/runner/query.cpp new file mode 100644 index 0000000..cf4cfb7 --- /dev/null +++ b/packages/wasm/c++/src/runner/query.cpp @@ -0,0 +1,61 @@ +#include "runner/query.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "kind.h" + +static std::unique_ptr CompileProgram(std::string source, SkSL::ProgramKind kind) { + SkSL::Compiler compiler(SkSL::ShaderCapsFactory::Standalone()); + SkSL::ProgramSettings settings; + settings.fUseMemoryPool = false; + settings.fOptimize = false; + settings.fForceNoInline = true; + if (SkSL::ProgramConfig::IsRuntimeEffect(kind)) { + settings.fAllowNarrowingConversions = true; + } + SkSL::Parser parser(&compiler, settings, kind, std::move(source)); + return parser.program(); +} + +QueryResult Query(QueryParams params) { + QueryResult result; + + auto kind_result = GetKind(params.source); + if (!kind_result) { + return result; + } + + auto kind = ToSkSLProgramKind(kind_result->str); + if (!kind) { + return result; + } + + auto program = CompileProgram(std::move(params.source), *kind); + if (!kind) { + return result; + } + + result.succeed = true; + result.kind = kind_result->str; + for (const auto& element : program->fOwnedElements) { + if (element->kind() == SkSL::ProgramElementKind::kGlobalVar) { + auto* var = element->as().varDeclaration().var(); + if (var->modifierFlags().isUniform()) { + result.uniforms.push_back(SkSLUniform {var->type().abbreviatedName(), std::string(var->name())}); + } + } + } + return result; +} diff --git a/packages/wasm/c++/src/runner/query.h b/packages/wasm/c++/src/runner/query.h new file mode 100644 index 0000000..9b7d619 --- /dev/null +++ b/packages/wasm/c++/src/runner/query.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +#include "data.h" +#include "simple_codec.h" + +struct QueryParams { + std::string source; + + friend std::size_t Read(std::span bytes, std::size_t offset, QueryParams* value) { + std::size_t read = 0; + read += Read(bytes, offset + read, &value->source); + return read; + } +}; + +struct QueryResult { + bool succeed = false; + std::string kind; + std::vector uniforms; + + friend void Write(std::vector* bytes, const QueryResult& value) { + Write(bytes, value.succeed); + Write(bytes, value.kind); + Write(bytes, value.uniforms); + } +}; + +QueryResult Query(QueryParams params); diff --git a/packages/wasm/c++/third_party/skia/CMakeLists.txt b/packages/wasm/c++/third_party/skia/CMakeLists.txt index ce13915..d8f7db7 100644 --- a/packages/wasm/c++/third_party/skia/CMakeLists.txt +++ b/packages/wasm/c++/third_party/skia/CMakeLists.txt @@ -5,6 +5,8 @@ cmake_path(SET SKIA_SOURCE_DIR NORMALIZE ${CMAKE_CURRENT_SOURCE_DIR}/../external cmake_path(SET SKIA_CMAKE_DIR NORMALIZE ${CMAKE_CURRENT_BINARY_DIR}/cmake) add_library(skia_sksl STATIC + ${SKIA_SOURCE_DIR}/src/core/SkRasterPipeline.cpp + ${SKIA_SOURCE_DIR}/src/sksl/SkSLAnalysis.cpp ${SKIA_SOURCE_DIR}/src/sksl/SkSLBuiltinTypes.cpp ${SKIA_SOURCE_DIR}/src/sksl/SkSLCompiler.cpp @@ -40,8 +42,8 @@ add_library(skia_sksl STATIC # ${SKIA_SOURCE_DIR}/src/sksl/analysis/SkSLReturnsInputAlpha.cpp ${SKIA_SOURCE_DIR}/src/sksl/analysis/SkSLSwitchCaseContainsExit.cpp ${SKIA_SOURCE_DIR}/src/sksl/analysis/SkSLSymbolTableStackBuilder.cpp - # ${SKIA_SOURCE_DIR}/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp - # ${SKIA_SOURCE_DIR}/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp + ${SKIA_SOURCE_DIR}/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp + ${SKIA_SOURCE_DIR}/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp ${SKIA_SOURCE_DIR}/src/sksl/ir/SkSLBinaryExpression.cpp ${SKIA_SOURCE_DIR}/src/sksl/ir/SkSLBlock.cpp ${SKIA_SOURCE_DIR}/src/sksl/ir/SkSLChildCall.cpp diff --git a/packages/wasm/src/sksl-wasm.d.ts b/packages/wasm/src/sksl-wasm.d.ts index 475b9e4..daf0a27 100644 --- a/packages/wasm/src/sksl-wasm.d.ts +++ b/packages/wasm/src/sksl-wasm.d.ts @@ -15,6 +15,7 @@ export interface SkSLWasm extends EmscriptenModule { _Hover(): void _Definition(): void _Completion(): void + _Query(): void } export default function createSkSLWasm(moduleOverrides?: Partial): Promise