add ganesh checkbox to skfiddle interface

BUG=skia:
R=mtklein@google.com, tfarina@chromium.org

Review URL: https://codereview.chromium.org/649313002
This commit is contained in:
Greg Humphreys 2014-10-13 18:12:33 -04:00
parent 380d7d7339
commit ccb54895c6
8 changed files with 79 additions and 28 deletions

View File

@ -1,6 +1,8 @@
#include <sys/time.h>
#include <sys/resource.h>
#include "GrContextFactory.h"
#include "SkCanvas.h"
#include "SkCommandLineFlags.h"
#include "SkData.h"
@ -21,6 +23,7 @@ DEFINE_string(out, "", "Filename of the PNG to write to.");
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.");
// Defined in template.cpp.
extern SkBitmap source;
@ -119,8 +122,22 @@ int main(int argc, char** argv) {
SkFILEWStream stream(FLAGS_out[0]);
SkImageInfo info = SkImageInfo::MakeN32(FLAGS_width, FLAGS_height, kPremul_SkAlphaType);
SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
SkCanvas* canvas = surface->getCanvas();
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();
@ -138,4 +155,5 @@ int main(int argc, char** argv) {
exit(1);
}
stream.write(data->data(), data->size());
delete grFactory;
}

View File

@ -25,6 +25,7 @@
var code = document.getElementById('code');
var output = document.getElementById('output');
var stdout = document.getElementById('stdout');
var gpu = document.getElementById('use-gpu');
var img = document.getElementById('img');
var imageWidth = document.getElementById('image-width');
var imageHeight = document.getElementById('image-height');
@ -215,6 +216,7 @@
img.src = '/i/'+body.hash+'.png';
imageWidth.value = body.width;
imageHeight.value = body.height;
gpu.checked = body.gpu;
sourceSelectByID(body.source);
if (permalink) {
permalink.href = '/c/' + body.hash;
@ -293,7 +295,14 @@
req.overrideMimeType('application/json');
req.open('POST', '/', true);
req.setRequestHeader('content-type', 'application/json');
req.send(JSON.stringify({'code': editor.getValue(), 'width': parseInt(imageWidth.value), 'height': parseInt(imageHeight.value), 'name': workspaceName, 'source': sourceId}));
req.send(JSON.stringify({
'code': editor.getValue(),
'width': parseInt(imageWidth.value),
'height': parseInt(imageHeight.value),
'name': workspaceName,
'source': sourceId,
'gpu': gpu.checked
}));
}
run.addEventListener('click', onSubmitCode);

View File

@ -11,4 +11,4 @@
[ -z "$WEBTRY_CACHE_DIR" ] && WEBTRY_CACHE_DIR="../../../../cache"
cp $WEBTRY_CACHE_DIR/$1.gyp $SKIA_ROOT/gyp
(cd $SKIA_ROOT ; ./gyp_skia gyp/$1.gyp gyp/most.gyp -D skia_gpu=0)
(cd $SKIA_ROOT ; ./gyp_skia gyp/$1.gyp gyp/most.gyp -Dskia_mesa=1)

View File

@ -36,6 +36,6 @@ git checkout master
# wget https://codereview.chromium.org/download/$PATCH
# git apply $PATCH
SKIA_GYP_OUTPUT_DIR=${SKIA_BUILD}/skia/out GYP_GENERATORS=ninja ./gyp_skia -Dskia_gpu=0
SKIA_GYP_OUTPUT_DIR=${SKIA_BUILD}/skia/out GYP_GENERATORS=ninja ./gyp_skia -Dskia_mesa=1
ninja -C ${SKIA_BUILD}/skia/out/Release skia_lib libjpeg libSkKTX libetc1 flags sk_tool_utils resources

View File

@ -1,6 +1,6 @@
apt-get install -y g++ libfreetype6 libfreetype6-dev libpng12-0 libpng12-dev \
libglu1-mesa-dev mesa-common-dev freeglut3-dev libgif-dev libfontconfig \
libfontconfig-dev git python wget
libfontconfig-dev git python wget libpoppler-cpp-dev libosmesa6-dev
mkdir /skia_build
chmod 777 /skia_build

View File

@ -19,6 +19,12 @@
<input type="number" class="form-control" id="image-height" value="{{.Height}}">
</div>
</div>
<div class="checkbox">
<label>
<input id="use-gpu" type="checkbox" value=""{{if .GPU}} checked{{end}}>
Ganesh
</label>
</div>
</form>
</div>
</div>

View File

@ -19,6 +19,7 @@
'include_dirs': [
'../include/config',
'../include/core',
'../include/gpu',
'../tools/flags',
'../src/core',
],

View File

