Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(698)

Side by Side Diff: tools/skiaserve/skiaserve.cpp

Issue 1707863003: added server-side breakpoint support to skiaserve (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fixed nit Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrCaps.h" 8 #include "GrCaps.h"
9 #include "GrContextFactory.h" 9 #include "GrContextFactory.h"
10 #include "SkCanvas.h" 10 #include "SkCanvas.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 122 }
123 } 123 }
124 png_set_filter(png, 0, PNG_NO_FILTERS); 124 png_set_filter(png, 0, PNG_NO_FILTERS);
125 png_set_rows(png, info_ptr, &rows[0]); 125 png_set_rows(png, info_ptr, &rows[0]);
126 png_set_write_fn(png, &out, write_png_callback, NULL); 126 png_set_write_fn(png, &out, write_png_callback, NULL);
127 png_write_png(png, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); 127 png_write_png(png, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
128 png_destroy_write_struct(&png, NULL); 128 png_destroy_write_struct(&png, NULL);
129 sk_free(rows); 129 sk_free(rows);
130 } 130 }
131 131
132 SkBitmap* getBitmapFromCanvas(SkCanvas* canvas) {
133 SkBitmap* bmp = new SkBitmap();
134 SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kRGBA_8888_S kColorType,
135 kOpaque_SkAlphaType);
136 bmp->setInfo(info);
137 if (!canvas->readPixels(bmp, 0, 0)) {
138 fprintf(stderr, "Can't read pixels\n");
139 return nullptr;
140 }
141 return bmp;
142 }
143
132 SkData* writeCanvasToPng(SkCanvas* canvas) { 144 SkData* writeCanvasToPng(SkCanvas* canvas) {
133 // capture pixels 145 // capture pixels
134 SkBitmap bmp; 146 SkAutoTDelete<SkBitmap> bmp(getBitmapFromCanvas(canvas));
135 bmp.setInfo(canvas->imageInfo()); 147 SkASSERT(bmp);
136 if (!canvas->readPixels(&bmp, 0, 0)) {
137 fprintf(stderr, "Can't read pixels\n");
138 return nullptr;
139 }
140 148
141 // write to png 149 // write to png
142 SkDynamicMemoryWStream buffer; 150 SkDynamicMemoryWStream buffer;
143 write_png((const png_bytep) bmp.getPixels(), bmp.width(), bmp.height(), buff er); 151 write_png((const png_bytep) bmp->getPixels(), bmp->width(), bmp->height(), b uffer);
144 return buffer.copyToData(); 152 return buffer.copyToData();
145 } 153 }
146 154
147 SkCanvas* getCanvasFromRequest(Request* request) { 155 SkCanvas* getCanvasFromRequest(Request* request) {
148 GrContextFactory* factory = request->fContextFactory; 156 GrContextFactory* factory = request->fContextFactory;
149 SkGLContext* gl = factory->getContextInfo(GrContextFactory::kNative_GLContex tType, 157 SkGLContext* gl = factory->getContextInfo(GrContextFactory::kNative_GLContex tType,
150 GrContextFactory::kNone_GLContextO ptions).fGLContext; 158 GrContextFactory::kNone_GLContextO ptions).fGLContext;
151 gl->makeCurrent(); 159 gl->makeCurrent();
152 SkASSERT(request->fDebugCanvas); 160 SkASSERT(request->fDebugCanvas);
153 SkCanvas* target = request->fSurface->getCanvas(); 161 SkCanvas* target = request->fSurface->getCanvas();
154 return target; 162 return target;
155 } 163 }
156 164
157 SkData* setupAndDrawToCanvasReturnPng(Request* request, int n) { 165 void drawToCanvas(Request* request, int n) {
158 SkCanvas* target = getCanvasFromRequest(request); 166 SkCanvas* target = getCanvasFromRequest(request);
159 request->fDebugCanvas->drawTo(target, n); 167 request->fDebugCanvas->drawTo(target, n);
160 return writeCanvasToPng(target); 168 }
169
170 SkData* drawToPng(Request* request, int n) {
171 drawToCanvas(request, n);
172 return writeCanvasToPng(getCanvasFromRequest(request));
161 } 173 }
162 174
163 SkSurface* setupCpuSurface() { 175 SkSurface* setupCpuSurface() {
164 SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kN32_SkColor Type, 176 SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kN32_SkColor Type,
165 kPremul_SkAlphaType); 177 kPremul_SkAlphaType);
166 return SkSurface::NewRaster(info); 178 return SkSurface::NewRaster(info);
167 } 179 }
168 180
169 static const size_t kBufferSize = 1024; 181 static const size_t kBufferSize = 1024;
170 182
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 } 330 }
319 331
320 int n; 332 int n;
321 // /img or /img/N 333 // /img or /img/N
322 if (commands.count() == 1) { 334 if (commands.count() == 1) {
323 n = request->fDebugCanvas->getSize() - 1; 335 n = request->fDebugCanvas->getSize() - 1;
324 } else { 336 } else {
325 sscanf(commands[1].c_str(), "%d", &n); 337 sscanf(commands[1].c_str(), "%d", &n);
326 } 338 }
327 339
328 SkAutoTUnref<SkData> data(setupAndDrawToCanvasReturnPng(request, n)); 340 SkAutoTUnref<SkData> data(drawToPng(request, n));
329 return SendData(connection, data, "image/png"); 341 return SendData(connection, data, "image/png");
330 } 342 }
331 }; 343 };
332 344
345 class BreakHandler : public UrlHandler {
346 public:
347 bool canHandle(const char* method, const char* url) override {
348 static const char* kBasePath = "/break";
349 return 0 == strcmp(method, MHD_HTTP_METHOD_GET) &&
350 0 == strncmp(url, kBasePath, strlen(kBasePath));
351 }
352
353 static SkColor GetPixel(Request* request, int x, int y) {
354 SkCanvas* canvas = getCanvasFromRequest(request);
355 canvas->flush();
356 SkAutoTDelete<SkBitmap> bitmap(getBitmapFromCanvas(canvas));
357 SkASSERT(bitmap);
358 bitmap->lockPixels();
359 uint8_t* start = ((uint8_t*) bitmap->getPixels()) + (y * kImageWidth + x ) * 4;
360 SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]);
361 bitmap->unlockPixels();
362 return result;
363 }
364
365 int handle(Request* request, MHD_Connection* connection,
366 const char* url, const char* method,
367 const char* upload_data, size_t* upload_data_size) override {
368 SkTArray<SkString> commands;
369 SkStrSplit(url, "/", &commands);
370
371 if (!request->fPicture.get() || commands.count() != 4) {
372 return MHD_NO;
373 }
374
375 // /break/<n>/<x>/<y>
376 int n;
377 sscanf(commands[1].c_str(), "%d", &n);
378 int x;
379 sscanf(commands[2].c_str(), "%d", &x);
380 int y;
381 sscanf(commands[3].c_str(), "%d", &y);
382
383 int count = request->fDebugCanvas->getSize();
384 SkASSERT(n < count);
385
386 SkCanvas* canvas = getCanvasFromRequest(request);
387 canvas->clear(SK_ColorWHITE);
388 int saveCount = canvas->save();
389 for (int i = 0; i <= n; ++i) {
390 request->fDebugCanvas->getDrawCommandAt(i)->execute(canvas);
391 }
392 SkColor target = GetPixel(request, x, y);
393 Json::Value response(Json::objectValue);
394 Json::Value startColor(Json::arrayValue);
395 startColor.append(Json::Value(SkColorGetR(target)));
396 startColor.append(Json::Value(SkColorGetG(target)));
397 startColor.append(Json::Value(SkColorGetB(target)));
398 startColor.append(Json::Value(SkColorGetA(target)));
399 response["startColor"] = startColor;
400 response["endColor"] = startColor;
401 response["endOp"] = Json::Value(n);
402 for (int i = n + 1; i < n + count; ++i) {
403 int index = i % count;
404 if (index == 0) {
405 // reset canvas for wraparound
406 canvas->restoreToCount(saveCount);
407 canvas->clear(SK_ColorWHITE);
408 saveCount = canvas->save();
409 }
410 request->fDebugCanvas->getDrawCommandAt(index)->execute(canvas);
411 SkColor current = GetPixel(request, x, y);
412 if (current != target) {
413 Json::Value endColor(Json::arrayValue);
414 endColor.append(Json::Value(SkColorGetR(current)));
415 endColor.append(Json::Value(SkColorGetG(current)));
416 endColor.append(Json::Value(SkColorGetB(current)));
417 endColor.append(Json::Value(SkColorGetA(current)));
418 response["endColor"] = endColor;
419 response["endOp"] = Json::Value(index);
420 break;
421 }
422 }
423 canvas->restoreToCount(saveCount);
424 SkDynamicMemoryWStream stream;
425 stream.writeText(Json::FastWriter().write(response).c_str());
426 SkAutoTUnref<SkData> data(stream.copyToData());
427 return SendData(connection, data, "application/json");
428 }
429 };
430
333 /** 431 /**
334 Updates the clip visualization alpha. On all subsequent /img requests, the cl ip will be drawn in 432 Updates the clip visualization alpha. On all subsequent /img requests, the cl ip will be drawn in
335 black with the specified alpha. 0 = no visible clip, 255 = fully opaque clip. 433 black with the specified alpha. 0 = no visible clip, 255 = fully opaque clip.
336 */ 434 */
337 class ClipAlphaHandler : public UrlHandler { 435 class ClipAlphaHandler : public UrlHandler {
338 public: 436 public:
339 bool canHandle(const char* method, const char* url) override { 437 bool canHandle(const char* method, const char* url) override {
340 static const char* kBasePath = "/clipAlpha/"; 438 static const char* kBasePath = "/clipAlpha/";
341 return 0 == strcmp(method, MHD_HTTP_METHOD_POST) && 439 return 0 == strcmp(method, MHD_HTTP_METHOD_POST) &&
342 0 == strncmp(url, kBasePath, strlen(kBasePath)); 440 0 == strncmp(url, kBasePath, strlen(kBasePath));
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 // Register handlers 674 // Register handlers
577 fHandlers.push_back(new RootHandler); 675 fHandlers.push_back(new RootHandler);
578 fHandlers.push_back(new PostHandler); 676 fHandlers.push_back(new PostHandler);
579 fHandlers.push_back(new ImgHandler); 677 fHandlers.push_back(new ImgHandler);
580 fHandlers.push_back(new ClipAlphaHandler); 678 fHandlers.push_back(new ClipAlphaHandler);
581 fHandlers.push_back(new CmdHandler); 679 fHandlers.push_back(new CmdHandler);
582 fHandlers.push_back(new InfoHandler); 680 fHandlers.push_back(new InfoHandler);
583 fHandlers.push_back(new DownloadHandler); 681 fHandlers.push_back(new DownloadHandler);
584 fHandlers.push_back(new DataHandler); 682 fHandlers.push_back(new DataHandler);
585 fHandlers.push_back(new FaviconHandler); 683 fHandlers.push_back(new FaviconHandler);
684 fHandlers.push_back(new BreakHandler);
586 } 685 }
587 686
588 ~UrlManager() { 687 ~UrlManager() {
589 for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; } 688 for (int i = 0; i < fHandlers.count(); i++) { delete fHandlers[i]; }
590 } 689 }
591 690
592 // This is clearly not efficient for a large number of urls and handlers 691 // This is clearly not efficient for a large number of urls and handlers
593 int invoke(Request* request, MHD_Connection* connection, const char* url, co nst char* method, 692 int invoke(Request* request, MHD_Connection* connection, const char* url, co nst char* method,
594 const char* upload_data, size_t* upload_data_size) const { 693 const char* upload_data, size_t* upload_data_size) const {
595 for (int i = 0; i < fHandlers.count(); i++) { 694 for (int i = 0; i < fHandlers.count(); i++) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 MHD_stop_daemon(daemon); 736 MHD_stop_daemon(daemon);
638 return 0; 737 return 0;
639 } 738 }
640 739
641 #if !defined SK_BUILD_FOR_IOS 740 #if !defined SK_BUILD_FOR_IOS
642 int main(int argc, char** argv) { 741 int main(int argc, char** argv) {
643 SkCommandLineFlags::Parse(argc, argv); 742 SkCommandLineFlags::Parse(argc, argv);
644 return skiaserve_main(); 743 return skiaserve_main();
645 } 744 }
646 #endif 745 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698