int handle(Request* request, MHD_Connection* connection, const char* url, const char* method, const char* upload_data, size_t* upload_data_size) override { SkTArray<SkString> commands; SkStrSplit(url, "/", &commands); if (!request->fPicture.get() || commands.count() > 3) { return MHD_NO; } // /cmd or /cmd/N or /cmd/N/[0|1] if (commands.count() == 1 && 0 == strcmp(method, MHD_HTTP_METHOD_GET)) { int n = request->fDebugCanvas->getSize() - 1; return SendJSON(connection, request->fDebugCanvas, n); } // /cmd/N, for now only delete supported if (commands.count() == 2 && 0 == strcmp(method, MHD_HTTP_METHOD_DELETE)) { int n; sscanf(commands[1].c_str(), "%d", &n); request->fDebugCanvas->deleteDrawCommandAt(n); return MHD_YES; } // /cmd/N/[0|1] if (commands.count() == 3 && 0 == strcmp(method, MHD_HTTP_METHOD_POST)) { int n, toggle; sscanf(commands[1].c_str(), "%d", &n); sscanf(commands[2].c_str(), "%d", &toggle); request->fDebugCanvas->toggleCommand(n, toggle); return MHD_YES; } return MHD_NO; }
SkCommandLineConfigGpu* parse_command_line_config_gpu(const SkString& tag, const SkTArray<SkString>& vias, const SkString& options) { // Defaults for GPU backend. bool seenAPI = false; SkCommandLineConfigGpu::ContextType contextType = GrContextFactory::kNative_GLContextType; bool seenUseNVPR = false; bool useNVPR = false; bool seenUseDIText =false; bool useDIText = false; bool seenSamples = false; int samples = 0; SkTArray<SkString> optionParts; SkStrSplit(options.c_str(), ",", kStrict_SkStrSplitMode, &optionParts); for (int i = 0; i < optionParts.count(); ++i) { SkTArray<SkString> keyValueParts; SkStrSplit(optionParts[i].c_str(), "=", kStrict_SkStrSplitMode, &keyValueParts); if (keyValueParts.count() != 2) { return nullptr; } const SkString& key = keyValueParts[0]; const SkString& value = keyValueParts[1]; bool valueOk = false; if (key.equals("api") && !seenAPI) { valueOk = parse_option_gpu_api(value, &contextType); seenAPI = true; } else if (key.equals("nvpr") && !seenUseNVPR) { valueOk = parse_option_bool(value, &useNVPR); seenUseNVPR = true; } else if (key.equals("dit") && !seenUseDIText) { valueOk = parse_option_bool(value, &useDIText); seenUseDIText = true; } else if (key.equals("samples") && !seenSamples) { valueOk = parse_option_int(value, &samples); seenSamples = true; } if (!valueOk) { return nullptr; } } return new SkCommandLineConfigGpu(tag, vias, contextType, useNVPR, useDIText, samples); }
// Splits off the last N suffixes of name (splitting on _) and appends them to out. // Returns the total number of characters consumed. static int split_suffixes(int N, const char* name, SkTArray<SkString>* out) { SkTArray<SkString> split; SkStrSplit(name, "_", &split); int consumed = 0; for (int i = 0; i < N; i++) { // We're splitting off suffixes from the back to front. out->push_back(split[split.count()-i-1]); consumed += out->back().size() + 1; // Add one for the _. } return consumed; }
// Prints shaders one line at the time. This ensures they don't get truncated by the adb log. void PrintLineByLine(const char* header, const SkSL::String& text) { if (header) { SkDebugf("%s\n", header); } SkSL::String pretty = PrettyPrint(text); SkTArray<SkString> lines; SkStrSplit(pretty.c_str(), "\n", kStrict_SkStrSplitMode, &lines); for (int i = 0; i < lines.count(); ++i) { SkDebugf("%4i\t%s\n", i + 1, lines[i].c_str()); } }
int handle(Request* request, MHD_Connection* connection, const char* url, const char* method, const char* upload_data, size_t* upload_data_size) override { SkTArray<SkString> commands; SkStrSplit(url, "/", &commands); if (!request->fPicture.get() || commands.count() > 2) { return MHD_NO; } int n; // /img or /img/N if (commands.count() == 1) { n = request->fDebugCanvas->getSize() - 1; } else { sscanf(commands[1].c_str(), "%d", &n); } SkAutoTUnref<SkData> data(setupAndDrawToCanvasReturnPng(request->fDebugCanvas, n)); return SendData(connection, data, "image/png"); }
int handle(Request* request, MHD_Connection* connection, const char* url, const char* method, const char* upload_data, size_t* upload_data_size) override { SkTArray<SkString> commands; SkStrSplit(url, "/", &commands); if (!request->fPicture.get() || commands.count() > 2) { return MHD_NO; } // drawTo SkAutoTUnref<SkSurface> surface(setupCpuSurface()); SkCanvas* canvas = surface->getCanvas(); int n; // /info or /info/N if (commands.count() == 1) { n = request->fDebugCanvas->getSize() - 1; } else { sscanf(commands[1].c_str(), "%d", &n); } // TODO this is really slow and we should cache the matrix and clip request->fDebugCanvas->drawTo(canvas, n); // make some json SkMatrix vm = request->fDebugCanvas->getCurrentMatrix(); SkIRect clip = request->fDebugCanvas->getCurrentClip(); Json::Value info(Json::objectValue); info["ViewMatrix"] = SkJSONCanvas::MakeMatrix(vm); info["ClipRect"] = SkJSONCanvas::MakeIRect(clip); std::string json = Json::FastWriter().write(info); // We don't want the null terminator so strlen is correct SkAutoTUnref<SkData> data(SkData::NewWithCopy(json.c_str(), strlen(json.c_str()))); return SendData(connection, data, "application/json"); }
void android_main(struct android_app* state) { struct VisualBenchState visualBenchState; // Make sure glue isn't stripped. app_dummy(); state->userData = &visualBenchState; state->onAppCmd = handle_cmd; visualBenchState.fApp = state; // Get command line arguments JavaVM* jvm = state->activity->vm; JNIEnv *env; jvm->AttachCurrentThread(&env, 0); jobject me = state->activity->clazz; jclass acl = env->GetObjectClass(me); //class pointer of NativeActivity jmethodID giid = env->GetMethodID(acl, "getIntent", "()Landroid/content/Intent;"); jobject intent = env->CallObjectMethod(me, giid); //Got our intent jclass icl = env->GetObjectClass(intent); //class pointer of Intent jmethodID gseid = env->GetMethodID(icl, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;"); jstring jsParam1 = (jstring)env->CallObjectMethod(intent, gseid, env->NewStringUTF("cmdLineFlags")); if (jsParam1) { const char* flags = env->GetStringUTFChars(jsParam1, 0); SkStrSplit(flags, " ", &visualBenchState.fFlags); env->ReleaseStringUTFChars(jsParam1, flags); } jvm->DetachCurrentThread(); while (1) { // Read all pending events. int ident; int events; struct android_poll_source* source; // We loop until all events are read, then continue to draw the next frame of animation. while ((ident=ALooper_pollAll(0, nullptr, &events, (void**)&source)) >= 0) { // Process this event. if (source != nullptr) { source->process(state, source); } // Check if we are exiting. if (state->destroyRequested != 0) { return; } } if (visualBenchState.fWindow) { if (visualBenchState.fWindow->destroyRequested()) { visualBenchState.fState = kDestroyRequested_State; } else { visualBenchState.fWindow->update(nullptr); } } if (kDestroyRequested_State == visualBenchState.fState) { delete visualBenchState.fWindow; visualBenchState.fWindow = nullptr; application_term(); ANativeActivity_finish(state->activity); visualBenchState.fState = kFinished_State; } } }
int tool_main(int argc, char** argv) { SkCommandLineFlags::SetUsage("Render .skp files."); SkCommandLineFlags::Parse(argc, argv); if (FLAGS_readPath.isEmpty()) { SkDebugf(".skp files or directories are required.\n"); exit(-1); } if (FLAGS_maxComponentDiff < 0 || FLAGS_maxComponentDiff > 256) { SkDebugf("--maxComponentDiff must be between 0 and 256\n"); exit(-1); } if (FLAGS_maxComponentDiff != 256 && !FLAGS_validate) { SkDebugf("--maxComponentDiff requires --validate\n"); exit(-1); } if (FLAGS_writeEncodedImages) { if (FLAGS_writePath.isEmpty()) { SkDebugf("--writeEncodedImages requires --writePath\n"); exit(-1); } if (FLAGS_deferImageDecoding) { SkDebugf("--writeEncodedImages is not compatible with --deferImageDecoding\n"); exit(-1); } } SkString errorString; SkAutoTUnref<sk_tools::PictureRenderer> renderer(parseRenderer(errorString, kRender_PictureTool)); if (errorString.size() > 0) { SkDebugf("%s\n", errorString.c_str()); } if (renderer.get() == NULL) { exit(-1); } SkAutoGraphics ag; SkString writePath; if (FLAGS_writePath.count() == 1) { writePath.set(FLAGS_writePath[0]); } SkString mismatchPath; if (FLAGS_mismatchPath.count() == 1) { mismatchPath.set(FLAGS_mismatchPath[0]); } sk_tools::ImageResultsAndExpectations jsonSummary; sk_tools::ImageResultsAndExpectations* jsonSummaryPtr = NULL; if (FLAGS_writeJsonSummaryPath.count() == 1) { jsonSummaryPtr = &jsonSummary; if (FLAGS_readJsonSummaryPath.count() == 1) { SkASSERT(jsonSummary.readExpectationsFile(FLAGS_readJsonSummaryPath[0])); } } int failures = 0; for (int i = 0; i < FLAGS_readPath.count(); i ++) { failures += process_input(FLAGS_readPath[i], &writePath, &mismatchPath, *renderer.get(), jsonSummaryPtr); } if (failures != 0) { SkDebugf("Failed to render %i pictures.\n", failures); return 1; } #if GR_CACHE_STATS && SK_SUPPORT_GPU if (renderer->isUsingGpuDevice()) { GrContext* ctx = renderer->getGrContext(); ctx->printCacheStats(); } #endif #if GR_GPU_STATS && SK_SUPPORT_GPU if (FLAGS_gpuStats && renderer->isUsingGpuDevice()) { renderer->getGrContext()->printGpuStats(); } #endif if (FLAGS_writeJsonSummaryPath.count() == 1) { // If there were any descriptions on the command line, insert them now. for (int i=0; i<FLAGS_descriptions.count(); i++) { SkTArray<SkString> tokens; SkStrSplit(FLAGS_descriptions[i], "=", &tokens); SkASSERT(tokens.count() == 2); jsonSummary.addDescription(tokens[0].c_str(), tokens[1].c_str()); } if (FLAGS_imageBaseGSUrl.count() == 1) { jsonSummary.setImageBaseGSUrl(FLAGS_imageBaseGSUrl[0]); } jsonSummary.writeToFile(FLAGS_writeJsonSummaryPath[0]); } return 0; }
void ParseConfigs(const SkCommandLineFlags::StringArray& configs, SkCommandLineConfigArray* outResult) { outResult->reset(); for (int i = 0; i < configs.count(); ++i) { SkString extendedBackend; SkString extendedOptions; SkString simpleBackend; SkTArray<SkString> vias; SkString tag(configs[i]); SkTArray<SkString> parts; SkStrSplit(tag.c_str(), "(", kStrict_SkStrSplitMode, &parts); if (parts.count() == 2) { SkTArray<SkString> parts2; SkStrSplit(parts[1].c_str(), ")", kStrict_SkStrSplitMode, &parts2); if (parts2.count() == 2 && parts2[1].isEmpty()) { SkStrSplit(parts[0].c_str(), "-", kStrict_SkStrSplitMode, &vias); if (vias.count()) { extendedBackend = vias[vias.count() - 1]; vias.pop_back(); } else { extendedBackend = parts[0]; } extendedOptions = parts2[0]; simpleBackend.printf("%s(%s)", extendedBackend.c_str(), extendedOptions.c_str()); } } if (extendedBackend.isEmpty()) { simpleBackend = tag; SkStrSplit(tag.c_str(), "-", kStrict_SkStrSplitMode, &vias); if (vias.count()) { simpleBackend = vias[vias.count() - 1]; vias.pop_back(); } // Note: no #if SK_ANGLE: this is a special rule in the via-tag grammar. if (vias.count() && simpleBackend.equals("gl") && vias[vias.count() - 1].equals("angle")) { simpleBackend = "angle-gl"; vias.pop_back(); } for (auto& predefinedConfig : gPredefinedConfigs) { if (simpleBackend.equals(predefinedConfig.predefinedConfig)) { extendedBackend = predefinedConfig.backend; extendedOptions = predefinedConfig.options; break; } } } SkCommandLineConfig* parsedConfig = nullptr; #if SK_SUPPORT_GPU if (extendedBackend.equals("gpu")) { parsedConfig = parse_command_line_config_gpu(tag, vias, extendedOptions); } #endif if (!parsedConfig) { parsedConfig = new SkCommandLineConfig(tag, simpleBackend, vias); } outResult->emplace_back(parsedConfig); } }