From f396442e0a544a232ef0abf561b18fbf0753d99e Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Tue, 2 Jun 2015 10:44:48 -0700 Subject: [PATCH] Implement a simple image cache for Sky in Dart. This doesn't yet do any eviction from the cache. R=abarth@chromium.org, abarth Review URL: https://codereview.chromium.org/1165753004 --- engine/core/loader/CanvasImageLoader.cpp | 7 ++--- engine/core/loader/CanvasImageLoader.h | 4 --- engine/core/loader/ImageLoader.idl | 1 - engine/core/painting/Image.idl | 4 +-- examples/raw/spinning_image.dart | 38 ++++++++++++++++++------ sdk/BUILD.gn | 1 + sdk/lib/framework/net/image_cache.dart | 33 ++++++++++++++++++++ 7 files changed, 67 insertions(+), 21 deletions(-) create mode 100644 sdk/lib/framework/net/image_cache.dart diff --git a/engine/core/loader/CanvasImageLoader.cpp b/engine/core/loader/CanvasImageLoader.cpp index 2879130d55f..fd325826a92 100644 --- a/engine/core/loader/CanvasImageLoader.cpp +++ b/engine/core/loader/CanvasImageLoader.cpp @@ -13,16 +13,13 @@ namespace blink { CanvasImageLoader::CanvasImageLoader(const String& src, PassOwnPtr callback) : callback_(callback) { // TODO(jackson): Figure out how to determine the proper base URL here - url_ = KURL(KURL(), src); + KURL url = KURL(KURL(), src); + fetcher_ = adoptPtr(new MojoFetcher(this, url)); } CanvasImageLoader::~CanvasImageLoader() { } -void CanvasImageLoader::load() { - fetcher_ = adoptPtr(new MojoFetcher(this, url_)); -} - void CanvasImageLoader::OnReceivedResponse(mojo::URLResponsePtr response) { if (response->status_code != 200) { callback_->handleEvent(nullptr); diff --git a/engine/core/loader/CanvasImageLoader.h b/engine/core/loader/CanvasImageLoader.h index 63db7656574..a8f255b0341 100644 --- a/engine/core/loader/CanvasImageLoader.h +++ b/engine/core/loader/CanvasImageLoader.h @@ -28,8 +28,6 @@ class CanvasImageLoader : public MojoFetcher::Client, } virtual ~CanvasImageLoader(); - void load(); - // MojoFetcher::Client void OnReceivedResponse(mojo::URLResponsePtr) override; @@ -43,8 +41,6 @@ class CanvasImageLoader : public MojoFetcher::Client, OwnPtr fetcher_; OwnPtr drainer_; RefPtr buffer_; - - KURL url_; OwnPtr callback_; }; diff --git a/engine/core/loader/ImageLoader.idl b/engine/core/loader/ImageLoader.idl index c4f7723958a..3bf59d3bd46 100644 --- a/engine/core/loader/ImageLoader.idl +++ b/engine/core/loader/ImageLoader.idl @@ -6,5 +6,4 @@ Constructor(DOMString src, ImageLoaderCallback callback), ImplementedAs=CanvasImageLoader, ] interface ImageLoader { - void load(); }; diff --git a/engine/core/painting/Image.idl b/engine/core/painting/Image.idl index 69fc8b35b0a..c1f79ea080e 100644 --- a/engine/core/painting/Image.idl +++ b/engine/core/painting/Image.idl @@ -6,6 +6,6 @@ Constructor(), ImplementedAs=CanvasImage, ] interface Image { - readonly attribute long width; - readonly attribute long height; + readonly attribute long width; // width in number of image pixels + readonly attribute long height; // height in number of image pixels }; diff --git a/examples/raw/spinning_image.dart b/examples/raw/spinning_image.dart index cd5339fbf01..b79162a2c01 100644 --- a/examples/raw/spinning_image.dart +++ b/examples/raw/spinning_image.dart @@ -3,10 +3,13 @@ // found in the LICENSE file. import 'dart:sky'; +import 'package:sky/framework/net/image_cache.dart' as image_cache; double timeBase = null; Image image = null; +String url1 = "https://www.dartlang.org/logos/dart-logo.png"; +String url2 = "http://i2.kym-cdn.com/photos/images/facebook/000/581/296/c09.jpg"; void beginFrame(double timeStamp) { if (timeBase == null) timeBase = timeStamp; @@ -22,15 +25,32 @@ void beginFrame(double timeStamp) { view.scheduleFrame(); } +void handleImageLoad(result) { + if (result != image) { + print("${result.width}x${result.width} image loaded!"); + image = result; + view.scheduleFrame(); + } else { + print("Existing image was loaded again"); + } +} + +bool handleEvent(Event event) { + if (event.type == "pointerdown") { + return true; + } + + if (event.type == "pointerup") { + image_cache.load(url2, handleImageLoad); + return true; + } + + return false; +} + void main() { - new ImageLoader("https://www.dartlang.org/logos/dart-logo.png", (result) { - if (result != null) { - print("${result.width}x${result.width} image loaded!"); - image = result; - view.scheduleFrame(); - } else { - print("Image failed to load"); - } - }).load(); + image_cache.load(url1, handleImageLoad); + image_cache.load(url1, handleImageLoad); + view.setEventCallback(handleEvent); view.setBeginFrameCallback(beginFrame); } diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index 981ca6466be..a0de9f50130 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -93,6 +93,7 @@ dart_pkg("sdk") { "lib/framework/fn2.dart", "lib/framework/layout.dart", "lib/framework/net/fetch.dart", + "lib/framework/net/image_cache.dart", "lib/framework/node.dart", "lib/framework/reflect.dart", "lib/framework/rendering/render_block.dart", diff --git a/sdk/lib/framework/net/image_cache.dart b/sdk/lib/framework/net/image_cache.dart new file mode 100644 index 00000000000..dcb2ac2e9d6 --- /dev/null +++ b/sdk/lib/framework/net/image_cache.dart @@ -0,0 +1,33 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:sky' as sky; +import 'dart:collection'; + +final HashMap> _pendingRequests = + new HashMap>(); + +final HashMap _completedRequests = + new HashMap(); + +void load(String url, sky.ImageLoaderCallback callback) { + sky.Image result = _completedRequests[url]; + if (result != null) { + callback(_completedRequests[url]); + return; + } + + bool newRequest = false; + _pendingRequests.putIfAbsent(url, () { + newRequest = true; + return new List(); + }).add(callback); + if (newRequest) { + new sky.ImageLoader(url, (image) { + _completedRequests[url] = image; + _pendingRequests[url].forEach((c) => c(image)); + _pendingRequests.remove(url); + }); + } +}