@ -255,8 +255,9 @@ func init() {
code TEXT DEFAULT '' NOT NULL,
create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
hash CHAR(64) DEFAULT '' NOT NULL,
width INTEGER DEFAULT 256 NOT NULL,
height INTEGER DEFAULT 256 NOT NULL,
width INTEGER DEFAULT 256 NOT NULL,
height INTEGER DEFAULT 256 NOT NULL,
gpu BOOL DEFAULT 0 NOT NULL,
source_image_id INTEGER DEFAULT 0 NOT NULL,
PRIMARY KEY(hash)
@ -280,8 +281,9 @@ func init() {
name CHAR(64) DEFAULT '' NOT NULL,
create_ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
hash CHAR(64) DEFAULT '' NOT NULL,
width INTEGER DEFAULT 256 NOT NULL,
height INTEGER DEFAULT 256 NOT NULL,
width INTEGER DEFAULT 256 NOT NULL,
height INTEGER DEFAULT 256 NOT NULL,
gpu BOOL DEFAULT 0 NOT NULL,
hidden INTEGER DEFAULT 0 NOT NULL,
source_image_id INTEGER DEFAULT 0 NOT NULL,
@ -354,6 +356,7 @@ type userCode struct {
Hash string
Width int
Height int
GPU bool
Source int
Titlebar Titlebar
}
@ -380,13 +383,17 @@ func expandToFile(filename string, code string, t *template.Template) error {
// expandCode expands the template into a file and calculates the MD5 hash.
// We include the width and height here so that a single hash can capture
// both the code and the supplied width/height parameters.
func expandCode(code string, source int, width, height int) (string, error) {
func expandCode(code string, source int, width, height int, gpu bool) (string, error) {
// in order to support fonts in the chroot jail, we need to make sure
// we're using portable typefaces.
// TODO(humper): Make this more robust, supporting things like setTypeface
inputCodeLines := strings.Split(code, "\n")
outputCodeLines := []string{"DECLARE_bool(portableFonts);", fmt.Sprintf("// WxH: %d, %d", width, height)}
outputCodeLines := []string{
"DECLARE_bool(portableFonts);",
fmt.Sprintf("// WxH: %d, %d", width, height),
fmt.Sprintf("// GPU: %v", gpu),
}
for _, line := range inputCodeLines {
outputCodeLines = append(outputCodeLines, line)
if strings.HasPrefix(strings.TrimSpace(line), "SkPaint p") {
@ -465,15 +472,15 @@ func reportTryError(w http.ResponseWriter, r *http.Request, err error, message,
w.Write(resp)
}
func writeToDatabase(hash string, code string, workspaceName string, source int, width, height int) {
func writeToDatabase(hash string, code string, workspaceName string, source int, width, height int, gpu bool) {
if db == nil {
return
}
if _, err := db.Exec("INSERT INTO webtry (code, hash, width, height, source_image_id) VALUES(?, ?, ?, ?, ?)", code, hash, width, height, source); err != nil {
if _, err := db.Exec("INSERT INTO webtry (code, hash, width, height, gpu, source_image_id) VALUES(?, ?, ?, ?, ?, ?)", code, hash, width, height, gpu, source); err != nil {
log.Printf("ERROR: Failed to insert code into database: %q\n", err)
}
if workspaceName != "" {
if _, err := db.Exec("INSERT INTO workspacetry (name, hash, width, height, source_image_id) VALUES(?, ?, ?, ?, ?)", workspaceName, hash, width, height, source); err != nil {
if _, err := db.Exec("INSERT INTO workspacetry (name, hash, width, height, gpu, source_image_id) VALUES(?, ?, ?, ?, ?, ?)", workspaceName, hash, width, height, gpu, source); err != nil {
log.Printf("ERROR: Failed to insert into workspacetry table: %q\n", err)
}
}
@ -616,6 +623,7 @@ type Workspace struct {
Width int
Height int
Source int
GPU bool
Tries []Try
Titlebar Titlebar
}
@ -637,16 +645,17 @@ func newWorkspace() (string, error) {
}
// getCode returns the code for a given hash, or the empty string if not found.
func getCode(hash string) (string, int, int, int, error) {
func getCode(hash string) (string, int, int, int, bool, error) {
code := ""
width := 0
height := 0
source := 0
if err := db.QueryRow("SELECT code, width, height, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &source); err != nil {
gpu := false
if err := db.QueryRow("SELECT code, width, height, gpu, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &gpu, &source); err != nil {
log.Printf("ERROR: Code for hash is missing: %q\n", err)
return code, width, height, source, err
return code, width, height, source, gpu, err
}
return code, width, height, source, nil
return code, width, height, source, gpu, nil
}
func workspaceHandler(w http.ResponseWriter, r *http.Request) {
@ -678,16 +687,17 @@ func workspaceHandler(w http.ResponseWriter, r *http.Request) {
var width int
var height int
source := 0
gpu := false
if len(tries) == 0 {
code = DEFAULT_SAMPLE
width = 256
height = 256
} else {
hash = tries[len(tries)-1].Hash
code, width, height, source, _ = getCode(hash)
code, width, height, source, gpu, _ = getCode(hash)
}
w.Header().Set("Content-Type", "text/html")
if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, Code: code, Name: name, Hash: hash, Width: width, Height: height, Source: source, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, Code: code, Name: name, Hash: hash, Width: width, Height: height, GPU: gpu, Source: source, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
log.Printf("ERROR: Failed to expand template: %q\n", err)
}
} else if r.Method == "POST" {
@ -715,6 +725,7 @@ type TryRequest struct {
Code string `json:"code"`
Width int `json:"width"`
Height int `json:"height"`
GPU bool `json:"gpu"`
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.
}
@ -737,14 +748,14 @@ func iframeHandler(w http.ResponseWriter, r *http.Request) {
return
}
var code string
code, width, height, source, err := getCode(hash)
code, width, height, source, gpu, err := getCode(hash)
if err != nil {
http.NotFound(w, r)
return
}
// Expand the template.
w.Header().Set("Content-Type", "text/html")
if err := iframeTemplate.Execute(w, userCode{Code: code, Width: width, Height: height, Hash: hash, Source: source}); err != nil {
if err := iframeTemplate.Execute(w, userCode{Code: code, Width: width, Height: height, GPU: gpu, Hash: hash, Source: source}); err != nil {
log.Printf("ERROR: Failed to expand template: %q\n", err)
}
}
@ -754,6 +765,7 @@ type TryInfo struct {
Code string `json:"code"`
Width int `json:"width"`
Height int `json:"height"`
GPU bool `json:"gpu"`
Source int `json:"source"`
}
@ -770,7 +782,7 @@ func tryInfoHandler(w http.ResponseWriter, r *http.Request) {
return
}
hash := match[1]
code, width, height, source, err := getCode(hash)
code, width, height, source, gpu, err := getCode(hash)
if err != nil {
http.NotFound(w, r)
return
@ -780,6 +792,7 @@ func tryInfoHandler(w http.ResponseWriter, r *http.Request) {
Code: code,
Width: width,
Height: height,
GPU: gpu,
Source: source,
}
resp, err := json.Marshal(m)
@ -806,6 +819,7 @@ func mainHandler(w http.ResponseWriter, r *http.Request) {
source := 0
width := 256
height := 256
gpu := false
match := directLink.FindStringSubmatch(r.URL.Path)
var hash string
if len(match) == 2 && r.URL.Path != "/" {
@ -815,14 +829,14 @@ func mainHandler(w http.ResponseWriter, r *http.Request) {
return
}
// Update 'code' with the code found in the database.
if err := db.QueryRow("SELECT code, width, height, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &source); err != nil {
if err := db.QueryRow("SELECT code, width, height, gpu, source_image_id FROM webtry WHERE hash=?", hash).Scan(&code, &width, &height, &gpu, &source); err != nil {
http.NotFound(w, r)
return
}
}
// Expand the template.
w.Header().Set("Content-Type", "text/html")
if err := indexTemplate.Execute(w, userCode{Code: code, Hash: hash, Source: source, Width: width, Height: height, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
if err := indexTemplate.Execute(w, userCode{Code: code, Hash: hash, Source: source, Width: width, Height: height, GPU: gpu, Titlebar: Titlebar{GitHash: gitHash, GitInfo: gitInfo}}); err != nil {
log.Printf("ERROR: Failed to expand template: %q\n", err)
}
} else if r.Method == "POST" {
@ -848,18 +862,21 @@ func mainHandler(w http.ResponseWriter, r *http.Request) {
reportTryError(w, r, err, "Preprocessor macros aren't allowed.", "")
return
}
hash, err := expandCode(LineNumbers(request.Code), request.Source, request.Width, request.Height)
hash, err := expandCode(LineNumbers(request.Code), request.Source, request.Width, request.Height, request.GPU)
if err != nil {
reportTryError(w, r, err, "Failed to write the code to compile.", hash)
return
}
writeToDatabase(hash, request.Code, request.Name, request.Source, request.Width, request.Height)
writeToDatabase(hash, request.Code, request.Name, request.Source, request.Width, request.Height, request.GPU)
err = expandGyp(hash)
if err != nil {
reportTryError(w, r, err, "Failed to write the gyp file.", hash)
return
}
cmd := fmt.Sprintf("scripts/fiddle_wrapper %s --width %d --height %d", hash, request.Width, request.Height)
if request.GPU {
cmd += " --gpu"
}
if *useChroot {
cmd = "schroot -c webtry --directory=/ -- /skia_build/skia/experimental/webtry/" + cmd
}