diff options
author | Jonathan Dixon <joth@google.com> | 2013-07-24 19:34:44 -0700 |
---|---|---|
committer | Jonathan Dixon <joth@google.com> | 2013-08-10 21:54:53 -0700 |
commit | 5c324e7af9e99afec4caf6cd48aecf2d1a596b28 (patch) | |
tree | cf223a3f3c8383bab617c962a371c58caa3354cd /chromium/plat_support | |
parent | d0b852900b559eabbeaa2136d69c89b68f59f449 (diff) | |
download | webview-5c324e7af9e99afec4caf6cd48aecf2d1a596b28.tar.gz |
Use new config and clip representation
Follow up to https://codereview.chromium.org/20234002/ to fill in the
new clip and config representations.
Change-Id: I081d1eb3ffa0454340caa67389f98bd61b2b2d29
Diffstat (limited to 'chromium/plat_support')
-rw-r--r-- | chromium/plat_support/graphics_utils.cpp | 117 |
1 files changed, 93 insertions, 24 deletions
diff --git a/chromium/plat_support/graphics_utils.cpp b/chromium/plat_support/graphics_utils.cpp index 4dc2966..6b0c38d 100644 --- a/chromium/plat_support/graphics_utils.cpp +++ b/chromium/plat_support/graphics_utils.cpp @@ -25,6 +25,8 @@ #include <cstdlib> #include <jni.h> #include <utils/Log.h> +#include <utils/UniquePtr.h> +#include <utils/Vector.h> #include "graphic_buffer_impl.h" #include "GraphicsJNI.h" #include "SkGraphics.h" @@ -35,30 +37,82 @@ namespace android { namespace { -struct PixelInfo : public AwPixelInfo { - PixelInfo(const SkBitmap* bitmap) - : bitmap_(bitmap) { - this->bitmap_->lockPixels(); - } - ~PixelInfo() { - this->bitmap_->unlockPixels(); - free(clip_region); - }; +class PixelInfo : public AwPixelInfo { + public: + PixelInfo(SkCanvas* canvas, const SkBitmap* bitmap); + ~PixelInfo(); + + void AddRectToClip(const SkIRect& rect); + + private: const SkBitmap* bitmap_; + SkAutoLockPixels bitmap_locker_; + Vector<int> clip_rect_storage_; }; -AwPixelInfo* GetPixels(JNIEnv* env, jobject java_canvas) { - SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, java_canvas); - if (!canvas) return NULL; +class ClipValidator : public SkCanvas::ClipVisitor { + public: + ClipValidator() : failed_(false) {} + bool failed() { return failed_; } + + // ClipVisitor + virtual void clipRect(const SkRect& rect, SkRegion::Op op, bool antialias) { + failed_ |= antialias; + } + + virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) { + failed_ |= antialias; + } + + private: + bool failed_; +}; + + +PixelInfo::PixelInfo(SkCanvas* canvas, const SkBitmap* bitmap) + : bitmap_(bitmap), + bitmap_locker_(*bitmap) {} + +PixelInfo::~PixelInfo() {} + +void PixelInfo::AddRectToClip(const SkIRect& rect) { + ALOG_ASSERT(rect.width() >= 0 && rect.height() >= 0); + clip_rect_storage_.push_back(rect.x()); + clip_rect_storage_.push_back(rect.y()); + clip_rect_storage_.push_back(rect.width()); + clip_rect_storage_.push_back(rect.height()); + clip_rects = const_cast<int*>(clip_rect_storage_.array()); + clip_rect_count = clip_rect_storage_.size() / 4; +} + +PixelInfo* TryToCreatePixelInfo(SkCanvas* canvas) { + // Check the clip can decompose into simple rectangles. This validator is + // not a perfect guarantee, but it's the closest I can do with the current + // API. TODO: compile this out in release builds as currently Java canvases + // do not allow for antialiased clip. + ClipValidator validator; + canvas->replayClips(&validator); + if (validator.failed()) + return NULL; + SkCanvas::LayerIter layer(SkCanvas::LayerIter(canvas, false)); - if (layer.done()) return NULL; + if (layer.done()) + return NULL; SkDevice* device = layer.device(); - if (!device) return NULL; + if (!device) + return NULL; const SkBitmap* bitmap = &device->accessBitmap(true); - if (!bitmap->lockPixelsAreWritable()) return NULL; + if (!bitmap->lockPixelsAreWritable()) + return NULL; + + UniquePtr<PixelInfo> pixels(new PixelInfo(canvas, bitmap)); + pixels->config = + bitmap->config() == SkBitmap::kARGB_8888_Config ? AwConfig_ARGB_8888 : + bitmap->config() == SkBitmap::kARGB_4444_Config ? AwConfig_ARGB_4444 : + bitmap->config() == SkBitmap::kRGB_565_Config ? AwConfig_RGB_565 : -1; + if (pixels->config < 0) + return NULL; - PixelInfo* pixels = new PixelInfo(bitmap); - pixels->config = bitmap->config(); pixels->width = bitmap->width(); pixels->height = bitmap->height(); pixels->row_bytes = bitmap->rowBytes(); @@ -68,20 +122,35 @@ AwPixelInfo* GetPixels(JNIEnv* env, jobject java_canvas) { pixels->matrix[i] = matrix.get(i); } + pixels->clip_rects = NULL; + pixels->clip_rect_count = 0; const SkRegion& region = layer.clip(); - pixels->clip_region = NULL; - pixels->clip_region_size = region.writeToMemory(NULL); - if (pixels->clip_region_size) { - pixels->clip_region = malloc(pixels->clip_region_size); - size_t written = region.writeToMemory(pixels->clip_region); - ALOG_ASSERT(written == pixels->clip_region_size); + if (region.isEmpty()) { + pixels->AddRectToClip(region.getBounds()); + } else { + SkRegion::Iterator clip_iterator(region); + for (; !clip_iterator.done(); clip_iterator.next()) { + pixels->AddRectToClip(clip_iterator.rect()); + } } + // TODO: Remove these when chromium no longer reads them + pixels->clip_region = NULL; + pixels->clip_region_size = 0; + // WebViewClassic used the DrawFilter for its own purposes (e.g. disabling // dithering when zooming/scrolling) so for now at least, just ignore any // client supplied DrawFilter. ALOGW_IF(canvas->getDrawFilter(), "DrawFilter not supported in webviewchromium, will be ignored"); - return pixels; + return pixels.release(); +} + +AwPixelInfo* GetPixels(JNIEnv* env, jobject java_canvas) { + SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, java_canvas); + if (!canvas) + return NULL; + + return TryToCreatePixelInfo(canvas); } void ReleasePixels(AwPixelInfo* pixels) { |