rework GUI, scripts, and fiddle main for multiple simultaneous configs
You can now select Raster, Ganesh, or both (PDF coming soon), and see all output simultaneously. BUG=skia: R=jcgregorio@google.com TBR=jcgregorio Review URL: https://codereview.chromium.org/688433002
This commit is contained in:
parent
6eea9e7871
commit
af58b5fcba
@ -19,11 +19,13 @@
|
||||
|
||||
__SK_FORCE_IMAGE_DECODER_LINKING;
|
||||
|
||||
DEFINE_string(out, "", "Filename of the PNG to write to.");
|
||||
DEFINE_string(out, "", "Output basename; fiddle will append the config used and the appropriate extension");
|
||||
DEFINE_string(source, "", "Filename of the source image.");
|
||||
DEFINE_int32(width, 256, "Width of output image.");
|
||||
DEFINE_int32(height, 256, "Height of output image.");
|
||||
DEFINE_bool(gpu, false, "Use GPU (Mesa) rendering.");
|
||||
DEFINE_bool(raster, true, "Use Raster rendering.");
|
||||
DEFINE_bool(pdf, false, "Use PDF rendering.");
|
||||
|
||||
// Defined in template.cpp.
|
||||
extern SkBitmap source;
|
||||
@ -98,6 +100,44 @@ static void setLimits() {
|
||||
|
||||
extern void draw(SkCanvas* canvas);
|
||||
|
||||
static void drawAndDump(SkSurface* surface, SkWStream* stream) {
|
||||
SkCanvas *canvas = surface->getCanvas();
|
||||
draw(canvas);
|
||||
|
||||
// Write out the image as a PNG.
|
||||
SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
|
||||
SkAutoTUnref<SkData> data(image->encode(SkImageEncoder::kPNG_Type, 100));
|
||||
if (NULL == data.get()) {
|
||||
printf("Failed to encode\n");
|
||||
exit(1);
|
||||
}
|
||||
stream->write(data->data(), data->size());
|
||||
}
|
||||
|
||||
static void drawRaster(SkWStream* stream, SkImageInfo info) {
|
||||
SkAutoTUnref<SkSurface> surface;
|
||||
surface.reset(SkSurface::NewRaster(info));
|
||||
drawAndDump(surface, stream);
|
||||
}
|
||||
|
||||
static void drawGPU(SkWStream* stream, SkImageInfo info) {
|
||||
SkAutoTUnref<SkSurface> surface;
|
||||
GrContextFactory* grFactory = NULL;
|
||||
|
||||
GrContext::Options grContextOpts;
|
||||
grFactory = new GrContextFactory(grContextOpts);
|
||||
GrContext* gr = grFactory->get(GrContextFactory::kMESA_GLContextType);
|
||||
surface.reset(SkSurface::NewRenderTarget(gr,info));
|
||||
|
||||
drawAndDump(surface, stream);
|
||||
|
||||
delete grFactory;
|
||||
}
|
||||
|
||||
static void drawPDF(SkWStream* stream, SkImageInfo info) {
|
||||
printf( "Not implemented yet...\n");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
SkCommandLineFlags::Parse(argc, argv);
|
||||
SkAutoGraphics init;
|
||||
@ -119,41 +159,42 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
SkFILEWStream stream(FLAGS_out[0]);
|
||||
// make sure to open any needed output files before we set up the security
|
||||
// jail
|
||||
|
||||
SkWStream* streams[3];
|
||||
|
||||
if (FLAGS_raster) {
|
||||
SkString outPath;
|
||||
outPath.printf("%s_raster.png", FLAGS_out[0]);
|
||||
streams[0] = SkNEW_ARGS(SkFILEWStream,(outPath.c_str()));
|
||||
}
|
||||
if (FLAGS_gpu) {
|
||||
SkString outPath;
|
||||
outPath.printf("%s_gpu.png", FLAGS_out[0]);
|
||||
streams[1] = SkNEW_ARGS(SkFILEWStream,(outPath.c_str()));
|
||||
}
|
||||
if (FLAGS_pdf) {
|
||||
SkString outPath;
|
||||
outPath.printf("%s.pdf", FLAGS_out[0]);
|
||||
streams[2] = SkNEW_ARGS(SkFILEWStream,(outPath.c_str()));
|
||||
}
|
||||
|
||||
SkImageInfo info = SkImageInfo::MakeN32(FLAGS_width, FLAGS_height, kPremul_SkAlphaType);
|
||||
|
||||
SkCanvas* canvas;
|
||||
SkAutoTUnref<SkSurface> surface;
|
||||
|
||||
GrContextFactory* grFactory = NULL;
|
||||
|
||||
if (FLAGS_gpu) {
|
||||
GrContext::Options grContextOpts;
|
||||
grFactory = new GrContextFactory(grContextOpts);
|
||||
GrContext* gr = grFactory->get(GrContextFactory::kMESA_GLContextType);
|
||||
surface.reset(SkSurface::NewRenderTarget(gr,info));
|
||||
} else {
|
||||
surface.reset(SkSurface::NewRaster(info));
|
||||
}
|
||||
|
||||
canvas = surface->getCanvas();
|
||||
|
||||
setLimits();
|
||||
|
||||
if (!install_syscall_filter()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
draw(canvas);
|
||||
|
||||
// Write out the image as a PNG.
|
||||
SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
|
||||
SkAutoTUnref<SkData> data(image->encode(SkImageEncoder::kPNG_Type, 100));
|
||||
if (NULL == data.get()) {
|
||||
printf("Failed to encode\n");
|
||||
exit(1);
|
||||
if (FLAGS_raster) {
|
||||
drawRaster(streams[0], info);
|
||||
}
|
||||
if (FLAGS_gpu) {
|
||||
drawGPU(streams[1], info);
|
||||
}
|
||||
if (FLAGS_pdf) {
|
||||
drawPDF(streams[2], info);
|
||||
}
|
||||
stream.write(data->data(), data->size());
|
||||
delete grFactory;
|
||||
}
|
||||
|
@ -26,7 +26,12 @@
|
||||
var output = document.getElementById('output');
|
||||
var outputWrapper = document.getElementById('output-wrapper');
|
||||
var gpu = document.getElementById('use-gpu');
|
||||
var img = document.getElementById('img');
|
||||
var raster = document.getElementById('use-raster');
|
||||
var pdf = document.getElementById('use-pdf');
|
||||
var rasterOutput = document.getElementById('raster-output');
|
||||
var rasterImg = document.getElementById('raster-img');
|
||||
var gpuOutput = document.getElementById('gpu-output');
|
||||
var gpuImg = document.getElementById('gpu-img');
|
||||
var imageWidth = document.getElementById('image-width');
|
||||
var imageHeight = document.getElementById('image-height');
|
||||
var tryHistory = document.getElementById('tryHistory');
|
||||
@ -148,6 +153,20 @@
|
||||
enableSource.addEventListener('click', sourceClick, true);
|
||||
selectedSource.addEventListener('click', sourceClick, true);
|
||||
|
||||
function configChange(e) {
|
||||
if (!(gpu.checked || raster.checked || pdf.checked)) {
|
||||
run.disabled = true;
|
||||
run.innerHTML = "Choose a configuration"
|
||||
} else {
|
||||
run.disabled = false;
|
||||
run.innerHTML = "Run"
|
||||
}
|
||||
}
|
||||
|
||||
gpu.addEventListener('change', configChange);
|
||||
raster.addEventListener('change', configChange);
|
||||
pdf.addEventListener('change', configChange);
|
||||
|
||||
|
||||
var editor = CodeMirror.fromTextArea(code, {
|
||||
theme: "default",
|
||||
@ -217,7 +236,8 @@
|
||||
body = JSON.parse(e.target.response);
|
||||
code.value = body.code;
|
||||
editor.setValue(body.code);
|
||||
img.src = '/i/'+body.hash+'.png';
|
||||
rasterImg.src = '/i/'+body.hash+'_raster.png';
|
||||
gpuImg.src = '/i/'+body.hash+'_gpu.png';
|
||||
imageWidth.value = body.width;
|
||||
imageHeight.value = body.height;
|
||||
gpu.checked = body.gpu;
|
||||
@ -304,14 +324,23 @@
|
||||
outputWrapper.style.display = 'block';
|
||||
}
|
||||
}
|
||||
if (body.hasOwnProperty('img')) {
|
||||
img.src = 'data:image/png;base64,' + body.img;
|
||||
if (body.hasOwnProperty('rasterImg') && body.rasterImg != "") {
|
||||
rasterImg.src = 'data:image/png;base64,' + body.rasterImg;
|
||||
rasterOutput.style.display = "inline-block";
|
||||
} else {
|
||||
img.src = '';
|
||||
rasterOutput.style.display = "none";
|
||||
rasterImg.src = '';
|
||||
}
|
||||
if (body.hasOwnProperty('gpuImg') && body.gpuImg != "") {
|
||||
gpuImg.src = 'data:image/png;base64,' + body.gpuImg;
|
||||
gpuOutput.style.display = "inline-block";
|
||||
} else {
|
||||
gpuImg.src = '';
|
||||
gpuOutput.style.display = "none";
|
||||
}
|
||||
// Add the image to the history if we are on a workspace page.
|
||||
if (tryHistory) {
|
||||
addToHistory(body.hash, 'data:image/png;base64,' + body.img);
|
||||
addToHistory(body.hash, 'data:image/png;base64,' + body.rasterImg);
|
||||
} else {
|
||||
window.history.pushState(null, null, '/c/' + body.hash);
|
||||
}
|
||||
@ -327,7 +356,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function onSubmitCode() {
|
||||
beginWait();
|
||||
clearOutput();
|
||||
@ -343,7 +371,9 @@
|
||||
'height': parseInt(imageHeight.value),
|
||||
'name': workspaceName,
|
||||
'source': sourceId,
|
||||
'gpu': gpu.checked
|
||||
'gpu': gpu.checked,
|
||||
'raster': raster.checked,
|
||||
'pdf': pdf.checked
|
||||
}));
|
||||
}
|
||||
run.addEventListener('click', onSubmitCode);
|
||||
@ -375,3 +405,26 @@
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
// TODO (humper) -- move the following functions out of the global
|
||||
// namespace as part of a web-components based fiddle frontend rewrite.
|
||||
|
||||
function collectionHas(a, b) { //helper function (see below)
|
||||
for(var i = 0, len = a.length; i < len; i ++) {
|
||||
if(a[i] == b) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function findParentBySelector(elm, selector) {
|
||||
var all = document.querySelectorAll(selector);
|
||||
var cur = elm.parentNode;
|
||||
while(cur && !collectionHas(all, cur)) { //keep going up until you find a match
|
||||
cur = cur.parentNode; //go up
|
||||
}
|
||||
return cur; //will return null if not found
|
||||
}
|
||||
|
||||
function onLoadImage(img) {
|
||||
var wrapper = findParentBySelector(img, ".image-wrapper");
|
||||
wrapper.style.display = "inline-block";
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -118,6 +118,10 @@ code {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#chooseSource {
|
||||
display: none;
|
||||
}
|
||||
|
@ -8,4 +8,4 @@
|
||||
[ -z $SKIA_ROOT ] && SKIA_ROOT="/skia_build/skia"
|
||||
[ -z $WEBTRY_INOUT ] && WEBTRY_INOUT="/skia_build/inout"
|
||||
|
||||
$SKIA_ROOT/out/Release/$1 --out $WEBTRY_INOUT/$1.png "${@:2}"
|
||||
$SKIA_ROOT/out/Release/$1 --out $WEBTRY_INOUT/$1 "${@:2}"
|
||||
|
@ -51,9 +51,28 @@
|
||||
<input type="text" value="" id="embed" readonly style="display:none;">
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<img touch-action='none' class='zoom' id='img' src='{{if .Hash}}/i/{{.Hash}}.png{{end}}'/>
|
||||
</p>
|
||||
<div id="raster-output" class="image-wrapper panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
Raster Output
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<img touch-action='none' class='zoom' id='raster-img' onload="onLoadImage(this)" src='{{if .Hash}}/i/{{.Hash}}_raster.png{{end}}'/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="gpu-output" class="image-wrapper panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
Ganesh Output
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<img touch-action='none' class='zoom' id='gpu-img' onload="onLoadImage(this)" src='{{if .Hash}}/i/{{.Hash}}_gpu.png{{end}}'/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p id='zoomHex'></p>
|
||||
|
||||
<div id="output-wrapper">
|
||||
|
@ -1,9 +0,0 @@
|
||||
<link rel='stylesheet' href='/res/webtry/css/webtry.css' type='text/css'>
|
||||
<link rel='stylesheet' href='/res/css/cm/codemirror.css' type='text/css'>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
<script src="/res/webtry/js/bootstrap.js"></script>
|
||||
<script src='/res/js/polyfill.js' type='text/javascript'></script>
|
||||
<script src='/res/js/cm/codemirror.js' type='text/javascript'></script>
|
||||
<script src='/res/js/cm/clike.js' type='text/javascript'></script>
|
||||
<script src='/res/js/webtry.js' type='text/javascript'></script>
|
@ -1,2 +1,12 @@
|
||||
<meta charset='utf-8' />
|
||||
<meta name=viewport content='width=device-width, initial-scale=1'>
|
||||
|
||||
<link rel='stylesheet' href='/res/webtry/css/webtry.css' type='text/css'>
|
||||
<link rel='stylesheet' href='/res/css/cm/codemirror.css' type='text/css'>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
|
||||
<script src="/res/webtry/js/bootstrap.js"></script>
|
||||
<script src='/res/js/polyfill.js' type='text/javascript'></script>
|
||||
<script src='/res/js/cm/codemirror.js' type='text/javascript'></script>
|
||||
<script src='/res/js/cm/clike.js' type='text/javascript'></script>
|
||||
<script src='/res/js/webtry.js' type='text/javascript'></script>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
Options
|
||||
Fiddle Options
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@ -19,12 +19,35 @@
|
||||
<input type="number" class="form-control" id="image-height" value="{{.Height}}">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
Run Configuration
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form id="run-configuration" class="form-horizontal" role="form">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input id="use-raster" type="checkbox" value="" checked>
|
||||
Raster
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input id="use-gpu" type="checkbox" value="">
|
||||
Ganesh
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input id="use-pdf" type="checkbox" value="" disabled>
|
||||
PDF (coming soon)
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -79,7 +79,7 @@ var (
|
||||
iframeLink = regexp.MustCompile("^/iframe/([a-f0-9]+)$")
|
||||
|
||||
// imageLink is the regex that matches URLs paths that are direct links to PNGs.
|
||||
imageLink = regexp.MustCompile("^/i/([a-z0-9-]+.png)$")
|
||||
imageLink = regexp.MustCompile("^/i/([a-z0-9-_]+.png)$")
|
||||
|
||||
// tryInfoLink is the regex that matches URLs paths that are direct links to data about a single try.
|
||||
tryInfoLink = regexp.MustCompile("^/json/([a-f0-9]+)$")
|
||||
@ -407,7 +407,8 @@ func expandGyp(hash string) error {
|
||||
type response struct {
|
||||
Message string `json:"message"`
|
||||
CompileErrors []compileError `json:"compileErrors"`
|
||||
Img string `json:"img"`
|
||||
RasterImg string `json:"rasterImg"`
|
||||
GPUImg string `json:"gpuImg"`
|
||||
Hash string `json:"hash"`
|
||||
}
|
||||
|
||||
@ -724,6 +725,8 @@ type TryRequest struct {
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
GPU bool `json:"gpu"`
|
||||
Raster bool `json:"raster"`
|
||||
PDF bool `json:"pdf"`
|
||||
Name string `json:"name"` // Optional name of the workspace the code is in.
|
||||
Source int `json:"source"` // ID of the source image, 0 if none.
|
||||
}
|
||||
@ -858,6 +861,10 @@ func mainHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reportTryError(w, r, err, "Coulnd't decode JSON.", "")
|
||||
return
|
||||
}
|
||||
if !(request.GPU || request.Raster || request.PDF) {
|
||||
reportTryError(w, r, nil, "No run configuration supplied...", "")
|
||||
return
|
||||
}
|
||||
if hasPreProcessor(request.Code) {
|
||||
err := fmt.Errorf("Found preprocessor macro in code.")
|
||||
reportTryError(w, r, err, "Preprocessor macros aren't allowed.", "")
|
||||
@ -875,9 +882,15 @@ func mainHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
cmd := fmt.Sprintf("scripts/fiddle_wrapper %s --width %d --height %d", hash, request.Width, request.Height)
|
||||
if request.Raster {
|
||||
cmd += " --raster"
|
||||
}
|
||||
if request.GPU {
|
||||
cmd += " --gpu"
|
||||
}
|
||||
if request.PDF {
|
||||
cmd += " --pdf"
|
||||
}
|
||||
if *useChroot {
|
||||
cmd = "schroot -c webtry --directory=/ -- /skia_build/skia/experimental/webtry/" + cmd
|
||||
}
|
||||
@ -920,16 +933,30 @@ func mainHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
png, err := ioutil.ReadFile("../../../inout/" + hash + ".png")
|
||||
if err != nil {
|
||||
reportTryError(w, r, err, "Failed to open the generated PNG.", hash)
|
||||
return
|
||||
}
|
||||
|
||||
m := response{
|
||||
Img: base64.StdEncoding.EncodeToString([]byte(png)),
|
||||
Hash: hash,
|
||||
}
|
||||
|
||||
if request.Raster {
|
||||
png, err := ioutil.ReadFile("../../../inout/" + hash + "_raster.png")
|
||||
if err != nil {
|
||||
reportTryError(w, r, err, "Failed to open the raster-generated PNG.", hash)
|
||||
return
|
||||
}
|
||||
|
||||
m.RasterImg = base64.StdEncoding.EncodeToString([]byte(png))
|
||||
}
|
||||
|
||||
if request.GPU {
|
||||
png, err := ioutil.ReadFile("../../../inout/" + hash + "_GPU.png")
|
||||
if err != nil {
|
||||
reportTryError(w, r, err, "Failed to open the GPU-generated PNG.", hash)
|
||||
return
|
||||
}
|
||||
|
||||
m.GPUImg = base64.StdEncoding.EncodeToString([]byte(png))
|
||||
}
|
||||
|
||||
resp, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
reportTryError(w, r, err, "Failed to serialize a response.", hash)
|
||||
|
Loading…
Reference in New Issue
Block a user