Fix up picture clip bounds in SkiaServe

BUG=skia:5067
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1781653002

Review URL: https://codereview.chromium.org/1781653002
This commit is contained in:
joshualitt 2016-03-09 10:07:02 -08:00 committed by Commit bot
parent 0fcfb7525f
commit e0449cf9f4
5 changed files with 54 additions and 49 deletions

View File

@ -9,8 +9,8 @@
#include "png.h" #include "png.h"
const int Request::kImageWidth = 1920; #include "SkPictureRecorder.h"
const int Request::kImageHeight = 1080; #include "SkPixelSerializer.h"
static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) { static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr); SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
@ -55,13 +55,13 @@ Request::Request(SkString rootUrl)
// create surface // create surface
GrContextOptions grContextOpts; GrContextOptions grContextOpts;
fContextFactory.reset(new GrContextFactory(grContextOpts)); fContextFactory.reset(new GrContextFactory(grContextOpts));
fSurface.reset(this->createCPUSurface());
} }
SkBitmap* Request::getBitmapFromCanvas(SkCanvas* canvas) { SkBitmap* Request::getBitmapFromCanvas(SkCanvas* canvas) {
SkBitmap* bmp = new SkBitmap(); SkBitmap* bmp = new SkBitmap();
SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kRGBA_8888_SkColorType, SkIRect bounds = fPicture->cullRect().roundOut();
kOpaque_SkAlphaType); SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(),
kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
bmp->setInfo(info); bmp->setInfo(info);
if (!canvas->readPixels(bmp, 0, 0)) { if (!canvas->readPixels(bmp, 0, 0)) {
fprintf(stderr, "Can't read pixels\n"); fprintf(stderr, "Can't read pixels\n");
@ -72,7 +72,7 @@ SkBitmap* Request::getBitmapFromCanvas(SkCanvas* canvas) {
SkData* Request::writeCanvasToPng(SkCanvas* canvas) { SkData* Request::writeCanvasToPng(SkCanvas* canvas) {
// capture pixels // capture pixels
SkAutoTDelete<SkBitmap> bmp(getBitmapFromCanvas(canvas)); SkAutoTDelete<SkBitmap> bmp(this->getBitmapFromCanvas(canvas));
SkASSERT(bmp); SkASSERT(bmp);
// write to png // write to png
@ -87,6 +87,11 @@ SkCanvas* Request::getCanvas() {
GrContextFactory::kNone_GLContextOptions).fGLContext; GrContextFactory::kNone_GLContextOptions).fGLContext;
gl->makeCurrent(); gl->makeCurrent();
SkASSERT(fDebugCanvas); SkASSERT(fDebugCanvas);
// create the appropriate surface if necessary
if (!fSurface) {
this->enableGPU(fGPUEnabled);
}
SkCanvas* target = fSurface->getCanvas(); SkCanvas* target = fSurface->getCanvas();
return target; return target;
} }
@ -101,8 +106,27 @@ SkData* Request::drawToPng(int n, int m) {
return writeCanvasToPng(this->getCanvas()); return writeCanvasToPng(this->getCanvas());
} }
SkData* Request::writeOutSkp() {
// Playback into picture recorder
SkIRect bounds = fPicture->cullRect().roundOut();
SkPictureRecorder recorder;
SkCanvas* canvas = recorder.beginRecording(bounds.width(), bounds.height());
fDebugCanvas->draw(canvas);
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
SkDynamicMemoryWStream outStream;
SkAutoTUnref<SkPixelSerializer> serializer(SkImageEncoder::CreatePixelSerializer());
picture->serialize(&outStream, serializer);
return outStream.copyToData();
}
SkSurface* Request::createCPUSurface() { SkSurface* Request::createCPUSurface() {
SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kN32_SkColorType, SkIRect bounds = fPicture->cullRect().roundOut();
SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), kN32_SkColorType,
kPremul_SkAlphaType); kPremul_SkAlphaType);
return SkSurface::NewRaster(info); return SkSurface::NewRaster(info);
} }
@ -110,9 +134,8 @@ SkSurface* Request::createCPUSurface() {
SkSurface* Request::createGPUSurface() { SkSurface* Request::createGPUSurface() {
GrContext* context = fContextFactory->get(GrContextFactory::kNative_GLContextType, GrContext* context = fContextFactory->get(GrContextFactory::kNative_GLContextType,
GrContextFactory::kNone_GLContextOptions); GrContextFactory::kNone_GLContextOptions);
int maxRTSize = context->caps()->maxRenderTargetSize(); SkIRect bounds = fPicture->cullRect().roundOut();
SkImageInfo info = SkImageInfo::Make(SkTMin(kImageWidth, maxRTSize), SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(),
SkTMin(kImageHeight, maxRTSize),
kN32_SkColorType, kPremul_SkAlphaType); kN32_SkColorType, kPremul_SkAlphaType);
uint32_t flags = 0; uint32_t flags = 0;
SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
@ -145,7 +168,8 @@ bool Request::initPictureFromStream(SkStream* stream) {
} }
// pour picture into debug canvas // pour picture into debug canvas
fDebugCanvas.reset(new SkDebugCanvas(kImageWidth, Request::kImageHeight)); SkIRect bounds = fPicture->cullRect().roundOut();
fDebugCanvas.reset(new SkDebugCanvas(bounds.width(), bounds.height()));
fDebugCanvas->drawPicture(fPicture); fDebugCanvas->drawPicture(fPicture);
// for some reason we need to 'flush' the debug canvas by drawing all of the ops // for some reason we need to 'flush' the debug canvas by drawing all of the ops
@ -235,3 +259,16 @@ SkData* Request::getJsonInfo(int n) {
// We don't want the null terminator so strlen is correct // We don't want the null terminator so strlen is correct
return SkData::NewWithCopy(json.c_str(), strlen(json.c_str())); return SkData::NewWithCopy(json.c_str(), strlen(json.c_str()));
} }
SkColor Request::getPixel(int x, int y) {
SkCanvas* canvas = this->getCanvas();
canvas->flush();
SkAutoTDelete<SkBitmap> bitmap(this->getBitmapFromCanvas(canvas));
SkASSERT(bitmap);
bitmap->lockPixels();
uint8_t* start = ((uint8_t*) bitmap->getPixels()) + (y * bitmap->width() + x) * 4;
SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]);
bitmap->unlockPixels();
return result;
}

