Re-land ganesh checkbox. I needed to increase the size of the address
space available to a fiddle because linking against libGL causes the amount of memory used by a process to bloat to over 100M. Yikes. BUG=skia: Review URL: https://codereview.chromium.org/638003008
This commit is contained in:
parent
67f2d3c514
commit
54142261de
@ -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;
|
||||
@ -85,9 +88,9 @@ static void setLimits() {
|
||||
perror("setrlimit(RLIMIT_CPU)");
|
||||
}
|
||||
|
||||
// Limit to 50M of Address space.
|
||||
n.rlim_cur = 50000000;
|
||||
n.rlim_max = 50000000;
|
||||
// Limit to 150M of Address space.
|
||||
n.rlim_cur = 150000000;
|
||||
n.rlim_max = 150000000;
|
||||
if (setrlimit(RLIMIT_AS, &n)) {
|
||||
perror("setrlimit(RLIMIT_CPU)");
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -19,6 +19,7 @@
|
||||
'include_dirs': [
|
||||
'../include/config',
|
||||
'../include/core',
|
||||
'../include/gpu',
|
||||
'../tools/flags',
|
||||
'../src/core',
|
||||
],
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user