OLD | NEW |
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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 MHD_PostProcessor* fPostProcessor; | 65 MHD_PostProcessor* fPostProcessor; |
66 MHD_Connection* connection; | 66 MHD_Connection* connection; |
67 }; | 67 }; |
68 | 68 |
69 struct Request { | 69 struct Request { |
70 Request(SkString rootUrl) : fUploadContext(nullptr), fUrlDataManager(rootUrl
) {} | 70 Request(SkString rootUrl) : fUploadContext(nullptr), fUrlDataManager(rootUrl
) {} |
71 UploadContext* fUploadContext; | 71 UploadContext* fUploadContext; |
72 SkAutoTUnref<SkPicture> fPicture; | 72 SkAutoTUnref<SkPicture> fPicture; |
73 SkAutoTUnref<SkDebugCanvas> fDebugCanvas; | 73 SkAutoTUnref<SkDebugCanvas> fDebugCanvas; |
74 SkAutoTDelete<GrContextFactory> fContextFactory; | 74 SkAutoTDelete<GrContextFactory> fContextFactory; |
75 SkAutoTUnref<SkSurface> fSurface; | 75 SkAutoTDelete<SkBitmap> fBitmap; |
76 UrlDataManager fUrlDataManager; | 76 UrlDataManager fUrlDataManager; |
77 }; | 77 }; |
78 | 78 |
79 // TODO factor this out into functions, also handle CPU path | 79 // TODO factor this out into functions, also handle CPU path |
80 SkSurface* setupSurface(GrContextFactory* factory) { | 80 SkSurface* setupSurface(GrContextFactory* factory) { |
81 GrContext* context = factory->get(GrContextFactory::kNative_GLContextType, | 81 GrContext* context = factory->get(GrContextFactory::kNative_GLContextType, |
82 GrContextFactory::kNone_GLContextOptions); | 82 GrContextFactory::kNone_GLContextOptions); |
83 int maxRTSize = context->caps()->maxRenderTargetSize(); | 83 int maxRTSize = context->caps()->maxRenderTargetSize(); |
84 SkImageInfo info = SkImageInfo::Make(SkTMin(kImageWidth, maxRTSize), | 84 SkImageInfo info = SkImageInfo::Make(SkTMin(kImageWidth, maxRTSize), |
85 SkTMin(kImageHeight, maxRTSize), | 85 SkTMin(kImageHeight, maxRTSize), |
(...skipping 13 matching lines...) Expand all Loading... |
99 } | 99 } |
100 | 100 |
101 static void write_png(const png_bytep rgba, png_uint_32 width, png_uint_32 heigh
t, SkWStream& out) { | 101 static void write_png(const png_bytep rgba, png_uint_32 width, png_uint_32 heigh
t, SkWStream& out) { |
102 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
NULL); | 102 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
NULL); |
103 SkASSERT(png != nullptr); | 103 SkASSERT(png != nullptr); |
104 png_infop info_ptr = png_create_info_struct(png); | 104 png_infop info_ptr = png_create_info_struct(png); |
105 SkASSERT(info_ptr != nullptr); | 105 SkASSERT(info_ptr != nullptr); |
106 if (setjmp(png_jmpbuf(png))) { | 106 if (setjmp(png_jmpbuf(png))) { |
107 SkFAIL("png encode error"); | 107 SkFAIL("png encode error"); |
108 } | 108 } |
109 png_set_IHDR(png, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGBA, PNG_INTER
LACE_NONE, | 109 png_set_IHDR(png, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERL
ACE_NONE, |
110 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); | 110 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); |
111 png_set_compression_level(png, 1); | 111 png_set_compression_level(png, 1); |
112 png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*)); | 112 png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*)); |
| 113 png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 3); |
113 for (png_size_t y = 0; y < height; ++y) { | 114 for (png_size_t y = 0; y < height; ++y) { |
114 rows[y] = (png_bytep) rgba + y * width * 4; | 115 const png_bytep src = rgba + y * width * 4; |
| 116 rows[y] = pixels + y * width * 3; |
| 117 // convert from RGBA to RGB |
| 118 for (png_size_t x = 0; x < width; ++x) { |
| 119 rows[y][x * 3] = src[x * 4]; |
| 120 rows[y][x * 3 + 1] = src[x * 4 + 1]; |
| 121 rows[y][x * 3 + 2] = src[x * 4 + 2]; |
| 122 } |
115 } | 123 } |
116 png_set_filter(png, 0, PNG_NO_FILTERS); | 124 png_set_filter(png, 0, PNG_NO_FILTERS); |
117 png_set_rows(png, info_ptr, &rows[0]); | 125 png_set_rows(png, info_ptr, &rows[0]); |
118 png_set_write_fn(png, &out, write_png_callback, NULL); | 126 png_set_write_fn(png, &out, write_png_callback, NULL); |
119 png_write_png(png, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); | 127 png_write_png(png, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); |
120 png_destroy_write_struct(&png, NULL); | 128 png_destroy_write_struct(&png, NULL); |
121 sk_free(rows); | 129 sk_free(rows); |
122 } | 130 } |
123 | 131 |
124 SkData* writeCanvasToPng(SkCanvas* canvas) { | 132 SkData* writeBitmapToPng(SkBitmap& bmp) { |
125 // capture pixels | |
126 SkBitmap bmp; | |
127 bmp.setInfo(canvas->imageInfo()); | |
128 if (!canvas->readPixels(&bmp, 0, 0)) { | |
129 fprintf(stderr, "Can't read pixels\n"); | |
130 return nullptr; | |
131 } | |
132 | |
133 // write to png | 133 // write to png |
134 SkDynamicMemoryWStream buffer; | 134 SkDynamicMemoryWStream buffer; |
135 write_png((const png_bytep) bmp.getPixels(), bmp.width(), bmp.height(), buff
er); | 135 write_png((const png_bytep) bmp.getPixels(), bmp.width(), bmp.height(), buff
er); |
136 return buffer.copyToData(); | 136 return buffer.copyToData(); |
137 } | 137 } |
138 | 138 |
139 SkData* setupAndDrawToCanvasReturnPng(Request* request, int n) { | 139 SkData* setupAndDrawToCanvasReturnPng(Request* request, int n) { |
140 GrContextFactory* factory = request->fContextFactory; | 140 GrContextFactory* factory = request->fContextFactory; |
141 SkGLContext* gl = factory->getContextInfo(GrContextFactory::kNative_GLContex
tType, | 141 SkGLContext* gl = factory->getContextInfo(GrContextFactory::kNative_GLContex
tType, |
142 GrContextFactory::kNone_GLContextO
ptions).fGLContext; | 142 GrContextFactory::kNone_GLContextO
ptions).fGLContext; |
143 gl->makeCurrent(); | 143 gl->makeCurrent(); |
144 SkASSERT(request->fDebugCanvas); | 144 SkASSERT(request->fDebugCanvas); |
145 SkCanvas* target = request->fSurface->getCanvas(); | 145 SkCanvas target(*request->fBitmap); |
146 request->fDebugCanvas->drawTo(target, n); | 146 request->fDebugCanvas->drawTo(&target, n); |
147 return writeCanvasToPng(target); | 147 return writeBitmapToPng(*request->fBitmap); |
148 } | 148 } |
149 | 149 |
150 SkSurface* setupCpuSurface() { | 150 SkSurface* setupCpuSurface() { |
151 SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kN32_SkColor
Type, | 151 SkImageInfo info = SkImageInfo::Make(kImageWidth, kImageHeight, kN32_SkColor
Type, |
152 kPremul_SkAlphaType); | 152 kPremul_SkAlphaType); |
153 return SkSurface::NewRaster(info); | 153 return SkSurface::NewRaster(info); |
154 } | 154 } |
155 | 155 |
156 static const size_t kBufferSize = 1024; | 156 static const size_t kBufferSize = 1024; |
157 | 157 |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 request->fPicture.reset( | 387 request->fPicture.reset( |
388 SkPicture::CreateFromStream(request->fUploadContext->fStream.detachA
sStream())); | 388 SkPicture::CreateFromStream(request->fUploadContext->fStream.detachA
sStream())); |
389 if (!request->fPicture.get()) { | 389 if (!request->fPicture.get()) { |
390 fprintf(stderr, "Could not create picture from stream.\n"); | 390 fprintf(stderr, "Could not create picture from stream.\n"); |
391 return MHD_NO; | 391 return MHD_NO; |
392 } | 392 } |
393 | 393 |
394 // create surface | 394 // create surface |
395 GrContextOptions grContextOpts; | 395 GrContextOptions grContextOpts; |
396 request->fContextFactory.reset(new GrContextFactory(grContextOpts)); | 396 request->fContextFactory.reset(new GrContextFactory(grContextOpts)); |
397 request->fSurface.reset(setupSurface(request->fContextFactory.get())); | |
398 | 397 |
399 // pour picture into debug canvas | 398 // pour picture into debug canvas |
400 request->fDebugCanvas.reset(new SkDebugCanvas(kImageWidth, kImageHeight)
); | 399 request->fDebugCanvas.reset(new SkDebugCanvas(kImageWidth, kImageHeight)
); |
401 request->fDebugCanvas->drawPicture(request->fPicture); | 400 request->fDebugCanvas->drawPicture(request->fPicture); |
402 | 401 |
| 402 request->fBitmap.reset(new SkBitmap); |
| 403 SkImageInfo imageInfo = SkImageInfo::Make(kImageWidth, kImageHeight, kRG
BA_8888_SkColorType, |
| 404 kOpaque_SkAlphaType); |
| 405 request->fBitmap->allocPixels(imageInfo); |
| 406 |
403 // clear upload context | 407 // clear upload context |
404 delete request->fUploadContext; | 408 delete request->fUploadContext; |
405 request->fUploadContext = nullptr; | 409 request->fUploadContext = nullptr; |
406 | 410 |
407 return SendTemplate(connection, true, "/"); | 411 return SendTemplate(connection, true, "/"); |
408 } | 412 } |
409 }; | 413 }; |
410 | 414 |
411 class DownloadHandler : public UrlHandler { | 415 class DownloadHandler : public UrlHandler { |
412 public: | 416 public: |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 MHD_stop_daemon(daemon); | 627 MHD_stop_daemon(daemon); |
624 return 0; | 628 return 0; |
625 } | 629 } |
626 | 630 |
627 #if !defined SK_BUILD_FOR_IOS | 631 #if !defined SK_BUILD_FOR_IOS |
628 int main(int argc, char** argv) { | 632 int main(int argc, char** argv) { |
629 SkCommandLineFlags::Parse(argc, argv); | 633 SkCommandLineFlags::Parse(argc, argv); |
630 return skiaserve_main(); | 634 return skiaserve_main(); |
631 } | 635 } |
632 #endif | 636 #endif |
OLD | NEW |