View File

@ -31,6 +31,7 @@ struct Request {
// draws to skia draw op N, highlighting the Mth batch(-1 means no highlight) // draws to skia draw op N, highlighting the Mth batch(-1 means no highlight)
SkData* drawToPng(int n, int m = -1); SkData* drawToPng(int n, int m = -1);
SkData* writeOutSkp();
SkCanvas* getCanvas(); SkCanvas* getCanvas();
SkBitmap* getBitmapFromCanvas(SkCanvas* canvas); SkBitmap* getBitmapFromCanvas(SkCanvas* canvas);
bool enableGPU(bool enable); bool enableGPU(bool enable);
@ -48,9 +49,8 @@ struct Request {
// Returns json with the viewMatrix and clipRect // Returns json with the viewMatrix and clipRect
SkData* getJsonInfo(int n); SkData* getJsonInfo(int n);
// TODO probably want to make this configurable // returns the color of the pixel at (x,y) in the canvas
static const int kImageWidth; SkColor getPixel(int x, int y);
static const int kImageHeight;
UploadContext* fUploadContext; UploadContext* fUploadContext;
SkAutoTUnref<SkDebugCanvas> fDebugCanvas; SkAutoTUnref<SkDebugCanvas> fDebugCanvas;

View File

@ -19,19 +19,6 @@ bool BreakHandler::canHandle(const char* method, const char* url) {
0 == strncmp(url, kBasePath, strlen(kBasePath)); 0 == strncmp(url, kBasePath, strlen(kBasePath));
} }
SkColor BreakHandler::GetPixel(Request* request, int x, int y) {
SkCanvas* canvas = request->getCanvas();
canvas->flush();
SkAutoTDelete<SkBitmap> bitmap(request->getBitmapFromCanvas(canvas));
SkASSERT(bitmap);
bitmap->lockPixels();
uint8_t* start = ((uint8_t*) bitmap->getPixels()) + (y * Request::kImageWidth + x) * 4;
SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]);
bitmap->unlockPixels();
return result;
}
int BreakHandler::handle(Request* request, MHD_Connection* connection, int BreakHandler::handle(Request* request, MHD_Connection* connection,
const char* url, const char* method, const char* url, const char* method,
const char* upload_data, size_t* upload_data_size) { const char* upload_data, size_t* upload_data_size) {
@ -59,7 +46,7 @@ int BreakHandler::handle(Request* request, MHD_Connection* connection,
for (int i = 0; i <= n; ++i) { for (int i = 0; i <= n; ++i) {
request->fDebugCanvas->getDrawCommandAt(i)->execute(canvas); request->fDebugCanvas->getDrawCommandAt(i)->execute(canvas);
} }
SkColor target = GetPixel(request, x, y); SkColor target = request->getPixel(x, y);
Json::Value response(Json::objectValue); Json::Value response(Json::objectValue);
Json::Value startColor(Json::arrayValue); Json::Value startColor(Json::arrayValue);
startColor.append(Json::Value(SkColorGetR(target))); startColor.append(Json::Value(SkColorGetR(target)));
@ -78,7 +65,7 @@ int BreakHandler::handle(Request* request, MHD_Connection* connection,
saveCount = canvas->save(); saveCount = canvas->save();
} }
request->fDebugCanvas->getDrawCommandAt(index)->execute(canvas); request->fDebugCanvas->getDrawCommandAt(index)->execute(canvas);
SkColor current = GetPixel(request, x, y); SkColor current = request->getPixel(x, y);
if (current != target) { if (current != target) {
Json::Value endColor(Json::arrayValue); Json::Value endColor(Json::arrayValue);
endColor.append(Json::Value(SkColorGetR(current))); endColor.append(Json::Value(SkColorGetR(current)));

View File

@ -8,8 +8,6 @@
#include "UrlHandler.h" #include "UrlHandler.h"
#include "microhttpd.h" #include "microhttpd.h"
#include "SkPictureRecorder.h"
#include "SkPixelSerializer.h"
#include "../Request.h" #include "../Request.h"
#include "../Response.h" #include "../Response.h"
@ -27,22 +25,7 @@ int DownloadHandler::handle(Request* request, MHD_Connection* connection,
return MHD_NO; return MHD_NO;
} }
// TODO move to a function SkAutoTUnref<SkData> data(request->writeOutSkp());
// Playback into picture recorder
SkPictureRecorder recorder;
SkCanvas* canvas = recorder.beginRecording(Request::kImageWidth,
Request::kImageHeight);
request->fDebugCanvas->draw(canvas);
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
SkDynamicMemoryWStream outStream;
SkAutoTUnref<SkPixelSerializer> serializer(SkImageEncoder::CreatePixelSerializer());
picture->serialize(&outStream, serializer);
SkAutoTUnref<SkData> data(outStream.copyToData());
// TODO fancier name handling // TODO fancier name handling
return SendData(connection, data, "application/octet-stream", true, return SendData(connection, data, "application/octet-stream", true,

View File

@ -41,8 +41,6 @@ public:
int handle(Request* request, MHD_Connection* connection, int handle(Request* request, MHD_Connection* connection,
const char* url, const char* method, const char* url, const char* method,
const char* upload_data, size_t* upload_data_size) override; const char* upload_data, size_t* upload_data_size) override;
private:
static SkColor GetPixel(Request* request, int x, int y);
}; };
/** /**