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:
parent
0fcfb7525f
commit
e0449cf9f4
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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)));
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user